import streamlit as st import pandas as pd from datetime import datetime import os import json from PIL import Image import google.generativeai as genai import gspread from google.oauth2.service_account import Credentials # --- CONFIGURACIÓN DE PÁGINA --- st.set_page_config(page_title="Escáner IA con Gemini", page_icon="✨", layout="centered") st.title("✨ Escáner Inteligente con Gemini AI") look = pd.read_csv("Informacion - Estados.csv") df_ubicaciones = pd.read_excel('Municipios (1).xlsx', engine='openpyxl') #AGG GOOGLE SHEET try: SCOPE = ["https://www.googleapis.com/auth/spreadsheets"] # LA NUEVA FORMA SEGURA (Cargando desde un Secreto oculto) credenciales_secretas = os.environ.get("GOOGLE_SHEETS_JSON") # Convertimos el texto secreto de vuelta a un diccionario de Python creds_dict = json.loads(credenciales_secretas) CREDS = Credentials.from_service_account_info(creds_dict, scopes=SCOPE) client = gspread.authorize(CREDS) sheet_id = "1dDgUALSVyqgMQJTkCxs2kjI3S5IVoggxxias4dEcqb8" # TU ID ACTUAL workbook = client.open_by_key(sheet_id) # ¡IMPORTANTE! Crea una hoja nueva llamada "Encuestas" en tu archivo de Google Sheets worksheet = workbook.worksheet("Registro") except: worksheet = None # --- CONECTAR CON GOOGLE AI STUDIO --- GOOGLE_API_KEY = os.environ.get("GEMINI_API_KEY") genai.configure(api_key=GOOGLE_API_KEY) # Usamos Gemini 1.5 Flash porque es rapidísimo, excelente viendo imágenes y 100% gratis en AI Studio modelo = genai.GenerativeModel('gemini-2.5-flash') def calcular_edad(fecha_str): try: fecha_nac = datetime.strptime(fecha_str, "%d-%m-%Y") hoy = datetime.now() return hoy.year - fecha_nac.year - ((hoy.month, hoy.day) < (fecha_nac.month, fecha_nac.day)) except: return "N/A" # --- INTERFAZ --- st.markdown("---") curso = st.radio("Tipo de registro*", ["Jugador", "Entrenador", "Desarrollador de talento"], horizontal=True, index=None) st.markdown("---") look = look.rename(columns = {'Estado':'ESTADO'}) estados = look['ESTADO'].unique().tolist() selected_state = st.selectbox( "1. Selecciona el estado:", options=[''] + estados, index=0 ) st.markdown("---") selected_municipality = None if selected_state: # Filtra los municipios que pertenecen al estado seleccionado state_municipalities = df_ubicaciones[df_ubicaciones['ESTADO'] == selected_state]['MUNICIPIO'].unique().tolist() selected_municipality = st.selectbox( "3. Selecciona el municipio:", options=[''] + state_municipalities, index=0 ) st.markdown("---") opcion = st.radio("Método de entrada:", ("Usar Cámara 📷", "Subir Archivo 📁"), horizontal=True) imagen_pil = None if opcion == "Usar Cámara 📷": foto = st.camera_input("Toma la foto de la cédula (no importa si está un poco torcida)") if foto: imagen_pil = Image.open(foto) else: archivo_subido = st.file_uploader("Sube la imagen de la cédula", type=["jpg", "jpeg", "png"]) if archivo_subido: imagen_pil = Image.open(archivo_subido) # --- PROCESAMIENTO CON GEMINI --- if imagen_pil is not None: st.image(imagen_pil, caption="Imagen Capturada", use_column_width=True) if st.button("🚀 Analizar Cédula con Gemini"): with st.spinner("La IA está leyendo la cédula..."): # El "Prompt" (Las instrucciones exactas para la IA) prompt = """ Eres un sistema de OCR avanzado de nivel bancario. Analiza esta imagen de una cédula de identidad venezolana. REGLA DE ORO: El fondo tiene un escudo amarillo y letras pequeñas, IGNORA EL ESCUDO y el fondo. Concéntrate SOLO en el texto negro principal. Extrae estos datos con precisión absoluta: 1. Cédula: Busca la 'V' o 'E', seguida de números. Quita los puntos. (Ejemplo: V-12345678). 2. Apellidos: Está justo a la derecha de la etiqueta "APELLIDOS". 3. Nombres: Está justo a la derecha de la etiqueta "NOMBRES". 4. Fecha de nacimiento: Formato DD-MM-YYYY. Suele estar en el centro, cerca de la etiqueta "F. NACIMIENTO". ¡No la confundas con la fecha de expedición o vencimiento! Devuelve ÚNICAMENTE un JSON válido con estas claves exactas: "cedula", "apellidos", "nombres", "fecha_nacimiento". Si algún dato está demasiado borroso, escribe "No legible". NO INVENTES NÚMEROS. """ try: # Enviamos la imagen y las instrucciones a Gemini respuesta = modelo.generate_content([prompt, imagen_pil]) texto_respuesta = respuesta.text.strip() # Limpiamos por si Gemini añade ```json al principio por error if texto_respuesta.startswith("```json"): texto_respuesta = texto_respuesta[7:-3] elif texto_respuesta.startswith("```"): texto_respuesta = texto_respuesta[3:-3] # Convertimos la respuesta de texto a un diccionario de Python datos_extraidos = json.loads(texto_respuesta) cedula = datos_extraidos.get("cedula", "Error") apellidos = datos_extraidos.get("apellidos", "Error") nombres = datos_extraidos.get("nombres", "Error") fecha_nac = datos_extraidos.get("fecha_nacimiento", "Error") edad = calcular_edad(fecha_nac) # Mostrar resultados st.success("¡Análisis completado al instante!") col1, col2 = st.columns(2) col1.text_input("Cédula", value=cedula) col1.text_input("Apellidos", value=apellidos) col2.text_input("Fecha de Nacimiento", value=fecha_nac) col2.text_input("Nombres", value=nombres) st.metric("Edad Calculada", f"{edad} años" if isinstance(edad, int) else edad) # Guardar en Excel fila_a_guardar = [cedula, apellidos, nombres, fecha_nac, edad, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), curso, selected_state,selected_municipality] if worksheet: try: worksheet.append_row(fila_a_guardar) st.success("✅ ¡Gracias! Tu encuesta ha sido registrada exitosamente.") st.balloons() except Exception as e: st.error(f"Error al conectar con Google Sheets: {str(e)}") else: st.error("⚠️ No hay conexión configurada con la base de datos (Google Sheets).") except Exception as e: st.error(f"Hubo un error al procesar con la IA. Asegúrate de que la foto sea clara. Detalles: {e}") with st.expander("Ver respuesta cruda de la IA (Depuración)"): st.write(respuesta.text if 'respuesta' in locals() else "Sin respuesta")