Infinity-1995 commited on
Commit
12d215c
·
verified ·
1 Parent(s): eedc4e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -26
app.py CHANGED
@@ -13,6 +13,7 @@ from reportlab.lib.pagesizes import letter
13
  import spacy
14
  from geopy.geocoders import Nominatim
15
  import folium
 
16
  from reportlab.pdfbase import pdfmetrics
17
  from reportlab.pdfbase.ttfonts import TTFont
18
 
@@ -83,25 +84,43 @@ def generate_itinerary(mood, location, budget, days):
83
  budget_text = "any budget" if budget == "Any" else budget
84
  location_text = location if location.strip() != "" else "any destination"
85
 
 
86
  prompt = (
87
- f"Create a {days}-day travel itinerary to {location_text}. "
88
- f"The mood of the traveler is {mood_text} and the budget is {budget_text}. "
 
89
  f"Use Markdown formatting with **bold headings** for days and time slots."
90
  )
91
-
 
92
  completion = client.chat.completions.create(
93
- model="openai/gpt-oss-20b",
94
  messages=[
95
  {"role": "system", "content": "You are an expert travel planner."},
96
  {"role": "user", "content": prompt}
97
  ],
98
- temperature=1,
99
- max_completion_tokens=8192,
100
  top_p=1,
101
- reasoning_effort="medium",
102
- stream=False,
103
- stop=None
104
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  itinerary_text = completion.choices[0].message.content
107
  image_path = os.path.abspath(MOOD_IMAGES.get(mood, MOOD_IMAGES["Any"]))
@@ -111,20 +130,20 @@ def generate_itinerary(mood, location, budget, days):
111
  return itinerary_text, image_path, map_html
112
 
113
  def get_best_season(location):
114
- """AI-powered function to recommend the best season to visit any city, state, or country."""
115
  if not location.strip() or location.lower() == "any destination":
116
  return "🌤️ Best season info is available for specific locations only."
117
 
118
  prompt = (
119
- f"Based on weather, tourism, and festivals, suggest the best season or months to visit {location}. "
120
- f"Explain briefly in 25 words or less."
121
  )
122
 
123
  try:
124
  response = client.chat.completions.create(
125
- model="openai/gpt-oss-20b", # You can replace this with any working model, e.g. "llama-3.1-8b"
126
  messages=[
127
- {"role": "system", "content": "You are an expert travel advisor."},
128
  {"role": "user", "content": prompt}
129
  ],
130
  temperature=0.7,
@@ -133,7 +152,7 @@ def get_best_season(location):
133
  stream=False
134
  )
135
 
136
- # Safely extract the content depending on SDK format
137
  if hasattr(response.choices[0].message, "content"):
138
  season_text = response.choices[0].message.content
139
  else:
@@ -146,31 +165,34 @@ def get_best_season(location):
146
  return "🌤️ Unable to determine the best season right now."
147
 
148
 
 
149
  def generate_pdf(itinerary_text):
150
  if not itinerary_text.strip():
151
  return None, gr.update(visible=False)
152
 
 
153
  temp_dir = tempfile.gettempdir()
154
- temp_path = os.path.join(temp_dir, "feelaway_itinerary.pdf")
155
-
156
- if os.path.exists(temp_path):
157
- os.remove(temp_path)
158
 
 
159
  doc = SimpleDocTemplate(temp_path, pagesize=letter,
160
  rightMargin=40, leftMargin=40,
161
  topMargin=40, bottomMargin=40)
162
 
163
- # Register a Unicode font (DejaVu Sans is widely available)
164
- pdfmetrics.registerFont(TTFont("DejaVuSans", "DejaVuSans.ttf"))
165
  styles = getSampleStyleSheet()
166
  style = styles["Normal"]
167
- style.fontName = "DejaVuSans" # Use Unicode-safe font
168
- style.fontSize = 12
169
- style.leading = 16
170
 
 
171
  html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
172
- paragraphs = html_text.split('\n')
173
 
 
 
 
 
174
  story = []
175
  for para in paragraphs:
176
  p = Paragraph(para if para.strip() else ' ', style)
@@ -178,8 +200,8 @@ def generate_pdf(itinerary_text):
178
  story.append(Spacer(1, 6))
179
 
180
  doc.build(story)
181
-
182
  return temp_path, gr.update(visible=True)
 
183
  # ---------------------- UI ----------------------
184
  with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
185
 
 
13
  import spacy
14
  from geopy.geocoders import Nominatim
15
  import folium
16
+ import time
17
  from reportlab.pdfbase import pdfmetrics
18
  from reportlab.pdfbase.ttfonts import TTFont
19
 
 
84
  budget_text = "any budget" if budget == "Any" else budget
85
  location_text = location if location.strip() != "" else "any destination"
86
 
87
+ # 🧠 AI prompt
88
  prompt = (
89
+ f"Create a detailed {days}-day travel itinerary for {location_text}. "
90
+ f"The traveler’s mood is {mood_text}, with a {budget_text} budget. "
91
+ f"Include daily activities, key landmarks, and meal or cultural suggestions. "
92
  f"Use Markdown formatting with **bold headings** for days and time slots."
93
  )
94
+
95
+ # 🧩 Generate itinerary
96
  completion = client.chat.completions.create(
97
+ model="llama-3.1-8b", # Use gemma or gpt-oss if this doesn't work
98
  messages=[
99
  {"role": "system", "content": "You are an expert travel planner."},
100
  {"role": "user", "content": prompt}
101
  ],
102
+ temperature=0.8,
103
+ max_tokens=2800, # enough for multi-day itineraries
104
  top_p=1,
105
+ stream=False
 
 
106
  )
107
+
108
+ itinerary_text = completion.choices[0].message.content
109
+
110
+ # 🌤️ Get general season/weather info
111
+ season_text = get_best_season(location_text)
112
+
113
+ # 📍 Map and image
114
+ image_path = os.path.abspath(MOOD_IMAGES.get(mood, MOOD_IMAGES["Any"]))
115
+ map_html = extract_places_and_map(
116
+ itinerary_text,
117
+ city_context=location_text if location_text.lower() != "any destination" else None
118
+ )
119
+
120
+ # 🧾 Combine output
121
+ combined_output = f"### {season_text}\n\n{itinerary_text}"
122
+ return combined_output, image_path, map_html
123
+
124
 
125
  itinerary_text = completion.choices[0].message.content
126
  image_path = os.path.abspath(MOOD_IMAGES.get(mood, MOOD_IMAGES["Any"]))
 
130
  return itinerary_text, image_path, map_html
131
 
132
  def get_best_season(location):
133
+ """AI-powered function to recommend the best season or general weather for any location."""
134
  if not location.strip() or location.lower() == "any destination":
135
  return "🌤️ Best season info is available for specific locations only."
136
 
137
  prompt = (
138
+ f"Suggest the best season or time of year to visit {location} based on weather and tourism. "
139
+ f"Keep it short and under 25 words."
140
  )
141
 
142
  try:
143
  response = client.chat.completions.create(
144
+ model="llama-3.1-8b", # or openai/gpt-oss-20b if supported
145
  messages=[
146
+ {"role": "system", "content": "You are a travel expert."},
147
  {"role": "user", "content": prompt}
148
  ],
149
  temperature=0.7,
 
152
  stream=False
153
  )
154
 
155
+ # Extract content safely
156
  if hasattr(response.choices[0].message, "content"):
157
  season_text = response.choices[0].message.content
158
  else:
 
165
  return "🌤️ Unable to determine the best season right now."
166
 
167
 
168
+
169
  def generate_pdf(itinerary_text):
170
  if not itinerary_text.strip():
171
  return None, gr.update(visible=False)
172
 
173
+ # Unique file name for each download
174
  temp_dir = tempfile.gettempdir()
175
+ temp_filename = f"feelaway_itinerary_{int(time.time())}.pdf"
176
+ temp_path = os.path.join(temp_dir, temp_filename)
 
 
177
 
178
+ # Create a clean PDF
179
  doc = SimpleDocTemplate(temp_path, pagesize=letter,
180
  rightMargin=40, leftMargin=40,
181
  topMargin=40, bottomMargin=40)
182
 
 
 
183
  styles = getSampleStyleSheet()
184
  style = styles["Normal"]
185
+ style.fontName = "Times-Roman"
186
+ style.fontSize = 13
187
+ style.leading = 18
188
 
189
+ # Convert markdown bold to HTML bold
190
  html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
 
191
 
192
+ # Handle Markdown tables safely
193
+ html_text = re.sub(r'\|[^\n]*\|', lambda m: m.group(0).replace('|', ' '), html_text)
194
+
195
+ paragraphs = html_text.split('\n')
196
  story = []
197
  for para in paragraphs:
198
  p = Paragraph(para if para.strip() else ' ', style)
 
200
  story.append(Spacer(1, 6))
201
 
202
  doc.build(story)
 
203
  return temp_path, gr.update(visible=True)
204
+
205
  # ---------------------- UI ----------------------
206
  with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
207