Spaces:
Build error
Build error
File size: 14,025 Bytes
8af6919 f88f9c9 28574ad 5d9778c dd86a62 ca89374 9e0d400 f88f9c9 de130ab 139801a 8282dc0 ef63143 d9fd372 f88f9c9 2366c23 f88f9c9 d9fd372 45a3c45 39ebe89 45a3c45 de130ab 39ebe89 45a3c45 de130ab 45a3c45 de130ab 45a3c45 3cdf325 6cd83aa 39ebe89 3cdf325 ca2bd3a de130ab 39ebe89 45a3c45 39ebe89 45a3c45 39ebe89 45a3c45 0629ab8 39ebe89 0629ab8 39ebe89 0629ab8 2bf9471 39ebe89 2bf9471 6cd83aa 39ebe89 6cd83aa 45a3c45 432d6d7 0629ab8 45a3c45 74ff3e4 139801a 6d3695c f88f9c9 895818c bf7aa4c f88f9c9 895818c 9e0d400 f88f9c9 9e0d400 f88f9c9 9e0d400 3389243 8acb57b 2fd7874 39ebe89 2fd7874 de130ab f88f9c9 de130ab 139801a 39ebe89 139801a 39ebe89 139801a 2fd7874 6cd83aa 2fd7874 f88f9c9 2fd7874 6cd83aa 2fd7874 6cd83aa 2fd7874 39ebe89 f88f9c9 2fd7874 de130ab 139801a 39ebe89 895818c 7099996 | 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 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | import streamlit as st
import openai
import os
import time
import base64
import random
from dotenv import load_dotenv
from google.cloud import texttospeech, aiplatform
from google.auth import default
import PyPDF2
from fpdf import FPDF
import tempfile
# Cargar variables de entorno desde el archivo .env
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
google_api_key = os.getenv("GOOGLE_API_KEY")
google_cx = os.getenv("GOOGLE_CX")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
project_id = os.getenv("GOOGLE_PROJECT_ID")
location = os.getenv("GOOGLE_LOCATION")
# Configuración de Streamlit
st.set_page_config(page_title="Asistente Teológico", page_icon="📖")
# Estilos CSS personalizados
st.markdown(
"""
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
body {
background-color: #000000;
color: #ECF0F1;
background-image: url('https://s1.1zoom.me/big0/395/Fields_Sunrises_and_499477.jpg');
background-size: cover;
font-family: 'Roboto', sans-serif;
}
.stButton>button {
background-color: #4CAF50;
color: white;
border-radius: 10px;
font-size: 16px;
padding: 10px 20px;
}
.stTextInput>div>div>input {
border: 1px solid #4CAF50;
border-radius: 10px;
font-size: 16px;
padding: 10px;
}
.stMarkdown>div>p {
color: black;
max-height: 300px;
overflow-y: auto;
font-size: 16px;
}
.stMarkdown>h1, .stMarkdown>h2, .stMarkdown>h3, .stMarkdown>h4, .stMarkdown>h5, .stMarkdown>h6 {
color: white;
font-weight: bold;
font-style: italic;
}
.stAudio {
margin-top: 20px;
border: 2px solid #4CAF50;
border-radius: 10px;
}
.stFileUploader>div>div>input {
border: 1px solid #4CAF50;
border-radius: 10px;
font-size: 16px;
}
.spinner {
border: 8px solid #f3f3f3;
border-top: 8px solid #4CAF50;
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.video-container {
border: 3px solid blue;
background-color: gold;
padding: 10px;
border-radius: 10px;
margin-bottom: 20px;
}
.assistant-response {
max-height: 200px;
overflow-y: auto;
font-size: 16px;
}
</style>
""",
unsafe_allow_html=True,
)
# Encabezado
st.image("biblie.jpg")
st.title("📖 LOS CÓDIGOS DE DIOS - BOTIDINAMIX AI")
st.markdown("Bienvenido al Asistente Teológico, donde puedes preguntar sobre interpretaciones y reflexiones bíblicas.")
# Barra lateral para la navegación
st.sidebar.title("Navegación")
page = st.sidebar.selectbox("Selecciona una página", ["Página Principal", "Chat Asistente", "Generador de Frases Bíblicas", "Recibir Reflexión", "La conexión", "Diario Reflexivo"])
# Inicializar el cliente de Vertex AI
credentials, _ = default()
aiplatform.init(project=project_id, location=location, credentials=credentials)
# Función para generar imágenes con Vertex AI
def generar_imagen_vertex(prompt):
response = aiplatform.TextToImageModel.from_pretrained("text-to-image").predict({"prompt": prompt})
return response["generated_images"][0]["image_uri"]
# Función para generar texto con Vertex AI
def generar_texto_vertex(prompt):
response = aiplatform.TextGenerationModel.from_pretrained("text-bison").predict({"prompt": prompt})
return response["generated_text"]
# Función para generar reflexión usando Vertex AI
def generar_reflexion(keyword):
prompt = f"Genera una reflexión inspiradora sobre {keyword} en el contexto de la espiritualidad y la Biblia."
respuesta = generar_texto_vertex(prompt)
return respuesta
# Función para convertir texto a voz
def text_to_speech_base64(text):
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(text=text)
voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL)
audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
response = client.synthesize_speech(input=input_text, voice=voice, audio_config=audio_config)
return base64.b64encode(response.audio_content).decode("utf-8")
# Función para obtener un audio aleatorio de la carpeta "reflexiones"
def obtener_audio_aleatorio():
carpeta_reflexiones = "reflexiones" # Cambia esta ruta por la correcta
archivos = os.listdir(carpeta_reflexiones)
archivos_mp3 = [archivo for archivo in archivos if archivo.endswith(".mp3")]
if archivos_mp3:
audio_seleccionado = random.choice(archivos_mp3)
with open(os.path.join(carpeta_reflexiones, audio_seleccionado), "rb") as audio_file:
audio_bytes = audio_file.read()
return base64.b64encode(audio_bytes).decode("utf-8"), audio_seleccionado
return None, None
# Función para extraer texto de un PDF
def extraer_texto_pdf(pdf_path):
text = ""
with open(pdf_path, "rb") as file:
reader = PyPDF2.PdfFileReader(file)
for page_num in range(reader.numPages):
text += reader.getPage(page_num).extract_text()
return text
# Función "La conexión" para generar oraciones del PDF
def generar_oracion_desde_pdf():
pdf_path = "diario-de-oraciones.pdf" # Ruta al PDF
texto_pdf = extraer_texto_pdf(pdf_path)
prompt = f"Genera una oración inspiradora basada en el siguiente texto: {texto_pdf[:2000]}" # Limitar a los primeros 2000 caracteres
respuesta = generar_texto_vertex(prompt)
return respuesta
# Función para generar y descargar un PDF con la entrada del diario
def generar_pdf(fecha, versiculo, rema, investigacion, reflexion):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.set_fill_color(230, 230, 230)
pdf.set_text_color(0, 0, 0)
pdf.image("flores.png", x=10, y=8, w=190) # Puedes cambiar la imagen por otra
pdf.ln(20)
pdf.cell(0, 10, f"Fecha: {fecha}", ln=True, fill=True)
pdf.cell(0, 10, f"Versículo: {versiculo}", ln=True, fill=True)
pdf.cell(0, 10, "Rema:", ln=True, fill=True)
pdf.multi_cell(0, 10, rema, fill=True)
pdf.cell(0, 10, "Investigación:", ln=True, fill=True)
pdf.multi_cell(0, 10, investigacion, fill=True)
pdf.cell(0, 10, "Reflexión:", ln=True, fill=True)
pdf.multi_cell(0, 10, reflexion, fill=True)
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmpfile:
pdf.output(tmpfile.name)
return tmpfile.name
if page == "Página Principal":
# Video de YouTube que se reproduce automáticamente
st.markdown(
"""
<iframe width="560" height="315" src="https://www.youtube.com/embed/dPRrJ8za3qU?autoplay=1&mute=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
""",
unsafe_allow_html=True,
)
elif page == "Chat Asistente":
# Chat con el asistente
st.subheader("🗣️ Chat con el Asistente")
if 'mensajes' not in st.session_state:
st.session_state.mensajes = []
for mensaje in st.session_state.mensajes:
with st.chat_message(mensaje["role"]):
if isinstance(mensaje["content"], str):
st.markdown(mensaje["content"])
elif isinstance(mensaje["content"], bytes):
st.image(mensaje["content"])
pregunta_usuario = st.text_input("Escribe tu pregunta sobre la Biblia:", key="pregunta_input")
imagen_usuario = st.file_uploader("Sube una imagen (opcional):", type=["png", "jpg", "jpeg"])
if st.button("Enviar"):
if pregunta_usuario or imagen_usuario:
if pregunta_usuario:
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(pregunta_usuario)
if imagen_usuario:
imagen_bytes = imagen_usuario.getvalue()
st.session_state.mensajes.append({"role": "user", "content": imagen_bytes, "timestamp": time.time()})
with st.chat_message("user"):
st.image(imagen_bytes)
# Limpiar el campo de texto usando JavaScript para evitar el error de modificación del estado
st.markdown(
"""
<script>
document.querySelector('input[type="text"]').value = "";
</script>
""",
unsafe_allow_html=True,
)
with st.spinner("Meditando su respuesta..."):
with st.empty():
spinner = st.markdown('<div class="spinner"></div>', unsafe_allow_html=True)
time.sleep(2) # Simulación del tiempo de procesamiento
spinner.empty()
if pregunta_usuario:
respuesta = generar_reflexion(pregunta_usuario)
st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(f'<div class="assistant-response">{respuesta}</div>', unsafe_allow_html=True)
# Convertir texto a voz
audio_base64 = text_to_speech_base64(respuesta)
audio_html = f"""
<audio autoplay>
<source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
</audio>
"""
st.markdown(audio_html, unsafe_allow_html=True)
# Reproducir video automáticamente
st.markdown('<div class="video-container">', unsafe_allow_html=True)
st.markdown(
"""
<video autoplay loop muted playsinline style="width: 100%;">
<source src="https://cdn.pika.art/v1/3d0aafad-36b6-4341-b2bf-b4d5fbcf0445/Hola_bienvenido_a_este_maravilloso_programa._Donde_podr_s_conocer_y_profundizar_m_s_en_la_palabra_de_seed3422648958323119.mp4" type="video/mp4">
</video>
""",
unsafe_allow_html=True,
)
st.markdown('</div>', unsafe_allow_html=True)
else:
st.warning("Por favor, ingresa una pregunta antes de enviar.")
elif page == "Generador de Frases Bíblicas":
# Función para generar una imagen y reflexión
def generar_imagen_y_reflexion(keyword):
try:
reflexion = generar_reflexion(keyword)
audio_base64 = text_to_speech_base64(reflexion)
imagen_url = generar_imagen_vertex(f"spirituality {keyword}")
st.image(imagen_url)
st.markdown(reflexion)
audio_html = f"""
<audio autoplay>
<source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
</audio>
"""
st.markdown(audio_html, unsafe_allow_html=True)
except Exception as e:
st.error(f"Error al generar la imagen y reflexión: {e}")
st.subheader("✨ Generador de Frases Bíblicas")
keyword = st.text_input("Introduce una palabra clave:")
if st.button("Generar"):
if keyword:
generar_imagen_y_reflexion(keyword)
else:
st.warning("Por favor, introduce una palabra clave.")
elif page == "Recibir Reflexión":
st.subheader("🔊 Recibir Reflexión")
if st.button("Reproducir Reflexión"):
audio_base64, audio_nombre = obtener_audio_aleatorio()
if audio_base64:
st.markdown(f"Reproduciendo: {audio_nombre}")
audio_html = f"""
<audio autoplay>
<source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
</audio>
"""
st.markdown(audio_html, unsafe_allow_html=True)
else:
st.warning("No se encontraron reflexiones en la carpeta especificada.")
elif page == "La conexión":
st.subheader("🙏 La conexión: Generador de Oraciones")
if st.button("Generar Oración"):
oracion = generar_oracion_desde_pdf()
st.markdown(oracion)
audio_base64 = text_to_speech_base64(oracion)
audio_html = f"""
<audio autoplay>
<source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
</audio>
"""
st.markdown(audio_html, unsafe_allow_html=True)
elif page == "Diario Reflexivo":
st.subheader("📔 Diario Reflexivo")
with st.form("diario_reflexivo_form"):
fecha = st.date_input("Fecha")
versiculo = st.text_input("Versículo")
rema = st.text_area("Rema")
investigacion = st.text_area("Investigación en la palabra de Dios")
reflexion = st.text_area("Reflexión")
submit_button = st.form_submit_button(label="Guardar en PDF")
if submit_button:
pdf_path = generar_pdf(fecha, versiculo, rema, investigacion, reflexion)
with open(pdf_path, "rb") as f:
st.download_button(
label="Descargar Diario Reflexivo en PDF",
data=f,
file_name="diario_reflexivo.pdf",
mime="application/pdf"
)
|