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
"""
@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)