WebApp_builder/generate.py

257 lines
8.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gzip, shutil, os, errno, json, subprocess, sys, getopt
# from distutils import dir_util
from string import Template
import gitrev
__author__ = "Pavel Brychta"
__copyright__ = "Copyright (c) 2019-2023, Pavel Brychta"
__credits__ = ["Pavel Brychta"]
__license__ = "Private"
__version__ = "1.4.0"
__maintainer__ = "Pavel Brychta"
__email__ = "Pablo@xPablo.cz"
__status__ = "Beta"
PROJECT_FILE = "project.json" # soubor s popisem sestaveni projektu
project = {}
templatevars = {}
flist = None
flistcontent = ""
version = ""
# Vycisteni ciloveho adresare (bez jeho vymazu - jen vyprazdneni)
def cleanup(path):
for root, dirs, files in os.walk(path):
for f in files:
os.unlink(os.path.join(root, f))
for d in dirs:
shutil.rmtree(os.path.join(root, d), ignore_errors=True, onerror=None)
# Vytvoreni pripadne chybejici cesty
def maketree(filename):
if not os.path.exists(os.path.dirname(filename)):
try:
os.makedirs(os.path.dirname(filename))
except OSError as exc: # ochrana proti race condition
if exc.errno != errno.EEXIST:
raise
# Kopirovani adresaroveho stromu na cilove misto
def copytree(src, dst):
for item in os.listdir(src):
s = os.path.normpath(os.path.join(src, item))
d = os.path.normpath(os.path.join(dst, item))
maketree(d)
if os.path.isdir(s):
print(s + ' (D)-> ' + d)
copytree(s, d)
else:
print(s + ' (F)-> ' + d)
shutil.copy2(s, d)
# Kopirovani seznamu souboru
def copyfiles(files, ffrom, where):
for entry in files:
if "synthetic" not in entry:
inf = entry["src"]
outf = entry["dst"]
if outf == '':
outf = inf
if os.path.isdir(ffrom + inf):
copytree(ffrom + inf, where + outf)
else:
if "istemplate" in entry and entry["istemplate"]:
with open(ffrom + inf, 'r') as infile:
print(ffrom + inf + ' (T)-> ' + where + outf)
maketree(where + outf)
# https://stackoverflow.com/questions/4406102/light-weight-template-engine-for-python
form = Template(infile.read()).substitute(templatevars)
outfile = open(where + outf, 'w')
outfile.write(form)
outfile.close()
else:
with open(ffrom + inf, 'rb') as infile:
print(ffrom + inf + ' (F)-> ' + where + outf)
maketree(where + outf)
outfile = open(where + outf, 'wb')
outfile.write(infile.read())
outfile.close()
# else:
# if "istemplate" in entry and entry["istemplate"]:
# inf = entry["src"]
# with open(where + inf, 'r') as infile:
# print(where + inf + ' (ST)-> ' + where + inf)
# form = Template(infile.read()).substitute(templatevars)
# outfile = open(where + inf, 'w')
# outfile.write(form)
# outfile.close()
# Spojovani soubru
def joinfilesindir(dir, outfile):
for item in os.listdir(dir):
fn = os.path.join(dir, item)
if os.path.isfile(fn):
with open(fn, 'rb') as infile:
outfile.write(infile.read())
else:
if not fn.endswith("/"):
fn += "/"
joinfilesindir(fn, outfile)
def joinfiles(srclist, srcPath, outfName):
outfName = os.path.normpath(outfName)
maketree(outfName)
print(outfName + ' =')
with open(outfName, 'wb') as outfile:
for fname in srclist:
fname = os.path.normpath(fname)
print(' + ' + fname)
if os.path.isfile(srcPath + fname):
with open(srcPath + fname, 'rb') as infile:
outfile.write(infile.read())
else:
joinfilesindir(srcPath + fname, outfile)
outfile.close()
def copycompresstree(src, dst, compress, dirbase):
global flist
global flistcontent
for item in os.listdir(src):
s = os.path.normpath(os.path.join(src, item))
d = os.path.normpath(os.path.join(dst, item))
maketree(d)
if os.path.isdir(s):
d = os.path.normpath(os.path.join(dst, item))
print(s + ' (D)-> ' + d)
copycompresstree(s, d, compress, dirbase)
else:
dopack = 0
rpath = os.path.relpath(dst, dirbase)
if rpath == ".":
rpath = ""
else:
rpath = "/" + rpath
fignore = False
fforce = False
for entry in compress:
target = os.path.normpath(entry["src"])
if entry["dst"] != "":
target = os.path.normpath(entry["dst"])
if s.endswith(target):
if "compress" in entry and entry["compress"]:
dopack += 1
if "flistignore" in entry:
fignore = True
if "flistforce" in entry:
fforce = True
if dopack != 0:
d = os.path.normpath(os.path.join(dst, item + ".gz"))
print(s + ' (C)-> ' + d)
# packing & copying
with open(s, 'rb') as infile:
maketree(d)
outfile = gzip.open(d, 'wb')
outfile.writelines(infile)
outfile.close()
if (flist is not None) and (not fignore):
flc = item + ".gz"
if fforce:
flc += ",force"
flistcontent += rpath + "/" + flc + "\r\n"
else:
d = os.path.normpath(os.path.join(dst, item))
print(s + ' (F)-> ' + d)
shutil.copy2(s, d)
if (flist is not None) and (not fignore):
flc = item
if fforce:
flc += ",force"
flistcontent += rpath + "/" + flc + "\r\n"
# Ziskani verze repozitare z gitu
def getgitversion():
version = gitrev.version_info()
return str(version)
def main(argv):
global flist
global flistcontent
projectfile = PROJECT_FILE # default jmeno projektoveho souboru
try:
opts, args = getopt.getopt(argv, "hi:o:", ["ifile="])
except getopt.GetoptError:
print("Chyba")
sys.exit(2)
for opt, arg in opts:
if opt in ("-p", "-project"):
projectfile = arg
version = getgitversion()
datadir = None
templatevars['version'] = version
print("Web version " + version)
with open(projectfile) as fd:
project = json.load(fd)
if "templatevariables" in project:
tv = project["templatevariables"]
for entry in tv:
templatevars[entry] = tv[entry]
if "build" in project:
build = project["build"]
approotdir = build["approotdir"]
outputdir = build["outputdir"]
if "datadir" in build:
datadir = build["datadir"]
if "flist" in build:
flist = build["flist"]
# Vycistime vystupni adresare
cleanup(outputdir)
if datadir is not None:
cleanup(datadir)
# Zacneme kombinaci soubou
if "combine" in build:
combine = build["combine"]
for entry in combine:
outname = entry["name"]
items = entry["items"]
joinfiles(items, approotdir, outputdir + outname)
# Pokracujeme kopirovanim souboru/adresaru
if "copy" in build:
copy = build["copy"]
copyfiles(copy, approotdir, outputdir)
# .. a koncime prekopirovanim souboru do vystupniho adresare s prubeznou kompresi pozadovanych souboru a vytvareni flist.txt
if datadir is not None:
deploy = []
if flist is not None:
flistcontent = ":" + version + "\r\n"
if "copy" in build:
deploy = build["copy"]
copycompresstree(outputdir, datadir, deploy, datadir)
if flist is not None:
with open(os.path.normpath(os.path.join(datadir, flist)), 'wb') as outfile:
outfile.write(flistcontent.encode('ascii', 'ignore'))
outfile.close()
if __name__ == "__main__":
main(sys.argv[1:])