From 7be5570d2120f8935257819ca7c01db2aa86b148 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Sat, 21 Oct 2023 15:52:39 +0200 Subject: [PATCH] working version --- DFGdocs.py | 151 ++++++++++++++++++++++++++----------- abschlussbericht/info.json | 17 +++-- sachbeihilfe/info.json | 17 +++-- 3 files changed, 133 insertions(+), 52 deletions(-) diff --git a/DFGdocs.py b/DFGdocs.py index d8e5e94..fb9e397 100755 --- a/DFGdocs.py +++ b/DFGdocs.py @@ -1,15 +1,10 @@ #!/usr/bin/python3 import sys +import json +import attrs import pathlib import argparse -from IPython import embed - -# The script should create a new DFG document from the templates -# It takes the template name and the name of the project. -# It copies over the needed files and replaces some information? -# dfg_header.tex, the main.tex, the makefile and the Logo -# renames the main file to the new name, updates the makefile class MyParser(argparse.ArgumentParser): def error(self, message): @@ -18,22 +13,91 @@ class MyParser(argparse.ArgumentParser): sys.exit(2) -templates = ["project", "lebenslauf", "cv", "abschlussbericht"] -version = ["53.01 - 09/22", "53.200 - 03/23", "53.200 - 03/23", "3.06 - 01/23"] -language = ["en", "de", "en", "de"] +@attrs.define +class Template(): + name: str + alias: str + language: str + version: str + author: str + brief: str + path: str + mainfile: str + files: list[str] = attrs.Factory(list) -required_files = {"project": ["header.tex", "Makefile", "DFG_logo.png", "dfg_sachbeihilfe.tex"], - "lebenslauf": ["header.tex", "Makefile", "DFG_logo.png", "lebenslauf.tex"], - "cv": ["header.tex", "Makefile", "DFG_logo.png", "cv.tex"], - "abschlussbericht": ["header.tex", "Makefile", "DFG_logo.png", "abschlussbericht.tex"] - } + def compact_info(self, col_width=25): + info = (f"\t{self.alias}{(col_width - len(self.alias)) * ' '}{self.name}{(col_width - len(self.name)) * ' '}{self.version}{(col_width - len(self.version)) * ' '}{self.language}") + return info + + def full_info(self): + print(f"{self.name} (alias {self.alias}) \t form version: {self.version}") + print(f"{self.brief}") + print(f"Language: {self.language}") + print(f"Template by: {self.author}") + print(f"Template location:{self.path}") + print(f"Template files:") + for f in self.files: + print(f'\t{f}') + + def patch_make(self, source, dest, new_name): + lines = [] + with open(source, "r") as f: + for l in f.readlines(): + if l.startswith("BASENAME"): + l = f"BASENAME={new_name}\n" + lines.append(l) + else: + lines.append(l) + with open(dest, "w") as f: + f.writelines(lines) + + def copy_files(self, destination, project_name): + dest = pathlib.Path(destination) + if dest.exists() and dest.is_dir(): + if len(list(dest.glob("*.*"))) > 0: + raise ValueError(f"Destination folder ({str(dest.absolute())}) already exists and is not empty") + dest.mkdir(exist_ok=True) + src_path = pathlib.Path(self.path) + # copy files + for f in self.files: + source_file = src_path.joinpath(f) + dest_file = dest.joinpath(f) + if f == self.mainfile: # rename main file to match project name + dest_file = dest.joinpath(source_file.with_stem(project_name).name) + dest_file.write_bytes(source_file.read_bytes()) + elif f == "Makefile": + self.patch_make(source_file, dest_file, project_name) + else: + dest_file.write_bytes(source_file.read_bytes()) -def print_templates(): +def find_templates(): + templates = {} + for file_path in pathlib.Path.cwd().glob("*"): + if pathlib.Path.is_dir(file_path): + if pathlib.Path.joinpath(file_path, "info.json").exists(): + with open(pathlib.Path.joinpath(file_path, "info.json")) as f: + data = json.load(f) + if "templates" in data: + for t in data["templates"]: + if t["alias"] in templates: + print(UserWarning(f"A template with the alias {t['alias']} already exists! Ignoring template in path {str(file_path)}.")) + continue + templates[t["alias"]] = (Template(**t, path=str(file_path))) + return templates + + +def print_templates(templates, col_width=25): print("Available templates: ") - print(f"\tname{(15*' ')}version{14*' '}language") - for t, v, l in zip(templates, version, language): - print(f"\t{t}{(20 - len(t)) * ' '}{v}{(20 - len(v)) * ' '}{l}") + print(f"\talias{(col_width - len('alias')) * ' '}name{(col_width - len('name')) * ' '}version{(col_width - len('language')) * ' '}language") + for t in templates.keys(): + print(templates[t].compact_info(col_width)) + + +def copy_template(args, templates): + t = templates.get(args.template) + if t is not None: + t.copy_files(args.destination, args.name) def create_parser(): @@ -44,41 +108,44 @@ def create_parser(): parser.add_argument("-l", "--list", action="store_true", help="List the available templates.") parser.add_argument("-d", "--destination", type=str, default=".", help="The destination folder as absolute or relative path.") + parser.add_argument("-i", "--info", action="store_true", help="More info on a specific template.") + parser.add_argument("template", nargs='?', type=str, help="The alias of the DFG document template (use -l or --list argument to get a list of templates).") parser.add_argument("name", nargs='?', type=str, help="The project name") - parser.add_argument("template", nargs='?', type=str, help="Name of the DFG document template.") return parser -def copy_template(args): - # assemble project name and destination - # check if destination folder exists - # if not, create - # if exists, check if empty - # if not empty refuse to work - # copy files - # change filename of main.tex - # change Makefile - pass - - -def main(): - parser = create_parser() - args = parser.parse_args() - +def args_check(args, parser, templates): if args.list: - print_templates() + print_templates(templates) sys.exit(0) + if args.template is None: + print(f"Error using DFGdocs. TEMPLATE argument is not defined!") + parser.print_help() + sys.exit(2) + if args.name is None: print(f"Error using DFGdocs. NAME argument is not defined!") parser.print_help() sys.exit(2) - if args.template is None: - print(f"Error using DFGdocs. TEMPLATE argument is not defined!") - print_templates() - sys.exit(2) - copy_template(args) + if args.template not in templates: + print(f"Error using DFGdocs. Template {args.template} is not defined!") + print_templates(templates) + sys.exit(0) + + if args.info and args.template is not None: + templates[args.template].full_info() + sys.exit(0) + + +def main(): + parser = create_parser() + args = parser.parse_args() + templates = find_templates() + args_check(args, parser, templates) + copy_template(args, templates) + if __name__ == "__main__": main() \ No newline at end of file diff --git a/abschlussbericht/info.json b/abschlussbericht/info.json index b393e71..8fd734a 100644 --- a/abschlussbericht/info.json +++ b/abschlussbericht/info.json @@ -1,7 +1,14 @@ { - "NAME": "Abschlussbericht", - "LANGUAGE: "de", - "VERSION": "3.06 - 01/23", - "AUTHOR": "Jan Grewe", - "BRIEF": "Template for the final project report." + "templates": [ + { + "name": "Abschlussbericht", + "alias": "reportDE", + "language": "de", + "version": "3.06 - 01/23", + "author": "Jan Grewe", + "brief": "Template for the final project report.", + "mainfile": "abschlussbericht.tex", + "files": ["header.tex", "DFG_logo.png", "Makefile", "abschlussbericht.tex"] + } + ] } \ No newline at end of file diff --git a/sachbeihilfe/info.json b/sachbeihilfe/info.json index dffa882..81eb59c 100644 --- a/sachbeihilfe/info.json +++ b/sachbeihilfe/info.json @@ -1,7 +1,14 @@ { - "NAME": "Sachbeihilfe", - "LANGUAGE: "de", - "VERSION": "53.01 - 09/22", - "AUTHOR": "Jan Grewe", - "BRIEF": "Template for grant application as Sachbeihilfe." + "templates": [ + { + "name": "Sachbeihilfe", + "alias": "projectDE", + "language": "de", + "version": "53.01 - 09/22", + "author": "Jan Grewe", + "brief": "Template for grant application as Sachbeihilfe.", + "mainfile": "sachbeihilfe.tex", + "files": ["header.tex", "DFG_logo.png", "Makefile", "sachbeihilfe.tex"] + } + ] } \ No newline at end of file