osint-dashboard/app/camera_config.py

50 lines
2.4 KiB
Python
Raw Normal View History

"""Camera discovery configuration (12-factor, env-driven).
All knobs read from the environment with container-friendly defaults.
"""
from __future__ import annotations
import os
# ── Camera scraper ─────────────────────────────────────────────────────────
# Comma-separated public directory/list URLs to scrape. Two formats supported:
# * Insecam-style HTML directory pages (lat/lon embedded per camera)
# * Plain-text lists, one camera per line:
# <url>[|<lat>,<lon>|<vendor>|<location_name>]
# NOTE: docker-compose always defines CAMERA_SOURCE_URLS (empty when no .env),
# so os.getenv()'s default would never apply — use `or` semantics instead.
_DEFAULT_SOURCE_URL = (
# Publicly published open-camera list (markdown bullets of stream URLs).
"https://raw.githubusercontent.com/fury999io/public-ip-cams/main/README.md"
)
CAMERA_SOURCE_URLS = [
u.strip()
for u in (os.getenv("CAMERA_SOURCE_URLS") or _DEFAULT_SOURCE_URL).split(",")
if u.strip() # empty env var → fall back to the default above
]
# Seconds between full scrape cycles of every source.
CAMERA_SCRAPE_INTERVAL = int(os.getenv("CAMERA_SCRAPE_INTERVAL", "3600"))
# Politeness: minimum seconds between consecutive requests to the SAME host.
CAMERA_REQUEST_DELAY = float(os.getenv("CAMERA_REQUEST_DELAY", "2.0"))
# Max cameras accepted per scrape cycle per source (safety cap).
CAMERA_MAX_PER_SOURCE = int(os.getenv("CAMERA_MAX_PER_SOURCE", "5000"))
# ── Geocoding (Nominatim — free, 1 req/s hard politeness limit) ────────────
NOMINATIM_URL = os.getenv("NOMINATIM_URL", "https://nominatim.openstreetmap.org")
NOMINATIM_MIN_INTERVAL = float(os.getenv("NOMINATIM_MIN_INTERVAL", "1.0"))
USER_AGENT = os.getenv(
"OSINT_USER_AGENT", "osint-dashboard-camera-scraper/1.0 (self-hosted)"
)
# ── Snapshot cache ─────────────────────────────────────────────────────────
SNAPSHOT_CACHE_DIR = os.getenv("SNAPSHOT_CACHE_DIR", "/data/snapshots")
SNAPSHOT_TTL_SECONDS = int(os.getenv("SNAPSHOT_TTL_SECONDS", "300"))
SNAPSHOT_TIMEOUT = float(os.getenv("SNAPSHOT_TIMEOUT", "8.0"))
# NATS subject cameras are published on (consumed by the shared ingester).
CAMERA_NATS_SUBJECT = os.getenv("CAMERA_NATS_SUBJECT", "events.camera")