import os import subprocess import uuid from flask import Flask, request, render_template_string, send_file, jsonify app = Flask(__name__) # Safe directories using the user's home directory context UPLOAD_FOLDER = os.path.expanduser('~/uploads') OUTPUT_FOLDER = os.path.expanduser('~/outputs') os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(OUTPUT_FOLDER, exist_ok=True) # Extension mapping matrix defining what can safely turn into what ALLOWED_CONVERSIONS = { 'docx': ['pdf', 'odt', 'txt', 'html'], 'doc': ['pdf', 'docx', 'odt'], 'xlsx': ['pdf', 'csv', 'ods', 'html'], 'xls': ['pdf', 'xlsx', 'csv'], 'pptx': ['pdf', 'odp', 'html'], 'ppt': ['pdf', 'pptx'], 'odt': ['pdf', 'docx', 'txt'], 'ods': ['pdf', 'xlsx', 'csv'], 'txt': ['pdf', 'docx'], 'csv': ['xlsx', 'pdf'] } HTML_TEMPLATE = """ Universal Multi-Format Document Converter

Multi-Format Converter

Powered by optimized LibreOffice daemon

Drag & drop your document here

Supports DOCX, XLSX, PPTX, ODT, TXT, CSV etc.

""" @app.route('/') def index(): return render_template_string(HTML_TEMPLATE, mapping=ALLOWED_CONVERSIONS) @app.route('/convert', methods=['POST']) def convert(): if 'file' not in request.files or 'target' not in request.form: return jsonify({"error": "Malformed query structure payload"}), 400 file = request.files['file'] target_ext = request.form['target'].lower() if file.filename == '': return jsonify({"error": "Empty filename structure context"}), 400 source_ext = file.filename.split('.')[-1].lower() if source_ext not in ALLOWED_CONVERSIONS or target_ext not in ALLOWED_CONVERSIONS[source_ext]: return jsonify({"error": "Unsupported cross-format compilation sequence requested"}), 400 # Ensure thread-safe runtime paths job_id = str(uuid.uuid4()) input_filename = f"{job_id}.{source_ext}" output_filename = f"{job_id}.{target_ext}" input_path = os.path.join(UPLOAD_FOLDER, input_filename) output_path = os.path.join(OUTPUT_FOLDER, output_filename) file.save(input_path) try: # We hook straight into the background listening port 2002 via 'unoconvert' # From app.py line ~160 subprocess.run([ 'unoconvert', '--port', '2002', # Connects to unoserver's main port '--convert-to', target_ext, input_path, output_path ], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if os.path.exists(output_path): return send_file(output_path, as_attachment=True) else: return jsonify({"error": "Pipeline processing did not generate binary assets"}), 500 except subprocess.CalledProcessError as e: return jsonify({"error": "Daemon stream pipeline communications broken"}), 500 finally: # Continuous clean execution lifecycle routines if os.path.exists(input_path): os.remove(input_path) if os.path.exists(output_path): os.remove(output_path) if __name__ == '__main__': # Fallback to standard testing configurations locally if needed app.run(host='0.0.0.0', port=7860)