Karten-Ausbau (OSM), Forum-Erweiterung, UI-Komponenten, Refactor Tagebuch/Gassi (DRY), Landing/SEO — APP_VER 1155
This commit is contained in:
parent
2d907f6370
commit
10e39ed135
18 changed files with 871 additions and 405 deletions
|
|
@ -586,6 +586,25 @@ async def toggle_like(data: LikeBody, user=Depends(get_current_user)):
|
|||
return {"liked": liked, "count": count}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# GET /api/forum/likes/{target_type}/{target_id} — Wer hat geliked?
|
||||
# ------------------------------------------------------------------
|
||||
@router.get("/likes/{target_type}/{target_id}")
|
||||
async def list_likers(target_type: str, target_id: int):
|
||||
if target_type not in _LIKE_TABLE:
|
||||
raise HTTPException(400, "Ungültiger Typ.")
|
||||
with db() as conn:
|
||||
rows = conn.execute(
|
||||
"""SELECT u.name AS name, u.founder_number AS founder_number
|
||||
FROM forum_likes fl
|
||||
JOIN users u ON u.id = fl.user_id
|
||||
WHERE fl.target_type = ? AND fl.target_id = ?
|
||||
ORDER BY fl.id DESC""",
|
||||
(target_type, target_id)
|
||||
).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# POST /api/forum/report
|
||||
# ------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -423,3 +423,65 @@ async def submit_poi_edit(osm_id: str, data: PoiEditCreate,
|
|||
poi[data.field], data.new_value.strip(), user["id"])
|
||||
)
|
||||
return {"status": "pending", "message": "Korrektur wurde zur Prüfung eingereicht."}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Geocoding-Proxy GET /api/osm/geocode?q=…
|
||||
# Nominatim-Rate-Limit: 1 req/s — serverseitig throttled
|
||||
# ------------------------------------------------------------------
|
||||
_nominatim_sem = asyncio.Semaphore(1)
|
||||
_nominatim_last = 0.0
|
||||
|
||||
@router.get('/geocode')
|
||||
async def geocode_search(q: str = Query(..., min_length=2, max_length=200)):
|
||||
import time
|
||||
global _nominatim_last
|
||||
async with _nominatim_sem:
|
||||
wait = 1.1 - (time.monotonic() - _nominatim_last)
|
||||
if wait > 0:
|
||||
await asyncio.sleep(wait)
|
||||
_nominatim_last = time.monotonic()
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=6.0) as client:
|
||||
resp = await client.get(
|
||||
'https://nominatim.openstreetmap.org/search',
|
||||
params={
|
||||
'q': q,
|
||||
'format': 'jsonv2',
|
||||
'limit': 6,
|
||||
'countrycodes': 'de,at,ch',
|
||||
'addressdetails': 1,
|
||||
'accept-language': 'de',
|
||||
},
|
||||
headers={
|
||||
'User-Agent': _OVERPASS_UA,
|
||||
'Referer': 'https://banyaro.app/',
|
||||
}
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
except Exception as e:
|
||||
logger.warning("Nominatim-Fehler: %s", e)
|
||||
raise HTTPException(502, "Geocoding nicht verfügbar")
|
||||
|
||||
out = []
|
||||
for r in data[:6]:
|
||||
addr = r.get('address', {})
|
||||
short = (
|
||||
addr.get('amenity') or addr.get('shop') or addr.get('leisure') or
|
||||
addr.get('road') or addr.get('village') or addr.get('town') or
|
||||
addr.get('city') or r.get('name') or
|
||||
r.get('display_name', '').split(',')[0]
|
||||
)
|
||||
city = addr.get('city') or addr.get('town') or addr.get('village') or addr.get('municipality') or ''
|
||||
state = addr.get('state', '')
|
||||
subtitle = ', '.join(filter(None, [city, state]))
|
||||
out.append({
|
||||
'lat': float(r['lat']),
|
||||
'lon': float(r['lon']),
|
||||
'name': short,
|
||||
'subtitle': subtitle,
|
||||
'full': r.get('display_name', ''),
|
||||
'type': r.get('type', ''),
|
||||
})
|
||||
return out
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue