# Copyright Sage Vaillancourt 2021 import os import subprocess from dataclasses import dataclass from flask import send_from_directory, Response def get_unique(): import uuid unique = str(uuid.uuid1().hex) return unique def get_datetime(): from datetime import datetime now = datetime.now() return now.strftime("%Y-%m-%d %H:%M:%S") root_dir = os.path.dirname(os.getcwd()) proj_dir = root_dir + '/undercover/' output_dir = proj_dir + 'outputs/' base_tex_text = open(proj_dir + "/letter_templates/base.tex", "r").read() @dataclass class CLData: selectedLetter: int # Metadata username: str company: str jobAndPronoun: str skillTypes: str mySkills: str closingText: str body: str def get_pairs(self): return [ ("username", self.username), ("company", self.company), ("jobAndPronoun", self.jobAndPronoun), ("skillTypes", self.skillTypes), ("mySkills", self.mySkills), ("closingText", self.closingText), ("body", self.body), ] def generate_pdf(self) -> Response: """ :return: Response when successful :raise ValueError: e.args[0] is a list of error strings, if generation fails """ import threading unique_id = get_unique() unique_file = output_dir + unique_id + ".tex" f = open(unique_file, "w") for pair in self.get_pairs(): f.write("\\def \\" + pair[0] + "{" + pair[1] + "}\n") f.write(base_tex_text) f.close() output_arg = "-jobname=outputs/" + unique_id + " " + unique_file com = "pdflatex -halt-on-error " + output_arg build_text = "[" + get_datetime() + "] Building for " + unique_id + " " result = subprocess.run( ['bash', '-c', com], stdout=subprocess.PIPE, text=True ) if result.returncode == 0: print(build_text + "[SUCCESS]") result = subprocess.run( [ 'gs', '-sDEVICE=pdfwrite', '-dCompatibilityLevel=1.5', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-dPrinted=false', '-sOutputFile=outputs/' + unique_id + '.compressed.pdf', 'outputs/' + unique_id + '.pdf' ], stdout=subprocess.PIPE, text=True ) threading.Timer(60 * 5, cleanup, [output_dir + unique_id]).start() output_file = unique_id if result.returncode == 0: output_file += ".compressed.pdf" else: output_file += ".pdf" return send_from_directory( output_dir, output_file, download_name=self.username.replace(" ", "") + "_CoverLetter.pdf", as_attachment=True ) else: print(build_text + "[FAIL]") # Collect output but delete boilerplate text errors = list(map(str.strip, result.stdout.split("\n"))) del errors[:13] del errors[-2:] raise ValueError(errors) def cleanup(unique): subprocess.run(['bash', '-c', "rm " + unique + ".*"])