fabriquedoc-backend/main.py
2023-05-17 15:53:44 -04:00

114 lines
3.8 KiB
Python

import datetime
import logging
from fastapi import FastAPI
from fastapi.responses import FileResponse
import pypandoc
import json
from fastapi.testclient import TestClient
import os
import shutil
from DocumentSpecs import DocumentSpecs
from FormatParameters import FormatParameters
from convert_pdf import convert_pdf
from extract_emojis import replace_emojis
from list_dir import list_dir
from responses import Styles, Formats, App
app = FastAPI()
@app.get("/")
async def get_root():
app = App(app='fabriquedoc')
return app
@app.get("/styles/")
async def get_styles():
styles = Styles(styles=list_dir("./styles"))
return styles
@app.get("/formats/{style}/")
async def get_formats(style: str):
formats = Formats(formats=list_dir(f"./styles/{style}/"))
return formats
@app.get("/format_parameters/{style}/{format}/")
async def get_format_parameters(style: str, format: str):
# open styles/format_parameters.json as a dictionary
with open(f"./styles/{style}/format_parameters.json", "r") as f:
format_data = json.load(f).get(format)
logging.log(logging.INFO, str(format_data))
# load data from format_data into the FormatParameters object
parameters = FormatParameters(**format_data)
return parameters
@app.get("/generer/")
async def generer(specs: DocumentSpecs):
header_file = f'{os.getcwd()}/styles/{specs.style}/{specs.format}/header.tex'
cover_file = f'{os.getcwd()}/styles/{specs.style}/{specs.format}/cover.tex'
datef = datetime.datetime.now().strftime("%m-%d-%Y")
os.makedirs("out", exist_ok=True)
output_file = f"./out/{specs.style}-{specs.format}-{datef}-output.pdf"
filters = []
pdoc_args = [
f'--include-in-header={header_file}',
f'--include-after-body={cover_file}',
'--listings',
'--dpi=300',
f'--toc-depth={specs.tocdepth}',
f'--pdf-engine={specs.pdfengine}',
'-V', f'linkcolor={specs.linkcolor}',
'-V', f'fontsize={specs.fontsize}pt',
'-V', f'geometry:paperwidth={specs.paperwidth / 300}in',
'-V', f'geometry:paperheight={specs.paperheight / 300}in',
'-V', f'geometry:margin={specs.margin / 300}in',
'-V', f'geometry:vmargin={specs.vmargin / 300}in'
]
try:
logging.info("Dossier courant = " + os.getcwd())
text_to_convert = replace_emojis(specs.content)
result = pypandoc.convert_text(source=text_to_convert,
to='pdf',
format='markdown+implicit_figures+smart',
encoding='utf-8',
extra_args=pdoc_args,
filters=filters,
cworkdir=os.getcwd(),
outputfile=output_file
)
logging.info(result)
except RuntimeError as rerr:
logging.exception(rerr)
except OSError as oerr:
logging.exception(oerr)
if specs.extension in ["png", "jpg"]:
zip_filename = os.path.splitext(os.path.basename(output_file))[0]
png_output_dir = "./png_output"
if not os.path.exists(png_output_dir):
os.mkdir(png_output_dir)
try:
convert_pdf(output_file, specs.extension, png_output_dir, resolution=300)
shutil.make_archive(zip_filename, 'zip', png_output_dir)
shutil.rmtree(png_output_dir)
except Exception as e:
logging.exception(e)
return FileResponse(zip_filename + ".zip")
elif specs.extension == "pdf":
return FileResponse(output_file)
else:
return 0
client = TestClient(app)
def test_getroot():
response = client.get("/")
assert response.status_code == 200