Newer
Older
import http.server
import cgi
from urllib.parse import unquote, parse_qs
import re
import subprocess
URL_FORMAT = re.compile(
r"^(?:(?:https://)?platform\.physik\.kit\.edu/codimd/)?(?P<id>[\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
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:
[
"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,
)
assert os.path.isfile(TMP_PDF)
except Exception as e:
if isinstance(e, subprocess.CalledProcessError):
self.errored(
"Error occured while converting markdown to pdf:\n\n" +
e.output.decode("utf-8"),
)
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)))
with open(TMP_PDF, "rb") as pdf_file:
self.copyfile(pdf_file, self.wfile)
clean_up()
#self.wfile.write(pdf)
with http.server.ThreadingHTTPServer(("", PORT), CodiToPdfHandler) as httpd: