#!/usr/bin/env python3 """LibreOffice converter — Flask HTTP service. POST .doc → .docx.""" import subprocess, tempfile, os from flask import Flask, request, send_file app = Flask(__name__) @app.route("/convert", methods=["POST"]) def convert(): if "file" not in request.files: return {"ok": False, "error": "no file"}, 400 f = request.files["file"] with tempfile.NamedTemporaryFile(suffix=".doc", delete=False) as tmp: f.save(tmp) doc_path = tmp.name tmpdir = tempfile.mkdtemp() try: subprocess.run( ["libreoffice", "--headless", "--convert-to", "docx", "--outdir", tmpdir, doc_path], timeout=120, capture_output=True, check=True ) docx_files = [x for x in os.listdir(tmpdir) if x.endswith(".docx")] if not docx_files: return {"ok": False, "error": "conversion produced no .docx"}, 500 return send_file(os.path.join(tmpdir, docx_files[0]), mimetype="application/vnd.openxmlformats-officedocument.wordprocessingml.document", as_attachment=True, download_name=os.path.splitext(f.filename)[0] + ".docx") except subprocess.TimeoutExpired: return {"ok": False, "error": "conversion timeout"}, 500 except subprocess.CalledProcessError as e: return {"ok": False, "error": f"libreoffice: {e.stderr.decode() if e.stderr else 'unknown'}"}, 500 finally: if os.path.exists(doc_path): os.unlink(doc_path) for x in os.listdir(tmpdir): os.unlink(os.path.join(tmpdir, x)) os.rmdir(tmpdir) @app.route("/health", methods=["GET"]) def health(): return {"ok": True} if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)