Sahm269 commited on
Commit
bb9a231
·
verified ·
1 Parent(s): 2b92fac

Upload 2 files

Browse files
client/pages/nutri.py CHANGED
@@ -17,13 +17,16 @@ from server.db.dbmanager import (
17
  delete_conversation,
18
  load_chatbot_suggestions,
19
  save_chatbot_suggestions,
 
 
20
  )
 
21
  import logging
22
 
 
23
  logging.basicConfig(level=logging.INFO, handlers=[logging.StreamHandler()])
24
  logger = logging.getLogger(__name__)
25
 
26
-
27
  # 🔹 Chargement des variables de session pour éviter les rechargements inutiles
28
  if "id_conversation" not in st.session_state:
29
  st.session_state.id_conversation = None
@@ -57,7 +60,7 @@ except Exception as e:
57
  # 🔹 Chargement de la base de données
58
  db_manager = st.session_state["db_manager"]
59
  user_id = st.session_state["user_id"]
60
-
61
  if "chatbot_suggestions" not in st.session_state:
62
  st.session_state["chatbot_suggestions"] = load_chatbot_suggestions(
63
  db_manager, user_id
@@ -242,8 +245,6 @@ if prompt := st.chat_input("Dîtes quelque-chose"):
242
 
243
  time.sleep(0.03)
244
 
245
- # 🔹 Vérifier si la réponse contient une suggestion de recette
246
-
247
  # 🔹 Vérifier si la réponse contient des suggestions de recettes
248
  keywords = ["recette", "plat", "préparer", "ingrédients"]
249
 
@@ -278,18 +279,55 @@ if prompt := st.chat_input("Dîtes quelque-chose"):
278
  save_chatbot_suggestions(
279
  db_manager, user_id, new_recipes
280
  )
 
281
  except Exception as e:
282
  print(
283
  f"❌ Erreur lors de l'extraction des suggestions : {e}"
284
  )
285
 
286
  break # On ne veut ajouter qu'une seule suggestion par réponse
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
- # end_time = time.time() # 🔹 Fin du chronomètre
289
- # latency = round(end_time - start_time, 2) # 🔹 Calcul de la latence
290
 
291
- # print(f"✅ Réponse générée en {latency} secondes.")
292
- # print(f"✅ Nombre de tokens de sortie : {output_tokens}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  except Exception as e:
294
  if hasattr(e, "status_code") and e.status_code == 429:
295
  retries += 1
@@ -368,3 +406,19 @@ if prompt := st.chat_input("Dîtes quelque-chose"):
368
  "🤖 Entraînement du guardrail à reconnaître le prompt comme dangereux effectué avec succès"
369
  )
370
  st.stop()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  delete_conversation,
18
  load_chatbot_suggestions,
19
  save_chatbot_suggestions,
20
+ save_recipes_with_ingredients,
21
+ add_ingredients_column_if_not_exists
22
  )
23
+
24
  import logging
25
 
26
+
27
  logging.basicConfig(level=logging.INFO, handlers=[logging.StreamHandler()])
28
  logger = logging.getLogger(__name__)
29
 
 
30
  # 🔹 Chargement des variables de session pour éviter les rechargements inutiles
31
  if "id_conversation" not in st.session_state:
32
  st.session_state.id_conversation = None
 
60
  # 🔹 Chargement de la base de données
61
  db_manager = st.session_state["db_manager"]
62
  user_id = st.session_state["user_id"]
63
+ add_ingredients_column_if_not_exists(db_manager)
64
  if "chatbot_suggestions" not in st.session_state:
65
  st.session_state["chatbot_suggestions"] = load_chatbot_suggestions(
66
  db_manager, user_id
 
245
 
246
  time.sleep(0.03)
247
 
 
 
248
  # 🔹 Vérifier si la réponse contient des suggestions de recettes
249
  keywords = ["recette", "plat", "préparer", "ingrédients"]
250
 
 
279
  save_chatbot_suggestions(
280
  db_manager, user_id, new_recipes
281
  )
282
+
283
  except Exception as e:
284
  print(
285
  f"❌ Erreur lors de l'extraction des suggestions : {e}"
286
  )
287
 
288
  break # On ne veut ajouter qu'une seule suggestion par réponse
289
+ time.sleep(1)
290
+ # 🔹 EXTRACTION ET ENREGISTREMENT DES RECETTES
291
+ # 🔍 Vérifier si la réponse contient des suggestions de recettes
292
+ # 🔹 EXTRACTION ET ENREGISTREMENT DES RECETTES
293
+ # 🔍 Vérifier si la réponse contient des suggestions de recettes
294
+ for word in keywords:
295
+ if word in response.lower():
296
+ try:
297
+ print("🔍 Détection de recettes, extraction en cours...")
298
+
299
+ # 🔹 Utiliser `extract_recipes_and_ingredients` pour extraire plusieurs recettes
300
+ extracted_recipes = mistral.extract_recipes_and_ingredients(response)
301
+
302
+ if extracted_recipes:
303
+ print(f"✅ {len(extracted_recipes)} recettes détectées : {extracted_recipes}")
304
+
305
+ # 🔹 Sauvegarder les recettes et leurs ingrédients dans la base de données
306
+ for recipe in extracted_recipes:
307
+ title = recipe["titre"].lstrip("-").strip() # Supprime les tirets et espaces inutiles
308
+ ingredients = recipe["ingredients"].strip()
309
+
310
+ # 🔹 Supprimer une virgule finale si présente dans le titre
311
+ title_cleaned = title.rstrip(",") # Enlève uniquement la virgule à la fin
312
 
313
+ print(f"💾 Enregistrement de la recette '{title_cleaned}' avec les ingrédients : {ingredients}")
 
314
 
315
+ save_recipes_with_ingredients(db_manager, user_id, title_cleaned, ingredients)
316
+
317
+ else:
318
+ print("⚠️ Aucune recette détectée.")
319
+
320
+ except Exception as e:
321
+ print(f"❌ Erreur lors de l'extraction des recettes et ingrédients : {e}")
322
+
323
+ break # Éviter d'ajouter plusieurs fois la même recette
324
+
325
+
326
+ end_time = time.time() # 🔹 Fin du chronomètre
327
+ latency = round(end_time - start_time, 2) # 🔹 Calcul de la latence
328
+
329
+ print(f"✅ Réponse générée en {latency} secondes.")
330
+ print(f"✅ Nombre de tokens de sortie : {output_tokens}")
331
  except Exception as e:
332
  if hasattr(e, "status_code") and e.status_code == 429:
333
  retries += 1
 
406
  "🤖 Entraînement du guardrail à reconnaître le prompt comme dangereux effectué avec succès"
407
  )
408
  st.stop()
409
+ # def check_if_ingredients_saved(db_manager, user_id):
410
+ # query = "SELECT repas_suggestion, ingredients FROM suggestions_repas WHERE id_utilisateur = ?"
411
+ # recipes = db_manager.execute_safe(query, (user_id,), fetch=True)
412
+
413
+ # if recipes:
414
+ # print("✅ Recettes enregistrées en base :")
415
+ # for recipe in recipes:
416
+ # recette_nom = recipe[0]
417
+ # ingredients = recipe[1] if recipe[1] else "⚠️ Aucun ingrédient enregistré"
418
+ # print(f"📌 {recette_nom} - Ingrédients : {ingredients}")
419
+ # else:
420
+ # print("⚠️ Aucune recette enregistrée.")
421
+
422
+ # # Appel pour tester
423
+ # check_if_ingredients_saved(db_manager, user_id)
424
+
client/pages/user__course_list.py CHANGED
@@ -1,17 +1,78 @@
1
  import streamlit as st
2
- from server.db.db import get_ingredients
 
 
3
 
 
 
 
 
4
 
5
- # Page des courses
6
  def course_list():
7
- st.write("Voici votre liste des courses.")
 
 
 
 
8
 
9
- ingredients_list = get_ingredients()
 
 
 
 
 
10
 
11
- if ingredients_list:
12
- for ingredient in ingredients_list:
13
- st.write(f"🍎 {ingredient[0]}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  else:
15
- st.write("Aucun ingrédient trouvé.")
 
 
 
16
 
17
- st.checkbox("Ajouter un nouvel article")
 
 
 
 
 
 
1
  import streamlit as st
2
+ import pandas as pd
3
+ import unicodedata
4
+ from server.db.dbmanager import get_db_manager
5
 
6
+ def normalize_text(text):
7
+ """Normalise un texte en supprimant les accents et en le mettant en minuscules"""
8
+ text = unicodedata.normalize("NFKD", text).encode("ASCII", "ignore").decode("utf-8").strip().lower()
9
+ return text
10
 
 
11
  def course_list():
12
+ # Récupérer l'ID utilisateur
13
+ user_id = st.session_state.get("user_id")
14
+ if not user_id:
15
+ st.warning("⚠️ Vous devez être connecté pour voir votre liste de courses.")
16
+ return
17
 
18
+ # Charger la base de données
19
+ db_manager = get_db_manager()
20
+
21
+ # Charger les recettes et leurs ingrédients depuis la base de données
22
+ query = "SELECT repas_suggestion, ingredients FROM suggestions_repas WHERE id_utilisateur = ?"
23
+ raw_recipes = db_manager.execute_safe(query, (user_id,), fetch=True)
24
 
25
+ if not raw_recipes:
26
+ st.warning("⚠️ Aucune recette enregistrée pour générer une liste de courses.")
27
+ return
28
+
29
+ # ✅ Normalisation et suppression des doublons
30
+ recipes = {}
31
+ formatted_titles = {}
32
+
33
+ for recipe in raw_recipes:
34
+ title, ingredients = recipe["repas_suggestion"], recipe["ingredients"]
35
+ normalized_title = normalize_text(title)
36
+
37
+ if normalized_title not in recipes or (not recipes[normalized_title] and ingredients):
38
+ recipes[normalized_title] = ingredients
39
+ formatted_titles[normalized_title] = title
40
+
41
+ recipe_titles = list(formatted_titles.values())
42
+
43
+ # Sélectionner des recettes
44
+ selected_recipes = st.multiselect("📌 Sélectionnez une ou plusieurs recettes", recipe_titles)
45
+
46
+ # Initialiser all_ingredients pour éviter UnboundLocalError
47
+ all_ingredients = []
48
+
49
+ # Récupérer les ingrédients des recettes sélectionnées
50
+ selected_ingredients = []
51
+ for recipe in selected_recipes:
52
+ normalized_recipe = normalize_text(recipe)
53
+ ingredients = recipes.get(normalized_recipe)
54
+ if ingredients:
55
+ selected_ingredients.extend(ingredients.split(", "))
56
+
57
+ # ✅ Option pour afficher la liste complète de courses
58
+ if st.checkbox("👀 Afficher la liste complète des courses"):
59
+ all_ingredients = list({ing for ing_list in recipes.values() if ing_list for ing in ing_list.split(", ")})
60
+
61
+ # Affichage des ingrédients récupérés
62
+ ingredients_to_display = selected_ingredients if selected_ingredients else all_ingredients
63
+ if ingredients_to_display:
64
+ st.subheader("📋 Ingrédients nécessaires")
65
+ for ingredient in ingredients_to_display:
66
+ st.write(f"🛒 {ingredient}")
67
  else:
68
+ st.warning("⚠️ Aucun ingrédient enregistré.")
69
+
70
+ # 📥 Exporter la liste des courses
71
+ df = pd.DataFrame({"Ingrédients": ingredients_to_display})
72
 
73
+ if st.download_button(
74
+ label="📥 Télécharger la liste des courses",
75
+ data=df.to_csv(index=False, sep=";").encode("utf-8-sig"),
76
+ file_name="liste_courses.csv",
77
+ mime="text/csv"):
78
+ st.success("✅ Liste des courses exportée en CSV avec succès !")