import os import io import subprocess from flask import Flask, render_template, request, send_file, Response app = Flask(__name__) # --- FUNCIÓN DE COMPRESIÓN (USANDO GHOSTSCRIPT) --- def compress_pdf_with_ghostscript(input_stream: io.BytesIO, quality: str) -> io.BytesIO: """ Comprime un PDF usando Ghostscript, forzando un perfil agresivo y baja resolución (100 DPI) para las imágenes internas. """ output_stream = io.BytesIO() input_stream.seek(0) # Parámetros para forzar la compresión máxima gs_command = [ "gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", # Usamos el perfil 'ebook' como base agresiva "-dPDFSETTINGS=/ebook", # Opciones para forzar el reescalado de imágenes a 100 DPI "-dDownsampleColorImages=true", "-dColorImageResolution=100", "-dDownsampleGrayImages=true", "-dGrayImageResolution=100", "-dNOPAUSE", "-dBATCH", "-dQUIET", "-sOutputFile=-", # Salida a stdout "-" # Entrada desde stdin ] try: # Ejecutar el comando Ghostscript process = subprocess.run( gs_command, input=input_stream.read(), capture_output=True, check=True ) output_stream.write(process.stdout) output_stream.seek(0) return output_stream except subprocess.CalledProcessError as e: raise Exception(f"Error de Ghostscript: {e.stderr.decode()}") except FileNotFoundError: raise Exception("Ghostscript no está instalado en el servidor. (Verifica el Dockerfile)") except Exception as e: raise Exception(f"Error desconocido durante la compresión: {e}") # --- RUTAS --- @app.route('/') def index(): """Muestra la interfaz del compresor.""" # Asegúrate de que compressor_index.html esté en la carpeta templates/ return render_template('compressor_index.html') @app.route('/compress', methods=['POST']) def compress_pdf_file(): """Ruta para recibir y comprimir el PDF subido.""" if 'pdf_file' not in request.files: return Response('No se seleccionó ningún archivo PDF', status=400) pdf_file = request.files['pdf_file'] quality_setting = request.form.get('quality', 'screen') # Recibe el perfil seleccionado try: input_stream = io.BytesIO(pdf_file.read()) # Comprimir el PDF subido compressed_stream = compress_pdf_with_ghostscript(input_stream, quality_setting) # Devolver el archivo comprimido return send_file( compressed_stream, as_attachment=True, download_name=f"comprimido_{pdf_file.filename}", mimetype='application/pdf' ) except Exception as e: return Response(f"Error en la compresión: {str(e)}", status=500) if __name__ == '__main__': port = int(os.environ.get('PORT', 7860)) app.run(host='0.0.0.0', port=port, debug=False)