File size: 3,937 Bytes
eec7f0a
 
 
 
e642214
698d2af
eec7f0a
e642214
 
eec7f0a
e642214
eec7f0a
 
 
e642214
 
eec7f0a
 
e642214
 
eec7f0a
 
b6ad860
698d2af
b6ad860
698d2af
 
b6ad860
 
 
 
 
 
 
 
 
 
 
698d2af
 
e642214
 
 
eec7f0a
 
 
698d2af
 
 
 
 
b6ad860
e642214
eec7f0a
698d2af
 
cd6f6b9
b6ad860
 
 
 
 
cd6f6b9
e642214
cd6f6b9
b6ad860
 
e642214
eec7f0a
cd6f6b9
 
 
 
e642214
eec7f0a
e642214
 
eec7f0a
e642214
 
 
 
eec7f0a
e642214
eec7f0a
e642214
 
 
eec7f0a
e642214
 
 
45b9d3b
e642214
 
 
 
 
45b9d3b
e642214
eec7f0a
 
b6ad860
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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()