Spaces:
Sleeping
Sleeping
| 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 --- | |
| 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') | |
| 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) |