JairoCesar commited on
Commit
d657b6b
·
verified ·
1 Parent(s): ef818a6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -123
app.py CHANGED
@@ -1,8 +1,6 @@
1
  import streamlit as st
2
  from pptx import Presentation
3
  from pptx.util import Inches, Pt
4
- from pptx.enum.shapes import MSO_SHAPE
5
- from pptx.dml.color import RGBColor
6
  import io
7
  from huggingface_hub import InferenceClient
8
  import json
@@ -10,47 +8,24 @@ import re
10
 
11
  @st.cache_resource
12
  def get_inference_client():
13
- return InferenceClient(model="mistralai/Mixtral-8x7B-Instruct-v0.1")
14
 
15
  def extract_and_clean_json(text):
16
- try:
17
- # Extracción del JSON de la respuesta
18
- json_match = re.search(r'\{.*?\}', text, re.DOTALL)
19
- if json_match:
20
- json_str = json_match.group()
21
- # Limpieza básica
22
- json_str = re.sub(r'[\n\t\r]', '', json_str)
23
- json_str = re.sub(r',\s*}', '}', json_str)
24
- json_str = re.sub(r',\s*]', ']', json_str)
25
-
26
- # Verificación y análisis del JSON
27
- try:
28
- data = json.loads(json_str)
29
- return data
30
- except json.JSONDecodeError as e:
31
- st.error(f"Error al decodificar JSON limpio: {str(e)}")
32
- st.text("JSON procesado (después de limpieza):")
33
- st.code(json_str)
34
- return None
35
- else:
36
- st.error("No se encontró un JSON válido en la respuesta")
37
- st.text("Respuesta original del modelo:")
38
- st.code(text)
39
- return None
40
- except Exception as e:
41
- st.error(f"Error inesperado al procesar el JSON: {str(e)}")
42
- st.text("Respuesta original del modelo:")
43
- st.code(text)
44
- return None
45
 
46
  def generate_presentation_content(topic, client):
47
  prompt = f"""Crea una presentación de PowerPoint sobre el tema: {topic}.
48
- Genera exactamente 9 diapositivas con la siguiente estructura:
49
- 1. Título de la presentación
50
- 2. Introducción
51
- 3. Índice
52
- 4-9. Contenido principal (6 diapositivas)
53
-
54
  Formatea la salida como un JSON con la siguiente estructura:
55
  {{
56
  "slides": [
@@ -65,87 +40,40 @@ def generate_presentation_content(topic, client):
65
 
66
  response = client.text_generation(prompt, max_new_tokens=1500, temperature=0.7)
67
 
68
- # Limpieza y procesamiento del JSON
69
- slides_data = extract_and_clean_json(response)
70
-
71
- if slides_data and 'slides' in slides_data:
72
- if len(slides_data['slides']) == 9:
73
- return slides_data['slides']
 
 
74
  else:
75
- st.error(f"El JSON no contiene exactamente 9 diapositivas. Contiene {len(slides_data['slides'])} diapositivas.")
76
- st.text("JSON procesado:")
77
- st.code(json.dumps(slides_data, indent=4))
78
- return None
79
- return None
80
-
81
- def apply_design(prs, design):
82
- if design == "Moderno":
83
- background = prs.slides[0].background
84
- fill = background.fill
85
- fill.solid()
86
- fill.fore_color.rgb = RGBColor(240, 240, 240)
87
-
88
- for slide in prs.slides:
89
- for shape in slide.shapes:
90
- if shape.has_text_frame:
91
- tf = shape.text_frame
92
- tf.text = tf.text
93
- for paragraph in tf.paragraphs:
94
- paragraph.font.color.rgb = RGBColor(0, 0, 0)
95
- if shape.name == 'Title':
96
- paragraph.font.size = Pt(44)
97
- else:
98
- paragraph.font.size = Pt(24)
99
- elif design == "Corporativo":
100
- background = prs.slides[0].background
101
- fill = background.fill
102
- fill.solid()
103
- fill.fore_color.rgb = RGBColor(255, 255, 255)
104
-
105
- for slide in prs.slides:
106
- left = top = Inches(0.5)
107
- width = Inches(1)
108
- height = Inches(0.5)
109
- shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
110
- shape.fill.solid()
111
- shape.fill.fore_color.rgb = RGBColor(0, 112, 192)
112
-
113
- for shape in slide.shapes:
114
- if shape.has_text_frame:
115
- tf = shape.text_frame
116
- tf.text = tf.text
117
- for paragraph in tf.paragraphs:
118
- paragraph.font.color.rgb = RGBColor(0, 0, 0)
119
- if shape.name == 'Title':
120
- paragraph.font.size = Pt(40)
121
- paragraph.font.color.rgb = RGBColor(0, 112, 192)
122
- else:
123
- paragraph.font.size = Pt(20)
124
 
125
- def create_powerpoint(slides, design):
126
  prs = Presentation()
127
 
128
- # Diapositiva de título
129
- slide = prs.slides.add_slide(prs.slide_layouts[0])
130
- title = slide.shapes.title
131
- subtitle = slide.placeholders[1]
132
- title.text = slides[0]['title']
133
- subtitle.text = slides[0]['content']
134
-
135
- # Otras diapositivas
136
- for slide_data in slides[1:]:
137
  slide = prs.slides.add_slide(prs.slide_layouts[1])
138
- title = slide.shapes.title
139
- content = slide.placeholders[1]
140
- title.text = slide_data['title']
141
- content.text = slide_data['content']
142
-
143
- # Diapositiva "Gracias"
144
- slide = prs.slides.add_slide(prs.slide_layouts[0])
145
- title = slide.shapes.title
146
- title.text = "¡Gracias!"
147
-
148
- apply_design(prs, design)
149
 
150
  pptx_buffer = io.BytesIO()
151
  prs.save(pptx_buffer)
@@ -160,11 +88,6 @@ def main():
160
 
161
  topic = st.text_input("Por favor, ingrese el tema de la presentación:")
162
 
163
- design = st.selectbox(
164
- "Seleccione un diseño para la presentación:",
165
- ("Simple", "Moderno", "Corporativo")
166
- )
167
-
168
  if st.button("Generar Presentación"):
169
  if topic:
170
  try:
@@ -173,7 +96,7 @@ def main():
173
 
174
  if slides:
175
  with st.spinner("Creando archivo PowerPoint..."):
176
- pptx_buffer = create_powerpoint(slides, design)
177
 
178
  st.success("Presentación generada con éxito!")
179
 
@@ -183,12 +106,10 @@ def main():
183
  file_name=f"{topic.replace(' ', '_')}_presentacion.pptx",
184
  mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
185
  )
186
- else:
187
- st.error("No se generó contenido de presentación válido.")
188
  except Exception as e:
189
  st.error(f"Ocurrió un error al generar la presentación: {str(e)}")
190
  else:
191
  st.warning("Por favor, ingrese un tema para la presentación.")
192
 
193
  if __name__ == "__main__":
194
- main()
 
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
 
8
 
9
  @st.cache_resource
10
  def get_inference_client():
11
+ return InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
12
 
13
  def extract_and_clean_json(text):
14
+ # Intenta encontrar un JSON válido en el texto
15
+ json_match = re.search(r'\{.*\}', text, re.DOTALL)
16
+ if json_match:
17
+ json_str = json_match.group()
18
+ # Limpia el JSON de caracteres no válidos
19
+ json_str = re.sub(r'[\n\t\r]', '', json_str)
20
+ # Intenta corregir problemas comunes de formato
21
+ json_str = re.sub(r',\s*}', '}', json_str) # Elimina comas finales extras
22
+ json_str = re.sub(r',\s*]', ']', json_str) # Elimina comas finales extras en arrays
23
+ return json_str
24
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  def generate_presentation_content(topic, client):
27
  prompt = f"""Crea una presentación de PowerPoint sobre el tema: {topic}.
28
+ Genera exactamente 5 diapositivas. Cada diapositiva debe tener un título y contenido.
 
 
 
 
 
29
  Formatea la salida como un JSON con la siguiente estructura:
30
  {{
31
  "slides": [
 
40
 
41
  response = client.text_generation(prompt, max_new_tokens=1500, temperature=0.7)
42
 
43
+ try:
44
+ json_str = extract_and_clean_json(response)
45
+ if json_str:
46
+ slides_data = json.loads(json_str)
47
+ if 'slides' in slides_data and len(slides_data['slides']) == 5:
48
+ return slides_data['slides']
49
+ else:
50
+ raise ValueError("El JSON no contiene exactamente 5 diapositivas")
51
  else:
52
+ raise ValueError("No se encontró un JSON válido en la respuesta")
53
+ except json.JSONDecodeError as e:
54
+ st.error(f"Error al decodificar JSON: {str(e)}")
55
+ st.text("JSON procesado (después de limpieza):")
56
+ st.code(json_str)
57
+ st.text("Respuesta original del modelo:")
58
+ st.code(response)
59
+ return None
60
+ except ValueError as e:
61
+ st.error(str(e))
62
+ st.text("Respuesta del modelo:")
63
+ st.code(response)
64
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ def create_powerpoint(slides):
67
  prs = Presentation()
68
 
69
+ for slide_data in slides:
 
 
 
 
 
 
 
 
70
  slide = prs.slides.add_slide(prs.slide_layouts[1])
71
+
72
+ title_shape = slide.shapes.title
73
+ content_shape = slide.placeholders[1]
74
+
75
+ title_shape.text = slide_data['title']
76
+ content_shape.text = slide_data['content']
 
 
 
 
 
77
 
78
  pptx_buffer = io.BytesIO()
79
  prs.save(pptx_buffer)
 
88
 
89
  topic = st.text_input("Por favor, ingrese el tema de la presentación:")
90
 
 
 
 
 
 
91
  if st.button("Generar Presentación"):
92
  if topic:
93
  try:
 
96
 
97
  if slides:
98
  with st.spinner("Creando archivo PowerPoint..."):
99
+ pptx_buffer = create_powerpoint(slides)
100
 
101
  st.success("Presentación generada con éxito!")
102
 
 
106
  file_name=f"{topic.replace(' ', '_')}_presentacion.pptx",
107
  mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
108
  )
 
 
109
  except Exception as e:
110
  st.error(f"Ocurrió un error al generar la presentación: {str(e)}")
111
  else:
112
  st.warning("Por favor, ingrese un tema para la presentación.")
113
 
114
  if __name__ == "__main__":
115
+ main()