jersonalvr commited on
Commit
71e67d0
·
verified ·
1 Parent(s): caafd22

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -39
app.py CHANGED
@@ -129,7 +129,7 @@ def cargar_modelo_traduccion(origen, destino):
129
 
130
  def traducir_texto(tokenizer, model, textos, dispositivo, batch_size=8):
131
  """
132
- Extrae el contenido del PDF, traduce el texto y crea un nuevo PDF traducido.
133
  """
134
  if not textos: # Add a check for empty text list
135
  logger.warning("Lista de textos vacía. Saltando traducción.")
@@ -279,9 +279,10 @@ def ajustar_tamano_fuente(texto, bbox, c, max_width, tamaño_fuente_original):
279
  logger.warning(f"Error al ajustar tamaño de fuente: {e}")
280
  return tamaño_fuente_original
281
 
282
- def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_destino):
283
  """
284
  Extrae el contenido del PDF, traduce el texto y crea un nuevo PDF traducido.
 
285
  """
286
  try:
287
  documento = fitz.open(archivo_pdf.name)
@@ -317,7 +318,8 @@ def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_de
317
  if not textos:
318
  logger.warning("No se encontraron textos válidos para traducir en el PDF.")
319
  documento.close()
320
- return archivo_pdf.name
 
321
 
322
  # Traducir texto
323
  try:
@@ -339,14 +341,14 @@ def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_de
339
  for numero_pagina in range(total_paginas):
340
  pagina = documento.load_page(numero_pagina)
341
  rect = pagina.rect
342
- ancho, alto = rect.width, rect.height
343
 
344
  # Ajustar el tamaño de página al tamaño original del PDF
345
- c.setPageSize((ancho, alto))
346
 
347
  # Definir márgenes dinámicos en base al tamaño de la página, ej: 5% de ancho y alto
348
- margen_x = ancho * 0.05
349
- margen_y = alto * 0.05
350
 
351
  # Procesar texto de esta página
352
  pagina_bloques = pagina.get_text("dict")["blocks"]
@@ -375,7 +377,7 @@ def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_de
375
 
376
  # Ajustar coordenadas al sistema de ReportLab (y invertida)
377
  x = x0
378
- y = alto - y1
379
 
380
  # Buscar fuente similar
381
  fuente_encontrada = buscar_fuente_similar(font, fuentes_sistema)
@@ -389,7 +391,7 @@ def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_de
389
  c.setFont(fuente_encontrada, size)
390
 
391
  # Ajustar el tamaño del texto si excede el ancho disponible
392
- max_width = (x1 - x0) - margen_x if (x1 - x0) > 0 else (ancho - 2 * margen_x)
393
  nuevo_tamaño = ajustar_tamano_fuente(texto_traducido, bbox, c, max_width, size)
394
 
395
  # Establecer el nuevo tamaño de fuente
@@ -425,29 +427,33 @@ def extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_de
425
  imagen_path = os.path.join(tempfile.gettempdir(), f"imagen_{numero_pagina}.png")
426
  img.save(imagen_path)
427
  img.close()
428
- c.drawImage(imagen_path, x0, alto - y1 - alto_img, width=ancho_img, height=alto_img)
429
 
430
  except Exception as e:
431
  logger.error(f"Error al procesar imagen: {e}")
432
  continue
433
-
 
 
 
434
  c.showPage()
435
 
436
  c.save()
437
  documento.close()
 
438
  return pdf_traducido_path
439
-
440
  except Exception as e:
441
- logger.error(f"Error general en extraer_y_traducir_pdf: {e}")
442
- return archivo_pdf.name
443
 
444
- def pdf_preview(file):
445
  """
446
- Previsualiza la primera página del PDF como una imagen.
447
  """
448
  try:
449
- doc = fitz.open(file.name)
450
- page = doc[0]
 
 
451
  pix = page.get_pixmap()
452
  image = np.frombuffer(pix.samples, np.uint8).reshape(pix.height, pix.width, pix.n)
453
  if pix.n == 4:
@@ -510,11 +516,16 @@ def boton_actualizar_fuentes(files):
510
 
511
  def procesar_pdf(archivo_pdf, fuentes_subidas):
512
  """
513
- Función principal para procesar y traducir el PDF.
 
514
  """
515
  try:
516
  if not archivo_pdf:
517
- return None, "No se ha subido ningún archivo PDF."
 
 
 
 
518
 
519
  # Extraer texto para detectar el idioma
520
  documento = fitz.open(archivo_pdf.name)
@@ -528,29 +539,27 @@ def procesar_pdf(archivo_pdf, fuentes_subidas):
528
  # Si el idioma de origen y destino son iguales, no realizar traducción
529
  if idioma_origen == idioma_sistema:
530
  logger.info("El idioma de origen y destino son iguales. No se realizará la traducción.")
531
- return archivo_pdf.name, "El idioma de origen y destino son iguales. No se realizó la traducción."
 
532
 
533
  # Cargar el modelo de traducción automáticamente
534
  tokenizer, model, dispositivo = cargar_modelo_traduccion(idioma_origen, idioma_sistema)
535
 
536
- # Traducir el PDF
537
- pdf_traducido_path = extraer_y_traducir_pdf(archivo_pdf, tokenizer, model, dispositivo, idioma_sistema)
 
 
 
 
 
538
 
539
- return pdf_traducido_path, "Traducción completada exitosamente."
 
 
 
540
  except Exception as e:
541
  logger.error(f"Error en procesar_pdf: {e}")
542
- return None, f"Error en la traducción: {e}"
543
-
544
- def actualizar_fuentes_cache():
545
- """
546
- Función para actualizar el caché de fuentes.
547
- """
548
- try:
549
- cachear_fuentes()
550
- return "Fuentes cacheadas exitosamente."
551
- except Exception as e:
552
- logger.error(f"Error al cachear fuentes: {e}")
553
- return f"Error al cachear fuentes: {e}"
554
 
555
  # Interfaz de usuario con Gradio
556
  with gr.Blocks(
@@ -577,17 +586,24 @@ with gr.Blocks(
577
  with gr.Column(scale=1):
578
  gr.Markdown("## Vista Previa")
579
  preview = gr.Image(label="Vista Previa", visible=True)
 
580
  traducir_btn = gr.Button("Traducir PDF")
581
- estado_traduccion = gr.Textbox(label="Estado", interactive=False)
 
 
582
  traducir_btn.click(
583
  fn=procesar_pdf,
584
  inputs=[pdf_input, fuentes_subidas],
585
- outputs=[gr.File(label="Descargar PDF traducido"), estado_traduccion]
 
586
  )
587
 
588
  # Vista previa del PDF
 
 
 
589
  pdf_input.change(
590
- fn=pdf_preview,
591
  inputs=pdf_input,
592
  outputs=preview
593
  )
 
129
 
130
  def traducir_texto(tokenizer, model, textos, dispositivo, batch_size=8):
131
  """
132
+ Traduce una lista de textos utilizando el modelo y tokenizer proporcionados.
133
  """
134
  if not textos: # Add a check for empty text list
135
  logger.warning("Lista de textos vacía. Saltando traducción.")
 
279
  logger.warning(f"Error al ajustar tamaño de fuente: {e}")
280
  return tamaño_fuente_original
281
 
282
+ def extraer_y_traducir_pdf_generador(archivo_pdf, tokenizer, model, dispositivo, idioma_destino):
283
  """
284
  Extrae el contenido del PDF, traduce el texto y crea un nuevo PDF traducido.
285
+ Esta versión utiliza 'yield' para emitir actualizaciones.
286
  """
287
  try:
288
  documento = fitz.open(archivo_pdf.name)
 
318
  if not textos:
319
  logger.warning("No se encontraron textos válidos para traducir en el PDF.")
320
  documento.close()
321
+ yield ("No se encontraron textos para traducir.", None)
322
+ return pdf_traducido_path
323
 
324
  # Traducir texto
325
  try:
 
341
  for numero_pagina in range(total_paginas):
342
  pagina = documento.load_page(numero_pagina)
343
  rect = pagina.rect
344
+ ancho_pagina, alto_pagina = rect.width, rect.height
345
 
346
  # Ajustar el tamaño de página al tamaño original del PDF
347
+ c.setPageSize((ancho_pagina, alto_pagina))
348
 
349
  # Definir márgenes dinámicos en base al tamaño de la página, ej: 5% de ancho y alto
350
+ margen_x = ancho_pagina * 0.05
351
+ margen_y = alto_pagina * 0.05
352
 
353
  # Procesar texto de esta página
354
  pagina_bloques = pagina.get_text("dict")["blocks"]
 
377
 
378
  # Ajustar coordenadas al sistema de ReportLab (y invertida)
379
  x = x0
380
+ y = alto_pagina - y1
381
 
382
  # Buscar fuente similar
383
  fuente_encontrada = buscar_fuente_similar(font, fuentes_sistema)
 
391
  c.setFont(fuente_encontrada, size)
392
 
393
  # Ajustar el tamaño del texto si excede el ancho disponible
394
+ max_width = (x1 - x0) - margen_x if (x1 - x0) > 0 else (ancho_pagina - 2 * margen_x)
395
  nuevo_tamaño = ajustar_tamano_fuente(texto_traducido, bbox, c, max_width, size)
396
 
397
  # Establecer el nuevo tamaño de fuente
 
427
  imagen_path = os.path.join(tempfile.gettempdir(), f"imagen_{numero_pagina}.png")
428
  img.save(imagen_path)
429
  img.close()
430
+ c.drawImage(imagen_path, x0, alto_pagina - y1 - alto_img, width=ancho_img, height=alto_img)
431
 
432
  except Exception as e:
433
  logger.error(f"Error al procesar imagen: {e}")
434
  continue
435
+
436
+ # Emitir estado y vista previa de la página actual
437
+ yield (f"Traduciendo página {numero_pagina + 1} de {total_paginas} al idioma {idioma_destino}...", pdf_preview(archivo_pdf.name, numero_pagina))
438
+
439
  c.showPage()
440
 
441
  c.save()
442
  documento.close()
443
+ yield ("Traducción completada exitosamente.", pdf_preview(pdf_traducido_path, pagina=0))
444
  return pdf_traducido_path
 
445
  except Exception as e:
446
+ logger.error(f"Error al extraer y traducir pdf: {e}")
 
447
 
448
+ def pdf_preview(file_path, pagina=0):
449
  """
450
+ Previsualiza una página específica del PDF como una imagen.
451
  """
452
  try:
453
+ doc = fitz.open(file_path)
454
+ if pagina >= len(doc):
455
+ pagina = 0 # Fallback a la primera página si el número es inválido
456
+ page = doc[pagina]
457
  pix = page.get_pixmap()
458
  image = np.frombuffer(pix.samples, np.uint8).reshape(pix.height, pix.width, pix.n)
459
  if pix.n == 4:
 
516
 
517
  def procesar_pdf(archivo_pdf, fuentes_subidas):
518
  """
519
+ Función generadora para procesar y traducir el PDF.
520
+ Emite actualizaciones de estado y vista previa durante el proceso.
521
  """
522
  try:
523
  if not archivo_pdf:
524
+ yield ("No se ha subido ningún archivo PDF.", None, None)
525
+ return
526
+
527
+ # Emitir estado inicial
528
+ yield ("Iniciando traducción...", pdf_preview(archivo_pdf.name, pagina=0), None)
529
 
530
  # Extraer texto para detectar el idioma
531
  documento = fitz.open(archivo_pdf.name)
 
539
  # Si el idioma de origen y destino son iguales, no realizar traducción
540
  if idioma_origen == idioma_sistema:
541
  logger.info("El idioma de origen y destino son iguales. No se realizará la traducción.")
542
+ yield ("El idioma de origen y destino son iguales. No se realizó la traducción.", pdf_preview(archivo_pdf.name, pagina=0), None)
543
+ return
544
 
545
  # Cargar el modelo de traducción automáticamente
546
  tokenizer, model, dispositivo = cargar_modelo_traduccion(idioma_origen, idioma_sistema)
547
 
548
+ # Realizar la traducción y emitir actualizaciones
549
+ generator = extraer_y_traducir_pdf_generador(
550
+ archivo_pdf, tokenizer, model, dispositivo, idioma_sistema
551
+ )
552
+ for update in generator:
553
+ status, imagen = update
554
+ yield (status, imagen, None)
555
 
556
+ # Emitir estado final
557
+ pdf_traducido_path = os.path.splitext(archivo_pdf.name)[0] + f"_traducido_{idioma_sistema}.pdf"
558
+ yield ("Traducción completada exitosamente.", pdf_preview(pdf_traducido_path, pagina=0), pdf_traducido_path)
559
+
560
  except Exception as e:
561
  logger.error(f"Error en procesar_pdf: {e}")
562
+ yield (f"Error en la traducción: {e}", None, None)
 
 
 
 
 
 
 
 
 
 
 
563
 
564
  # Interfaz de usuario con Gradio
565
  with gr.Blocks(
 
586
  with gr.Column(scale=1):
587
  gr.Markdown("## Vista Previa")
588
  preview = gr.Image(label="Vista Previa", visible=True)
589
+ status_md = gr.Markdown("**Estado:** Esperando traducción...")
590
  traducir_btn = gr.Button("Traducir PDF")
591
+ traducir_output = gr.File(label="Descargar PDF traducido", visible=True)
592
+
593
+ # Configurar el botón para usar la función generadora
594
  traducir_btn.click(
595
  fn=procesar_pdf,
596
  inputs=[pdf_input, fuentes_subidas],
597
+ outputs=[status_md, preview, traducir_output],
598
+ show_progress=True # Opcional: muestra una barra de progreso
599
  )
600
 
601
  # Vista previa del PDF
602
+ def actualizar_preview(file):
603
+ return pdf_preview(file.name, pagina=0) if file else None
604
+
605
  pdf_input.change(
606
+ fn=actualizar_preview,
607
  inputs=pdf_input,
608
  outputs=preview
609
  )