forked from Bestinhop23/WHERES-DA-CRAIC
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
153 lines (130 loc) · 5 KB
/
server.py
File metadata and controls
153 lines (130 loc) · 5 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
import csv
import json
import re
import urllib.request
from flask import Flask, jsonify, send_from_directory, request
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
INPUT_CSV = "places_ireland.csv"
CHECKPOINT_FILE = "enrichment_checkpoint.json"
@app.route('/')
def index():
return send_from_directory('.', 'index.html')
@app.route('/data')
def get_data():
"""Merges CSV and checkpoint data on the fly and returns GeoJSON."""
if not os.path.exists(INPUT_CSV):
return jsonify({"error": "CSV not found"}), 404
enriched_data = {}
if os.path.exists(CHECKPOINT_FILE):
try:
with open(CHECKPOINT_FILE, 'r', encoding='utf-8') as f:
enriched_data = json.load(f)
except Exception as e:
print(f"Error loading checkpoint: {e}")
return jsonify({"error": f"Checkpoint file corrupted: {str(e)}"}), 404
features = []
with open(INPUT_CSV, mode='r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
place_id = f"{row['name']}_{row['lat']}_{row['lon']}"
=======
# ONLY include places that are in the checkpoint
if place_id not in enriched_data:
continue
try:
culture = enriched_data[place_id]
feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [float(row['lon']), float(row['lat'])]
},
"properties": {
"name": row['name'],
"name_ga": row['name_ga'] or row['name'],
"county": row['county'] or "Ireland",
"type": row['type'],
**culture
}
}
features.append(feature)
except Exception as e:
print(f"Error processing {row['name']}: {e}")
continue
=======
geojson = {
"type": "FeatureCollection",
"features": features
}
return jsonify(geojson)
@app.route('/search')
def search():
"""Search enriched places by name, Irish name, or county."""
q = request.args.get('q', '').strip().lower()
if not q or len(q) < 2:
return jsonify([])
if not os.path.exists(INPUT_CSV):
return jsonify([])
enriched_data = {}
if os.path.exists(CHECKPOINT_FILE):
try:
with open(CHECKPOINT_FILE, 'r', encoding='utf-8') as f:
enriched_data = json.load(f)
except Exception as e:
print(f"Error loading checkpoint: {e}")
prefix_matches = []
partial_matches = []
with open(INPUT_CSV, mode='r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
place_id = f"{row['name']}_{row['lat']}_{row['lon']}"
if place_id not in enriched_data:
continue
name = row['name'].lower()
name_ga = (row.get('name_ga') or '').lower()
county = (row.get('county') or '').lower()
result = {
"name": row['name'],
"name_ga": row.get('name_ga', ''),
"county": row.get('county', ''),
"type": row.get('type', ''),
"lat": float(row['lat']),
"lon": float(row['lon']),
}
if name.startswith(q) or name_ga.startswith(q):
prefix_matches.append(result)
elif q in name or q in name_ga or q in county:
partial_matches.append(result)
results = (prefix_matches + partial_matches)[:10]
return jsonify(results)
@app.route('/og-image')
def og_image():
"""Fetch og:image from a luma event page and return the URL."""
url = request.args.get('url', '').strip()
if not url or not url.startswith('https://lu.ma/'):
return jsonify({'image': None}), 200
try:
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=5) as resp:
html = resp.read(32768).decode('utf-8', errors='ignore')
match = re.search(r'<meta[^>]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)["\']', html)
if not match:
match = re.search(r'<meta[^>]+content=["\']([^"\']+)["\'][^>]+property=["\']og:image["\']', html)
image_url = match.group(1) if match else None
return jsonify({'image': image_url})
except Exception:
return jsonify({'image': None})
@app.route('/events')
def get_events():
"""Return the events JSON."""
events_file = 'events_v1.json'
if not os.path.exists(events_file):
return jsonify({"events": []}), 200
with open(events_file, 'r', encoding='utf-8') as f:
return jsonify(json.load(f))
if __name__ == '__main__':
# Use port 5001 to avoid potential conflicts with port 5000
app.run(host='0.0.0.0', port=5001, debug=True)