Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -98,19 +98,19 @@ col1, col2 = st.columns([1, 2])
|
|
98 |
|
99 |
# Columna de entrada
|
100 |
with col1:
|
101 |
-
|
102 |
value=st.session_state.producto,
|
103 |
placeholder="Ejemplo: Curso de Inglés",
|
104 |
key="producto_input",
|
105 |
height=70)
|
106 |
-
st.session_state.producto =
|
107 |
|
108 |
-
|
109 |
value=st.session_state.habilidades,
|
110 |
placeholder="Ejemplo: Enseñanza, comunicación, diseño de contenidos",
|
111 |
key="habilidades_input",
|
112 |
height=70)
|
113 |
-
st.session_state.habilidades =
|
114 |
|
115 |
# Botón para generar - Movido arriba del acordeón
|
116 |
submit = st.button("CREAR MI CLIENTE IDEAL SOÑADO ➤➤", on_click=update_profile)
|
@@ -121,34 +121,34 @@ with col1:
|
|
121 |
if 'publico_objetivo' not in st.session_state:
|
122 |
st.session_state.publico_objetivo = ""
|
123 |
|
124 |
-
|
125 |
value=st.session_state.publico_objetivo,
|
126 |
placeholder="Ejemplo: Profesionales entre 25-40 años interesados en desarrollo personal",
|
127 |
key="publico_objetivo_input",
|
128 |
height=70)
|
129 |
-
st.session_state.publico_objetivo =
|
130 |
|
131 |
# Selector de formato
|
132 |
from format.format import buyer_persona_formats
|
133 |
|
134 |
# Usar directamente las claves del diccionario sin filtrar
|
135 |
-
|
136 |
"Formato del perfil",
|
137 |
options=list(buyer_persona_formats.keys()),
|
138 |
format_func=lambda x: x.capitalize(),
|
139 |
index=list(buyer_persona_formats.keys()).index(st.session_state.formato) if st.session_state.formato in buyer_persona_formats else 0,
|
140 |
help="Selecciona el formato en el que se presentará el perfil del cliente ideal"
|
141 |
)
|
142 |
-
st.session_state.formato =
|
143 |
|
144 |
# Nivel de creatividad con slider
|
145 |
-
|
146 |
min_value=0.0,
|
147 |
max_value=2.0,
|
148 |
value=st.session_state.creatividad,
|
149 |
step=0.1,
|
150 |
key="creatividad_slider")
|
151 |
-
st.session_state.creatividad =
|
152 |
|
153 |
# Selector de nivel de conciencia
|
154 |
consciousness_options = []
|
@@ -183,7 +183,7 @@ with col2:
|
|
183 |
if st.session_state.producto and st.session_state.habilidades:
|
184 |
with st.spinner("Creando tu Cliente Ideal Soñado..."):
|
185 |
# Generar el perfil del cliente
|
186 |
-
|
187 |
st.session_state.producto,
|
188 |
st.session_state.habilidades,
|
189 |
st.session_state.publico_objetivo,
|
@@ -193,56 +193,56 @@ with col2:
|
|
193 |
)
|
194 |
|
195 |
# Mejorar la limpieza del perfil para eliminar estructuras JSON/diccionario
|
196 |
-
if isinstance(
|
197 |
import re
|
198 |
import json
|
199 |
|
200 |
# Eliminar marcadores de código markdown como ```json, ```python, etc.
|
201 |
-
|
202 |
-
|
203 |
|
204 |
# Intentar detectar y limpiar formato JSON
|
205 |
-
if '{' in
|
206 |
# Intentar extraer solo el contenido textual, eliminando estructuras JSON
|
207 |
# Primero, intentar encontrar el JSON completo
|
208 |
json_pattern = r'(\{.*?\})'
|
209 |
-
json_matches = re.findall(json_pattern,
|
210 |
|
211 |
if json_matches:
|
212 |
for json_match in json_matches:
|
213 |
# Intentar extraer el contenido real del JSON
|
214 |
try:
|
215 |
# Reemplazar el JSON con una cadena vacía
|
216 |
-
|
217 |
except:
|
218 |
pass
|
219 |
|
220 |
# Limpiar líneas que parecen ser parte de un diccionario
|
221 |
-
lines =
|
222 |
cleaned_lines = []
|
223 |
for line in lines:
|
224 |
# Omitir líneas que parecen ser claves de diccionario
|
225 |
if not re.match(r'^\s*["\']?[a-zA-Z_]+["\']?\s*:', line):
|
226 |
cleaned_lines.append(line)
|
227 |
|
228 |
-
|
229 |
|
230 |
# Eliminar llaves sueltas y corchetes
|
231 |
-
|
232 |
|
233 |
# Eliminar comillas y dos puntos que parecen ser de un diccionario
|
234 |
-
|
235 |
|
236 |
# Eliminar "template", "description", "example" y otras palabras clave comunes en el formato
|
237 |
keywords = ["template", "description", "example", "Nivel de conciencia"]
|
238 |
for keyword in keywords:
|
239 |
-
|
240 |
|
241 |
# Eliminar comillas sueltas
|
242 |
-
|
243 |
|
244 |
# Normalizar espacios en blanco y sangrías
|
245 |
-
lines =
|
246 |
cleaned_lines = []
|
247 |
for line in lines:
|
248 |
# Eliminar sangrías excesivas pero mantener estructura básica
|
@@ -251,34 +251,34 @@ with col2:
|
|
251 |
cleaned_lines.append(cleaned_line)
|
252 |
|
253 |
# Unir las líneas con saltos de línea adecuados
|
254 |
-
|
255 |
|
256 |
# Eliminar espacios en blanco adicionales
|
257 |
-
|
258 |
-
|
259 |
|
260 |
# Al inicio del archivo, junto con las otras inicializaciones
|
261 |
if 'perfil_cliente_plain' not in st.session_state:
|
262 |
st.session_state.perfil_cliente_plain = None
|
263 |
|
264 |
# Guardar versión sin formato antes de aplicar estilos HTML
|
265 |
-
st.session_state.perfil_cliente_plain =
|
266 |
|
267 |
# Convertir los asteriscos de formato Markdown a HTML para una correcta visualización
|
268 |
# Convertir **texto** a <strong>texto</strong>
|
269 |
-
|
270 |
# Convertir *texto* a <em>texto</em>
|
271 |
-
|
272 |
|
273 |
# Mejorar el formato HTML para una mejor visualización
|
274 |
-
|
275 |
<div style="line-height: 1.3; text-align: left;">
|
276 |
{}
|
277 |
</div>
|
278 |
-
""".format(
|
279 |
|
280 |
# Guardar en session_state
|
281 |
-
st.session_state.perfil_cliente =
|
282 |
# Resetear el estado de envío
|
283 |
st.session_state.submitted = False
|
284 |
|
|
|
98 |
|
99 |
# Columna de entrada
|
100 |
with col1:
|
101 |
+
product = st.text_area("¿Qué producto o servicio ofreces?",
|
102 |
value=st.session_state.producto,
|
103 |
placeholder="Ejemplo: Curso de Inglés",
|
104 |
key="producto_input",
|
105 |
height=70)
|
106 |
+
st.session_state.producto = product
|
107 |
|
108 |
+
skills = st.text_area("¿Cuáles son tus habilidades principales?",
|
109 |
value=st.session_state.habilidades,
|
110 |
placeholder="Ejemplo: Enseñanza, comunicación, diseño de contenidos",
|
111 |
key="habilidades_input",
|
112 |
height=70)
|
113 |
+
st.session_state.habilidades = skills
|
114 |
|
115 |
# Botón para generar - Movido arriba del acordeón
|
116 |
submit = st.button("CREAR MI CLIENTE IDEAL SOÑADO ➤➤", on_click=update_profile)
|
|
|
121 |
if 'publico_objetivo' not in st.session_state:
|
122 |
st.session_state.publico_objetivo = ""
|
123 |
|
124 |
+
target_audience = st.text_area("¿Cuál es tu público objetivo? (opcional)",
|
125 |
value=st.session_state.publico_objetivo,
|
126 |
placeholder="Ejemplo: Profesionales entre 25-40 años interesados en desarrollo personal",
|
127 |
key="publico_objetivo_input",
|
128 |
height=70)
|
129 |
+
st.session_state.publico_objetivo = target_audience
|
130 |
|
131 |
# Selector de formato
|
132 |
from format.format import buyer_persona_formats
|
133 |
|
134 |
# Usar directamente las claves del diccionario sin filtrar
|
135 |
+
format_type = st.selectbox(
|
136 |
"Formato del perfil",
|
137 |
options=list(buyer_persona_formats.keys()),
|
138 |
format_func=lambda x: x.capitalize(),
|
139 |
index=list(buyer_persona_formats.keys()).index(st.session_state.formato) if st.session_state.formato in buyer_persona_formats else 0,
|
140 |
help="Selecciona el formato en el que se presentará el perfil del cliente ideal"
|
141 |
)
|
142 |
+
st.session_state.formato = format_type
|
143 |
|
144 |
# Nivel de creatividad con slider
|
145 |
+
temperature = st.slider("Nivel de creatividad",
|
146 |
min_value=0.0,
|
147 |
max_value=2.0,
|
148 |
value=st.session_state.creatividad,
|
149 |
step=0.1,
|
150 |
key="creatividad_slider")
|
151 |
+
st.session_state.creatividad = temperature
|
152 |
|
153 |
# Selector de nivel de conciencia
|
154 |
consciousness_options = []
|
|
|
183 |
if st.session_state.producto and st.session_state.habilidades:
|
184 |
with st.spinner("Creando tu Cliente Ideal Soñado..."):
|
185 |
# Generar el perfil del cliente
|
186 |
+
buyer_persona = generate_buyer_persona(
|
187 |
st.session_state.producto,
|
188 |
st.session_state.habilidades,
|
189 |
st.session_state.publico_objetivo,
|
|
|
193 |
)
|
194 |
|
195 |
# Mejorar la limpieza del perfil para eliminar estructuras JSON/diccionario
|
196 |
+
if isinstance(buyer_persona, str):
|
197 |
import re
|
198 |
import json
|
199 |
|
200 |
# Eliminar marcadores de código markdown como ```json, ```python, etc.
|
201 |
+
buyer_persona = re.sub(r'```[a-z]*\n', '', buyer_persona)
|
202 |
+
buyer_persona = re.sub(r'```', '', buyer_persona)
|
203 |
|
204 |
# Intentar detectar y limpiar formato JSON
|
205 |
+
if '{' in buyer_persona and '}' in buyer_persona:
|
206 |
# Intentar extraer solo el contenido textual, eliminando estructuras JSON
|
207 |
# Primero, intentar encontrar el JSON completo
|
208 |
json_pattern = r'(\{.*?\})'
|
209 |
+
json_matches = re.findall(json_pattern, buyer_persona, re.DOTALL)
|
210 |
|
211 |
if json_matches:
|
212 |
for json_match in json_matches:
|
213 |
# Intentar extraer el contenido real del JSON
|
214 |
try:
|
215 |
# Reemplazar el JSON con una cadena vacía
|
216 |
+
buyer_persona = buyer_persona.replace(json_match, '')
|
217 |
except:
|
218 |
pass
|
219 |
|
220 |
# Limpiar líneas que parecen ser parte de un diccionario
|
221 |
+
lines = buyer_persona.split('\n')
|
222 |
cleaned_lines = []
|
223 |
for line in lines:
|
224 |
# Omitir líneas que parecen ser claves de diccionario
|
225 |
if not re.match(r'^\s*["\']?[a-zA-Z_]+["\']?\s*:', line):
|
226 |
cleaned_lines.append(line)
|
227 |
|
228 |
+
buyer_persona = '\n'.join(cleaned_lines)
|
229 |
|
230 |
# Eliminar llaves sueltas y corchetes
|
231 |
+
buyer_persona = re.sub(r'[{}[\]]', '', buyer_persona)
|
232 |
|
233 |
# Eliminar comillas y dos puntos que parecen ser de un diccionario
|
234 |
+
buyer_persona = re.sub(r'["\']\s*:\s*["\']', '', buyer_persona)
|
235 |
|
236 |
# Eliminar "template", "description", "example" y otras palabras clave comunes en el formato
|
237 |
keywords = ["template", "description", "example", "Nivel de conciencia"]
|
238 |
for keyword in keywords:
|
239 |
+
buyer_persona = re.sub(rf'["\']?{keyword}["\']?\s*:\s*["\']?', '', buyer_persona)
|
240 |
|
241 |
# Eliminar comillas sueltas
|
242 |
+
buyer_persona = re.sub(r'^\s*["\']|["\']$', '', buyer_persona)
|
243 |
|
244 |
# Normalizar espacios en blanco y sangrías
|
245 |
+
lines = buyer_persona.split('\n')
|
246 |
cleaned_lines = []
|
247 |
for line in lines:
|
248 |
# Eliminar sangrías excesivas pero mantener estructura básica
|
|
|
251 |
cleaned_lines.append(cleaned_line)
|
252 |
|
253 |
# Unir las líneas con saltos de línea adecuados
|
254 |
+
buyer_persona = '\n'.join(cleaned_lines)
|
255 |
|
256 |
# Eliminar espacios en blanco adicionales
|
257 |
+
buyer_persona = re.sub(r'\n\s*\n', '\n\n', buyer_persona)
|
258 |
+
buyer_persona = buyer_persona.strip()
|
259 |
|
260 |
# Al inicio del archivo, junto con las otras inicializaciones
|
261 |
if 'perfil_cliente_plain' not in st.session_state:
|
262 |
st.session_state.perfil_cliente_plain = None
|
263 |
|
264 |
# Guardar versión sin formato antes de aplicar estilos HTML
|
265 |
+
st.session_state.perfil_cliente_plain = buyer_persona
|
266 |
|
267 |
# Convertir los asteriscos de formato Markdown a HTML para una correcta visualización
|
268 |
# Convertir **texto** a <strong>texto</strong>
|
269 |
+
buyer_persona = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', buyer_persona)
|
270 |
# Convertir *texto* a <em>texto</em>
|
271 |
+
buyer_persona = re.sub(r'\*(.*?)\*', r'<em>\1</em>', buyer_persona)
|
272 |
|
273 |
# Mejorar el formato HTML para una mejor visualización
|
274 |
+
buyer_persona = """
|
275 |
<div style="line-height: 1.3; text-align: left;">
|
276 |
{}
|
277 |
</div>
|
278 |
+
""".format(buyer_persona.replace('\n', '<br><br>'))
|
279 |
|
280 |
# Guardar en session_state
|
281 |
+
st.session_state.perfil_cliente = buyer_persona
|
282 |
# Resetear el estado de envío
|
283 |
st.session_state.submitted = False
|
284 |
|