import http.server import cgi from urllib.parse import unquote, parse_qs import re import subprocess import os PORT = 8000 URL_FORMAT = re.compile( r"^(?:(?:https://)?platform\.physik\.kit\.edu/codimd/)?(?P[\w_-]+)([\?#].*)?$" ) TMP_MD = "tmp.md" TMP_PDF = "tmp.pdf" def remove_if_exists(filename): if os.path.isfile(filename): os.remove(filename) return def clean_up(): remove_if_exists(TMP_MD) remove_if_exists(TMP_PDF) return class CodiToPdfHandler(http.server.SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory="/app/html", **kwargs) return # forward get requests def do_GET(self): print(self.path) print(self.headers) super().do_GET() return def errored(self, msg): _msg = msg.encode("utf-8") self.send_response(400) self.send_header("Content-Type", "text/plain; charset=UTF-8") self.send_header("Content-Length", str(len(_msg))) self.end_headers() self.wfile.write(_msg) return def do_POST(self): try: content_length = int(self.headers["Content-Length"]) _body = self.rfile.read(content_length) body = unquote(_body.decode("ASCII")) post_data = parse_qs(body) pad = post_data["pad"][0] except: self.errored("Invalid POST request!") return try: pad_id = URL_FORMAT.match(pad).group("id") except: self.errored("Invalid format for pad id!") return try: subprocess.check_call(["codimd", "export", "--md", pad_id, TMP_MD]) assert os.path.isfile(TMP_MD) except Exception as e: if isinstance(e, subprocess.CalledProcessError): self.errored("Could not retrieve pad from address!") else: self.errored("Unknown error") print("Unknown error in codimd process:") print(e) remove_if_exists(TMP_MD) return try: subprocess.check_call( [ "pandoc", # disable yaml in markdown "-t", "latex-yaml_metadata_block", # limit to 64MiB memory "+RTS", "-M64M", "-RTS", # use a4 paper "-s", "-V", "papersize:a4", "-o", TMP_PDF, TMP_MD ] ) assert os.path.isfile(TMP_PDF) except Exception as e: if isinstance(e, subprocess.CalledProcessError): self.errored("Error while converting markdown to pdf:\n" + str(e)) else: self.errored("Unknown error") clean_up() return self.send_response(200) self.send_header("Content-Type", "application/pdf") #self.send_header("Content-Length", str(len(pdf))) self.end_headers() with open(TMP_PDF, "rb") as pdf_file: self.copyfile(pdf_file, self.wfile) clean_up() #self.wfile.write(pdf) return with http.server.ThreadingHTTPServer(("", PORT), CodiToPdfHandler) as httpd: httpd.serve_forever()