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"
            )