leonett commited on
Commit
d2d8373
verified
1 Parent(s): b7c0e2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -28
app.py CHANGED
@@ -7,7 +7,6 @@ import re
7
  import os
8
  import tempfile
9
  import base64
10
- # No se usan fpdf en este ejemplo
11
 
12
  # ---------------- Funciones de an谩lisis y grafo -------------------
13
 
@@ -120,23 +119,19 @@ def analizar_transaccion(tx_id):
120
  if es_mixer:
121
  if heuristic_mixer and es_mixer_blockchain:
122
  mixer_message = (
123
- "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> "
124
- "La transacci贸n cumple criterios heur铆sticos y la API de blockchain.com la etiqueta como MIXER.</p>"
125
  )
126
  elif heuristic_mixer:
127
  mixer_message = (
128
- "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> "
129
- "La transacci贸n cumple criterios heur铆sticos compatibles con un mixer.</p>"
130
  )
131
  elif es_mixer_blockchain:
132
  mixer_message = (
133
- "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> "
134
- "La API de blockchain.com etiqueta esta transacci贸n como MIXER.</p>"
135
  )
136
  else:
137
  mixer_message = (
138
- "<p style='color: #4CAF50;'><strong>Sin indicios de mezcla:</strong> "
139
- "La transacci贸n no presenta patrones de mixer.</p>"
140
  )
141
 
142
  btc_price = get_btc_price() or 0
@@ -221,6 +216,7 @@ def analizar_transaccion(tx_id):
221
  fee_str = f"{fee:.8f} BTC"
222
  fee_str += f" (${fee * btc_price:,.2f})" if btc_price else ""
223
 
 
224
  reporte = f"""
225
  <div style="padding: 20px; border-radius: 10px;">
226
  <h3 style="color: {'#FF5252' if es_mixer else '#4CAF50'};">
@@ -232,13 +228,12 @@ def analizar_transaccion(tx_id):
232
  <p><strong>Tama帽o:</strong> {size if size else 'N/A'} bytes</p>
233
  <p><strong>Peso:</strong> {weight}</p>
234
  <p><strong>Fee rate:</strong> {fee_rate_str}</p>
235
- <hr>
236
  <p>馃摜 <strong>Inputs:</strong> {num_inputs}</p>
237
  {mixer_metrics}
238
- <p>馃挼 <strong>Total Entradas:</strong> {total_input_str}</p>
239
- <p>馃捀 <strong>Total Salidas:</strong> {total_output_str}</p>
240
- <p>馃Ь <strong>Fee:</strong> {fee_str}</p>
241
- <p>馃敂 <strong>Estado de Confirmaci贸n:</strong> {"Confirmada" if status.get("confirmed", False) else "No confirmada"}</p>
242
  {mixer_message}
243
  <p style="font-size: 0.9em;">
244
  Nota: La detecci贸n se basa en heur铆sticas y en informaci贸n adicional de blockchain.com. Se recomienda usar herramientas especializadas para un an谩lisis forense completo.
@@ -250,25 +245,23 @@ def analizar_transaccion(tx_id):
250
  except Exception as e:
251
  return f"鈿狅笍 Error durante el an谩lisis: {str(e)}", None, None
252
 
253
- # ---------------- Funci贸n para mostrar el modal mediante HTML -------------------
254
-
255
  def mostrar_modal(analysis_tuple):
256
  """
257
- A partir de la tupla de an谩lisis, devuelve un HTML con un modal emergente que contiene el informe.
258
  """
259
  if not analysis_tuple:
260
  return "<p>No hay an谩lisis generado.</p>"
261
  report, _ = analysis_tuple
262
  html_modal = f'''
263
- <div id="myModal" style="
264
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
265
- background: rgba(0,0,0,0.8); z-index: 9999;">
266
  <div style="
267
- position: absolute; top: 50%; left: 50%;
268
- transform: translate(-50%, -50%);
269
- background: white; padding: 20px; max-height: 90%; overflow-y: auto;">
270
  {report}
271
- <br><br><button onclick="document.getElementById('myModal').remove();"
 
272
  style='padding: 5px 10px; font-size: 12px;'>Cerrar</button>
273
  </div>
274
  </div>
@@ -288,12 +281,13 @@ with gr.Blocks(
288
  gr.Markdown("**Nota:** Este analizador funciona 煤nicamente con transacciones de Bitcoin. No se pueden analizar transacciones de Ethereum.")
289
 
290
  with gr.Row():
291
- # Columna izquierda: Campo de TXID, Ejemplos y Explicaci贸n de campos
292
  with gr.Column(scale=1):
293
  tx_input = gr.Textbox(
294
  label="TXID de la Transacci贸n",
295
  placeholder="Ej: 9dd51e2d45f4f7bddcc3f0f7a05c3fd60543a11cfc9fbd0e1ca4434668cfa3e1"
296
  )
 
297
  gr.Markdown("### Ejemplos de TXIDs v谩lidos:")
298
  gr.Examples(
299
  examples=[
@@ -328,16 +322,15 @@ with gr.Blocks(
328
  with gr.Column(scale=1):
329
  plot_output = gr.Plot()
330
  reporte_html = gr.HTML()
331
- analyze_btn = gr.Button("Analizar Transacci贸n", elem_classes=["custom-btn"])
332
  modal_btn = gr.Button("GENERAR ANALISIS", elem_classes=["custom-btn"])
333
  modal_output = gr.HTML()
334
 
335
  # Estado para almacenar el an谩lisis (tupla: (reporte, fig))
336
  analysis_state = gr.State()
337
 
338
- # Al hacer clic en "Analizar Transacci贸n", se generan reporte, grafo y se guarda el an谩lisis
339
  analyze_btn.click(fn=analizar_transaccion, inputs=tx_input, outputs=[reporte_html, plot_output, analysis_state])
340
- # Al hacer clic en "GENERAR ANALISIS", se muestra un modal emergente con el informe completo
341
  modal_btn.click(fn=mostrar_modal, inputs=analysis_state, outputs=modal_output)
342
 
343
- demo.launch()
 
7
  import os
8
  import tempfile
9
  import base64
 
10
 
11
  # ---------------- Funciones de an谩lisis y grafo -------------------
12
 
 
119
  if es_mixer:
120
  if heuristic_mixer and es_mixer_blockchain:
121
  mixer_message = (
122
+ "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> La transacci贸n cumple criterios heur铆sticos y la API de blockchain.com la etiqueta como MIXER.</p>"
 
123
  )
124
  elif heuristic_mixer:
125
  mixer_message = (
126
+ "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> La transacci贸n cumple criterios heur铆sticos compatibles con un mixer.</p>"
 
127
  )
128
  elif es_mixer_blockchain:
129
  mixer_message = (
130
+ "<p style='color: #FF5252;'><strong>Alerta de Mixer / CoinJoin:</strong> La API de blockchain.com etiqueta esta transacci贸n como MIXER.</p>"
 
131
  )
132
  else:
133
  mixer_message = (
134
+ "<p style='color: #4CAF50;'><strong>Sin indicios de mezcla:</strong> La transacci贸n no presenta patrones de mixer.</p>"
 
135
  )
136
 
137
  btc_price = get_btc_price() or 0
 
216
  fee_str = f"{fee:.8f} BTC"
217
  fee_str += f" (${fee * btc_price:,.2f})" if btc_price else ""
218
 
219
+ # Se ha eliminado el <hr> para que la informaci贸n aparezca de forma continua.
220
  reporte = f"""
221
  <div style="padding: 20px; border-radius: 10px;">
222
  <h3 style="color: {'#FF5252' if es_mixer else '#4CAF50'};">
 
228
  <p><strong>Tama帽o:</strong> {size if size else 'N/A'} bytes</p>
229
  <p><strong>Peso:</strong> {weight}</p>
230
  <p><strong>Fee rate:</strong> {fee_rate_str}</p>
 
231
  <p>馃摜 <strong>Inputs:</strong> {num_inputs}</p>
232
  {mixer_metrics}
233
+ <p><strong>Total Entradas:</strong> {total_input_str}</p>
234
+ <p><strong>Total Salidas:</strong> {total_output_str}</p>
235
+ <p><strong>Fee:</strong> {fee_str}</p>
236
+ <p><strong>Estado de Confirmaci贸n:</strong> {"Confirmada" if status.get("confirmed", False) else "No confirmada"}</p>
237
  {mixer_message}
238
  <p style="font-size: 0.9em;">
239
  Nota: La detecci贸n se basa en heur铆sticas y en informaci贸n adicional de blockchain.com. Se recomienda usar herramientas especializadas para un an谩lisis forense completo.
 
245
  except Exception as e:
246
  return f"鈿狅笍 Error durante el an谩lisis: {str(e)}", None, None
247
 
 
 
248
  def mostrar_modal(analysis_tuple):
249
  """
250
+ A partir de la tupla de an谩lisis, devuelve un HTML que simula un modal emergente con el informe completo.
251
  """
252
  if not analysis_tuple:
253
  return "<p>No hay an谩lisis generado.</p>"
254
  report, _ = analysis_tuple
255
  html_modal = f'''
256
+ <div id="modalOverlay" style="
257
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
258
+ background: rgba(0,0,0,0.8); z-index: 9999; overflow: auto;">
259
  <div style="
260
+ position: relative; margin: 5% auto; padding: 20px;
261
+ background: inherit; max-width: 800px; border-radius: 10px;">
 
262
  {report}
263
+ <br><br>
264
+ <button onclick="document.getElementById('modalOverlay').remove();"
265
  style='padding: 5px 10px; font-size: 12px;'>Cerrar</button>
266
  </div>
267
  </div>
 
281
  gr.Markdown("**Nota:** Este analizador funciona 煤nicamente con transacciones de Bitcoin. No se pueden analizar transacciones de Ethereum.")
282
 
283
  with gr.Row():
284
+ # Columna izquierda: Campo de TXID, ejemplos y explicaci贸n de campos
285
  with gr.Column(scale=1):
286
  tx_input = gr.Textbox(
287
  label="TXID de la Transacci贸n",
288
  placeholder="Ej: 9dd51e2d45f4f7bddcc3f0f7a05c3fd60543a11cfc9fbd0e1ca4434668cfa3e1"
289
  )
290
+ analyze_btn = gr.Button("Analizar Transacci贸n", elem_classes=["custom-btn"])
291
  gr.Markdown("### Ejemplos de TXIDs v谩lidos:")
292
  gr.Examples(
293
  examples=[
 
322
  with gr.Column(scale=1):
323
  plot_output = gr.Plot()
324
  reporte_html = gr.HTML()
 
325
  modal_btn = gr.Button("GENERAR ANALISIS", elem_classes=["custom-btn"])
326
  modal_output = gr.HTML()
327
 
328
  # Estado para almacenar el an谩lisis (tupla: (reporte, fig))
329
  analysis_state = gr.State()
330
 
331
+ # Al pulsar "Analizar Transacci贸n", se generan reporte, grafo y se guarda el an谩lisis.
332
  analyze_btn.click(fn=analizar_transaccion, inputs=tx_input, outputs=[reporte_html, plot_output, analysis_state])
333
+ # Al pulsar "GENERAR ANALISIS", se muestra un modal emergente con el informe completo.
334
  modal_btn.click(fn=mostrar_modal, inputs=analysis_state, outputs=modal_output)
335
 
336
+ demo.launch()