#!/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 __author__ = "Pavel Brychta" __copyright__ = "Copyright (c) 2019-2020, Pavel Brychta" __credits__ = ["Pavel Brychta"] __license__ = "Private" __version__ = "1.3.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() # 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(): isgit = True after = b"0" mod = b"" try: tag = subprocess.check_output(["git", "describe", "--tags", "--always"]).strip() except: tag = b"0.0.0" isgit = False if isgit: if tag.find(b".") < 0: tag = b"0.0.0" if tag == b"0.0.0": after = subprocess.check_output(["git", "rev-list", "--all", "--count"]).strip() else: if tag.find(b"-") > 0: taginfo = tag.split(b'-') tag = taginfo[0] after = taginfo[1] else: after = subprocess.check_output(["git", "rev-list", tag + "..HEAD", "--count"]).strip() mod = subprocess.check_output(["git", "diff-index", "HEAD"]).strip() if after == b"0": revision = tag else: revision = tag + b'.' + after if mod != b"": revision = revision + b"m" else: revision = b"0.0.0.x" return revision.decode("utf-8") 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:])