jeysshon commited on
Commit
f808679
·
verified ·
1 Parent(s): db2ab52

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -68
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import os
2
- import io
3
  import random
4
  import pandas as pd
5
  import chainlit as cl
@@ -15,15 +14,10 @@ EXCEL_PATH = "MasterData SISO - Actualizada - Jan-29-2025.xlsx"
15
  AUDIO_PATH = "Manual del Operador de Tienda.wav"
16
  CERTIFICATE_TEMPLATE = "certificate_template_.pdf"
17
 
18
- # Convertimos la ruta del audio a un path tipo URL (opcional)
19
  abs_path = os.path.abspath(AUDIO_PATH).replace("\\", "/")
20
  AUDIO_URL = f"file:///{quote(abs_path)}"
21
 
22
- # Carpeta de salida para “generar” el PDF
23
- OUTPUT_FOLDER = "Certificates"
24
- if not os.path.exists(OUTPUT_FOLDER):
25
- os.makedirs(OUTPUT_FOLDER)
26
-
27
  # ===== PREGUNTAS DEL EXAMEN =====
28
  PREGUNTAS = [
29
  {
@@ -93,7 +87,7 @@ def cargar_datos():
93
  ],
94
  dtype={'SAPId': 'int32'}
95
  )
96
- # Creamos columnas extra si no existen
97
  for col in ['Fecha', 'Calificacion', 'Curso']:
98
  if col not in df.columns:
99
  df[col] = None
@@ -102,7 +96,7 @@ def cargar_datos():
102
  print(f"Error cargando datos: {str(e)}")
103
  return {}
104
 
105
- def actualizar_excel(sap_id, aprobado: bool):
106
  """Marca en Excel la fecha, el resultado y el curso para el SAP ID dado."""
107
  try:
108
  df = pd.read_excel(EXCEL_PATH)
@@ -114,34 +108,7 @@ def actualizar_excel(sap_id, aprobado: bool):
114
  except Exception as e:
115
  print(f"Error actualizando Excel: {str(e)}")
116
 
117
- # ===== FUNCIÓN PARA "GENERAR" (COPIAR) EL PDF =====
118
- def generar_pdf_sin_texto(sap_id: int) -> str:
119
- """
120
- Retorna la ruta de un PDF “generado” a partir de la plantilla original.
121
- Aquí NO dibujamos ni agregamos texto. Simplemente copiamos la plantilla
122
- y la renombramos con el ID de la persona.
123
- """
124
- # Lee la plantilla
125
- try:
126
- with open(CERTIFICATE_TEMPLATE, "rb") as f_in:
127
- pdf_data = f_in.read()
128
- except Exception as e:
129
- print(f"Error leyendo la plantilla: {e}")
130
- return None
131
-
132
- # Crea un nuevo archivo .pdf para este SAP
133
- final_name = f"{sap_id}_certificate.pdf"
134
- final_path = os.path.join(OUTPUT_FOLDER, final_name)
135
- try:
136
- with open(final_path, "wb") as f_out:
137
- f_out.write(pdf_data)
138
- except Exception as e:
139
- print(f"Error escribiendo el PDF final: {e}")
140
- return None
141
-
142
- return final_path
143
-
144
- # ===== CHAINLIT: LÓGICA DE CONVERSACIÓN =====
145
  @cl.on_chat_start
146
  async def inicio():
147
  SAP_DICT = cargar_datos()
@@ -153,12 +120,12 @@ async def manejar_mensaje(message: cl.Message):
153
  SAP_DICT = cl.user_session.get("SAP_DICT")
154
  user_data = cl.user_session.get("user_data")
155
 
156
- # Si ya estamos en el examen, procesamos la respuesta
157
  if user_data and user_data.get("en_examen"):
158
  await procesar_respuesta(message)
159
  return
160
 
161
- # Si no, interpretamos el mensaje como SAP ID
162
  try:
163
  sap_id = int(message.content)
164
  if sap_id not in SAP_DICT:
@@ -173,7 +140,7 @@ async def manejar_mensaje(message: cl.Message):
173
  └ Centro Coste: {usuario['Centro de coste']}
174
  """
175
 
176
- # Guardamos en sesión
177
  cl.user_session.set("user_data", {
178
  "sap_id": sap_id,
179
  "puntaje": 0,
@@ -191,13 +158,13 @@ async def mostrar_pregunta():
191
  user_data = cl.user_session.get("user_data")
192
  num_pregunta = user_data["pregunta_actual"]
193
 
194
- # Si ya no hay más preguntas, mostramos resultado
195
  if num_pregunta >= len(PREGUNTAS):
196
  await mostrar_resultado()
197
  return
198
 
199
- pregunta = PREGUNTAS[num_pregunta]
200
- mensaje = f"📝 **Pregunta {num_pregunta + 1}**\n{pregunta['pregunta']}\n\n" + "\n".join(pregunta['opciones'])
201
  await cl.Message(content=mensaje + "\n\n🔘 Respuesta (A/B/C/D):").send()
202
 
203
  async def procesar_respuesta(message: cl.Message):
@@ -206,12 +173,9 @@ async def procesar_respuesta(message: cl.Message):
206
 
207
  respuesta = message.content.strip().upper()
208
 
209
- # Validar la respuesta (debe ser A, B, C o D)
210
  if len(respuesta) != 1 or respuesta not in ['A', 'B', 'C', 'D']:
211
- await cl.Message(content="""
212
- ⚠️ **Formato incorrecto** ⚠️
213
- Por favor ingrese solo la letra correspondiente (A/B/C/D).
214
- """).send()
215
  return
216
 
217
  correcta = PREGUNTAS[num_pregunta]['respuesta']
@@ -224,7 +188,7 @@ async def procesar_respuesta(message: cl.Message):
224
  user_data["pregunta_actual"] += 1
225
  cl.user_session.set("user_data", user_data)
226
 
227
- # Si quedan preguntas, mostramos la siguiente; si no, resultado final
228
  if user_data["pregunta_actual"] < len(PREGUNTAS):
229
  await mostrar_pregunta()
230
  else:
@@ -233,8 +197,8 @@ async def procesar_respuesta(message: cl.Message):
233
  async def mostrar_resultado():
234
  user_data = cl.user_session.get("user_data")
235
  SAP_DICT = cl.user_session.get("SAP_DICT")
236
-
237
- # Nota de aprobación => 3 correctas (de 5)
238
  aprobado = user_data['puntaje'] >= 3
239
  actualizar_excel(user_data['sap_id'], aprobado)
240
 
@@ -244,23 +208,18 @@ async def mostrar_resultado():
244
  "❌ **LO SENTIMOS, REPROBADO**\n"
245
  )
246
  mensaje += f"Puntaje Final: {user_data['puntaje']}/5"
247
-
248
  if aprobado:
249
- # Generar PDF sin texto adicional
250
- pdf_path = generar_pdf_sin_texto(user_data['sap_id'])
251
- if pdf_path:
252
- # Lo enviamos como archivo descargable
253
- await cl.Message(
254
- content=mensaje,
255
- elements=[
256
- cl.File(path=pdf_path, name="Certificado de Aprobación")
257
- ]
258
- ).send()
259
- else:
260
- # En caso de error leyendo/escribiendo PDF
261
- await cl.Message(content=mensaje + "\n\n(⚠️ Error al generar el PDF)").send()
262
  else:
263
- # Si reprueba => Mostrar audio
264
  await cl.Message(
265
  content=mensaje,
266
  elements=[
@@ -272,8 +231,8 @@ async def mostrar_resultado():
272
  )
273
  ]
274
  ).send()
275
-
276
- # Reiniciamos la sesión
277
  cl.user_session.set("user_data", None)
278
  await cl.Message(content="\nIngrese nuevo SAP ID para otro examen:").send()
279
 
 
1
  import os
 
2
  import random
3
  import pandas as pd
4
  import chainlit as cl
 
14
  AUDIO_PATH = "Manual del Operador de Tienda.wav"
15
  CERTIFICATE_TEMPLATE = "certificate_template_.pdf"
16
 
17
+ # Convertimos la ruta del audio a un path tipo URL (opcional, útil localmente)
18
  abs_path = os.path.abspath(AUDIO_PATH).replace("\\", "/")
19
  AUDIO_URL = f"file:///{quote(abs_path)}"
20
 
 
 
 
 
 
21
  # ===== PREGUNTAS DEL EXAMEN =====
22
  PREGUNTAS = [
23
  {
 
87
  ],
88
  dtype={'SAPId': 'int32'}
89
  )
90
+ # Si faltan columnas, las agregamos
91
  for col in ['Fecha', 'Calificacion', 'Curso']:
92
  if col not in df.columns:
93
  df[col] = None
 
96
  print(f"Error cargando datos: {str(e)}")
97
  return {}
98
 
99
+ def actualizar_excel(sap_id, aprobado):
100
  """Marca en Excel la fecha, el resultado y el curso para el SAP ID dado."""
101
  try:
102
  df = pd.read_excel(EXCEL_PATH)
 
108
  except Exception as e:
109
  print(f"Error actualizando Excel: {str(e)}")
110
 
111
+ # ===== CHAINLIT =====
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  @cl.on_chat_start
113
  async def inicio():
114
  SAP_DICT = cargar_datos()
 
120
  SAP_DICT = cl.user_session.get("SAP_DICT")
121
  user_data = cl.user_session.get("user_data")
122
 
123
+ # Si el usuario ya está en examen, verificamos la respuesta
124
  if user_data and user_data.get("en_examen"):
125
  await procesar_respuesta(message)
126
  return
127
 
128
+ # Sino, interpretamos como SAP ID
129
  try:
130
  sap_id = int(message.content)
131
  if sap_id not in SAP_DICT:
 
140
  └ Centro Coste: {usuario['Centro de coste']}
141
  """
142
 
143
+ # Guardamos datos en la sesión
144
  cl.user_session.set("user_data", {
145
  "sap_id": sap_id,
146
  "puntaje": 0,
 
158
  user_data = cl.user_session.get("user_data")
159
  num_pregunta = user_data["pregunta_actual"]
160
 
161
+ # Si ya no hay más preguntas, mostramos resultado final
162
  if num_pregunta >= len(PREGUNTAS):
163
  await mostrar_resultado()
164
  return
165
 
166
+ p = PREGUNTAS[num_pregunta]
167
+ mensaje = f"📝 **Pregunta {num_pregunta + 1}**\n{p['pregunta']}\n\n" + "\n".join(p['opciones'])
168
  await cl.Message(content=mensaje + "\n\n🔘 Respuesta (A/B/C/D):").send()
169
 
170
  async def procesar_respuesta(message: cl.Message):
 
173
 
174
  respuesta = message.content.strip().upper()
175
 
176
+ # Validar la respuesta
177
  if len(respuesta) != 1 or respuesta not in ['A', 'B', 'C', 'D']:
178
+ await cl.Message(content="⚠️ **Formato incorrecto**. Respuesta = A/B/C/D").send()
 
 
 
179
  return
180
 
181
  correcta = PREGUNTAS[num_pregunta]['respuesta']
 
188
  user_data["pregunta_actual"] += 1
189
  cl.user_session.set("user_data", user_data)
190
 
191
+ # Si quedan preguntas, mostramos la siguiente
192
  if user_data["pregunta_actual"] < len(PREGUNTAS):
193
  await mostrar_pregunta()
194
  else:
 
197
  async def mostrar_resultado():
198
  user_data = cl.user_session.get("user_data")
199
  SAP_DICT = cl.user_session.get("SAP_DICT")
200
+
201
+ # Nota de aprobación (3/5)
202
  aprobado = user_data['puntaje'] >= 3
203
  actualizar_excel(user_data['sap_id'], aprobado)
204
 
 
208
  "❌ **LO SENTIMOS, REPROBADO**\n"
209
  )
210
  mensaje += f"Puntaje Final: {user_data['puntaje']}/5"
211
+
212
  if aprobado:
213
+ # Solo mostramos la plantilla PDF tal cual
214
+ await cl.Message(
215
+ content=mensaje,
216
+ elements=[
217
+ # Se envía la plantilla como archivo descargable
218
+ cl.File(path=CERTIFICATE_TEMPLATE, name="Certificado de Aprobación")
219
+ ]
220
+ ).send()
 
 
 
 
 
221
  else:
222
+ # Si no aprueba, muestra el audio
223
  await cl.Message(
224
  content=mensaje,
225
  elements=[
 
231
  )
232
  ]
233
  ).send()
234
+
235
+ # Reiniciamos para un nuevo examen
236
  cl.user_session.set("user_data", None)
237
  await cl.Message(content="\nIngrese nuevo SAP ID para otro examen:").send()
238