AlessandroArgiolas02 commited on
Commit
3397992
·
verified ·
1 Parent(s): ccba573

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -88
app.py CHANGED
@@ -8,106 +8,101 @@ genai.configure(api_key=GEMINI_KEY)
8
  model = genai.GenerativeModel('gemini-pro')
9
 
10
  CSS = """
11
- body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
12
- .header { text-align: center; margin-bottom: 30px; }
13
- .input-section { display: flex; gap: 10px; margin-bottom: 20px; }
14
- #question { flex-grow: 1; padding: 10px; }
15
- .category { margin: 25px 0; border-bottom: 2px solid #eee; padding-bottom: 20px; }
16
- .category-title { color: #2c3e50; font-size: 1.4em; margin-bottom: 15px; }
17
- .item-card { background: white; padding: 15px; border-radius: 8px; margin: 10px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
18
- .item-card h3 { margin: 0 0 8px 0; color: #3498db; }
19
- .link { color: #2980b9; text-decoration: underline; }
20
  """
21
 
22
- def parse_response(response):
23
- categories = {}
24
- current_category = None
25
 
26
- # Dividi in categorie
27
- lines = response.split('\n')
28
- for line in lines:
29
- if line.startswith('## '):
30
- current_category = line.replace('## ', '').strip()
31
- categories[current_category] = []
32
- elif line.startswith('- **') or line.startswith('1. **'):
33
- parts = re.split(r'\*\*|\*', line)
34
- name = parts[1].strip()
35
- desc = parts[-1].strip()
36
-
37
- # Estrai link
38
- links = re.findall(r'(https?://\S+)', desc)
39
- desc = re.sub(r'(https?://\S+)', '', desc).strip()
40
-
41
- categories[current_category].append({
42
- "name": name,
43
- "description": desc,
44
- "links": links
45
- })
46
 
47
- return categories
48
-
49
- def generate_response(question):
50
- # Controlla se è una richiesta specifica
51
- specific_query = re.search(r'\b(dove|cosa|come|quale|quando)\b', question, re.IGNORECASE)
52
-
53
- if specific_query:
54
- # Modalità risposta libera
55
- response = model.generate_content(f"Rispondi in italiano in formato testo semplice: {question}").text
56
- return f"<div class='free-response'>{response}</div>"
57
- else:
58
- # Modalità strutturata
59
- city = re.search(r'\b(a|in|per|su)\s+([A-Za-z\s]+)', question, re.IGNORECASE)
60
- city = city.group(2).strip() if city else question
61
 
62
- prompt = f"""
63
- Genera una guida turistica per {city} in italiano con:
64
- - 3-5 luoghi da vedere con breve descrizione e sito ufficiale se disponibile
65
- - 3 ristoranti tipici con specialità e eventuale sito web
66
- - 3 opzioni alloggio con range prezzi
67
- - 2-3 attività caratteristiche
68
- - Formatta in markdown con categorie ##
69
- - Includi link dove appropriato
70
- """
 
 
71
 
72
- response = model.generate_content(prompt).text
73
- categories = parse_response(response)
74
 
75
- html_output = ""
76
- for category, items in categories.items():
77
- section = f"""
78
- <div class='category'>
79
- <div class='category-title'>{category}</div>
 
 
 
 
80
  """
81
-
82
- for item in items:
83
- links = "".join([f"<a href='{link}' class='link' target='_blank'>Sito ufficiale</a>" for link in item['links']])
84
-
85
- section += f"""
86
- <div class='item-card'>
87
- <h3>{item['name']}</h3>
88
- <p>{item['description']}</p>
89
- {links}
90
- </div>
91
- """
92
-
93
- section += "</div>"
94
- html_output += section
95
-
96
- return html_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
  with gr.Blocks(css=CSS) as app:
99
- gr.HTML("<div class='header'><h1>🌍 Guida Turistica Digitale</h1><p>Chiedimi informazioni su qualsiasi destinazione!</p></div>")
 
 
 
100
 
101
- with gr.Row(equal_height=True, variant="panel"):
102
- question = gr.Textbox(placeholder="Es: Cosa visitare a Roma?", elem_id="question")
103
- submit_btn = gr.Button("Cerca", variant="primary")
104
 
105
- output = gr.HTML()
 
106
 
107
- submit_btn.click(
108
- fn=generate_response,
109
- inputs=question,
110
- outputs=output
111
- )
112
 
113
  app.launch()
 
8
  model = genai.GenerativeModel('gemini-pro')
9
 
10
  CSS = """
11
+ body { background: #f5f7fa; font-family: 'Arial', sans-serif; }
12
+ .chat-container { max-width: 800px; margin: 0 auto; }
13
+ .msg-user { background: #e3f2fd; padding: 15px; border-radius: 15px; margin: 10px; max-width: 70%; float: right; }
14
+ .msg-bot { background: white; padding: 15px; border-radius: 15px; margin: 10px; max-width: 70%; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
15
+ .card { border-left: 4px solid #2196F3; padding: 10px; margin: 10px 0; }
16
+ .price { color: #2e7d32; font-weight: bold; }
17
+ .link { color: #1565C0; text-decoration: underline; }
18
+ .reset-btn { margin-top: 20px; }
 
19
  """
20
 
21
+ class ChatManager:
22
+ def __init__(self):
23
+ self.context = {"city": None}
24
 
25
+ def extract_city(self, text):
26
+ cities = re.findall(r'\b(?:a|in|su|per)\s+([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b', text, re.IGNORECASE)
27
+ return cities[0] if cities else self.context["city"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ def format_response(self, response):
30
+ structured = []
31
+ current_item = {}
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ lines = response.split('\n')
34
+ for line in lines:
35
+ if line.startswith('- **'):
36
+ parts = re.split(r'\*\*:?|\*', line)
37
+ if len(parts) > 2:
38
+ key = parts[1].strip().lower()
39
+ value = parts[2].strip()
40
+ current_item[key] = value
41
+ elif line.strip() == '' and current_item:
42
+ structured.append(current_item)
43
+ current_item = {}
44
 
45
+ if current_item:
46
+ structured.append(current_item)
47
 
48
+ html = ""
49
+ for item in structured:
50
+ html += f"""
51
+ <div class='card'>
52
+ <h3>{item.get('nome', '')}</h3>
53
+ <p>{item.get('descrizione', '')}</p>
54
+ <p class='price'>{item.get('prezzo', '')}</p>
55
+ {f"<a href='{item['link']}' class='link' target='_blank'>Maggiori informazioni</a>" if 'link' in item else ''}
56
+ </div>
57
  """
58
+ return html if html else response
59
+
60
+ chat_manager = ChatManager()
61
+
62
+ def respond(message, history):
63
+ # Estrai e mantieni contesto città
64
+ city = chat_manager.extract_city(message)
65
+ if city:
66
+ chat_manager.context["city"] = city
67
+
68
+ if not chat_manager.context["city"]:
69
+ return "Per favore dimmi prima di quale città vuoi informazioni! 🌍"
70
+
71
+ # Genera risposta
72
+ prompt = f"""
73
+ Sei un esperto guida turistica per {chat_manager.context["city"]}.
74
+ Rispondi in italiano strutturando ogni suggerimento con:
75
+ - **Nome**: [nome luogo]
76
+ - **Descrizione**: [breve descrizione 20-30 parole]
77
+ - **Prezzo**: [se applicabile]
78
+ - **Link**: [sito ufficiale se disponibile]
79
+
80
+ Richiesta utente: {message}
81
+ """
82
+
83
+ try:
84
+ response = model.generate_content(prompt).text
85
+ return chat_manager.format_response(response)
86
+ except Exception as e:
87
+ return f"⚠️ Errore: {str(e)}"
88
+
89
+ def reset_context():
90
+ chat_manager.context = {"city": None}
91
+ return "Contesto resettato. Di quale città vuoi parlare ora? 🌆"
92
 
93
  with gr.Blocks(css=CSS) as app:
94
+ gr.Markdown("# 🗺️ Assistente Turistico Chat")
95
+
96
+ chatbot = gr.Chatbot(label="Chat", elem_classes="chat-container")
97
+ msg = gr.Textbox(label="Scrivi il tuo messaggio...")
98
 
99
+ with gr.Row():
100
+ send_btn = gr.Button("Invia")
101
+ reset_btn = gr.Button("Cambia Città", variant="secondary")
102
 
103
+ send_btn.click(respond, [msg, chatbot], [msg, chatbot])
104
+ reset_btn.click(reset_context, None, [chatbot])
105
 
106
+ msg.submit(respond, [msg, chatbot], [msg, chatbot])
 
 
 
 
107
 
108
  app.launch()