DaniFera commited on
Commit
24b9436
·
verified ·
1 Parent(s): 5f0bd13

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -22
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # Versión 3.1: App Pública con Logs de Seguridad en Consola
2
  import gradio as gr
3
  import pandas as pd
4
  import config
@@ -7,57 +7,73 @@ import time
7
  import threading
8
  from core import PDFEngine
9
 
 
10
  os.environ["GRADIO_TEMP_DIR"] = config.TEMP_DIR
 
11
  engine = PDFEngine()
12
 
13
- # --- SEGURIDAD: GARBAGE COLLECTOR CON LOGS (VERBOSE) ---
14
  def cleanup_cron():
 
 
 
 
 
 
 
 
15
  while True:
16
  try:
17
- time.sleep(60) # Revisar cada 30 segundos.
 
18
 
19
  LIMIT_MINUTES = 5
20
  cutoff = time.time() - (LIMIT_MINUTES * 60)
21
 
22
- # Solo imprimimos cabecera si hay actividad para no ensuciar el log
23
- # print(f"--- [SEGURIDAD] Ronda... ---") # Comentado para reducir ruido
24
 
25
  if os.path.exists(config.TEMP_DIR):
26
  files = os.listdir(config.TEMP_DIR)
27
 
 
 
 
 
28
  for filename in files:
29
  filepath = os.path.join(config.TEMP_DIR, filename)
30
 
31
  if os.path.isfile(filepath):
32
- # OFUSCACIÓN: Mostramos solo los primeros 4 caracteres y la extensión
33
- # Ejemplo: "a1b2c3d4_dni.pdf" -> "a1b2****.pdf"
 
 
 
34
  if len(filename) > 8:
35
- masked_name = f"{filename[:4]}****{os.path.splitext(filename)[1]}"
36
  else:
37
- masked_name = "****" + os.path.splitext(filename)[1]
38
 
39
  if os.path.getmtime(filepath) < cutoff:
40
  try:
41
  os.remove(filepath)
42
- # Log seguro: Informa de la acción pero no del dato
43
- print(f"🛡️ [SEC-CLEAN] Archivo expirado eliminado: {masked_name}")
44
  except Exception as e:
45
- print(f"⚠️ [ERROR] Fallo al borrar {masked_name}")
46
  else:
47
- # Opcional: No imprimir nada para los vigentes en producción
48
- # para no dar pistas de CUÁNDO hay tráfico.
49
- # Si quieres verlos, usa el nombre enmascarado:
50
- print(f"👁️ [MONITOR] Archivo activo: {masked_name}")
51
- pass
52
 
 
 
 
53
  except Exception as e:
54
  print(f"[CRITICAL] Error en limpieza: {e}")
55
 
56
- # Iniciar el hilo "chivato"
57
  threading.Thread(target=cleanup_cron, daemon=True).start()
58
 
59
- # --- WRAPPERS (Lógica de enlace UI -> Core) ---
60
- # (Idénticos a versiones anteriores)
61
  def update_file_list(files):
62
  if not files: return pd.DataFrame(), ""
63
  data = [[i, f.split("/")[-1]] for i, f in enumerate(files)]
@@ -193,9 +209,13 @@ with gr.Blocks(title=config.APP_TITLE, theme=gr.themes.Soft()) as demo:
193
 
194
  # 2. DIVIDIR / REORDENAR
195
  with gr.TabItem("Dividir / Reordenar"):
 
 
196
  dr_f = gr.File(label="PDF Origen", file_types=[".pdf"])
197
  dr_inf = gr.Markdown("")
198
  dr_pg = gr.State(0)
 
 
199
  with gr.Tabs():
200
  with gr.Tab("Extraer"):
201
  gr.Markdown("Separa páginas en un ZIP.")
@@ -210,6 +230,7 @@ with gr.Blocks(title=config.APP_TITLE, theme=gr.themes.Soft()) as demo:
210
  s_out = gr.File(label="ZIP")
211
  s_prv.click(update_split_preview, [dr_f, s_rng, dr_pg], s_gal)
212
  s_btn.click(process_split, [dr_f, s_rng], s_out)
 
213
  with gr.Tab("Reordenar"):
214
  gr.Markdown("Crea un PDF con nuevo orden.")
215
  with gr.Row():
@@ -219,6 +240,7 @@ with gr.Blocks(title=config.APP_TITLE, theme=gr.themes.Soft()) as demo:
219
  with gr.Column():
220
  r_out = gr.File(label="PDF Reordenado")
221
  r_btn.click(process_reorder, [dr_f, r_ord], r_out)
 
222
  dr_f.change(load_info, dr_f, [dr_inf, dr_pg, s_out])
223
 
224
  # 3. COMPRIMIR
@@ -227,7 +249,7 @@ with gr.Blocks(title=config.APP_TITLE, theme=gr.themes.Soft()) as demo:
227
  with gr.Column():
228
  c_f = gr.File(label="PDF Original", file_types=[".pdf"])
229
  c_l = gr.Radio(["Baja (Máxima calidad)", "Media (Recomendado - eBook)", "Alta (Pantalla - 72dpi)"], label="Nivel", value="Media (Recomendado - eBook)")
230
- c_b = gr.Button("Comprimir", variant="primary")
231
  with gr.Column():
232
  c_out = gr.File(label="PDF Comprimido")
233
  c_b.click(process_compress, [c_f, c_l], c_out)
@@ -320,7 +342,6 @@ with gr.Blocks(title=config.APP_TITLE, theme=gr.themes.Soft()) as demo:
320
  mb.click(process_meta, [tf, mt, ma, ms], mo)
321
 
322
  if __name__ == "__main__":
323
- # CONFIGURACIÓN PÚBLICA
324
  demo.queue(default_concurrency_limit=2).launch(
325
  server_name="0.0.0.0",
326
  server_port=7860
 
1
+ # Versión 3.2: App Pública con Logs ACTIVOS (Para verificar que funciona)
2
  import gradio as gr
3
  import pandas as pd
4
  import config
 
7
  import threading
8
  from core import PDFEngine
9
 
10
+ # Configuración de carpeta temporal para Gradio
11
  os.environ["GRADIO_TEMP_DIR"] = config.TEMP_DIR
12
+
13
  engine = PDFEngine()
14
 
15
+ # --- SEGURIDAD: GARBAGE COLLECTOR CON LOGS VISIBLES ---
16
  def cleanup_cron():
17
+ """
18
+ Revisa cada minuto y borra archivos mayores a 5 minutos.
19
+ Muestra actividad en consola para verificar funcionamiento.
20
+ """
21
+ # MENSAJE DE ARRANQUE INMEDIATO
22
+ print("[INIT] 🛡️ Sistema de seguridad y auto-borrado ACTIVO.")
23
+ print("[INIT] ⏳ Primera ronda de limpieza programada en 60 segundos...")
24
+
25
  while True:
26
  try:
27
+ # Esperar 60 segundos
28
+ time.sleep(60)
29
 
30
  LIMIT_MINUTES = 5
31
  cutoff = time.time() - (LIMIT_MINUTES * 60)
32
 
33
+ # 1. AVISO DE RONDA (Descomentado)
34
+ print(f"--- [SEGURIDAD] Ronda de limpieza: {time.strftime('%H:%M:%S')} ---")
35
 
36
  if os.path.exists(config.TEMP_DIR):
37
  files = os.listdir(config.TEMP_DIR)
38
 
39
+ # Si no hay archivos, lo decimos
40
+ if not files:
41
+ print("[ESTADO] Carpeta limpia (0 archivos).")
42
+
43
  for filename in files:
44
  filepath = os.path.join(config.TEMP_DIR, filename)
45
 
46
  if os.path.isfile(filepath):
47
+ # Calcular edad
48
+ age_sec = time.time() - os.path.getmtime(filepath)
49
+ age_str = f"{int(age_sec // 60)}m {int(age_sec % 60)}s"
50
+
51
+ # Ofuscación de nombre (Seguridad visual)
52
  if len(filename) > 8:
53
+ masked = f"{filename[:4]}****{os.path.splitext(filename)[1]}"
54
  else:
55
+ masked = filename
56
 
57
  if os.path.getmtime(filepath) < cutoff:
58
  try:
59
  os.remove(filepath)
60
+ print(f"❌ [BORRADO] {masked} | Edad: {age_str}")
 
61
  except Exception as e:
62
+ print(f"⚠️ [ERROR] {masked}: {e}")
63
  else:
64
+ # 2. AVISO DE ARCHIVO VIGENTE (Descomentado)
65
+ print(f"✅ [VIGENTE] {masked} | Edad: {age_str}")
 
 
 
66
 
67
+ else:
68
+ print("[INFO] Carpeta temporal aún no creada.")
69
+
70
  except Exception as e:
71
  print(f"[CRITICAL] Error en limpieza: {e}")
72
 
73
+ # Iniciar hilo en segundo plano
74
  threading.Thread(target=cleanup_cron, daemon=True).start()
75
 
76
+ # --- WRAPPERS ---
 
77
  def update_file_list(files):
78
  if not files: return pd.DataFrame(), ""
79
  data = [[i, f.split("/")[-1]] for i, f in enumerate(files)]
 
209
 
210
  # 2. DIVIDIR / REORDENAR
211
  with gr.TabItem("Dividir / Reordenar"):
212
+
213
+ # BLOQUE SUPERIOR
214
  dr_f = gr.File(label="PDF Origen", file_types=[".pdf"])
215
  dr_inf = gr.Markdown("")
216
  dr_pg = gr.State(0)
217
+
218
+ # BLOQUE INFERIOR
219
  with gr.Tabs():
220
  with gr.Tab("Extraer"):
221
  gr.Markdown("Separa páginas en un ZIP.")
 
230
  s_out = gr.File(label="ZIP")
231
  s_prv.click(update_split_preview, [dr_f, s_rng, dr_pg], s_gal)
232
  s_btn.click(process_split, [dr_f, s_rng], s_out)
233
+
234
  with gr.Tab("Reordenar"):
235
  gr.Markdown("Crea un PDF con nuevo orden.")
236
  with gr.Row():
 
240
  with gr.Column():
241
  r_out = gr.File(label="PDF Reordenado")
242
  r_btn.click(process_reorder, [dr_f, r_ord], r_out)
243
+
244
  dr_f.change(load_info, dr_f, [dr_inf, dr_pg, s_out])
245
 
246
  # 3. COMPRIMIR
 
249
  with gr.Column():
250
  c_f = gr.File(label="PDF Original", file_types=[".pdf"])
251
  c_l = gr.Radio(["Baja (Máxima calidad)", "Media (Recomendado - eBook)", "Alta (Pantalla - 72dpi)"], label="Nivel", value="Media (Recomendado - eBook)")
252
+ c_b = gr.Button("Comprimir Documento", variant="primary")
253
  with gr.Column():
254
  c_out = gr.File(label="PDF Comprimido")
255
  c_b.click(process_compress, [c_f, c_l], c_out)
 
342
  mb.click(process_meta, [tf, mt, ma, ms], mo)
343
 
344
  if __name__ == "__main__":
 
345
  demo.queue(default_concurrency_limit=2).launch(
346
  server_name="0.0.0.0",
347
  server_port=7860