File size: 4,126 Bytes
4466e02
 
 
f299d77
0374a9d
4466e02
e7720f0
4466e02
 
 
f129c2d
4466e02
 
f299d77
4466e02
 
f129c2d
4466e02
 
f299d77
 
 
e9044ba
f299d77
 
 
 
 
 
 
 
 
 
 
 
 
afc97e1
 
 
 
 
 
f299d77
430849c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f299d77
 
4466e02
 
f129c2d
afc97e1
 
 
 
 
 
430849c
 
 
 
 
afc97e1
430849c
afc97e1
 
 
 
f299d77
0374a9d
4466e02
0374a9d
f299d77
4466e02
0374a9d
4466e02
f129c2d
f299d77
 
430849c
afc97e1
 
4e828a3
f299d77
4e828a3
0374a9d
4e828a3
4466e02
 
430849c
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
104
105
106
107
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 mostrar_pdf(ruta_pdf):
    """
    Devuelve un HTML con un iframe que usa PDF.js para mostrar un archivo PDF.
    """
    if ruta_pdf:
        # Aseg煤rate de usar rutas correctas para los archivos procesados
        return f"""
        <html>
        <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js"></script>
        </head>
        <body>
        <iframe src="{ruta_pdf}" width="100%" height="600px" style="border: none;"></iframe>
        </body>
        </html>
        """
    return "<p>No se pudo generar la vista previa del PDF.</p>"

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

            # Crear vista previa para PDF.js
            pdf_vista_html = mostrar_pdf(ruta_final)

            return pdf_vista_html, gr.File(value=ruta_final, label="Descargar PDF procesado")
        except Exception as e:
            logger.exception(f"Error durante el procesamiento: {e}")
            raise gr.Error(f"Error al procesar el PDF: {e}")
        finally:
            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.HTML(label="Visor PDF")  # Cambiado a gr.HTML
        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()