Spaces:
Sleeping
Sleeping
Update format/format.py
Browse files- format/format.py +148 -1
format/format.py
CHANGED
@@ -585,4 +585,151 @@ validation_questions = {
|
|
585 |
Ensure your buyer persona thoroughly addresses these questions to create an accurate profile of someone who will value and invest in your offering.
|
586 |
---
|
587 |
"""
|
588 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
585 |
Ensure your buyer persona thoroughly addresses these questions to create an accurate profile of someone who will value and invest in your offering.
|
586 |
---
|
587 |
"""
|
588 |
+
}
|
589 |
+
|
590 |
+
# Funciones para manejar el texto crudo y renderizado
|
591 |
+
|
592 |
+
def get_raw_format(format_name):
|
593 |
+
"""
|
594 |
+
Devuelve el texto crudo (sin renderizar) de un formato específico.
|
595 |
+
|
596 |
+
Args:
|
597 |
+
format_name (str): Nombre del formato ('Jung's_Avatar', 'Búsqueda', o 'Storytelling')
|
598 |
+
|
599 |
+
Returns:
|
600 |
+
dict: Diccionario con las claves 'template', 'description' y 'example' conteniendo el texto crudo
|
601 |
+
"""
|
602 |
+
if format_name not in buyer_persona_formats:
|
603 |
+
raise ValueError(f"Formato '{format_name}' no encontrado. Formatos disponibles: {', '.join(buyer_persona_formats.keys())}")
|
604 |
+
|
605 |
+
return {
|
606 |
+
'template': buyer_persona_formats[format_name]['template'],
|
607 |
+
'description': buyer_persona_formats[format_name]['description'],
|
608 |
+
'example': buyer_persona_formats[format_name]['example']
|
609 |
+
}
|
610 |
+
|
611 |
+
def get_rendered_format(format_name, **kwargs):
|
612 |
+
"""
|
613 |
+
Devuelve el texto renderizado de un formato específico, reemplazando los placeholders
|
614 |
+
con los valores proporcionados en kwargs.
|
615 |
+
|
616 |
+
Args:
|
617 |
+
format_name (str): Nombre del formato ('Jung's_Avatar', 'Búsqueda', o 'Storytelling')
|
618 |
+
**kwargs: Pares clave-valor para reemplazar en el template
|
619 |
+
|
620 |
+
Returns:
|
621 |
+
str: Texto del template con los placeholders reemplazados
|
622 |
+
"""
|
623 |
+
if format_name not in buyer_persona_formats:
|
624 |
+
raise ValueError(f"Formato '{format_name}' no encontrado. Formatos disponibles: {', '.join(buyer_persona_formats.keys())}")
|
625 |
+
|
626 |
+
template = buyer_persona_formats[format_name]['template']
|
627 |
+
|
628 |
+
# Reemplazar placeholders simples
|
629 |
+
for key, value in kwargs.items():
|
630 |
+
placeholder = f"[{key}]"
|
631 |
+
template = template.replace(placeholder, value)
|
632 |
+
|
633 |
+
return template
|
634 |
+
|
635 |
+
def format_for_display(text, disable_accordion=True):
|
636 |
+
"""
|
637 |
+
Formatea el texto para su visualización, desactivando el comportamiento de acordeón
|
638 |
+
y asegurando que el formato sea consistente.
|
639 |
+
|
640 |
+
Args:
|
641 |
+
text (str): El texto a formatear
|
642 |
+
disable_accordion (bool): Si es True, elimina cualquier marcado que pueda causar comportamiento de acordeón
|
643 |
+
|
644 |
+
Returns:
|
645 |
+
str: Texto formateado para visualización
|
646 |
+
"""
|
647 |
+
# Asegurar que los saltos de línea se preserven correctamente
|
648 |
+
text = text.replace('\n', '<br>')
|
649 |
+
|
650 |
+
# Asegurar que los elementos de lista con viñetas se muestren correctamente
|
651 |
+
text = text.replace('• ', '• ')
|
652 |
+
|
653 |
+
# Envolver el contenido en un div con estilos que eviten el comportamiento de acordeón
|
654 |
+
html = f"""
|
655 |
+
<div class="static-content" style="white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word;">
|
656 |
+
{text}
|
657 |
+
</div>
|
658 |
+
"""
|
659 |
+
|
660 |
+
return html
|
661 |
+
|
662 |
+
def fix_storytelling_description():
|
663 |
+
"""
|
664 |
+
Corrige la descripción del formato Storytelling para que refleje correctamente sus características.
|
665 |
+
"""
|
666 |
+
buyer_persona_formats["Storytelling"]["description"] = """
|
667 |
+
**Formato Historia**
|
668 |
+
|
669 |
+
Este formato utiliza la estructura narrativa para contar la historia del cliente ideal, desde su situación problemática hasta la transformación que experimenta con tu solución.
|
670 |
+
|
671 |
+
**Características principales:**
|
672 |
+
- Enfoque en la narrativa y el viaje del cliente
|
673 |
+
- Estructura de historia con inicio, nudo y desenlace
|
674 |
+
- Énfasis en la transformación y el cambio
|
675 |
+
- Formato ideal para conectar emocionalmente
|
676 |
+
|
677 |
+
**Ideal para:**
|
678 |
+
- Páginas de ventas y landing pages
|
679 |
+
- Estudios de caso y testimonios
|
680 |
+
- Cuando necesitas generar conexión emocional
|
681 |
+
- Comunicar claramente el antes y después de tu solución
|
682 |
+
"""
|
683 |
+
return "Descripción del formato Storytelling corregida."
|
684 |
+
|
685 |
+
# Función para generar HTML que muestre el resultado sin acordeón
|
686 |
+
def get_response_html_wrapper(content, title="Tu Cliente Ideal"):
|
687 |
+
"""
|
688 |
+
Envuelve el contenido en un div con estilos que evitan el comportamiento de acordeón
|
689 |
+
y aplica un formato consistente.
|
690 |
+
|
691 |
+
Args:
|
692 |
+
content (str): El contenido a mostrar
|
693 |
+
title (str): El título del contenedor
|
694 |
+
|
695 |
+
Returns:
|
696 |
+
str: HTML formateado para mostrar el contenido
|
697 |
+
"""
|
698 |
+
return f"""
|
699 |
+
<div style="padding: 15px; border: 2px solid #3D89B8; border-radius: 8px;
|
700 |
+
box-shadow: 0 2px 5px rgba(61, 137, 184, 0.1); margin-bottom: 5px;
|
701 |
+
white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word;">
|
702 |
+
<h3 style="color: #1A3A5F; padding-bottom: 10px; border-bottom: 1px solid #3D89B8; margin-bottom: 15px;">{title}</h3>
|
703 |
+
<div>{content}</div>
|
704 |
+
</div>
|
705 |
+
"""
|
706 |
+
|
707 |
+
# Función para generar el perfil completo
|
708 |
+
def generate_buyer_persona(format_name, data):
|
709 |
+
"""
|
710 |
+
Genera un perfil de cliente ideal basado en el formato especificado y los datos proporcionados.
|
711 |
+
|
712 |
+
Args:
|
713 |
+
format_name (str): Nombre del formato a utilizar
|
714 |
+
data (dict): Diccionario con los datos para rellenar el template
|
715 |
+
|
716 |
+
Returns:
|
717 |
+
str: HTML con el perfil de cliente ideal generado y formateado para visualización
|
718 |
+
"""
|
719 |
+
try:
|
720 |
+
# Obtener el template renderizado
|
721 |
+
rendered_text = get_rendered_format(format_name, **data)
|
722 |
+
|
723 |
+
# Formatear para visualización
|
724 |
+
formatted_html = format_for_display(rendered_text)
|
725 |
+
|
726 |
+
# Envolver en el contenedor de respuesta
|
727 |
+
result_html = get_response_html_wrapper(formatted_html)
|
728 |
+
|
729 |
+
return result_html
|
730 |
+
|
731 |
+
except Exception as e:
|
732 |
+
return f"<div class='error'>Error al generar el perfil: {str(e)}</div>"
|
733 |
+
|
734 |
+
# Corregir la descripción del formato Storytelling
|
735 |
+
fix_storytelling_description()
|