File size: 6,154 Bytes
4e07023
 
 
 
 
 
26aa008
f0544a6
26aa008
 
4e07023
f0544a6
 
 
 
 
 
26aa008
4e07023
 
 
 
 
 
26aa008
4e07023
 
26aa008
 
 
 
 
 
 
4e07023
 
26aa008
4e07023
26aa008
4e07023
26aa008
 
 
4e07023
26aa008
4e07023
26aa008
 
 
 
 
 
 
4e07023
26aa008
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f0544a6
26aa008
4e07023
 
 
 
26aa008
4e07023
 
 
 
 
 
 
26aa008
4e07023
 
 
 
26aa008
 
 
 
 
4e07023
26aa008
 
4e07023
26aa008
4e07023
26aa008
 
4e07023
 
26aa008
 
 
4e07023
26aa008
4e07023
26aa008
 
4e07023
26aa008
 
 
 
 
4e07023
 
 
 
26aa008
4e07023
26aa008
4e07023
26aa008
4e07023
 
 
 
 
 
26aa008
4e07023
26aa008
 
 
 
 
f0544a6
26aa008
 
 
 
 
 
 
 
4e07023
26aa008
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import streamlit as st
import pandas as pd
from PIL import Image
import sys
import os

# --- CORRECCIÓN DE RUTAS ---
current_dir = os.path.dirname(os.path.abspath(__file__))
src_path = os.path.join(current_dir, '/src') # Ajuste para subir un nivel y entrar a src
sys.path.append(os.path.abspath(src_path))

try:
    from inference import MemePredictor
except ImportError as e:
    st.error(f"Error crítico de importación: {e}")
    st.stop()

# --- 1. CONFIGURACIÓN DE PÁGINA ---
st.set_page_config(
    page_title="DIME-MEX",
    layout="centered",
    initial_sidebar_state="collapsed"
)

# --- 2. ESTILOS CSS "APPLE STYLE" ---
st.markdown("""
    <style>
        /* Tipografía limpia (System Fonts) */
        html, body, [class*="css"] {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            color: #1d1d1f;
        }
        
        /* Ocultar elementos nativos de Streamlit */
        #MainMenu {visibility: hidden;}
        footer {visibility: hidden;}
        header {visibility: hidden;}
        
        /* Contenedor principal con más aire */
        .block-container {
            padding-top: 3rem;
            padding-bottom: 3rem;
            max-width: 700px;
        }
/* --- BOTÓN ANALIZAR --- */
        div.stButton > button:first-child {
            background-color: #0071e3; /* Azul Apple */
            color: white;
            border: none;
            border-radius: 12px;
            padding: 15px 30px; /* Más grande */
            font-size: 18px;    /* Texto más grande */
            font-weight: 600;
            width: 100%;
            transition: all 0.2s ease;
            box-shadow: 0 4px 6px rgba(0, 113, 227, 0.2);
        }
        
        div.stButton > button:first-child:hover {
            background-color: #0077ED;
            transform: scale(1.01);
        }

        /* --- RADIO BUTTON (La bolita azul) --- */
        div[role="radiogroup"] label > div:first-child {
            background-color: #0071e3 !important;
            border-color: #0071e3 !important;
        }
        /* Estilo de las Métricas (Tarjetas grises tipo iOS) */
        div[data-testid="stMetric"] {
            background-color: #f5f5f7;
            border-radius: 18px;
            padding: 20px;
            text-align: center;
            border: 1px solid #e5e5e5;
        }
        
        div[data-testid="stMetricLabel"] {
            font-size: 14px;
            color: #86868b;
        }
        
        div[data-testid="stMetricValue"] {
            font-size: 24px;
            font-weight: 600;
            color: #1d1d1f;
        }

        /* Imágenes con bordes redondeados */
        img {
            border-radius: 18px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.08);
        }
        
        /* File Uploader más limpio */
        div[data-testid="stFileUploader"] {
            margin-top: 20px;
            margin-bottom: 20px;
        }
        
        /* Títulos */
        h1, h2, h3 {
            font-weight: 600;
            letter-spacing: -0.02em;
        }
    </style>
""", unsafe_allow_html=True)

# --- 3. CARGA DEL MOTOR ---
@st.cache_resource
def get_engine():
    return MemePredictor()

try:
    predictor = get_engine()
except Exception as e:
    st.error("El servicio no está disponible en este momento.")
    st.stop()

# --- 4. INTERFAZ DE USUARIO ---

# Encabezado Minimalista
st.markdown("<h1 style='text-align: center; margin-bottom: 10px;'>DIME-MEX</h1>", unsafe_allow_html=True)
st.markdown("<p style='text-align: center; color: #86868b; font-size: 18px;'>Análisis de contenido mediante IA.</p>", unsafe_allow_html=True)

st.write("") # Espaciador

# Configuración (Acordeón limpio)
with st.expander("Elegir modelo"):
    task_mode = st.radio(
        "Sensibilidad del modelo",
        options=["simple", "complex"],
        format_func=lambda x: "Estándar ( none, inappropriate, hate-speech )" if x == "simple" else "Detallado ( none, inappropriate, sexism, racism, classicis, hate-speech )",
        label_visibility="collapsed"
    )

# Área de Carga
uploaded_file = st.file_uploader("Subir imagen", type=["jpg", "png", "jpeg"], label_visibility="collapsed")
    
if uploaded_file is not None:
    # Mostrar imagen
    image = Image.open(uploaded_file)
    # CORRECCIÓN: Usamos use_container_width en lugar de use_column_width
    st.image(image, use_container_width=True)
    
    st.write("") # Espaciador vertical
    
    # Botón de Acción
    if st.button("Analizar"):
        with st.spinner("Analizando..."):
            try:
                result = predictor.predict(uploaded_file, task=task_mode)
                
                if "error" in result:
                    st.error("No se pudo procesar la imagen.")
                else:
                    st.write("") # Espaciador
                    
                    # --- RESULTADOS (Tarjetas) ---
                    col1, col2 = st.columns(2)
                    
                    with col1:
                        st.metric(label="Clasificación", value=result['label'])
                    
                    with col2:
                        st.metric(label="Certeza", value=f"{result['confidence']:.1%}")
                    
                    # --- DETALLES (Acordeón inferior) ---
                    st.write("")
                    with st.expander("Detalles del análisis"):
                        st.caption("TEXTO DETECTADO")
                        st.markdown(f"_{result['ocr_text']}_")
                        
                        st.write("")
                        st.caption("PROBABILIDADES")
                        # Crear dataframe limpio para la gráfica
                        chart_data = pd.DataFrame({
                            "Categoría": result['all_labels'],
                            "Probabilidad": result['probabilities']
                        })
                        st.bar_chart(chart_data.set_index("Categoría"), color="#86868b")

            except Exception:
                st.error("Ocurrió un error inesperado durante el análisis.")