feat(gps-tracks): GPX download from public track popup
Реализация ET-011: кнопка «Скачать GPX» в popup публичного GPS-трека и
новый эндпоинт GET /api/gps-tracks/{track_id}/download (GPX 1.1 +
Content-Disposition с UTF-8 именем по RFC 5987). Реэкспорт защищён
per-source флагом `download_allowed` в `config/gps_sources.yaml`
(default-deny, MVP whitelist = `osm`).
Backend:
- `src/api/gps_tracks/export.py` — чистый stdlib-builder GPX 1.1
(`build_gpx`) + санитизация имени файла (`safe_filename`, RFC 5987).
- `src/api/gps_tracks/endpoint.py` — новый route с проверками
400 / 403 / 404 / 413; cap 200 000 точек (REQ-NF-02).
- `src/api/gps_tracks/config.py` — `load_download_allowed_sources()`
читает YAML, default-deny при отсутствии поля; fallback на `{"osm"}`
при отсутствии конфига.
- `src/api/main.py` — пробрасывает `GPS_SOURCES_CONFIG_PATH` в router.
Frontend:
- `src/web/gps_tracks.js` — кнопка в `_renderTrackPopupHtml`,
обработчик `_downloadPublicTrack` (fetch + Blob + a.download — тот же
паттерн, что в `app.js::downloadGPX`, R-1 митигирован), парсер
`_parseFilenameFromCD` для RFC 5987, маппинг ошибок
`_handleDownloadError` (403/404/413/5xx → showToast).
- `src/web/app.css` — стиль кнопки, 32×32 CSS px (REQ-NF-04).
Тесты:
- 13 unit для GPX-builder (UT-01/02/03/05; XSD-валидация против
`tests/fixtures/gpx-1.1/gpx.xsd`).
- 10 unit для `safe_filename` (UT-04).
- 11 integration для download-эндпоинта (IT-01..08 +
ANY-rule license check + default-deny без конфига).
ADR-014 (gpx-download-endpoint), ADR-015 (source-redistribution-policy).
Refs: ET-011
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,8 @@ sources:
|
||||
parser_module: "src.api.gps_tracks.sources.osm"
|
||||
save_user_field: true
|
||||
external_url_template: "https://www.openstreetmap.org/user/{user}/traces/{external_id_numeric}"
|
||||
# ET-011 / ADR-015: ODbL разрешает реэкспорт при атрибуции.
|
||||
download_allowed: true
|
||||
|
||||
- id: enduro_russia
|
||||
name: "EnduroRussia.ru"
|
||||
@@ -22,6 +24,8 @@ sources:
|
||||
parser_module: "src.api.gps_tracks.sources.enduro_russia"
|
||||
save_user_field: false
|
||||
source_priority: 80
|
||||
# ET-011 / ADR-015: ToS не содержит явного разрешения на ре-экспорт.
|
||||
download_allowed: false
|
||||
|
||||
- id: wikiloc
|
||||
name: "Wikiloc"
|
||||
@@ -36,6 +40,8 @@ sources:
|
||||
source_priority: 70
|
||||
activity_filter: [motorcycle, enduro]
|
||||
max_tracks_per_run: 50
|
||||
# ET-011 / ADR-015: proprietary, ToS запрещает массовый ре-экспорт.
|
||||
download_allowed: false
|
||||
|
||||
- id: ttrails
|
||||
name: "Тропинки.ру"
|
||||
@@ -47,3 +53,5 @@ sources:
|
||||
attribution: "ttrails.ru"
|
||||
parser_module: "src.api.gps_tracks.sources.ttrails"
|
||||
save_user_field: false
|
||||
# ET-011 / ADR-015: collection-ADR proposed (blocked), реэкспорт запрещён.
|
||||
download_allowed: false
|
||||
|
||||
Reference in New Issue
Block a user