60 lines
1.9 KiB
Python

from fastapi import FastAPI, staticfiles, UploadFile
from starlette.responses import FileResponse
import aiofile
from asyncio import subprocess
import tempfile
import os
import glob
import enum
class OutputFormat(enum.Enum):
pdf = "pdf"
data_dir = os.path.realpath(os.environ.get("DATA_DIR", "./data"))
soffice_data_dir = os.path.realpath(os.environ.get("UNO_DATA_DIR", data_dir))
os.makedirs(data_dir, exist_ok=True)
soffice_command = os.environ.get("UNO_COMMAND", "soffice --convert-to {outputfmt} --outdir {outputdir} {inputfilename}")
app = FastAPI()
app.mount("/static", staticfiles.StaticFiles(directory="static"), name="static")
@app.get("/")
async def get_index():
return FileResponse('static/index.html')
@app.post("/")
async def convert_file(file: UploadFile, output_format: OutputFormat | None = None):
output_format = output_format or OutputFormat.pdf
outpath = tempfile.mkdtemp(dir=data_dir)
inputfile = os.path.join(outpath, file.filename)
uno_path = os.path.join(soffice_data_dir, os.path.relpath(outpath, data_dir))
uno_inputfile = os.path.join(uno_path, file.filename)
async with aiofile.AIOFile(inputfile, mode="wb+") as fp:
try:
while True:
content = await file.read(1024*1024*4)
if not content:
break
await fp.write(content)
except EOFError:
pass
else:
print(f"file written to {inputfile}")
command = soffice_command.format(outputfmt=output_format.value, outputdir=uno_path, inputfilename=uno_inputfile)
result_process = await subprocess.create_subprocess_shell(command)
assert await result_process.wait() == 0, f"expect return code 0, got {result_process.returncode}"
outfiles = glob.glob(f"{uno_path}/*.{output_format.value}")
assert len(outfiles) == 1, f"expect one output file, got {outfiles}"
return FileResponse(outfiles[0])