Infinity-1995 commited on
Commit
7c9b40f
·
verified ·
1 Parent(s): 6a789b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +147 -42
app.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import os
2
  import gradio as gr
3
  from groq import Groq
@@ -5,14 +7,16 @@ from reportlab.pdfgen import canvas
5
  from reportlab.lib.pagesizes import letter
6
  import tempfile
7
  import re
8
- from textwrap import wrap
9
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
10
- from reportlab.lib.pagesizes import letter
11
  from reportlab.lib.styles import getSampleStyleSheet
 
 
 
 
12
 
13
- # Load API key securely from environment
14
- GROQ_API_KEY = os.getenv("GROQ_API_KEY")
15
- client = Groq(api_key=GROQ_API_KEY)
16
 
17
  MOODS = [
18
  "Adventure",
@@ -36,6 +40,41 @@ MOOD_IMAGES = {
36
  "Any": "images/default.png"
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  def generate_itinerary(mood, location, budget, days):
40
  mood_text = "any mood" if mood == "Any" else mood
41
  budget_text = "any budget" if budget == "Any" else budget
@@ -45,7 +84,6 @@ def generate_itinerary(mood, location, budget, days):
45
  f"Create a {days}-day travel itinerary to {location_text}. "
46
  f"The mood of the traveler is {mood_text} and the budget is {budget_text}. "
47
  f"Use Markdown formatting with **bold headings** for days and time slots."
48
- f"In the last line show the Approximate budget for one person in Dollars."
49
  )
50
 
51
  completion = client.chat.completions.create(
@@ -61,12 +99,15 @@ def generate_itinerary(mood, location, budget, days):
61
  )
62
 
63
  itinerary_text = completion.choices[0].message.content
64
- image_path = MOOD_IMAGES.get(mood, MOOD_IMAGES["Any"])
65
- return itinerary_text, image_path, gr.update(visible=True)
 
 
 
66
 
67
  def generate_pdf(itinerary_text):
68
  if not itinerary_text.strip():
69
- return None
70
 
71
  temp_dir = tempfile.gettempdir()
72
  temp_path = os.path.join(temp_dir, "feelaway_itinerary.pdf")
@@ -80,9 +121,9 @@ def generate_pdf(itinerary_text):
80
 
81
  styles = getSampleStyleSheet()
82
  style = styles["Normal"]
83
- style.fontName = "Courier"
84
- style.fontSize = 10
85
- style.leading = 14
86
 
87
  html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
88
  paragraphs = html_text.split('\n')
@@ -95,12 +136,10 @@ def generate_pdf(itinerary_text):
95
 
96
  doc.build(story)
97
 
98
- return temp_path
99
-
100
-
101
-
102
  with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
103
- # Header with gr.HTML for styles and animation
104
  header_html = """
105
  <style>
106
  @keyframes colorCycle {
@@ -111,52 +150,118 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")
111
  100% { color: #20b2aa; }
112
  }
113
  .color-cycle {
114
- animation: colorCycle 4s infinite;
 
 
 
 
115
  }
116
  .tagline {
117
  font-style: italic;
118
- color: #007777;
119
- font-size: 18px;
120
  margin-top: 4px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
  </style>
123
- <div style='text-align: center;'>
124
- <h1 class="color-cycle" style="font-size: 38px; margin-bottom: 0;">FEEL AWAY APP</h1>
125
- <p class="tagline">"Your Mood, Your Journey – Personalized Itineraries, Instantly"</p>
126
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  """
128
- with gr.Row():
 
129
  gr.HTML(header_html)
130
 
131
- # Inputs
132
- with gr.Row():
133
- mood = gr.Dropdown(MOODS, label="Mood", value="Any", info="Select the mood of your trip")
134
- location = gr.Textbox(label="Destination", placeholder="e.g., India, Japan, France (leave blank for Any)", info="Where do you want to go?")
135
-
136
- with gr.Row():
137
- budget = gr.Dropdown(["Low", "Medium", "High", "Any"], label="Budget", value="Any", info="Choose your budget level")
138
- days = gr.Slider(1, 10, value=5, step=1, label="Days", info="Number of days for the itinerary")
139
-
140
- generate_btn = gr.Button("✨ Generate Itinerary", variant="primary")
 
 
141
 
142
- with gr.Column():
143
- itinerary_output = gr.Markdown(label="Generated Itinerary")
144
- image_output = gr.Image(label="Travel Mood Image", type="filepath", visible=False)
 
 
 
 
 
 
145
 
146
- with gr.Column():
147
- download_btn = gr.Button("📥 Download Itinerary as PDF", variant="secondary")
148
- pdf_file = gr.File(label="Download PDF", file_types=[".pdf"])
149
 
150
  generate_btn.click(
151
  generate_itinerary,
152
  inputs=[mood, location, budget, days],
153
- outputs=[itinerary_output, image_output, image_output]
 
154
  )
155
 
156
  download_btn.click(
157
  generate_pdf,
158
  inputs=[itinerary_output],
159
- outputs=pdf_file
160
  )
161
 
162
  demo.launch()
 
1
+ import spacy.cli
2
+ spacy.cli.download("en_core_web_sm")
3
  import os
4
  import gradio as gr
5
  from groq import Groq
 
7
  from reportlab.lib.pagesizes import letter
8
  import tempfile
9
  import re
 
10
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
 
11
  from reportlab.lib.styles import getSampleStyleSheet
12
+ from reportlab.lib.pagesizes import letter
13
+ import spacy
14
+ from geopy.geocoders import Nominatim
15
+ import folium
16
 
17
+ # Load API key
18
+ GR_API_KEY = os.getenv("GR_API_KEY")
19
+ client = Groq(api_key=GR_API_KEY)
20
 
21
  MOODS = [
22
  "Adventure",
 
40
  "Any": "images/default.png"
41
  }
42
 
43
+ nlp = spacy.load("en_core_web_sm")
44
+
45
+ def clean_place_name(name):
46
+ return re.sub(r'^(the|a|an)\s+', '', name, flags=re.IGNORECASE).strip()
47
+
48
+ def extract_places_and_map(itinerary_text, city_context=None):
49
+ pattern = r"(visit|explore|trip to|at|go to|see)\s+([A-Z][A-Za-zÀ-ÖØ-öø-ÿ'’\- ]+)"
50
+ matches = re.findall(pattern, itinerary_text, re.IGNORECASE)
51
+ rule_places = [m[1].strip() for m in matches]
52
+
53
+ doc = nlp(itinerary_text)
54
+ ner_places = [ent.text for ent in doc.ents if ent.label_ in ["GPE", "LOC", "FAC"]]
55
+
56
+ places = list(set(rule_places + ner_places))
57
+
58
+ geolocator = Nominatim(user_agent="feelaway_app")
59
+ locations = []
60
+ for place in places:
61
+ try:
62
+ query = f"{place}, {city_context}" if city_context else place
63
+ loc = geolocator.geocode(query, language='en', timeout=10)
64
+ if loc:
65
+ locations.append((place, loc.latitude, loc.longitude))
66
+ except Exception:
67
+ continue
68
+
69
+ if not locations:
70
+ return "<p>No locations found for mapping.</p>"
71
+
72
+ m = folium.Map(location=[locations[0][1], locations[0][2]], zoom_start=10)
73
+ for name, lat, lon in locations:
74
+ folium.Marker([lat, lon], popup=name).add_to(m)
75
+
76
+ return m._repr_html_()
77
+
78
  def generate_itinerary(mood, location, budget, days):
79
  mood_text = "any mood" if mood == "Any" else mood
80
  budget_text = "any budget" if budget == "Any" else budget
 
84
  f"Create a {days}-day travel itinerary to {location_text}. "
85
  f"The mood of the traveler is {mood_text} and the budget is {budget_text}. "
86
  f"Use Markdown formatting with **bold headings** for days and time slots."
 
87
  )
88
 
89
  completion = client.chat.completions.create(
 
99
  )
100
 
101
  itinerary_text = completion.choices[0].message.content
102
+ image_path = os.path.abspath(MOOD_IMAGES.get(mood, MOOD_IMAGES["Any"]))
103
+
104
+ map_html = extract_places_and_map(itinerary_text, city_context=location_text if location_text.lower() != "any destination" else None)
105
+
106
+ return itinerary_text, image_path, map_html
107
 
108
  def generate_pdf(itinerary_text):
109
  if not itinerary_text.strip():
110
+ return None, gr.update(visible=False)
111
 
112
  temp_dir = tempfile.gettempdir()
113
  temp_path = os.path.join(temp_dir, "feelaway_itinerary.pdf")
 
121
 
122
  styles = getSampleStyleSheet()
123
  style = styles["Normal"]
124
+ style.fontName = "Times-Roman"
125
+ style.fontSize = 14
126
+ style.leading = 18
127
 
128
  html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
129
  paragraphs = html_text.split('\n')
 
136
 
137
  doc.build(story)
138
 
139
+ return temp_path, gr.update(visible=True)
140
+ # ---------------------- UI ----------------------
 
 
141
  with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
142
+
143
  header_html = """
144
  <style>
145
  @keyframes colorCycle {
 
150
  100% { color: #20b2aa; }
151
  }
152
  .color-cycle {
153
+ animation: colorCycle 3s infinite;
154
+ font-weight: 800;
155
+ letter-spacing: 1.5px;
156
+ text-transform: uppercase;
157
+ text-shadow: 1px 1px 3px #a0d1d1;
158
  }
159
  .tagline {
160
  font-style: italic;
161
+ color: #007777 !important;
162
+ font-size: 20px;
163
  margin-top: 4px;
164
+ height: 30px;
165
+ white-space: nowrap;
166
+ overflow: hidden;
167
+ font-weight: 600;
168
+ animation: pulseOpacity 2s infinite;
169
+ }
170
+ .equal-row {
171
+ display: flex;
172
+ gap: 16px;
173
+ }
174
+ .equal-row > div {
175
+ flex: 1;
176
+ }
177
+ #map-container iframe,
178
+ #image-container img {
179
+ width: 100%;
180
+ height: 500px;
181
+ border-radius: 8px;
182
+ object-fit: cover;
183
+ display: block;
184
  }
185
  </style>
186
+ <div style='text-align: center; margin-top: 30px; margin-bottom: 30px;'>
187
+ <h1 class="color-cycle" style="font-size: 42px; margin: 0;">FEEL AWAY APP</h1>
188
+ <p class="tagline" id="typing-text-main"></p>
189
  </div>
190
+ <script>
191
+ const tagline = "Your Mood, Your Journey – Personalized Itineraries, Instantly!";
192
+ function typeWriter(elId) {
193
+ let i = 0;
194
+ let forward = true;
195
+ const el = document.getElementById(elId);
196
+ function typing() {
197
+ if (forward) {
198
+ if (i < tagline.length) {
199
+ el.innerHTML += tagline.charAt(i);
200
+ i++;
201
+ } else {
202
+ forward = false;
203
+ setTimeout(typing, 2000);
204
+ return;
205
+ }
206
+ } else {
207
+ if (i > 0) {
208
+ el.innerHTML = tagline.substring(0, i-1);
209
+ i--;
210
+ } else {
211
+ forward = true;
212
+ }
213
+ }
214
+ setTimeout(typing, 60);
215
+ }
216
+ typing();
217
+ }
218
+ window.onload = () => {
219
+ typeWriter("typing-text-main");
220
+ }
221
+ </script>
222
  """
223
+
224
+ with gr.Column(elem_id="main-content"):
225
  gr.HTML(header_html)
226
 
227
+ with gr.Row():
228
+ mood = gr.Dropdown(MOODS, label="Mood", value="Any")
229
+ location = gr.Textbox(label="Destination", placeholder="e.g., India, Japan, France (leave blank for Any)")
230
+
231
+ with gr.Row():
232
+ budget = gr.Dropdown(["Low", "Medium", "High", "Any"], label="Budget", value="Any")
233
+ days = gr.Slider(1, 10, value=5, step=1, label="Days")
234
+
235
+ generate_btn = gr.Button("Generate Itinerary", variant="primary")
236
+
237
+ with gr.Column():
238
+ itinerary_output = gr.Markdown(label="Generated Itinerary")
239
 
240
+ with gr.Row(elem_classes="equal-row"):
241
+ with gr.Column(scale=1):
242
+ gr.HTML("<div id='image-container'>")
243
+ image_output = gr.Image(type="filepath", show_label=False)
244
+ gr.HTML("</div>")
245
+ with gr.Column(scale=1):
246
+ gr.HTML("<div id='map-container'>")
247
+ map_output = gr.HTML(show_label=False)
248
+ gr.HTML("</div>")
249
 
250
+ with gr.Column():
251
+ download_btn = gr.Button("Download Itinerary as PDF", variant="secondary")
252
+ pdf_file = gr.File(file_types=[".pdf"], visible=False)
253
 
254
  generate_btn.click(
255
  generate_itinerary,
256
  inputs=[mood, location, budget, days],
257
+ outputs=[itinerary_output, image_output, map_output],
258
+ show_progress=True
259
  )
260
 
261
  download_btn.click(
262
  generate_pdf,
263
  inputs=[itinerary_output],
264
+ outputs=[pdf_file, pdf_file]
265
  )
266
 
267
  demo.launch()