WIP: list credits for all serving providers; pin 511NY imagery to https
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
aa5b71d853
commit
af00139079
@@ -62,9 +62,13 @@ class Ny511Provider(CameraProvider):
|
||||
|
||||
async def fetch_catalog(self) -> List[Camera]:
|
||||
rows = await ny511._fetch("getcameras", ny511.normalize_camera)
|
||||
# Hosts for the 511x imagery are unverified, so pin the scheme at least:
|
||||
# only https URLs reach the browser.
|
||||
def https(u):
|
||||
return u if isinstance(u, str) and u.startswith("https://") else None
|
||||
out = [
|
||||
make_camera("ny511", r["id"], r["lat"], r["lon"], name=r["name"], roadway=r["roadway"],
|
||||
direction=r["direction"], image_url=r["image_url"], video_url=r["video_url"])
|
||||
direction=r["direction"], image_url=https(r["image_url"]), video_url=https(r["video_url"]))
|
||||
for r in rows
|
||||
]
|
||||
return require_parsed(len(rows), out, "511NY")
|
||||
|
||||
@@ -181,18 +181,20 @@ async def cameras_in_bbox(bbox: BBox) -> dict:
|
||||
"""Cameras from every SERVING provider whose coverage meets ``bbox``.
|
||||
Providers that are off are never fetched."""
|
||||
conf = await get_settings()
|
||||
live = [pid for pid, cat in CATALOGS.items()
|
||||
if effective(PROVIDERS[pid], conf.get(pid))[0] and bbox_intersects(PROVIDERS[pid].meta.coverage, bbox)]
|
||||
serving = [pid for pid in CATALOGS if effective(PROVIDERS[pid], conf.get(pid))[0]]
|
||||
live = [pid for pid in serving if bbox_intersects(PROVIDERS[pid].meta.coverage, bbox)]
|
||||
await asyncio.gather(*(CATALOGS[pid].get() for pid in live))
|
||||
cams: List[Camera] = []
|
||||
providers = []
|
||||
for pid in live:
|
||||
# Every SERVING provider is listed (credits included) even when the bbox
|
||||
# misses it, so a client holding one of its cameras from another view can
|
||||
# still render the required attribution. Only intersecting ones are fetched.
|
||||
for pid in serving:
|
||||
cat = CATALOGS[pid]
|
||||
hits = in_bbox(cat.items, bbox)
|
||||
hits = in_bbox(cat.items, bbox) if pid in live else []
|
||||
room = max(0, MAX_ITEMS - len(cams))
|
||||
cams.extend(hits[:room])
|
||||
providers.append({"id": pid, "name": PROVIDERS[pid].meta.name, **credit(pid),
|
||||
"fetched_at": cat.fetched_at, "error": cat.error,
|
||||
"total_in_bbox": len(hits), "truncated": len(hits) > room})
|
||||
return {"cameras": cams, "providers": providers,
|
||||
"serving_count": sum(1 for pid in CATALOGS if effective(PROVIDERS[pid], conf.get(pid))[0])}
|
||||
return {"cameras": cams, "providers": providers, "serving_count": len(serving)}
|
||||
|
||||
@@ -148,8 +148,12 @@ def test_query_returns_attribution_and_skips_providers_outside_bbox(store):
|
||||
patch.object(registry.PROVIDERS["tfl"], "fetch_catalog", tfl_fetch):
|
||||
out = run(registry.cameras_in_bbox((-34.0, 151.0, -33.7, 151.4)))
|
||||
assert [c["id"] for c in out["cameras"]] == ["nsw:x"]
|
||||
assert out["providers"][0]["attribution"] == "Transport for NSW, CC BY 4.0"
|
||||
by_id = {p["id"]: p for p in out["providers"]}
|
||||
assert by_id["nsw"]["attribution"] == "Transport for NSW, CC BY 4.0"
|
||||
assert tfl_fetch.await_count == 0 # London never fetched for a Sydney bbox
|
||||
# ...but its credit is still listed, for cameras the client holds from another view
|
||||
assert by_id["tfl"]["attribution"] == "Powered by TfL Open Data" and by_id["tfl"]["total_in_bbox"] == 0
|
||||
assert out["serving_count"] == 2
|
||||
|
||||
|
||||
# ── admin routes ─────────────────────────────────────────────────────────────
|
||||
@@ -263,10 +267,11 @@ def test_ontario_needs_its_key(monkeypatch):
|
||||
|
||||
def test_ny511_provider_wraps_legacy_client_and_carries_daa_metadata():
|
||||
row = {"id": "NYSDOT-1", "lat": 41.03, "lon": -73.76, "name": "I-287", "roadway": "I-287",
|
||||
"direction": "Northbound", "image_url": "https://x/1", "video_url": None}
|
||||
"direction": "Northbound", "image_url": "https://x/1", "video_url": "javascript:alert(1)"}
|
||||
with patch.object(regional.ny511, "_fetch", AsyncMock(return_value=[row])):
|
||||
cams = run(regional.Ny511Provider().fetch_catalog())
|
||||
assert cams[0]["id"] == "ny511:NYSDOT-1" and cams[0]["heading_deg"] == 0
|
||||
assert cams[0]["video_url"] is None # non-https never reaches the browser
|
||||
lic = regional.Ny511Provider.meta.licence
|
||||
assert lic.attribution == "powered by 511NY" and lic.attribution_url == "https://511ny.org"
|
||||
assert "with all faults" in lic.disclaimer and lic.gated
|
||||
|
||||
Reference in New Issue
Block a user