cursor.execute('''
INSERT INTO analyses (user_id, content_type, content_preview, risk_level, risk_score, analysis_result)
VALUES (?, ?, ?, ?, ?, ?)
''', (current_session["user_id"], content_type, content_preview[:200], risk_level, risk_score, analysis_result))
conn.commit()
conn.close()
except Exception as e:
print(f"Error guardando : {e}")
def get_user_profile():
"""Obtiene información completa del perfil del usuario"""
if not current_session["logged_in"]:
return None
try:
conn = sqlite3.connect(DATABASE_FILE)
cursor = conn.cursor()
# Obtener datos del usuario
cursor.execute('''
SELECT email, full_name, avatar_url, is_pro, created_at, last_login,
subscription_expires, total_analyses
FROM users WHERE id = ?
''', (current_session["user_id"],))
user_data = cursor.fetchone()
if not user_data:
conn.close()
return None
# Obtener estadísticas de análisis
cursor.execute('''
SELECT COUNT(*) as total,
SUM(CASE WHEN risk_level = 'ALTO' THEN 1 ELSE 0 END) as high_risk,
SUM(CASE WHEN risk_level = 'MEDIO' THEN 1 ELSE 0 END) as medium_risk,
SUM(CASE WHEN risk_level = 'BAJO' THEN 1 ELSE 0 END) as low_risk
FROM analyses WHERE user_id = ?
''', (current_session["user_id"],))
stats = cursor.fetchone()
# Obtener historial reciente
cursor.execute('''
SELECT content_type, content_preview, risk_level, risk_score, created_at
FROM analyses WHERE user_id = ?
ORDER BY created_at DESC LIMIT 10
''', (current_session["user_id"],))
recent_analyses = cursor.fetchall()
conn.close()
email, full_name, avatar_url, is_pro, created_at, last_login, sub_expires, total_analyses = user_data
total, high_risk, medium_risk, low_risk = stats or (0, 0, 0, 0)
return {
"email": email,
"full_name": full_name,
"avatar_url": avatar_url or "",
"is_pro": is_pro,
"created_at": created_at,
"last_login": last_login,
"subscription_expires": sub_expires,
"total_analyses": total_analyses or 0,
"stats": {
"total": total or 0,
"high_risk": high_risk or 0,
"medium_risk": medium_risk or 0,
"low_risk": low_risk or 0
},
"recent_analyses": recent_analyses
}
except Exception as e:
print(f"Error obteniendo perfil: {e}")
return None
def chat_interface(message, files, history):
"""Interfaz principal del chat con análisis avanzado"""
global current_session
# Verificar autenticación
if not current_session["logged_in"]:
auth_message = """
🔐 Acceso Requerido
Debes iniciar sesión para usar AntiScam AI
¿Ya tienes cuenta? Inicia sesión
¿Nuevo usuario? Regístrate gratis
"""
history.append([message or "Análisis solicitado", auth_message])
return "", history, None
# Verificar límites de uso
can_use, reason = can_analyze()
if not can_use:
if reason == "Límite diario alcanzado":
upgrade_message = f"""
⛔ Límite Diario Alcanzado
Has usado tus {DAILY_FREE_LIMIT} análisis gratuitos de hoy.
🚀 Actualiza a AntiScam AI Pro
${PRO_PRICE}/mes+ 7 días gratis
✅ Análisis ilimitados
🧠 IA más avanzada
📊 Informes detallados
🔍 OCR para imágenes
🎵 Análisis de audio
📞 Soporte prioritario
📈 Estadísticas avanzadas
🔄 Historial completo
Límite se renueva mañana a las 00:00
"""
history.append([message or "Límite alcanzado", upgrade_message])
return "", history, None
# Procesar contenido
content_to_analyze = ""
content_type = "texto"
if message and message.strip():
content_to_analyze = message
content_type = "texto"
# Procesar archivos (simulado por ahora)
file_results = []
if files:
for file in files:
file_path = getattr(file, 'name', str(file)) if file else ""
if not file_path:
continue
file_extension = file_path.lower().split('.')[-1] if '.' in file_path else ''
if file_extension in ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']:
# Simular OCR
extracted_text = "Premio de $5000 - Haz clic para reclamar ahora - Oferta válida solo hoy"
file_results.append(f"📸 **Imagen analizada:** {extracted_text}")
content_to_analyze += f" [IMAGEN: {extracted_text}]"
content_type = "imagen con texto"
elif file_extension in ['mp3', 'wav', 'ogg', 'm4a', 'flac']:
# Simular transcripción
transcribed_text = "Felicidades, ha ganado un premio especial. Proporcione sus datos bancarios para procesar el pago inmediatamente."
file_results.append(f"🎵 **Audio transcrito:** {transcribed_text}")
content_to_analyze += f" [AUDIO: {transcribed_text}]"
content_type = "audio transcrito"
# Verificar contenido válido
if not content_to_analyze.strip():
error_message = """
⚠️ Contenido requerido
Para realizar un análisis, envía:
📱 Mensaje de texto sospechoso (SMS, WhatsApp, email)
📸 Captura de pantalla de comunicación sospechosa
🎵 Audio de llamada o mensaje de voz sospechoso
Ejemplo: "He recibido este SMS: 'Felicidades, has ganado $10,000. Haz clic aquí para reclamar'"
"""
history.append([message or "Sin contenido", error_message])
return "", history, None
# Realizar análisis avanzado
analysis = advanced_scam_analysis(content_to_analyze, content_type)
# Incrementar uso y guardar análisis
increment_usage()
save_analysis(
content_type=content_type,
content_preview=content_to_analyze[:200],
risk_level=analysis["risk_level"],
risk_score=analysis["risk_score"],
analysis_result=str(analysis)
)
# Formatear resultado
analysis_result = format_analysis_result(analysis)
# Agregar información de archivos si los hay
if file_results:
file_info = " ".join(file_results)
analysis_result = f"""
📁 Archivos Procesados
{file_info}
{analysis_result}
"""
# Información del usuario y uso
remaining = DAILY_FREE_LIMIT - current_session["daily_usage"] if not current_session["is_pro"] else "∞"
status_icon = "👑" if current_session["is_pro"] else "🆓"
plan_name = "PRO" if current_session["is_pro"] else "FREE"
user_info = f"""
{last_login_date.split()[0] if last_login_date != 'Nunca' else 'Hoy'}
Último acceso
{subscription_info}
📈 Estadísticas de Análisis
{stats['high_risk']}
🔴 Alto Riesgo
{high_risk_pct:.1f}%
{stats['medium_risk']}
🟡 Riesgo Medio
{medium_risk_pct:.1f}%
{stats['low_risk']}
🟢 Bajo Riesgo
{low_risk_pct:.1f}%
{recent_html}
⚙️ Configuración de Cuenta
"""
def create_payment_interface():
"""Crea la interfaz de pago con Stripe y PayPal"""
if not current_session["logged_in"]:
return "❌ Debes iniciar sesión para acceder a los planes de pago"
payment_status = "✅ Stripe configurado" if PAYMENTS_ENABLED else "⚠️ Pagos no configurados"
return f"""
🚀 Actualizar a AntiScam AI Pro
Protección ilimitada contra estafas digitales
{payment_status}
🆓 Plan Gratuito
$0
por mes
✅ {DAILY_FREE_LIMIT} análisis por día
✅ Detección básica de estafas
✅ Análisis de texto
❌ Análisis de imágenes
❌ Análisis de audio
❌ Informes detallados
❌ Soporte prioritario
⭐ RECOMENDADO
👑 Plan Pro
${PRO_PRICE}
por mes
+ 7 días GRATIS
✅ Análisis ILIMITADOS
✅ IA avanzada con mayor precisión
✅ Análisis de imágenes (OCR)
✅ Análisis de audio
✅ Informes detallados
✅ Historial completo
✅ Soporte prioritario 24/7
✅ Estadísticas avanzadas
✅ Exportar informes
💳 Métodos de Pago
{"" if PAYMENTS_ENABLED else '
⚠️ Los pagos no están configurados en el servidor. Contacta al administrador.
'}
💳
Tarjeta de Crédito/Débito
Procesado por Stripe
🔒 Pago 100% seguro
💳 Visa, Mastercard, Amex
⚡ Activación inmediata
🏦
PayPal
Pago seguro con PayPal
🔒 Protección del comprador
💼 Sin compartir datos bancarios
🌍 Aceptado mundialmente
🛡️ Garantías de Seguridad
🔒 Encriptación SSL 256-bit Tus datos están protegidos
"""
def logout_user():
"""Cierra sesión del usuario"""
global current_session
current_session = {
"logged_in": False,
"user_id": None,
"email": "",
"full_name": "",
"is_pro": False,
"avatar_url": "",
"subscription_expires": None,
"daily_usage": 0
}
return "✅ Sesión cerrada correctamente"
def handle_register(email, password, confirm_password, full_name):
"""Maneja el registro de usuario"""
if not all([email, password, confirm_password, full_name]):
return "❌ Todos los campos son obligatorios", gr.update(visible=True), gr.update(visible=False)
if password != confirm_password:
return "❌ Las contraseñas no coinciden", gr.update(visible=True), gr.update(visible=False)
if len(password) < 8:
return "❌ La contraseña debe tener al menos 8 caracteres", gr.update(visible=True), gr.update(visible=False)
success, message = register_user(email, password, full_name)
if success:
return message, gr.update(visible=True), gr.update(visible=False)
else:
return message, gr.update(visible=True), gr.update(visible=False)
def handle_login(email, password):
"""Maneja el login de usuario"""
if not email or not password:
return "❌ Email y contraseña son obligatorios", gr.update(visible=True), gr.update(visible=False)
success, message = login_user(email, password)
if success:
return message, gr.update(visible=False), gr.update(visible=True)
else:
return message, gr.update(visible=True), gr.update(visible=False)
def handle_verification(token):
"""Maneja la verificación de email"""
if not token:
return "❌ Token de verificación requerido"
success, message = verify_user_email(token)
return message
# CSS personalizado mejorado
custom_css = """
.gradio-container {
max-width: 1400px !important;
margin: auto !important;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.main-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2.5rem;
border-radius: 20px;
text-align: center;
margin-bottom: 2rem;
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
}
.auth-container {
max-width: 500px;
margin: 0 auto;
background: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.chat-container {
background: white;
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
overflow: hidden;
}
.profile-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem;
text-align: center;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin: 1rem 0;
}
.stat-card {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
padding: 1.5rem;
border-radius: 12px;
text-align: center;
border: 1px solid #dee2e6;
}
.pro-badge {
background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
color: #333;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.75em;
font-weight: bold;
display: inline-block;
}
.free-badge {
background: #6c757d;
color: white;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.75em;
font-weight: bold;
display: inline-block;
}
.risk-high { color: #dc3545 !important; }
.risk-medium { color: #fd7e14 !important; }
.risk-low { color: #28a745 !important; }
@media (max-width: 768px) {
.gradio-container {
padding: 1rem;
}
.main-header {
padding: 1.5rem;
}
.auth-container {
padding: 1.5rem;
}
}
"""
def create_interface():
"""Crea la interfaz completa de AntiScam AI"""
# Inicializar sistema
init_database()
load_ai_model()
with gr.Blocks(css=custom_css, title="🛡️ AntiScam AI Pro", theme=gr.themes.Soft()) as app:
# Header principal
gr.HTML("""
🛡️ AntiScam AI
Protección inteligente contra estafas digitales
🤖 Powered by IA avanzada • 🔒 Análisis ético y profesional • 🌍 Protección global
""")
# Estado de la aplicación
app_state = gr.State({"current_view": "auth"})
# Sección de autenticación
with gr.Column(visible=True) as auth_section:
with gr.Row():
with gr.Column(scale=1):
pass # Espaciado
with gr.Column(scale=2):
gr.HTML('
')
with gr.Tab("🔑 Iniciar Sesión") as login_tab:
with gr.Column():
login_email = gr.Textbox(
label="📧 Email",
placeholder="tu@email.com",
type="email"
)
login_password = gr.Textbox(
label="🔒 Contraseña",
placeholder="Tu contraseña",
type="password"
)
login_btn = gr.Button(
"🔑 Iniciar Sesión",
variant="primary",
size="lg"
)
login_output = gr.Markdown()
with gr.Tab("📝 Crear Cuenta") as register_tab:
with gr.Column():
reg_name = gr.Textbox(
label="👤 Nombre completo",
placeholder="Ej: Juan Pérez"
)
reg_email = gr.Textbox(
label="📧 Email",
placeholder="tu@email.com",
type="email"
)
reg_password = gr.Textbox(
label="🔒 Contraseña",
placeholder="Mínimo 8 caracteres",
type="password"
)
reg_confirm = gr.Textbox(
label="🔒 Confirmar contraseña",
placeholder="Repite tu contraseña",
type="password"
)
register_btn = gr.Button(
"📝 Crear cuenta gratuita",
variant="primary",
size="lg"
)
register_output = gr.Markdown()
with gr.Tab("✅ Verificar Email") as verify_tab:
with gr.Column():
verify_token = gr.Textbox(
label="🔑 Token de verificación",
placeholder="Pega aquí el token del email"
)
verify_btn = gr.Button(
"✅ Verificar cuenta",
variant="primary"
)
verify_output = gr.Markdown()
gr.HTML('
')
with gr.Column(scale=1):
pass # Espaciado
# Aplicación principal (inicialmente oculta)
with gr.Column(visible=False) as main_app:
# Navegación
with gr.Row():
nav_chat = gr.Button("💬 Chat", variant="primary")
nav_profile = gr.Button("👤 Perfil", variant="secondary")
nav_payment = gr.Button("💳 Pro", variant="secondary")
nav_logout = gr.Button("🚪 Salir", variant="secondary")
# Chat principal
with gr.Column(visible=True) as chat_section:
gr.HTML('
')
# Mensaje de bienvenida personalizado
welcome_html = f"""
🎉 ¡Bienvenido a AntiScam AI!
Estás protegido con nuestro sistema de IA avanzada. Como usuario FREE,
tienes {DAILY_FREE_LIMIT} análisis gratuitos por día.
🚀 ¿Cómo empezar?
📱 Copia un mensaje sospechoso que hayas recibido
📸 Sube una captura de WhatsApp, email o SMS
🎵 Comparte un audio de llamada sospechosa
📝 Describe la situación que te resulta extraña
💡 Ejemplos de análisis:
• "Has ganado $10,000. Haz clic aquí para reclamar"
• "Tu cuenta será suspendida. Confirma tus datos"
• "Inversión garantizada con 500% de retorno"
• "Soporte técnico de Microsoft. Tu PC está infectado"
💬 ¡Envía tu primer mensaje para comenzar!
"""
chatbot = gr.Chatbot(
value=[["👋 ¡Hola! ¿Cómo funciona AntiScam AI?", welcome_html]],
height=550,
show_label=False,
avatar_images=("👤", "🛡️"),
bubble_full_width=False
)
with gr.Row():
with gr.Column(scale=4):
msg = gr.Textbox(
placeholder="💬 Describe o pega aquí el contenido sospechoso que quieres analizar...",
show_label=False,
lines=3,
max_lines=5
)
with gr.Column(scale=1):
files = gr.File(
file_count="multiple",
file_types=["image", "audio"],
label="📎 Archivos",
show_label=True
)
with gr.Row():
send_btn = gr.Button(
"🔍 Analizar con IA",
variant="primary",
size="lg",
scale=2
)
clear_btn = gr.Button(
"🗑️ Limpiar",
variant="secondary",
scale=1
)
gr.HTML('