diff --git a/CHANGELOG.md b/CHANGELOG.md index 98ee67fdd..a5b1cd7cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,11 @@ - Credit adsbdb, which supplies the aircraft type, model name and registration on enriched flights and the airline and origin/destination pair behind the - tracked contact's route strip. `DATA_SOURCES.md` now records the terms adsbdb - publishes — aircraft data from PlaneBase, and route data that is the work of - David Taylor, Edinburgh, and Jim Mason, Glasgow, and may not be copied into - another database without his permission — along with the request bounds and - the gitignored 24-hour cache that keep the app inside them. A matching - `DATA_CREDITS` entry surfaces the credit in the in-app Data attribution - popover, and a test pins the wording the route data requires. + tracked contact's route strip. `DATA_SOURCES.md` now records adsbdb's + published credits and route-data restriction, along with the request bounds + and gitignored 24-hour local cache. A matching `DATA_CREDITS` entry surfaces + the credit in the in-app Data attribution popover, and a test protects it + against accidental removal. - Size the TomTom daily tile budget to the provider's real free allowance. `TOMTOM_DAILY_TILE_BUDGET` defaulted to 40,000/day against an allowance diff --git a/DATA_SOURCES.md b/DATA_SOURCES.md index d2472869d..7c822558a 100644 --- a/DATA_SOURCES.md +++ b/DATA_SOURCES.md @@ -63,7 +63,7 @@ How to read this: - **Google Maps Platform.** You supply your own API key and are bound by [Google's ToS](https://cloud.google.com/maps-platform/terms). Google Maps Content (tiles, geocodes, places) **may not be cached, stored, rehosted, or committed** — this app only ever uses it live, which is the compliant pattern. The "Google" attribution is displayed on the globe and must stay visible. Restrict your key (see [SECURITY.md](SECURITY.md)). - **OpenSky Network.** Its license is **non-commercial**, and operational use of the REST API in a live product can require a prior written agreement with OpenSky — even for non-profit/government use. If you deploy this commercially, contact OpenSky for your own terms. The flights layer is a toggle and runs anonymously by default. - **adsb.lol flight fallback.** When OpenSky is unavailable and no last-good OpenSky response exists, the server requests a cached, capped 250 nm adsb.lol point snapshot around the current camera subpoint. This is regional observed context, not worldwide completeness; provenance is exposed in the Flights stats/context row. Military ICAOs remain reconciled through the existing dedicated military registry rather than duplicated. -- **adsbdb enrichment.** `/api/adsbdb` resolves an ICAO hex to aircraft type, model name and registration, and the tracked flight's callsign to an airline and an origin/destination pair. Fan-out is deliberately small because adsbdb is a free community API that publishes no quota: at most 4 requests in flight, dispatches dripped to roughly 5/s, and each key asked for at most once per session, with route lookups reserved for the tracked aircraft. The dev-server proxy caches each key for 24 hours in `.gev-cache/adsbdb.json`, negative answers included, so a repeat session does not ask again. That cache is gitignored and stays on the operator's machine, which is what the route data's terms require: it may not be copied into another database without David J Taylor's permission, so it is never bundled with this repo or redistributed. Enrichment is best-effort and fail-silent — a flight that gets no answer keeps what the flight feed already gave it. +- **adsbdb enrichment.** `/api/adsbdb` resolves an ICAO hex to aircraft type, model name and registration, and the tracked flight's callsign to an airline and an origin/destination pair. Fan-out is deliberately small because adsbdb is a free community API that publishes no quota: at most 4 requests in flight, dispatches dripped to roughly 5/s, and each key asked for at most once per session, with route lookups reserved for the tracked aircraft. The dev-server proxy caches each key for 24 hours in `.gev-cache/adsbdb.json`, negative answers included, so fresh entries survive server restarts. That gitignored cache remains local to the deployment and is not bundled with this repo. adsbdb publishes no general service license; its README says the route data may not be copied, published, or incorporated into other databases without the explicit permission of David J Taylor, Edinburgh. Deployers are responsible for obtaining any permission their use requires. Enrichment is best-effort and fail-silent — a flight that gets no answer keeps what the flight feed already gave it. - **Launch Library 2.** `/api/launches` makes a server-side rolling-30-day query against the supported v2.3 detailed launch endpoint, caches successful responses for 15 minutes in memory and on disk, and serves the last successful response during a throttle or transient outage. Anonymous access is limited to 15 calls/hour; deployments can provide `LL2_API_TOKEN` for authenticated access. The Space Devs' published terms permit using and sharing the API data in any form, ask users not to forward it without adding value, disclaim complete accuracy, and encourage—but do not require—attribution. This app keeps a courtesy credit. Payload and stage/recovery records are shown only when supplied. Failed launches expose their source status and never receive fallback orbit geometry or a live/estimated marker. LL2 supplies launch context and event timing, not continuous ascent telemetry or live orbital state. - **TfL JamCams.** The camera list comes from the keyless `api.tfl.gov.uk` endpoint (an optional `TFL_APP_KEY` raises its rate limit); frames come from TfL's public S3 bucket. The "Powered by TfL Open Data" attribution is required by TfL's terms and is registered in the Data attribution popover. - **Ontario 511 CCTV.** The camera list comes from the keyless `511on.ca/api/v2/get/cameras` endpoint; frames are server-registered still images under `511on.ca/map/Cctv/`. The source is live-fetched at runtime and attributed under the Open Government Licence - Ontario. diff --git a/src/data/dataCredits.js b/src/data/dataCredits.js index 196256930..dde7d3b62 100644 --- a/src/data/dataCredits.js +++ b/src/data/dataCredits.js @@ -47,7 +47,8 @@ export const DATA_CREDITS = [ html: 'Aircraft type, registration & flight routes: ' + 'adsbdb ' + - '· aircraft data from PlaneBase · route data is the work of ' + + '· aircraft data from PlaneBase · ICAO-to-N-number conversion by ' + + 'Guillaume Michel · route data is the work of ' + 'David Taylor, Edinburgh, and Jim Mason, Glasgow, and may not be ' + 'copied, published, or incorporated into other databases without the ' + 'explicit permission of David J Taylor, Edinburgh', diff --git a/src/data/dataCredits.test.mjs b/src/data/dataCredits.test.mjs index 89d7fed87..5172867c4 100644 --- a/src/data/dataCredits.test.mjs +++ b/src/data/dataCredits.test.mjs @@ -18,17 +18,14 @@ test('every credit carries a unique key and some markup to render', () => { } }); -test('adsbdb is credited, and keeps the wording its route data requires', () => { +test('adsbdb is credited and carries its published route-data restriction', () => { const credit = DATA_CREDITS.find((entry) => entry.key === 'adsbdb'); assert.ok( credit, 'adsbdb supplies aircraft type and routes and must be credited', ); - // Not a stylistic preference: adsbdb states that the route data "may not be - // copied, published, or incorporated into other databases without the - // explicit permission of David J Taylor, Edinburgh". The names and that - // restriction are the attribution, so they are pinned here rather than left - // to survive the next edit by luck. + // adsbdb publishes this restriction for its route data. Pin the provider's + // credits and restriction here so a later edit cannot silently remove them. assert.match(credit.html, /David Taylor, Edinburgh/); assert.match(credit.html, /Jim Mason, Glasgow/); assert.match( @@ -37,5 +34,6 @@ test('adsbdb is credited, and keeps the wording its route data requires', () => ); assert.match(credit.html, /explicit permission of David J Taylor, Edinburgh/); assert.match(credit.html, /PlaneBase/); + assert.match(credit.html, /Guillaume Michel/); assert.match(credit.html, /href="https:\/\/www\.adsbdb\.com"/); });