Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import subprocess | |
| import logging | |
| import os | |
| import tempfile | |
| import shlex | |
| from gradio_pdf import PDF | |
| # Configuraci贸n de logs | |
| logger = logging.getLogger(__name__) | |
| logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") | |
| def ejecutar_comando(comando): | |
| """Ejecuta un comando de shell y maneja errores.""" | |
| try: | |
| resultado = subprocess.run(comando, shell=True, check=True, capture_output=True, text=True) | |
| logger.info(f"Comando ejecutado: {comando}\nSalida:\n{resultado.stdout}") | |
| return resultado.stdout | |
| except subprocess.CalledProcessError as e: | |
| error_message = f"Error al ejecutar el comando: {comando}\nError: {e}\nSalida de error:\n{e.stderr}" | |
| logger.error(error_message) | |
| raise RuntimeError(error_message) | |
| def reparar_pdf(input_pdf, output_pdf): | |
| """Repara un PDF usando qpdf.""" | |
| comando = f"qpdf --linearize {shlex.quote(input_pdf)} {shlex.quote(output_pdf)}" | |
| ejecutar_comando(comando) | |
| def simplificar_pdf(input_pdf, output_pdf): | |
| """Simplifica un PDF usando Ghostscript.""" | |
| comando = f"gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -sOutputFile={shlex.quote(output_pdf)} {shlex.quote(input_pdf)}" | |
| ejecutar_comando(comando) | |
| def crear_pdf_con_texto_incrustado(pdf_original, archivo_salida, idioma="spa"): | |
| """Procesa un PDF con OCR usando OCRmyPDF.""" | |
| comando = f"ocrmypdf -l {idioma} --force-ocr --deskew --output-type pdf {shlex.quote(pdf_original)} {shlex.quote(archivo_salida)}" | |
| try: | |
| output = ejecutar_comando(comando) | |
| logger.info(f"Salida de ocrmypdf: {output}") | |
| except RuntimeError as e: | |
| logger.error(f"Error en ocrmypdf: {e}") | |
| raise | |
| def mostrar_pdf(ruta_pdf): | |
| """ | |
| Devuelve un HTML con un iframe que usa PDF.js para mostrar un archivo PDF. | |
| """ | |
| if ruta_pdf: | |
| # Aseg煤rate de usar rutas correctas para los archivos procesados | |
| return f""" | |
| <html> | |
| <head> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js"></script> | |
| </head> | |
| <body> | |
| <iframe src="{ruta_pdf}" width="100%" height="600px" style="border: none;"></iframe> | |
| </body> | |
| </html> | |
| """ | |
| return "<p>No se pudo generar la vista previa del PDF.</p>" | |
| def flujo_principal(pdf_file, idioma="spa"): | |
| """Procesa un PDF subido con reparaci贸n, simplificaci贸n y OCR.""" | |
| if not pdf_file: | |
| raise gr.Error("No se subi贸 ning煤n archivo.") | |
| with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as temp_pdf: | |
| try: | |
| reparar_pdf(pdf_file, temp_pdf.name) | |
| simplificar_pdf(temp_pdf.name, temp_pdf.name) | |
| crear_pdf_con_texto_incrustado(temp_pdf.name, temp_pdf.name, idioma) | |
| ruta_final = temp_pdf.name | |
| # Crear vista previa para PDF.js | |
| pdf_vista_html = mostrar_pdf(ruta_final) | |
| return pdf_vista_html, gr.File(value=ruta_final, label="Descargar PDF procesado") | |
| except Exception as e: | |
| logger.exception(f"Error durante el procesamiento: {e}") | |
| raise gr.Error(f"Error al procesar el PDF: {e}") | |
| finally: | |
| if os.path.exists(temp_pdf.name): | |
| os.remove(temp_pdf.name) | |
| # Interfaz Gradio | |
| with gr.Blocks() as interfaz: | |
| gr.Markdown("## Procesador de PDFs con OCR") | |
| with gr.Row(): | |
| archivo_pdf = gr.File(label="Sube tu archivo PDF") | |
| idioma_ocr = gr.Dropdown(["spa", "eng", "fra", "deu"], label="Idioma OCR", value="spa") | |
| boton_procesar = gr.Button("Procesar OCR") | |
| with gr.Row(): | |
| pdf_vista = gr.HTML(label="Visor PDF") # Cambiado a gr.HTML | |
| pdf_descarga = gr.File(label="Descargar PDF procesado", visible=False) | |
| boton_procesar.click( | |
| fn=flujo_principal, | |
| inputs=[archivo_pdf, idioma_ocr], | |
| outputs=[pdf_vista, pdf_descarga], | |
| ) | |
| if __name__ == "__main__": | |
| interfaz.launch() | |