PDF__OCR / app.py
eberhenriquez94's picture
a
b6ad860 verified
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()