JairoCesar commited on
Commit
fa99fab
·
verified ·
1 Parent(s): bba218d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -97
app.py CHANGED
@@ -1,18 +1,19 @@
1
  import streamlit as st
2
  from pptx import Presentation
3
- from pptx.util import Inches, Pt
4
  import io
5
- from huggingface_hub import InferenceClient
6
  import json
7
  import re
8
  import os
 
9
 
10
-
11
- gemini_token=os.getenv("GEMINI_TOKEN")
 
12
 
13
  @st.cache_resource
14
- def get_inference_client():
15
- return InferenceClient("gemini-2.0-flash")
16
 
17
  def extract_and_clean_json(text):
18
  json_match = re.search(r'\{.*\}', text, re.DOTALL)
@@ -24,146 +25,101 @@ def extract_and_clean_json(text):
24
  return json_str
25
  return None
26
 
27
- def generate_presentation_content(topic, client, max_retries=3):
28
  prompt = f"""Genera una presentación de PowerPoint sobre el tema: "{topic}".
29
- Debes crear exactamente 9 diapositivas. Cada diapositiva debe tener un título y contenido.
30
- Es CRUCIAL que tu respuesta sea ÚNICAMENTE un JSON válido con la siguiente estructura exacta, sin texto adicional antes o después:
31
-
32
- {{
33
- "slides": [
34
- {{"title": "Título de la diapositiva 1", "content": "Contenido de la diapositiva 1"}},
35
- {{"title": "Título de la diapositiva 2", "content": "Contenido de la diapositiva 2"}},
36
- {{"title": "Título de la diapositiva 3", "content": "Contenido de la diapositiva 3"}},
37
- {{"title": "Título de la diapositiva 4", "content": "Contenido de la diapositiva 4"}},
38
- {{"title": "Título de la diapositiva 5", "content": "Contenido de la diapositiva 5"}},
39
- {{"title": "Título de la diapositiva 6", "content": "Contenido de la diapositiva 6"}},
40
- {{"title": "Título de la diapositiva 7", "content": "Contenido de la diapositiva 7"}},
41
- {{"title": "Título de la diapositiva 8", "content": "Contenido de la diapositiva 8"}},
42
- {{"title": "Título de la diapositiva 9", "content": "Contenido de la diapositiva 9"}}
43
- ]
44
- }}
45
-
46
- No incluyas ningún otro texto, explicación o saludo. Solo el JSON.
47
- """
48
-
49
  for attempt in range(max_retries):
50
- response = client.text_generation(prompt, max_new_tokens=2000, temperature=0.7)
51
-
52
  try:
53
- json_str = extract_and_clean_json(response)
54
  if json_str:
55
  slides_data = json.loads(json_str)
56
  if 'slides' in slides_data and len(slides_data['slides']) == 9:
57
  return slides_data['slides']
58
-
59
- # Si llegamos aquí, el JSON no era válido o no tenía la estructura correcta
60
  raise ValueError("JSON inválido o estructura incorrecta")
61
-
62
  except (json.JSONDecodeError, ValueError) as e:
63
- if attempt == max_retries - 1: # Último intento
64
- st.error(f"Error al generar el contenido después de {max_retries} intentos: {str(e)}")
65
  st.text("Última respuesta del modelo:")
66
- st.code(response)
67
  return None
68
  else:
69
  st.warning(f"Intento {attempt + 1} fallido. Reintentando...")
70
-
71
  return None
72
 
73
  def create_powerpoint(slides, template_path):
74
  prs = Presentation(template_path)
75
-
76
- # Agregar diapositivas generadas
77
  for slide_data in slides:
78
  slide = prs.slides.add_slide(prs.slide_layouts[1])
79
-
80
- title_shape = slide.shapes.title
81
- content_shape = slide.placeholders[1] if len(slide.placeholders) > 1 else None
82
-
83
- if title_shape:
84
- title_shape.text = slide_data['title']
85
-
86
- if content_shape:
87
- content_shape.text = slide_data['content']
88
  else:
89
- # Si no hay un placeholder para el contenido, añadimos un cuadro de texto
90
- left = Inches(0.5)
91
- top = Inches(1.5)
92
- width = Inches(9)
93
- height = Inches(5)
94
- txBox = slide.shapes.add_textbox(left, top, width, height)
95
- tf = txBox.text_frame
96
- tf.text = slide_data['content']
97
-
98
- # Agregar una diapositiva final con "Gracias"
99
- slide = prs.slides.add_slide(prs.slide_layouts[1])
100
- title_shape = slide.shapes.title
101
- content_shape = slide.placeholders[1] if len(slide.placeholders) > 1 else None
102
-
103
- if title_shape:
104
- title_shape.text = "Gracias"
105
-
106
- if content_shape:
107
- content_shape.text = ""
108
- else:
109
- # Si no hay un placeholder para el contenido, añadimos un cuadro de texto
110
- left = Inches(0.5)
111
- top = Inches(1.5)
112
- width = Inches(9)
113
- height = Inches(5)
114
- txBox = slide.shapes.add_textbox(left, top, width, height)
115
- tf = txBox.text_frame
116
- tf.text = ""
117
-
118
  pptx_buffer = io.BytesIO()
119
  prs.save(pptx_buffer)
120
  pptx_buffer.seek(0)
121
-
122
  return pptx_buffer
123
 
124
  def main():
125
- st.title("PowerPoint Mágico con el Buho")
126
-
127
- client = get_inference_client()
128
-
129
  topic = st.text_input("Por favor, ingrese el tema de la presentación:")
130
-
131
- # Opciones de plantillas
132
  template_options = {
133
  "Simple": "PLANTILLAS/Simple.pptx",
134
  "Corporativo": "PLANTILLAS/Corporativo.pptx",
135
  "Moderno": "PLANTILLAS/Moderno.pptx"
136
  }
137
-
138
  selected_template = st.selectbox("Seleccione una plantilla", list(template_options.keys()))
139
-
140
  if st.button("Generar Presentación"):
141
  if topic:
142
  try:
143
- with st.spinner("Generando contenido de la presentación..."):
144
- slides = generate_presentation_content(topic, client)
145
-
146
  if slides:
147
  template_path = template_options[selected_template]
148
  if not os.path.exists(template_path):
149
  st.error(f"No se encontró la plantilla: {template_path}")
150
  return
151
-
152
- with st.spinner("Creando archivo PowerPoint..."):
153
  pptx_buffer = create_powerpoint(slides, template_path)
154
-
155
- st.success("Presentación generada con éxito!")
156
-
157
  st.download_button(
158
  label="Descargar Presentación",
159
  data=pptx_buffer,
160
- file_name=f"{topic.replace(' ', '_')}_{selected_template}_presentacion.pptx",
161
  mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
162
  )
163
  except Exception as e:
164
- st.error(f"Ocurrió un error al generar la presentación: {str(e)}")
165
  else:
166
- st.warning("Por favor, ingrese un tema para la presentación.")
167
 
168
  if __name__ == "__main__":
169
  main()
 
1
  import streamlit as st
2
  from pptx import Presentation
3
+ from pptx.util import Inches
4
  import io
 
5
  import json
6
  import re
7
  import os
8
+ import google.generativeai as genai
9
 
10
+ # Configurar Gemini
11
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") # Asegúrate de que esté bien escrito
12
+ genai.configure(api_key=GEMINI_API_KEY)
13
 
14
  @st.cache_resource
15
+ def get_gemini_model():
16
+ return genai.GenerativeModel("gemini-1.5-flash") # Puedes cambiar al modelo que desees
17
 
18
  def extract_and_clean_json(text):
19
  json_match = re.search(r'\{.*\}', text, re.DOTALL)
 
25
  return json_str
26
  return None
27
 
28
+ def generate_presentation_content(topic, model, max_retries=3):
29
  prompt = f"""Genera una presentación de PowerPoint sobre el tema: "{topic}".
30
+ Debes crear exactamente 9 diapositivas. Cada diapositiva debe tener un título y contenido.
31
+ La respuesta debe ser SOLO un JSON válido con la estructura:
32
+
33
+ {{
34
+ "slides": [
35
+ {{"title": "Título 1", "content": "Contenido 1"}},
36
+ ...
37
+ {{"title": "Título 9", "content": "Contenido 9"}}
38
+ ]
39
+ }}"""
40
+
 
 
 
 
 
 
 
 
 
41
  for attempt in range(max_retries):
42
+ response = model.generate_content(prompt)
43
+
44
  try:
45
+ json_str = extract_and_clean_json(response.text)
46
  if json_str:
47
  slides_data = json.loads(json_str)
48
  if 'slides' in slides_data and len(slides_data['slides']) == 9:
49
  return slides_data['slides']
 
 
50
  raise ValueError("JSON inválido o estructura incorrecta")
 
51
  except (json.JSONDecodeError, ValueError) as e:
52
+ if attempt == max_retries - 1:
53
+ st.error(f"Error después de {max_retries} intentos: {str(e)}")
54
  st.text("Última respuesta del modelo:")
55
+ st.code(response.text)
56
  return None
57
  else:
58
  st.warning(f"Intento {attempt + 1} fallido. Reintentando...")
59
+
60
  return None
61
 
62
  def create_powerpoint(slides, template_path):
63
  prs = Presentation(template_path)
 
 
64
  for slide_data in slides:
65
  slide = prs.slides.add_slide(prs.slide_layouts[1])
66
+ if slide.shapes.title:
67
+ slide.shapes.title.text = slide_data['title']
68
+ if len(slide.placeholders) > 1:
69
+ slide.placeholders[1].text = slide_data['content']
 
 
 
 
 
70
  else:
71
+ textbox = slide.shapes.add_textbox(Inches(0.5), Inches(1.5), Inches(9), Inches(5))
72
+ textbox.text_frame.text = slide_data['content']
73
+
74
+ final_slide = prs.slides.add_slide(prs.slide_layouts[1])
75
+ if final_slide.shapes.title:
76
+ final_slide.shapes.title.text = "Gracias"
77
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  pptx_buffer = io.BytesIO()
79
  prs.save(pptx_buffer)
80
  pptx_buffer.seek(0)
 
81
  return pptx_buffer
82
 
83
  def main():
84
+ st.title("PowerPoint Mágico con GEMINI")
85
+
86
+ model = get_gemini_model()
 
87
  topic = st.text_input("Por favor, ingrese el tema de la presentación:")
88
+
 
89
  template_options = {
90
  "Simple": "PLANTILLAS/Simple.pptx",
91
  "Corporativo": "PLANTILLAS/Corporativo.pptx",
92
  "Moderno": "PLANTILLAS/Moderno.pptx"
93
  }
94
+
95
  selected_template = st.selectbox("Seleccione una plantilla", list(template_options.keys()))
96
+
97
  if st.button("Generar Presentación"):
98
  if topic:
99
  try:
100
+ with st.spinner("Generando contenido..."):
101
+ slides = generate_presentation_content(topic, model)
102
+
103
  if slides:
104
  template_path = template_options[selected_template]
105
  if not os.path.exists(template_path):
106
  st.error(f"No se encontró la plantilla: {template_path}")
107
  return
108
+
109
+ with st.spinner("Creando PowerPoint..."):
110
  pptx_buffer = create_powerpoint(slides, template_path)
111
+
112
+ st.success("¡Presentación generada!")
 
113
  st.download_button(
114
  label="Descargar Presentación",
115
  data=pptx_buffer,
116
+ file_name=f"{topic.replace(' ', '_')}_{selected_template}.pptx",
117
  mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
118
  )
119
  except Exception as e:
120
+ st.error(f"Ocurrió un error: {str(e)}")
121
  else:
122
+ st.warning("Por favor, ingrese un tema.")
123
 
124
  if __name__ == "__main__":
125
  main()