Feature: Ratings, Lightbox, Forum-Standort, Notifications, Routen-Recording, Chat-Picker
- Bewertungssystem (ratings.py): Sterne für Sitter/Walks/Places/Routen - Admin: Server-Log-Viewer + OSM-Cache-Statistiken - Chat: "Neue Nachricht"-Button mit Freundesliste-Picker - Forum: 5 neue Kategorien, Standorteingabe (locationPicker), Absende-Toast, Lightbox - Freunde: Aktivitäts-Filter (Chips), Freundschaftsanfrage → In-App-Notification - Sitter: locationPicker statt manuelle Koordinateneingabe + ratingStars - Tagebuch: Bilder-Lightbox im Detail-View, iOS-Modal-Header-Fix (90svh) - Routen: Start/Stopp-Button wechselt Zustand, nutzt Page_map.isRecording() - Benachrichtigungen: Delete-Button sichtbar, typ-basierte Navigation, Toast-Feedback - OSM: globales Semaphore + 429-Retry-Logic; Scheduler: München-Umland, täglich - SW by-v225, APP_VER 202
This commit is contained in:
parent
aa70a838f2
commit
e56183b642
21 changed files with 648 additions and 175 deletions
|
|
@ -20,6 +20,9 @@ CACHE_ZOOM = 12
|
|||
CACHE_DAYS = 14
|
||||
OVERPASS_URL = 'https://overpass-api.de/api/interpreter'
|
||||
|
||||
# Globales Limit: max 2 gleichzeitige Overpass-Anfragen (Prewarm + User geteilt)
|
||||
_overpass_sem = asyncio.Semaphore(2)
|
||||
|
||||
OSM_QUERIES = {
|
||||
'waste_basket': '[out:json][timeout:20];node["amenity"="waste_basket"]({bbox});out;',
|
||||
'dog_park': '[out:json][timeout:25];(way["leisure"="dog_park"]({bbox});node["leisure"="dog_park"]({bbox});way["leisure"="park"]["dog"="yes"]({bbox});node["leisure"="park"]["dog"="yes"]({bbox}););out center;',
|
||||
|
|
@ -61,10 +64,17 @@ def _covering_tiles(south, west, north, east, zoom):
|
|||
# Overpass-Fetch + Cache
|
||||
# ------------------------------------------------------------------
|
||||
async def _fetch_overpass(query):
|
||||
async with httpx.AsyncClient(timeout=40) as client:
|
||||
r = await client.post(OVERPASS_URL, data={'data': query})
|
||||
r.raise_for_status()
|
||||
return r.json().get('elements', [])
|
||||
for attempt in range(3):
|
||||
async with _overpass_sem:
|
||||
async with httpx.AsyncClient(timeout=40) as client:
|
||||
r = await client.post(OVERPASS_URL, data={'data': query})
|
||||
if r.status_code != 429:
|
||||
r.raise_for_status()
|
||||
return r.json().get('elements', [])
|
||||
logger.warning(f"Overpass 429 (Versuch {attempt + 1}/3)")
|
||||
# Semaphore freigeben, dann warten
|
||||
await asyncio.sleep(45 * (attempt + 1))
|
||||
raise Exception("Overpass 429 nach 3 Versuchen")
|
||||
|
||||
def _stale_tiles(poi_type, tiles):
|
||||
stale = []
|
||||
|
|
@ -143,11 +153,7 @@ async def get_pois(
|
|||
stale = _stale_tiles(type, tiles)
|
||||
|
||||
if stale and not fast:
|
||||
sem = asyncio.Semaphore(3)
|
||||
async def _limited(x, y):
|
||||
async with sem:
|
||||
await _fetch_and_store_tile(type, x, y)
|
||||
await asyncio.gather(*[_limited(x, y) for (x, y) in stale])
|
||||
await asyncio.gather(*[_fetch_and_store_tile(type, x, y) for (x, y) in stale])
|
||||
fetched_fresh = True
|
||||
|
||||
with db() as conn:
|
||||
|
|
@ -313,12 +319,8 @@ async def analyze_region(
|
|||
tiles = _covering_tiles(south, west, north, east, CACHE_ZOOM)
|
||||
|
||||
async def _warmup():
|
||||
sem = asyncio.Semaphore(3)
|
||||
async def _limited(poi_type, x, y):
|
||||
async with sem:
|
||||
await _fetch_and_store_tile(poi_type, x, y)
|
||||
tasks = [
|
||||
_limited(pt, x, y)
|
||||
_fetch_and_store_tile(pt, x, y)
|
||||
for pt in OSM_QUERIES
|
||||
for (x, y) in _stale_tiles(pt, tiles)
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue