| 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 |
|
|
| |
| 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') |
|
|
| |
| try: |
| SCOPE = ["https://www.googleapis.com/auth/spreadsheets"] |
| |
| credenciales_secretas = os.environ.get("GOOGLE_SHEETS_JSON") |
| |
| creds_dict = json.loads(credenciales_secretas) |
| CREDS = Credentials.from_service_account_info(creds_dict, scopes=SCOPE) |
| client = gspread.authorize(CREDS) |
| sheet_id = "1dDgUALSVyqgMQJTkCxs2kjI3S5IVoggxxias4dEcqb8" |
| workbook = client.open_by_key(sheet_id) |
| |
| |
| worksheet = workbook.worksheet("Registro") |
| except: |
| worksheet = None |
|
|
| |
| GOOGLE_API_KEY = os.environ.get("GEMINI_API_KEY") |
| genai.configure(api_key=GOOGLE_API_KEY) |
|
|
|
|
| |
| 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" |
|
|
| |
| 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: |
| |
| 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) |
|
|
| |
| 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..."): |
| |
| |
| 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: |
| |
| respuesta = modelo.generate_content([prompt, imagen_pil]) |
| texto_respuesta = respuesta.text.strip() |
| |
| |
| if texto_respuesta.startswith("```json"): |
| texto_respuesta = texto_respuesta[7:-3] |
| elif texto_respuesta.startswith("```"): |
| texto_respuesta = texto_respuesta[3:-3] |
| |
| |
| 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) |
|
|
| |
| 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) |
| |
| |
| 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") |
|
|