forked from academicpages/academicpages.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvetter-update-talkmap.py
More file actions
93 lines (71 loc) · 2.64 KB
/
vetter-update-talkmap.py
File metadata and controls
93 lines (71 loc) · 2.64 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
#!/usr/bin/env python3
"""Generate a Leaflet cluster map of talk locations.
Geocodes locations from _presentations/*.md front matter and caches results
in talkmap/geocode_cache.json so repeated runs are fast.
"""
import json
import glob
import os
import time
import frontmatter
from geopy import Nominatim
from geopy.extra.rate_limiter import RateLimiter
from geopy.exc import GeocoderTimedOut
import getorg
class CachedLocation:
"""Lightweight stand-in for geopy Location with .latitude/.longitude."""
def __init__(self, latitude, longitude):
self.latitude = latitude
self.longitude = longitude
CACHE_FILE = "talkmap/geocode_cache.json"
TIMEOUT = 5
def load_cache():
if os.path.exists(CACHE_FILE):
with open(CACHE_FILE) as f:
return json.load(f)
return {}
def save_cache(cache):
os.makedirs(os.path.dirname(CACHE_FILE), exist_ok=True)
with open(CACHE_FILE, "w") as f:
json.dump(cache, f, indent=2)
def main():
geocoder = Nominatim(user_agent="academicpages.github.io")
geocode = RateLimiter(geocoder.geocode, min_delay_seconds=2, max_retries=3)
cache = load_cache()
location_dict = {}
for file in sorted(glob.glob("_presentations/*.md")):
data = frontmatter.load(file).to_dict()
if "location" not in data:
continue
title = data["title"].strip()
venue = data["venue"].strip()
location = data["location"].strip()
description = f"{title}<br />{venue}; {location}"
# Check cache first (keyed by location string)
if location in cache:
lat, lon = cache[location]
location_dict[description] = CachedLocation(lat, lon)
print(f" cached: {location} -> ({lat}, {lon})")
continue
# Geocode (rate limiter handles delay and retries)
try:
result = geocode(location, timeout=TIMEOUT)
if result:
cache[location] = (result.latitude, result.longitude)
location_dict[description] = result
print(f" geocoded: {location} -> ({result.latitude}, {result.longitude})")
else:
print(f" warning: no result for {location}")
except GeocoderTimedOut:
print(f" timeout: {location}")
except Exception as ex:
print(f" error: {location} — {ex}")
save_cache(cache)
# Generate the map
m = getorg.orgmap.create_map_obj()
getorg.orgmap.output_html_cluster_map(
location_dict, folder_name="talkmap", hashed_usernames=False
)
print(f"Done. {len(location_dict)} locations mapped.")
if __name__ == "__main__":
main()