eberhenriquez94 commited on
Commit
4e828a3
verified
1 Parent(s): b67fede
Files changed (1) hide show
  1. app.py +22 -71
app.py CHANGED
@@ -1,22 +1,19 @@
1
  import gradio as gr
2
  import subprocess
3
  import logging
4
- from PyPDF2 import PdfReader
5
  import tempfile
6
  import os
7
  import shlex
8
  from gradio_pdf import PDF
9
- from pdf2image import convert_from_path # Importar para la funci贸n de mostrar_paginas
10
 
11
  # Configuraci贸n de logs
12
  logger = logging.getLogger(__name__)
13
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
14
 
15
  def verificar_comando(comando):
16
  """Verifica si un comando est谩 disponible en el sistema."""
17
  try:
18
  subprocess.run(f"which {comando}", shell=True, check=True, capture_output=True)
19
- logger.info(f"Comando encontrado: {comando}")
20
  except subprocess.CalledProcessError:
21
  raise gr.Error(f"El comando '{comando}' no est谩 disponible. Por favor, inst谩lalo antes de continuar.")
22
 
@@ -24,72 +21,35 @@ def ejecutar_comando(comando):
24
  """Ejecuta un comando de shell y maneja errores."""
25
  try:
26
  resultado = subprocess.run(comando, shell=True, check=True, capture_output=True, text=True)
27
- logger.info(f"Comando ejecutado: {comando}\nSalida:\n{resultado.stdout}")
28
  return resultado.stdout
29
  except subprocess.CalledProcessError as e:
30
- error_message = f"Error al ejecutar el comando: {comando}\nError: {e}\nSalida de error:\n{e.stderr}"
31
- logger.error(error_message)
32
- raise RuntimeError(error_message)
33
-
34
- def reparar_pdf(input_pdf, output_pdf):
35
- """Repara un PDF usando qpdf."""
36
- verificar_comando("qpdf")
37
- comando = f"qpdf --linearize {shlex.quote(input_pdf)} {shlex.quote(output_pdf)}"
38
- ejecutar_comando(comando)
39
-
40
- def simplificar_pdf(input_pdf, output_pdf):
41
- """Simplifica un PDF usando Ghostscript."""
42
- verificar_comando("gs")
43
- comando = f"gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -sOutputFile={shlex.quote(output_pdf)} {shlex.quote(input_pdf)}"
44
- ejecutar_comando(comando)
45
 
46
  def crear_pdf_con_texto_incrustado(pdf_original, archivo_salida, idioma="spa"):
47
- """Procesa un PDF con OCR usando OCRmyPDF."""
48
  verificar_comando("ocrmypdf")
49
- comando = f"ocrmypdf -l {idioma} --force-ocr --deskew --output-type pdf {shlex.quote(pdf_original)} {shlex.quote(archivo_salida)}"
50
  ejecutar_comando(comando)
51
 
52
  def flujo_principal(pdf_file, idioma="spa"):
53
- """Procesa un PDF subido con reparaci贸n, simplificaci贸n y OCR."""
54
  if not pdf_file:
55
  raise gr.Error("No se subi贸 ning煤n archivo.")
56
-
57
- input_pdf = pdf_file
58
- reparado_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name
59
- simplificado_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name
60
  output_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name
61
 
62
  try:
63
- # Reparar el PDF
64
- reparar_pdf(input_pdf, reparado_pdf)
65
-
66
- # Simplificar el PDF
67
- simplificar_pdf(reparado_pdf, simplificado_pdf)
68
-
69
- # Procesar con OCR
70
- crear_pdf_con_texto_incrustado(simplificado_pdf, output_pdf, idioma)
71
-
72
- return input_pdf, output_pdf
73
- except gr.Error as e:
74
- logger.error("Error durante el procesamiento del PDF.")
75
- raise e
76
  finally:
77
- # Limpiar archivos temporales
78
- for temp_file in [reparado_pdf, simplificado_pdf]:
79
- if os.path.exists(temp_file):
80
- os.remove(temp_file)
81
-
82
- def mostrar_pdf_zoom(pdf_path):
83
- return f"""
84
- <iframe
85
- src='viewer.html?file={pdf_path}#zoom=100'
86
- width='100%'
87
- height='800px'
88
- style='border: none;'
89
- ></iframe>
90
- """
91
 
92
  def mostrar_pdf(pdf_path):
 
93
  return f"""
94
  <iframe
95
  src='viewer.html?file={pdf_path}'
@@ -99,32 +59,23 @@ def mostrar_pdf(pdf_path):
99
  ></iframe>
100
  """
101
 
102
- def mostrar_paginas(pdf_path):
103
- pages = convert_from_path(pdf_path, dpi=150)
104
- temp_images = []
105
- for i, page in enumerate(pages):
106
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
107
- page.save(temp_file.name, "PNG")
108
- temp_images.append(temp_file.name)
109
- return temp_images
110
-
111
  with gr.Blocks() as interfaz:
112
  gr.Markdown("## Visualizador de PDFs con OCR")
113
 
114
  with gr.Row():
115
  archivo_pdf = PDF(label="Sube tu archivo PDF")
116
  idioma_ocr = gr.Dropdown(["spa", "eng", "fra", "deu"], label="Idioma OCR", value="spa")
117
- boton_procesar = gr.Button("Procesar OCR")
118
 
119
  with gr.Row():
120
- pdf_original_vista = gr.HTML(label="PDF Original")
121
- pdf_ocr_vista = gr.HTML(label="PDF con OCR")
122
- # Eliminamos el m茅todo `style` y configuramos las columnas y altura mediante atributos predefinidos
123
- imagenes = gr.Gallery(label="P谩ginas del PDF", show_label=True, elem_id="gallery-container")
124
 
125
- boton_procesar.click(fn=flujo_principal, inputs=[archivo_pdf, idioma_ocr], outputs=[pdf_original_vista, pdf_ocr_vista])
126
- boton_procesar.click(fn=mostrar_paginas, inputs=[archivo_pdf], outputs=[imagenes])
 
 
 
127
 
128
  if __name__ == "__main__":
129
  interfaz.launch()
130
-
 
1
  import gradio as gr
2
  import subprocess
3
  import logging
 
4
  import tempfile
5
  import os
6
  import shlex
7
  from gradio_pdf import PDF
 
8
 
9
  # Configuraci贸n de logs
10
  logger = logging.getLogger(__name__)
11
+ logging.basicConfig(level=logging.WARNING, format="%(asctime)s - %(levelname)s - %(message)s")
12
 
13
  def verificar_comando(comando):
14
  """Verifica si un comando est谩 disponible en el sistema."""
15
  try:
16
  subprocess.run(f"which {comando}", shell=True, check=True, capture_output=True)
 
17
  except subprocess.CalledProcessError:
18
  raise gr.Error(f"El comando '{comando}' no est谩 disponible. Por favor, inst谩lalo antes de continuar.")
19
 
 
21
  """Ejecuta un comando de shell y maneja errores."""
22
  try:
23
  resultado = subprocess.run(comando, shell=True, check=True, capture_output=True, text=True)
 
24
  return resultado.stdout
25
  except subprocess.CalledProcessError as e:
26
+ raise RuntimeError(f"Error al ejecutar el comando: {comando}\nError: {e.stderr}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  def crear_pdf_con_texto_incrustado(pdf_original, archivo_salida, idioma="spa"):
29
+ """Aplica OCR a un PDF para incrustar texto buscable."""
30
  verificar_comando("ocrmypdf")
31
+ comando = f"ocrmypdf -l {idioma} --deskew --output-type pdf {shlex.quote(pdf_original)} {shlex.quote(archivo_salida)}"
32
  ejecutar_comando(comando)
33
 
34
  def flujo_principal(pdf_file, idioma="spa"):
35
+ """Procesa el PDF subido con OCR."""
36
  if not pdf_file:
37
  raise gr.Error("No se subi贸 ning煤n archivo.")
38
+
39
+ # Crear un archivo temporal para el PDF procesado
 
 
40
  output_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name
41
 
42
  try:
43
+ crear_pdf_con_texto_incrustado(pdf_file, output_pdf, idioma)
44
+ return mostrar_pdf(output_pdf)
45
+ except Exception as e:
46
+ raise gr.Error(f"Error procesando el archivo: {str(e)}")
 
 
 
 
 
 
 
 
 
47
  finally:
48
+ if os.path.exists(output_pdf):
49
+ os.remove(output_pdf)
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  def mostrar_pdf(pdf_path):
52
+ """Genera un iframe que carga el PDF procesado con pdf.js."""
53
  return f"""
54
  <iframe
55
  src='viewer.html?file={pdf_path}'
 
59
  ></iframe>
60
  """
61
 
62
+ # Interfaz Gradio
 
 
 
 
 
 
 
 
63
  with gr.Blocks() as interfaz:
64
  gr.Markdown("## Visualizador de PDFs con OCR")
65
 
66
  with gr.Row():
67
  archivo_pdf = PDF(label="Sube tu archivo PDF")
68
  idioma_ocr = gr.Dropdown(["spa", "eng", "fra", "deu"], label="Idioma OCR", value="spa")
69
+ boton_procesar = gr.Button("Procesar PDF con OCR")
70
 
71
  with gr.Row():
72
+ visor_pdf = gr.HTML(label="PDF Procesado")
 
 
 
73
 
74
+ boton_procesar.click(
75
+ fn=flujo_principal,
76
+ inputs=[archivo_pdf, idioma_ocr],
77
+ outputs=[visor_pdf]
78
+ )
79
 
80
  if __name__ == "__main__":
81
  interfaz.launch()