Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import subprocess | |
| import logging | |
| import tempfile | |
| import os | |
| import shutil | |
| # Configurar logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| def ejecutar_comando(comando, mensaje_exito="", mensaje_error=""): | |
| """Ejecuta un comando de shell y maneja errores.""" | |
| try: | |
| resultado = subprocess.run(comando, shell=True, check=True, capture_output=True, text=True) | |
| if mensaje_exito: | |
| logging.info(f"{mensaje_exito}. Salida:\n{resultado.stdout}") | |
| return resultado.stdout | |
| except subprocess.CalledProcessError as e: | |
| error_message = f"{mensaje_error}. Error: {e}\nSalida de error:\n{e.stderr}" | |
| logging.error(error_message) | |
| raise RuntimeError(error_message) | |
| def reparar_pdf(input_pdf, output_pdf): | |
| """Repara un PDF usando qpdf.""" | |
| comando = f"qpdf --linearize '{input_pdf}' '{output_pdf}'" | |
| ejecutar_comando( | |
| comando, | |
| mensaje_exito="PDF reparado correctamente.", | |
| mensaje_error="Error al reparar el PDF." | |
| ) | |
| def convertir_pdf_a_compatible(input_pdf, output_pdf): | |
| """Convierte el PDF a un formato compatible usando pdftocairo.""" | |
| comando = f"pdftocairo -pdf '{input_pdf}' '{output_pdf}'" | |
| ejecutar_comando( | |
| comando, | |
| mensaje_exito="PDF convertido a un formato compatible.", | |
| mensaje_error="Error al convertir el PDF a un formato compatible." | |
| ) | |
| def procesar_pdf_con_ocr(pdf_subido, idioma="spa"): | |
| """Procesa un PDF subido con OCR y devuelve la ruta del archivo procesado.""" | |
| if not pdf_subido: | |
| raise gr.Error("No se subi贸 ning煤n archivo.") | |
| try: | |
| # Copiar el archivo subido a un nombre seguro | |
| safe_input_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name | |
| shutil.copy(pdf_subido.name, safe_input_pdf) | |
| reparado_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name | |
| convertido_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name | |
| output_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name | |
| # Reparar el PDF | |
| reparar_pdf(safe_input_pdf, reparado_pdf) | |
| # Convertir el PDF a un formato compatible | |
| convertir_pdf_a_compatible(reparado_pdf, convertido_pdf) | |
| # Ejecutar OCR en el PDF convertido | |
| comando = f"ocrmypdf -l {idioma} --force-ocr --deskew --output-type pdf '{convertido_pdf}' '{output_pdf}'" | |
| logging.info(f"Ejecutando comando: {comando}") | |
| ejecutar_comando( | |
| comando, | |
| mensaje_exito="OCR completado correctamente.", | |
| mensaje_error="Error al ejecutar el OCR." | |
| ) | |
| # Verificar que el archivo de salida se haya creado | |
| if not os.path.exists(output_pdf): | |
| raise gr.Error("El archivo procesado no se gener贸 correctamente.") | |
| return output_pdf # Ruta del archivo procesado | |
| except Exception as e: | |
| logging.error(f"Error al procesar el PDF: {e}") | |
| raise gr.Error(f"Ocurri贸 un error al procesar el archivo: {e}") | |
| def interfaz_ocr(): | |
| """Crea la interfaz Gradio para el flujo de OCR.""" | |
| with gr.Blocks() as app: | |
| gr.Markdown("## Procesador de PDFs con OCR") | |
| 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") | |
| salida_descarga = gr.File(label="Descargar PDF Procesado") | |
| def procesar_y_descargar(pdf_file, idioma): | |
| """Procesa el PDF subido y lo devuelve para descarga.""" | |
| return procesar_pdf_con_ocr(pdf_file, idioma) | |
| boton_procesar.click( | |
| fn=procesar_y_descargar, | |
| inputs=[archivo_pdf, idioma_ocr], | |
| outputs=[salida_descarga], | |
| ) | |
| return app | |
| if __name__ == "__main__": | |
| interfaz_ocr().launch() |