All checks were successful
secrets-guard / encrypted (pull_request) Successful in 6s
PR build (required check) / changes (pull_request) Successful in 12s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Successful in 1m24s
PR build (required check) / build-backend (pull_request) Successful in 1m32s
PR build (required check) / gate (pull_request) Successful in 1s
Introduce backend/city_copy.json: original, researched per-city editorial copy (a lede, 2-4 body paragraphs, and a records-page intro), keyed by slug next to the existing Wikipedia cities_flavor.json. Covers 83 of the 90 cities that had no flavor blurb at all; each entry carries the independent sources it was written from and reviewed:false pending a human spot-check. Wire it end to end: - cities.copy(slug) loader, mirroring cities.flavor() (lazy, tolerant of a missing file so pages render fine until copy exists). - A `copy` field on the city and records content payloads. PAYLOAD_VER p2->p3 so cached content rows rebuild with the new field instead of serving the old shape. - city.html.j2 renders the editorial lede + body in place of the Wikipedia blurb, falling back to the flavor blurb (with its "via Wikipedia" credit) wherever copy isn't written yet. records.html.j2 gains a per-city intro line it never had before. Additive and backward-compatible: no API contract bump, and any slug without a copy entry keeps its existing behavior.
30 lines
1.7 KiB
Python
30 lines
1.7 KiB
Python
"""Canonical filesystem locations, resolved once from the repo root.
|
|
|
|
Every path the backend needs (the climate cache, the accounts DB, logs, the
|
|
bundled city data) is derived here from the repository root rather than from
|
|
each module's own ``__file__``. That keeps the locations stable no matter how
|
|
deep in the package tree a module lives, so moving a module never silently
|
|
re-points the cache or the accounts DB.
|
|
|
|
Callers that support an environment override (e.g. ``THERMOGRAPH_ACCOUNTS_DB``)
|
|
keep doing so; these are only the defaults.
|
|
"""
|
|
import os
|
|
|
|
REPO_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
# Runtime state dirs default under the repo root, but MUST be overridable: after
|
|
# the repo split the code lives at the image root (/app), so the Python package
|
|
# `data/` and the runtime data dir `<root>/data` collide at the same path. When
|
|
# a persistent volume is mounted at that path (as the deploy compose does for
|
|
# the parquet cache / notifier.lock / geonames) it shadows and erases the
|
|
# `data/*.py` modules, so `import data.climate` fails at boot. Point
|
|
# THERMOGRAPH_DATA_DIR (and _LOGS_DIR) at a path OUTSIDE the code tree in the
|
|
# container to keep the volume clear of the package.
|
|
DATA_DIR = os.environ.get("THERMOGRAPH_DATA_DIR") or os.path.join(REPO_DIR, "data")
|
|
LOGS_DIR = os.environ.get("THERMOGRAPH_LOGS_DIR") or os.path.join(REPO_DIR, "logs")
|
|
|
|
# Bundled reference data shipped alongside the code (generated by gen_cities /
|
|
# gen_flavor), not runtime state — hence at the repo root, not data/.
|
|
CITIES_JSON = os.path.join(REPO_DIR, "cities.json")
|
|
CITIES_FLAVOR_JSON = os.path.join(REPO_DIR, "cities_flavor.json")
|
|
CITY_COPY_JSON = os.path.join(REPO_DIR, "city_copy.json")
|