Track what was actually built, and flag when it's stale
CI / check (push) Successful in 19s
CI / deploy (push) Successful in 16s

The .pmtiles files themselves carry no record of what upstream
snapshot they came from — only a local mtime. Each successful build
now writes a small sidecar (offline.pmtiles.meta.json: the Protomaps
build date used; terrain.pmtiles.meta.json: the Mapterhorn source
names/md5sums) recording that, surfaced in the panel next to the
existing size/updated line.

New GET .../check-update routes compare the recorded build against
the live upstream index/manifest — true/false/null, null meaning
"don't know" (no local build yet, or the check itself failed) rather
than a false "no". Kept separate from the plain status endpoints
(which map.js's own topbar dot hits on every page load) since this
one reaches an external service; only called once when the Offline
data panel is actually opened.

Also: flag emoji next to each country in the picker (derived from the
ISO code via Unicode regional indicators, no image assets needed).
This commit is contained in:
randy committed 2026-09-11 13:18:32 +02:00
1 parent 53c9a82af2
commit 4a3862189f
7 files changed
+261 -15

No files matched your search

+22 -4
View File
@@ -126,10 +126,11 @@ module Maptool
halt 401, json(error: "login required", login_url: "/login") unless logged_in?
end
def pmtiles_file_status(path)
def pmtiles_file_status(path, meta)
return { available: false } unless File.exist?(path)
{ available: true, size: File.size(path), mtime: File.mtime(path).utc.iso8601 }
status = { available: true, size: File.size(path), mtime: File.mtime(path).utc.iso8601 }
meta ? status.merge(meta: meta) : status
end
def callback_url
@@ -211,7 +212,7 @@ module Maptool
end
get "/api/offline-tiles" do
json pmtiles_file_status(OFFLINE_PMTILES_PATH)
json pmtiles_file_status(OFFLINE_PMTILES_PATH, PmtilesBuilder.offline_meta(DATA_DIR))
end
# Served as a plain range-request-capable file, not decoded server-side:
@@ -223,6 +224,18 @@ module Maptool
send_file OFFLINE_PMTILES_PATH, type: "application/octet-stream"
end
# Compares the recorded build (offline.pmtiles.meta.json) against the
# current latest Protomaps build without rebuilding anything —
# update_available is null (not true/false) if there's no local build
# yet, or the live index couldn't be reached, so the frontend can tell
# "don't know" apart from "no, up to date". Not folded into GET
# /api/offline-tiles above: that route is on the hot path (map.js's own
# topbar-dot check on every page load), this one only gets called when
# the Offline data panel is actually opened.
get "/api/offline-tiles/check-update" do
json update_available: PmtilesBuilder.offline_update_available?(DATA_DIR)
end
# Lists the selectable countries and which of them are currently
# selected (data/offline_regions.json) — read-only, no login needed,
# same tier as the plain availability checks above.
@@ -269,7 +282,7 @@ module Maptool
# docs/development.adoc for how to generate one, until then hillshade
# just stays unavailable while the offline basemap is active.
get "/api/terrain-tiles" do
json pmtiles_file_status(TERRAIN_PMTILES_PATH)
json pmtiles_file_status(TERRAIN_PMTILES_PATH, PmtilesBuilder.terrain_meta(DATA_DIR))
end
get "/tiles/terrain.pmtiles" do
@@ -278,6 +291,11 @@ module Maptool
send_file TERRAIN_PMTILES_PATH, type: "application/octet-stream"
end
# Same reasoning as GET /api/offline-tiles/check-update above.
get "/api/terrain-tiles/check-update" do
json update_available: PmtilesBuilder.terrain_update_available?(DATA_DIR)
end
post "/api/terrain-tiles/build" do
require_login!
begin