OCR / app.py
eberhenriquez94's picture
a
afc97e1 verified
raw
history blame
3.45 kB
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 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
return gr.File(value=ruta_final, label="PDF procesado"), ruta_final # gr.File para pdf_vista
except Exception as e:
logger.exception(f"Error durante el procesamiento: {e}") # Loggea la excepci贸n completa
raise gr.Error(f"Error al procesar el PDF: {e}")
finally:
# Elimina el archivo temporal al final, incluso si hay errores
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.File(label="Visor PDF") # Cambiado a gr.File
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()