Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -14,7 +14,6 @@ import spacy
|
|
| 14 |
from geopy.geocoders import Nominatim
|
| 15 |
import folium
|
| 16 |
|
| 17 |
-
|
| 18 |
# Load API key securely from environment
|
| 19 |
GR_API_KEY = os.getenv("GR_API_KEY")
|
| 20 |
client = Groq(api_key=GR_API_KEY)
|
|
@@ -67,20 +66,19 @@ def extract_places_and_map(itinerary_text, city_context=None):
|
|
| 67 |
loc = geolocator.geocode(query, language='en', timeout=10)
|
| 68 |
if loc:
|
| 69 |
locations.append((place, loc.latitude, loc.longitude))
|
| 70 |
-
except Exception
|
| 71 |
-
# Skip failed geocoding quietly
|
| 72 |
continue
|
| 73 |
|
| 74 |
if not locations:
|
| 75 |
return "<p>No locations found for mapping.</p>"
|
| 76 |
|
| 77 |
-
# Create Folium map
|
| 78 |
m = folium.Map(location=[locations[0][1], locations[0][2]], zoom_start=10)
|
| 79 |
for name, lat, lon in locations:
|
| 80 |
folium.Marker([lat, lon], popup=name).add_to(m)
|
| 81 |
|
| 82 |
-
#
|
| 83 |
-
return m.
|
| 84 |
|
| 85 |
def generate_itinerary(mood, location, budget, days):
|
| 86 |
mood_text = "any mood" if mood == "Any" else mood
|
|
@@ -111,51 +109,36 @@ def generate_itinerary(mood, location, budget, days):
|
|
| 111 |
# Generate map HTML from itinerary text and user location
|
| 112 |
map_html = extract_places_and_map(itinerary_text, city_context=location_text if location_text.lower() != "any destination" else None)
|
| 113 |
|
| 114 |
-
return itinerary_text, image_path,
|
| 115 |
|
| 116 |
def generate_pdf(itinerary_text):
|
| 117 |
if not itinerary_text.strip():
|
| 118 |
return None
|
| 119 |
|
| 120 |
-
# Create a temporary PDF file
|
| 121 |
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
|
| 122 |
-
|
| 123 |
-
# Prepare the document template with letter page size
|
| 124 |
doc = SimpleDocTemplate(temp_pdf.name, pagesize=letter,
|
| 125 |
rightMargin=40, leftMargin=40,
|
| 126 |
topMargin=40, bottomMargin=40)
|
| 127 |
|
| 128 |
-
# Get default stylesheet and customize the Normal style
|
| 129 |
styles = getSampleStyleSheet()
|
| 130 |
style = styles["Normal"]
|
| 131 |
-
style.fontName = "Courier"
|
| 132 |
style.fontSize = 10
|
| 133 |
-
style.leading = 14
|
| 134 |
|
| 135 |
-
# Convert markdown-style bold (**text**) to HTML <b>text</b>
|
| 136 |
html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
|
| 137 |
-
|
| 138 |
-
# Split the text into paragraphs by newlines
|
| 139 |
paragraphs = html_text.split('\n')
|
| 140 |
|
| 141 |
-
# Build the story (list of flowables)
|
| 142 |
story = []
|
| 143 |
for para in paragraphs:
|
| 144 |
-
|
| 145 |
-
if para.strip():
|
| 146 |
-
p = Paragraph(para, style)
|
| 147 |
-
else:
|
| 148 |
-
p = Paragraph(' ', style)
|
| 149 |
story.append(p)
|
| 150 |
-
story.append(Spacer(1, 6))
|
| 151 |
|
| 152 |
-
# Build the PDF document
|
| 153 |
doc.build(story)
|
| 154 |
-
|
| 155 |
return temp_pdf.name
|
| 156 |
|
| 157 |
with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
|
| 158 |
-
# Header with gr.HTML for styles and animation
|
| 159 |
header_html = """
|
| 160 |
<style>
|
| 161 |
@keyframes colorCycle {
|
|
@@ -165,15 +148,9 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")
|
|
| 165 |
75% { color: #008080; }
|
| 166 |
100% { color: #20b2aa; }
|
| 167 |
}
|
| 168 |
-
.color-cycle {
|
| 169 |
-
|
| 170 |
-
}
|
| 171 |
-
.tagline {
|
| 172 |
-
font-style: italic;
|
| 173 |
-
color: #007777;
|
| 174 |
-
font-size: 18px;
|
| 175 |
-
margin-top: 4px;
|
| 176 |
-
}
|
| 177 |
</style>
|
| 178 |
<div style='text-align: center;'>
|
| 179 |
<h1 class="color-cycle" style="font-size: 38px; margin-bottom: 0;">FEEL AWAY APP</h1>
|
|
@@ -183,7 +160,6 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")
|
|
| 183 |
with gr.Row():
|
| 184 |
gr.HTML(header_html)
|
| 185 |
|
| 186 |
-
# Inputs
|
| 187 |
with gr.Row():
|
| 188 |
mood = gr.Dropdown(MOODS, label="Mood", value="Any", info="Select the mood of your trip")
|
| 189 |
location = gr.Textbox(label="Destination", placeholder="e.g., India, Japan, France (leave blank for Any)", info="Where do you want to go?")
|
|
@@ -197,7 +173,7 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")
|
|
| 197 |
with gr.Column():
|
| 198 |
itinerary_output = gr.Markdown(label="Generated Itinerary")
|
| 199 |
image_output = gr.Image(label="Travel Mood Image", type="filepath", visible=False)
|
| 200 |
-
map_output = gr.HTML(label="Map of Suggested Places")
|
| 201 |
|
| 202 |
with gr.Column():
|
| 203 |
download_btn = gr.Button("📥 Download Itinerary as PDF", variant="secondary")
|
|
@@ -206,7 +182,7 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")
|
|
| 206 |
generate_btn.click(
|
| 207 |
generate_itinerary,
|
| 208 |
inputs=[mood, location, budget, days],
|
| 209 |
-
outputs=[itinerary_output, image_output,
|
| 210 |
)
|
| 211 |
|
| 212 |
download_btn.click(
|
|
|
|
| 14 |
from geopy.geocoders import Nominatim
|
| 15 |
import folium
|
| 16 |
|
|
|
|
| 17 |
# Load API key securely from environment
|
| 18 |
GR_API_KEY = os.getenv("GR_API_KEY")
|
| 19 |
client = Groq(api_key=GR_API_KEY)
|
|
|
|
| 66 |
loc = geolocator.geocode(query, language='en', timeout=10)
|
| 67 |
if loc:
|
| 68 |
locations.append((place, loc.latitude, loc.longitude))
|
| 69 |
+
except Exception:
|
|
|
|
| 70 |
continue
|
| 71 |
|
| 72 |
if not locations:
|
| 73 |
return "<p>No locations found for mapping.</p>"
|
| 74 |
|
| 75 |
+
# Create Folium map
|
| 76 |
m = folium.Map(location=[locations[0][1], locations[0][2]], zoom_start=10)
|
| 77 |
for name, lat, lon in locations:
|
| 78 |
folium.Marker([lat, lon], popup=name).add_to(m)
|
| 79 |
|
| 80 |
+
# Return full HTML (with JS & CSS)
|
| 81 |
+
return m._repr_html_()
|
| 82 |
|
| 83 |
def generate_itinerary(mood, location, budget, days):
|
| 84 |
mood_text = "any mood" if mood == "Any" else mood
|
|
|
|
| 109 |
# Generate map HTML from itinerary text and user location
|
| 110 |
map_html = extract_places_and_map(itinerary_text, city_context=location_text if location_text.lower() != "any destination" else None)
|
| 111 |
|
| 112 |
+
return itinerary_text, image_path, map_html
|
| 113 |
|
| 114 |
def generate_pdf(itinerary_text):
|
| 115 |
if not itinerary_text.strip():
|
| 116 |
return None
|
| 117 |
|
|
|
|
| 118 |
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
|
|
|
|
|
|
|
| 119 |
doc = SimpleDocTemplate(temp_pdf.name, pagesize=letter,
|
| 120 |
rightMargin=40, leftMargin=40,
|
| 121 |
topMargin=40, bottomMargin=40)
|
| 122 |
|
|
|
|
| 123 |
styles = getSampleStyleSheet()
|
| 124 |
style = styles["Normal"]
|
| 125 |
+
style.fontName = "Courier"
|
| 126 |
style.fontSize = 10
|
| 127 |
+
style.leading = 14
|
| 128 |
|
|
|
|
| 129 |
html_text = re.sub(r'\*\*(.+?)\*\*', r'<b>\1</b>', itinerary_text)
|
|
|
|
|
|
|
| 130 |
paragraphs = html_text.split('\n')
|
| 131 |
|
|
|
|
| 132 |
story = []
|
| 133 |
for para in paragraphs:
|
| 134 |
+
p = Paragraph(para if para.strip() else ' ', style)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
story.append(p)
|
| 136 |
+
story.append(Spacer(1, 6))
|
| 137 |
|
|
|
|
| 138 |
doc.build(story)
|
|
|
|
| 139 |
return temp_pdf.name
|
| 140 |
|
| 141 |
with gr.Blocks(theme=gr.themes.Default(primary_hue="teal", secondary_hue="teal")) as demo:
|
|
|
|
| 142 |
header_html = """
|
| 143 |
<style>
|
| 144 |
@keyframes colorCycle {
|
|
|
|
| 148 |
75% { color: #008080; }
|
| 149 |
100% { color: #20b2aa; }
|
| 150 |
}
|
| 151 |
+
.color-cycle { animation: colorCycle 4s infinite; }
|
| 152 |
+
.tagline { font-style: italic; color: #007777; font-size: 18px; margin-top: 4px; }
|
| 153 |
+
#map-container iframe {height:500px;width:100%;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
</style>
|
| 155 |
<div style='text-align: center;'>
|
| 156 |
<h1 class="color-cycle" style="font-size: 38px; margin-bottom: 0;">FEEL AWAY APP</h1>
|
|
|
|
| 160 |
with gr.Row():
|
| 161 |
gr.HTML(header_html)
|
| 162 |
|
|
|
|
| 163 |
with gr.Row():
|
| 164 |
mood = gr.Dropdown(MOODS, label="Mood", value="Any", info="Select the mood of your trip")
|
| 165 |
location = gr.Textbox(label="Destination", placeholder="e.g., India, Japan, France (leave blank for Any)", info="Where do you want to go?")
|
|
|
|
| 173 |
with gr.Column():
|
| 174 |
itinerary_output = gr.Markdown(label="Generated Itinerary")
|
| 175 |
image_output = gr.Image(label="Travel Mood Image", type="filepath", visible=False)
|
| 176 |
+
map_output = gr.HTML(label="Map of Suggested Places", elem_id="map-container")
|
| 177 |
|
| 178 |
with gr.Column():
|
| 179 |
download_btn = gr.Button("📥 Download Itinerary as PDF", variant="secondary")
|
|
|
|
| 182 |
generate_btn.click(
|
| 183 |
generate_itinerary,
|
| 184 |
inputs=[mood, location, budget, days],
|
| 185 |
+
outputs=[itinerary_output, image_output, map_output]
|
| 186 |
)
|
| 187 |
|
| 188 |
download_btn.click(
|