Prepare web server with embedded files
This commit is contained in:
164
extra_pre.py
164
extra_pre.py
@@ -0,0 +1,164 @@
|
||||
print("running extra script...")
|
||||
|
||||
import os
|
||||
import sys
|
||||
import inspect
|
||||
import gzip
|
||||
import shutil
|
||||
|
||||
Import("env")
|
||||
|
||||
GEN_DIR = 'lib/generated'
|
||||
OWN_FILE = "extra_script.py"
|
||||
|
||||
INDEXJS = "index.js"
|
||||
INDEXCSS = "index.css"
|
||||
|
||||
# embedded files definition is generated inside here
|
||||
EMBEDDED_INCLUDE="embeddedfiles.h"
|
||||
|
||||
def basePath():
|
||||
#see: https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
|
||||
return os.path.dirname(inspect.getfile(lambda: None))
|
||||
|
||||
def is_current(infile, outfile):
|
||||
if os.path.exists(outfile):
|
||||
otime = os.path.getmtime(outfile)
|
||||
itime = os.path.getmtime(infile)
|
||||
if (otime >= itime):
|
||||
own = os.path.join(basePath(), OWN_FILE)
|
||||
if os.path.exists(own):
|
||||
owntime = os.path.getmtime(own)
|
||||
if owntime > otime:
|
||||
return False
|
||||
print(f"{outfile} is newer than {infile}, no need to recreate")
|
||||
return True
|
||||
return False
|
||||
|
||||
def compress_file(infile, outfile):
|
||||
if is_current(infile, outfile):
|
||||
return
|
||||
print(f"compressing {infile}")
|
||||
with open(infile, 'rb') as f_in:
|
||||
with gzip.open(outfile, 'wb') as f_out:
|
||||
shutil.copyfileobj(f_in, f_out)
|
||||
|
||||
def write_file_if_changed(filename, data):
|
||||
"""
|
||||
Create or update file if it not contains data as content
|
||||
"""
|
||||
if os.path.exists(filename):
|
||||
changetype = 'updating'
|
||||
with open(filename, 'r') as fh:
|
||||
if fh.read() == data:
|
||||
print(f"{filename} is up to date")
|
||||
return False
|
||||
else:
|
||||
changetype = 'generating'
|
||||
print(f"#{changetype} {filename}")
|
||||
with open(filename, 'w') as fh:
|
||||
fh.write(data)
|
||||
return True
|
||||
|
||||
def get_embedded_files(env):
|
||||
filelist = []
|
||||
efiles = env.GetProjectOption("board_build.embed_files")
|
||||
for f in efiles.split("\n"):
|
||||
if f == '':
|
||||
continue
|
||||
filelist.append(f)
|
||||
return filelist
|
||||
|
||||
def get_content_type(fn):
|
||||
if (fn.endswith('.gz')):
|
||||
fn = fn[0:-3]
|
||||
if (fn.endswith('html')):
|
||||
return "text/html"
|
||||
if (fn.endswith('json')):
|
||||
return "application/json"
|
||||
if (fn.endswith('js')):
|
||||
return "text/javascript"
|
||||
if (fn.endswith('css')):
|
||||
return "text/css"
|
||||
if (fn.endswith('png')):
|
||||
return "image/png"
|
||||
if (fn.endswith('jpg') or fn.endswith('jpeg')):
|
||||
return "image/jpeg"
|
||||
return "application/octet-stream"
|
||||
|
||||
def join_files(target, filename, dirlist):
|
||||
"""
|
||||
Join files named filename within different directories
|
||||
into one single gzip archive (located in generated dir)
|
||||
"""
|
||||
print("joinfiles: {} into {} from dirs [{}]".format(filename, target, ','.join(dirlist)))
|
||||
flist = []
|
||||
for dir in dirlist:
|
||||
fn = os.path.join(dir, filename)
|
||||
if os.path.exists(fn):
|
||||
flist.append(fn)
|
||||
current = False
|
||||
if os.path.exists(target):
|
||||
current = True
|
||||
for f in flist:
|
||||
if not is_current(f, target):
|
||||
current = False
|
||||
break
|
||||
if current:
|
||||
print(f"{target} is up to date")
|
||||
return
|
||||
print(f"creating {target}")
|
||||
|
||||
# add multiple files
|
||||
with gzip.open(target, "wb") as oh:
|
||||
for fn in flist:
|
||||
print("adding {} to {}".format(fn, target))
|
||||
with open(fn, "rb") as rh:
|
||||
shutil.copyfileobj(rh, oh)
|
||||
|
||||
def prebuild(env):
|
||||
print("#prebuild running")
|
||||
|
||||
# directory for dynamically generated files
|
||||
gendir = os.path.join(basePath(), GEN_DIR)
|
||||
if not os.path.exists(gendir):
|
||||
os.makedirs(gendir)
|
||||
if not os.path.isdir(gendir):
|
||||
print("unable to create directory {}".format(gendir))
|
||||
sys.exit(1)
|
||||
|
||||
# join static web server files
|
||||
|
||||
# only useful for different task dirs with custom configs
|
||||
# join_files(os.path.join(gendir, INDEXJS+".gz"), INDEXJS, ["web"])
|
||||
# join_files(os.path.join(gendir, INDEXCSS+".gz"), INDEXCSS, ["web"])
|
||||
|
||||
# platformio defined embedded files as list
|
||||
pio_embedded = get_embedded_files(env)
|
||||
|
||||
filedefs = []
|
||||
for ef in pio_embedded:
|
||||
print(f"#checking embedded file {ef}")
|
||||
# files are defined with relative path to platformio.ini
|
||||
# the name can be with extension gz or without
|
||||
(dn, fn) = os.path.split(ef)
|
||||
pureName = fn
|
||||
if pureName.endswith('.gz'):
|
||||
pureName = pureName[0:-3]
|
||||
usname = ef.replace('/','_').replace('.','_') # sanitize filenames
|
||||
filedefs.append((pureName, usname, get_content_type(pureName)))
|
||||
infile = os.path.join(basePath(), "web", pureName)
|
||||
if os.path.exists(infile):
|
||||
compress_file(infile, ef)
|
||||
else:
|
||||
print("#WARNING: infile {infile} for {ef} not found")
|
||||
|
||||
# generate c-header file for embedding zip files
|
||||
content = ""
|
||||
for entry in filedefs:
|
||||
content += 'EMBED_GZ_FILE("{}", {}, "{}");\n'.format(*entry)
|
||||
write_file_if_changed(os.path.join(gendir, EMBEDDED_INCLUDE), content)
|
||||
|
||||
print("#prescript...")
|
||||
prebuild(env)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user