-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
134 lines (110 loc) · 4.81 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
from flask import Flask, render_template, jsonify, request
import requests
from urllib.parse import urlparse, quote_plus
import logging
from flask_caching import Cache
import time
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__)
# Configure caching
cache = Cache(app, config={'CACHE_TYPE': 'SimpleCache'})
@app.route('/')
def index():
return render_template('index.html')
@app.route('/landmarks')
def get_landmarks():
# Get coordinates from query parameters
lat = float(request.args.get('lat'))
lon = float(request.args.get('lon'))
radius = int(float(request.args.get('radius', 10000))) # Default radius: 10km, converted to integer
filters = request.args.get('filters', '').split(',')
# Create a cache key that includes lat, lon, and radius
cache_key = f"landmarks_{lat}_{lon}_{radius}"
# Check if we have cached data for this key
cached_data = cache.get(cache_key)
if cached_data:
timestamp, landmarks = cached_data
# Check if the cached data is less than 5 minutes old
if time.time() - timestamp < 300:
return jsonify(landmarks)
# If no cached data or it's expired, fetch new data
url = f"https://en.wikipedia.org/w/api.php?action=query&list=geosearch&gsradius={radius}&gscoord={lat}|{lon}&gslimit=50&format=json"
logging.debug(f'Wikipedia API request URL: {url}')
response = requests.get(url)
data = response.json()
logging.debug(f'Wikipedia API response: {data}')
landmarks = []
if 'query' in data and 'geosearch' in data['query']:
for place in data['query']['geosearch']:
landmark_type = classify_landmark(place['title'])
if not filters or landmark_type in filters:
landmarks.append({
'pageid': place['pageid'],
'title': place['title'],
'lat': place['lat'],
'lon': place['lon'],
'type': landmark_type
})
else:
logging.error(f'Unexpected API response format: {data}')
# Cache the new data with the current timestamp
cache.set(cache_key, (time.time(), landmarks))
return jsonify(landmarks)
@app.route('/landmark/<int:pageid>')
@cache.memoize(timeout=3600) # Cache for 1 hour
def get_landmark_info(pageid):
# Query Wikipedia API for landmark details
url = f"https://en.wikipedia.org/w/api.php?action=query&pageids={pageid}&prop=extracts&exintro&format=json&explaintext"
response = requests.get(url)
data = response.json()
page = data['query']['pages'][str(pageid)]
extract = page.get('extract', 'No information available.')
return jsonify({
'title': page['title'],
'extract': extract[:200] + '...' if len(extract) > 200 else extract
})
@app.route('/search')
# Removed @cache.memoize decorator to ensure fresh results for each search
def search():
query = request.args.get('q', '')
logging.info(f"Received search query: {query}")
if not query:
logging.warning("No search query provided")
return jsonify({'error': 'No search query provided'}), 400
# Use Nominatim API for geocoding
encoded_query = quote_plus(query)
url = f"https://nominatim.openstreetmap.org/search?q={encoded_query}&format=json&limit=1"
headers = {'User-Agent': 'LocalLandmarksApp/1.0'}
try:
logging.info(f"Sending request to Nominatim API: {url}")
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
logging.info(f"Received response from Nominatim API: {data}")
if data:
result = data[0]
logging.info(f"Search result: {result}")
return jsonify({
'lat': float(result['lat']),
'lon': float(result['lon']),
'display_name': result['display_name']
})
else:
logging.warning(f"Location not found for query: {query}")
return jsonify({'error': 'Location not found'}), 404
except requests.RequestException as e:
logging.error(f"Error during geocoding request: {str(e)}")
return jsonify({'error': 'An error occurred during the search'}), 500
def classify_landmark(title):
# This is a simple classification based on keywords
# In a real-world scenario, you might want to use a more sophisticated method
title = title.lower()
if any(word in title for word in ['museum', 'castle', 'monument', 'memorial', 'church', 'cathedral']):
return 'historical'
elif any(word in title for word in ['park', 'mountain', 'lake', 'river', 'forest']):
return 'natural'
else:
return 'cultural'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)