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() |