geo-activity-playground 0.41.0__tar.gz → 0.42.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/PKG-INFO +2 -1
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/activities.py +4 -14
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/datamodel.py +44 -64
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/enrichment.py +11 -4
- geo_activity_playground-0.42.0/geo_activity_playground/core/missing_values.py +13 -0
- geo_activity_playground-0.42.0/geo_activity_playground/core/test_missing_values.py +19 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/tile_visits.py +1 -1
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/app.py +1 -1
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/activity_blueprint.py +18 -10
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/settings_blueprint.py +32 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/edit.html.j2 +15 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/show.html.j2 +14 -3
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/index.html.j2 +9 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-edit.html.j2 +17 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-list.html.j2 +19 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-new.html.j2 +17 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/pyproject.toml +6 -1
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/LICENSE +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/__main__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/README +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/env.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/script.py.mako +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/38882503dc7c_add_tags_to_activities.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/451e7836b53d_add_square_planner_bookmark.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/63d3b7f6f93c_initial_version.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/93cc82ad1b60_add_parametricplotspec.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/ab83b9d23127_add_upstream_id.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/b03491c593f6_add_crop_indices.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/e02e27876deb_add_square_planner_bookmark_name.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/script.py.mako +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/config.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/coordinates.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/heart_rate.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/meta_search.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/parametric_plot.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/paths.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/privacy_zones.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/raster_map.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/similarity.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/summary_stats.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/tasks.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_datamodel.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_meta_search.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_summary_stats.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_tiles.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_time_conversion.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/tiles.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/core/time_conversion.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/grid_file.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/video.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/heatmap_video.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/activity_parsers.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/csv_parser.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/directory.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/strava_api.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/strava_checkout.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_csv_parser.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_directory.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_strava_api.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/authenticator.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/__init__.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/auth_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/calendar_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/eddington_blueprints.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/entry_views.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/equipment_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/explorer_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/heatmap_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/plot_builder_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/search_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/square_planner_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/summary_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/tile_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/upload_blueprint.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/columns.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/flasher.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/plot_util.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/search_util.py +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/Leaflet.fullscreen.min.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/MarkerCluster.Default.css +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/MarkerCluster.css +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/android-chrome-192x192.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/android-chrome-512x512.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/apple-touch-icon.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap-dark-mode.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap.bundle.min.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap.min.css +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/browserconfig.xml +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-16x16.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-32x32.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-48x48.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon.ico +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon.svg +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/fullscreen.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/fullscreen@2x.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/layers-2x.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/layers.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-icon-2x.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-icon.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-shadow.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.css +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.fullscreen.css +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.markercluster.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/mstile-150x150.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/site.webmanifest +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/table-sort.min.js +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega-embed@6 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega-lite@4 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega@5 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/web-app-manifest-192x192.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/web-app-manifest-512x512.png +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/day.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/lines.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/name.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/trim.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/auth/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/calendar/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/calendar/month.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/eddington/distance.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/elevation_eddington/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/equipment/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/explorer/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/explorer/server-side.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/heatmap/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/home.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/page.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/plot_builder/edit.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/plot_builder/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/search/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/search_form.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/admin-password.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/color-schemes.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/heart-rate.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/manage-equipments.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/manage-kinds.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/metadata-extraction.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/privacy-zones.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/segmentation.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/sharepic.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/strava.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/square_planner/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/summary/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/upload/index.html.j2 +0 -0
- {geo_activity_playground-0.41.0 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/upload/reload.html.j2 +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: geo-activity-playground
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.42.0
|
4
4
|
Summary: Analysis of geo data activities like rides, runs or hikes.
|
5
5
|
License: MIT
|
6
6
|
Author: Martin Ueding
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
14
15
|
Requires-Dist: Pillow (>=11.0.0,<12.0.0)
|
15
16
|
Requires-Dist: alembic (>=1.15.2,<2.0.0)
|
16
17
|
Requires-Dist: altair (>=5.5.0,<6.0.0)
|
@@ -2,6 +2,7 @@ import datetime
|
|
2
2
|
import functools
|
3
3
|
import logging
|
4
4
|
from collections.abc import Callable
|
5
|
+
from collections.abc import Sequence
|
5
6
|
from typing import Any
|
6
7
|
from typing import Optional
|
7
8
|
|
@@ -21,17 +22,6 @@ from geo_activity_playground.core.datamodel import query_activity_meta
|
|
21
22
|
logger = logging.getLogger(__name__)
|
22
23
|
|
23
24
|
|
24
|
-
def make_activity_meta() -> ActivityMeta:
|
25
|
-
return ActivityMeta(
|
26
|
-
calories=None,
|
27
|
-
commute=False,
|
28
|
-
consider_for_achievements=True,
|
29
|
-
equipment="Unknown",
|
30
|
-
kind="Unknown",
|
31
|
-
steps=None,
|
32
|
-
)
|
33
|
-
|
34
|
-
|
35
25
|
class ActivityRepository:
|
36
26
|
def __len__(self) -> int:
|
37
27
|
return len(self.get_activity_ids())
|
@@ -52,14 +42,14 @@ class ActivityRepository:
|
|
52
42
|
else:
|
53
43
|
return None
|
54
44
|
|
55
|
-
def get_activity_ids(self, only_achievements: bool = False) ->
|
45
|
+
def get_activity_ids(self, only_achievements: bool = False) -> Sequence[int]:
|
56
46
|
query = sqlalchemy.select(Activity.id)
|
57
47
|
if only_achievements:
|
58
48
|
query = query.where(Kind.consider_for_achievements)
|
59
|
-
result = DB.session.scalars(query).all()
|
49
|
+
result = DB.session.scalars(query.order_by(Activity.start)).all()
|
60
50
|
return result
|
61
51
|
|
62
|
-
def iter_activities(self, new_to_old=True, drop_na=False) ->
|
52
|
+
def iter_activities(self, new_to_old=True, drop_na=False) -> Sequence[Activity]:
|
63
53
|
query = sqlalchemy.select(Activity)
|
64
54
|
if drop_na:
|
65
55
|
query = query.where(Activity.start.is_not(None))
|
@@ -117,9 +117,6 @@ class Activity(DB.Model):
|
|
117
117
|
secondary=activity_tag_association_table, back_populates="activities"
|
118
118
|
)
|
119
119
|
|
120
|
-
def __getitem__(self, item) -> Any:
|
121
|
-
return self.to_dict()[item]
|
122
|
-
|
123
120
|
def __str__(self) -> str:
|
124
121
|
return f"{self.start} {self.name}"
|
125
122
|
|
@@ -127,11 +124,15 @@ class Activity(DB.Model):
|
|
127
124
|
def average_speed_moving_kmh(self) -> Optional[float]:
|
128
125
|
if self.moving_time:
|
129
126
|
return self.distance_km / (self.moving_time.total_seconds() / 3_600)
|
127
|
+
else:
|
128
|
+
return None
|
130
129
|
|
131
130
|
@property
|
132
131
|
def average_speed_elapsed_kmh(self) -> Optional[float]:
|
133
132
|
if self.elapsed_time:
|
134
133
|
return self.distance_km / (self.elapsed_time.total_seconds() / 3_600)
|
134
|
+
else:
|
135
|
+
return None
|
135
136
|
|
136
137
|
@property
|
137
138
|
def raw_time_series(self) -> pd.DataFrame:
|
@@ -154,38 +155,6 @@ class Activity(DB.Model):
|
|
154
155
|
else:
|
155
156
|
return self.raw_time_series
|
156
157
|
|
157
|
-
def to_dict(self) -> ActivityMeta:
|
158
|
-
equipment = self.equipment.name if self.equipment is not None else "Unknown"
|
159
|
-
kind = self.kind.name if self.kind is not None else "Unknown"
|
160
|
-
consider_for_achievements = (
|
161
|
-
self.kind.consider_for_achievements if self.kind is not None else True
|
162
|
-
)
|
163
|
-
return ActivityMeta(
|
164
|
-
id=self.id,
|
165
|
-
name=self.name,
|
166
|
-
path=self.path,
|
167
|
-
distance_km=self.distance_km,
|
168
|
-
start=self.start,
|
169
|
-
elapsed_time=self.elapsed_time,
|
170
|
-
moving_time=self.moving_time,
|
171
|
-
start_latitude=self.start_latitude,
|
172
|
-
start_longitude=self.start_longitude,
|
173
|
-
end_latitude=self.end_latitude,
|
174
|
-
end_longitude=self.end_longitude,
|
175
|
-
elevation_gain=self.elevation_gain,
|
176
|
-
start_elevation=self.start_elevation,
|
177
|
-
end_elevation=self.end_elevation,
|
178
|
-
calories=self.calories,
|
179
|
-
steps=self.steps,
|
180
|
-
num_new_tiles_14=self.num_new_tiles_14,
|
181
|
-
num_new_tiles_17=self.num_new_tiles_17,
|
182
|
-
equipment=equipment,
|
183
|
-
kind=kind,
|
184
|
-
average_speed_moving_kmh=self.average_speed_moving_kmh,
|
185
|
-
average_speed_elapsed_kmh=self.average_speed_elapsed_kmh,
|
186
|
-
consider_for_achievements=consider_for_achievements,
|
187
|
-
)
|
188
|
-
|
189
158
|
|
190
159
|
class Tag(DB.Model):
|
191
160
|
__tablename__ = "tags"
|
@@ -199,6 +168,17 @@ class Tag(DB.Model):
|
|
199
168
|
)
|
200
169
|
|
201
170
|
|
171
|
+
def get_or_make_tag(tag: str) -> Tag:
|
172
|
+
tags = DB.session.scalars(sqlalchemy.select(Tag).where(Tag.tag == tag)).all()
|
173
|
+
if tags:
|
174
|
+
assert len(tags) == 1, f"There must be only one tag with name '{tag}'."
|
175
|
+
return tags[0]
|
176
|
+
else:
|
177
|
+
tag = Tag(tag=tag)
|
178
|
+
DB.session.add(tag)
|
179
|
+
return tag
|
180
|
+
|
181
|
+
|
202
182
|
def query_activity_meta() -> pd.DataFrame:
|
203
183
|
rows = DB.session.execute(
|
204
184
|
sqlalchemy.select(
|
@@ -276,6 +256,23 @@ class Equipment(DB.Model):
|
|
276
256
|
__table_args__ = (sa.UniqueConstraint("name", name="equipments_name"),)
|
277
257
|
|
278
258
|
|
259
|
+
def get_or_make_equipment(name: str, config: Config) -> Equipment:
|
260
|
+
equipments = DB.session.scalars(
|
261
|
+
sqlalchemy.select(Equipment).where(Equipment.name == name)
|
262
|
+
).all()
|
263
|
+
if equipments:
|
264
|
+
assert (
|
265
|
+
len(equipments) == 1
|
266
|
+
), f"There must be only one equipment with name '{name}'."
|
267
|
+
return equipments[0]
|
268
|
+
else:
|
269
|
+
equipment = Equipment(
|
270
|
+
name=name, offset_km=config.equipment_offsets.get(name, 0)
|
271
|
+
)
|
272
|
+
DB.session.add(equipment)
|
273
|
+
return equipment
|
274
|
+
|
275
|
+
|
279
276
|
class Kind(DB.Model):
|
280
277
|
__tablename__ = "kinds"
|
281
278
|
|
@@ -299,20 +296,6 @@ class Kind(DB.Model):
|
|
299
296
|
__table_args__ = (sa.UniqueConstraint("name", name="kinds_name"),)
|
300
297
|
|
301
298
|
|
302
|
-
class SquarePlannerBookmark(DB.Model):
|
303
|
-
__tablename__ = "square_planner_bookmarks"
|
304
|
-
|
305
|
-
id: Mapped[int] = mapped_column(primary_key=True)
|
306
|
-
|
307
|
-
zoom: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
308
|
-
x: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
309
|
-
y: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
310
|
-
size: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
311
|
-
name: Mapped[str] = mapped_column(sa.String, nullable=False)
|
312
|
-
|
313
|
-
__table_args__ = (sa.UniqueConstraint("zoom", "x", "y", "size", name="kinds_name"),)
|
314
|
-
|
315
|
-
|
316
299
|
def get_or_make_kind(name: str, config: Config) -> Kind:
|
317
300
|
kinds = DB.session.scalars(sqlalchemy.select(Kind).where(Kind.name == name)).all()
|
318
301
|
if kinds:
|
@@ -327,21 +310,18 @@ def get_or_make_kind(name: str, config: Config) -> Kind:
|
|
327
310
|
return kind
|
328
311
|
|
329
312
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
)
|
343
|
-
DB.session.add(equipment)
|
344
|
-
return equipment
|
313
|
+
class SquarePlannerBookmark(DB.Model):
|
314
|
+
__tablename__ = "square_planner_bookmarks"
|
315
|
+
|
316
|
+
id: Mapped[int] = mapped_column(primary_key=True)
|
317
|
+
|
318
|
+
zoom: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
319
|
+
x: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
320
|
+
y: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
321
|
+
size: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
322
|
+
name: Mapped[str] = mapped_column(sa.String, nullable=False)
|
323
|
+
|
324
|
+
__table_args__ = (sa.UniqueConstraint("zoom", "x", "y", "size", name="kinds_name"),)
|
345
325
|
|
346
326
|
|
347
327
|
class PlotSpec(DB.Model):
|
@@ -15,6 +15,7 @@ from .datamodel import ActivityMeta
|
|
15
15
|
from .datamodel import DB
|
16
16
|
from .datamodel import get_or_make_equipment
|
17
17
|
from .datamodel import get_or_make_kind
|
18
|
+
from .missing_values import some
|
18
19
|
from .paths import activity_extracted_meta_dir
|
19
20
|
from .paths import activity_extracted_time_series_dir
|
20
21
|
from .paths import time_series_dir
|
@@ -82,9 +83,9 @@ def populate_database_from_extracted(config: Config) -> None:
|
|
82
83
|
distance_km=0,
|
83
84
|
equipment=equipment,
|
84
85
|
kind=kind,
|
85
|
-
calories=extracted_metadata.get("calories", None),
|
86
|
-
elevation_gain=extracted_metadata.get("elevation_gain", None),
|
87
|
-
steps=extracted_metadata.get("steps", None),
|
86
|
+
calories=some(extracted_metadata.get("calories", None)),
|
87
|
+
elevation_gain=some(extracted_metadata.get("elevation_gain", None)),
|
88
|
+
steps=some(extracted_metadata.get("steps", None)),
|
88
89
|
path=extracted_metadata.get("path", None),
|
89
90
|
upstream_id=upstream_id,
|
90
91
|
)
|
@@ -92,7 +93,13 @@ def populate_database_from_extracted(config: Config) -> None:
|
|
92
93
|
update_via_time_series(activity, time_series)
|
93
94
|
|
94
95
|
DB.session.add(activity)
|
95
|
-
|
96
|
+
try:
|
97
|
+
DB.session.commit()
|
98
|
+
except sqlalchemy.exc.StatementError:
|
99
|
+
logger.error(
|
100
|
+
f"Could not insert the following activity into the database: {vars(activity)=}"
|
101
|
+
)
|
102
|
+
raise
|
96
103
|
|
97
104
|
enriched_time_series_path = time_series_dir() / f"{activity.id}.parquet"
|
98
105
|
time_series.to_parquet(enriched_time_series_path)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import numpy as np
|
2
|
+
|
3
|
+
from .missing_values import some
|
4
|
+
|
5
|
+
|
6
|
+
def test_none() -> None:
|
7
|
+
assert some(None) == None
|
8
|
+
|
9
|
+
|
10
|
+
def test_nan() -> None:
|
11
|
+
assert some(np.nan) == None
|
12
|
+
|
13
|
+
|
14
|
+
def test_float() -> None:
|
15
|
+
assert some(1.0) == 1.0
|
16
|
+
|
17
|
+
|
18
|
+
def test_integer() -> None:
|
19
|
+
assert some(1) == 1
|
@@ -176,7 +176,7 @@ def _process_activity(
|
|
176
176
|
activity_tiles["time"],
|
177
177
|
zip(activity_tiles["tile_x"], activity_tiles["tile_y"]),
|
178
178
|
):
|
179
|
-
if activity
|
179
|
+
if activity.kind.consider_for_achievements:
|
180
180
|
if tile not in tile_state["tile_visits"][zoom]:
|
181
181
|
new_tile_history_soa["activity_id"].append(activity_id)
|
182
182
|
new_tile_history_soa["time"].append(time)
|
@@ -70,7 +70,7 @@ def web_ui_main(
|
|
70
70
|
|
71
71
|
app = Flask(__name__)
|
72
72
|
|
73
|
-
database_path =
|
73
|
+
database_path = pathlib.Path("database.sqlite")
|
74
74
|
logger.info(f"Using database file at '{database_path.absolute()}'.")
|
75
75
|
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{database_path.absolute()}"
|
76
76
|
app.config["ALEMBIC"] = {"script_location": "../alembic/versions"}
|
@@ -29,6 +29,7 @@ from ...core.datamodel import Activity
|
|
29
29
|
from ...core.datamodel import DB
|
30
30
|
from ...core.datamodel import Equipment
|
31
31
|
from ...core.datamodel import Kind
|
32
|
+
from ...core.datamodel import Tag
|
32
33
|
from ...core.enrichment import update_via_time_series
|
33
34
|
from ...core.heart_rate import HeartRateZoneComputer
|
34
35
|
from ...core.privacy_zones import PrivacyZone
|
@@ -71,14 +72,14 @@ def make_activity_blueprint(
|
|
71
72
|
)
|
72
73
|
]
|
73
74
|
for _, group in repository.get_time_series(
|
74
|
-
activity
|
75
|
+
activity.id
|
75
76
|
).groupby("segment_id")
|
76
77
|
]
|
77
78
|
),
|
78
79
|
properties={
|
79
80
|
"color": matplotlib.colors.to_hex(cmap(i % 8)),
|
80
|
-
"activity_name": activity
|
81
|
-
"activity_id": str(activity
|
81
|
+
"activity_name": activity.name,
|
82
|
+
"activity_id": str(activity.id),
|
82
83
|
},
|
83
84
|
)
|
84
85
|
for i, activity in enumerate(repository.iter_activities())
|
@@ -99,7 +100,7 @@ def make_activity_blueprint(
|
|
99
100
|
|
100
101
|
meta = repository.meta
|
101
102
|
similar_activities = meta.loc[
|
102
|
-
(meta.name == activity
|
103
|
+
(meta.name == activity.name) & (meta.id != activity.id)
|
103
104
|
]
|
104
105
|
similar_activities = [row for _, row in similar_activities.iterrows()]
|
105
106
|
similar_activities.reverse()
|
@@ -107,7 +108,7 @@ def make_activity_blueprint(
|
|
107
108
|
new_tiles = {
|
108
109
|
zoom: sum(
|
109
110
|
tile_visit_accessor.tile_state["tile_history"][zoom]["activity_id"]
|
110
|
-
== activity
|
111
|
+
== activity.id
|
111
112
|
)
|
112
113
|
for zoom in sorted(config.explorer_zoom_levels)
|
113
114
|
}
|
@@ -117,7 +118,7 @@ def make_activity_blueprint(
|
|
117
118
|
for zoom in sorted(config.explorer_zoom_levels):
|
118
119
|
new_tiles = tile_visit_accessor.tile_state["tile_history"][zoom].loc[
|
119
120
|
tile_visit_accessor.tile_state["tile_history"][zoom]["activity_id"]
|
120
|
-
== activity
|
121
|
+
== activity.id
|
121
122
|
]
|
122
123
|
if len(new_tiles):
|
123
124
|
points = make_grid_points(
|
@@ -152,8 +153,8 @@ def make_activity_blueprint(
|
|
152
153
|
time_series[line_color_column],
|
153
154
|
line_color_columns_avail[line_color_column].format,
|
154
155
|
),
|
155
|
-
"date": activity
|
156
|
-
"time": activity
|
156
|
+
"date": activity.start.date(),
|
157
|
+
"time": activity.start.time(),
|
157
158
|
"new_tiles": new_tiles_per_zoom,
|
158
159
|
"new_tiles_geojson": new_tiles_geojson,
|
159
160
|
"line_color_column": line_color_column,
|
@@ -318,6 +319,7 @@ def make_activity_blueprint(
|
|
318
319
|
abort(404)
|
319
320
|
equipments = DB.session.scalars(sqlalchemy.select(Equipment)).all()
|
320
321
|
kinds = DB.session.scalars(sqlalchemy.select(Kind)).all()
|
322
|
+
tags = DB.session.scalars(sqlalchemy.select(Tag)).all()
|
321
323
|
|
322
324
|
if request.method == "POST":
|
323
325
|
activity.name = request.form.get("name")
|
@@ -326,13 +328,18 @@ def make_activity_blueprint(
|
|
326
328
|
if form_equipment == "null":
|
327
329
|
activity.equipment = None
|
328
330
|
else:
|
329
|
-
activity.equipment = DB.session.
|
331
|
+
activity.equipment = DB.session.get_one(Equipment, int(form_equipment))
|
330
332
|
|
331
333
|
form_kind = request.form.get("kind")
|
332
334
|
if form_kind == "null":
|
333
335
|
activity.kind = None
|
334
336
|
else:
|
335
|
-
activity.kind = DB.session.
|
337
|
+
activity.kind = DB.session.get_one(Kind, int(form_kind))
|
338
|
+
|
339
|
+
form_tags = request.form.getlist("tag")
|
340
|
+
activity.tags = [
|
341
|
+
DB.session.get_one(Tag, int(tag_id_str)) for tag_id_str in form_tags
|
342
|
+
]
|
336
343
|
|
337
344
|
DB.session.commit()
|
338
345
|
return redirect(url_for(".show", id=activity.id))
|
@@ -342,6 +349,7 @@ def make_activity_blueprint(
|
|
342
349
|
activity=activity,
|
343
350
|
kinds=kinds,
|
344
351
|
equipments=equipments,
|
352
|
+
tags=tags,
|
345
353
|
)
|
346
354
|
|
347
355
|
@blueprint.route("/trim/<id>", methods=["GET", "POST"])
|
@@ -18,6 +18,7 @@ from ...core.config import ConfigAccessor
|
|
18
18
|
from ...core.datamodel import DB
|
19
19
|
from ...core.datamodel import Equipment
|
20
20
|
from ...core.datamodel import Kind
|
21
|
+
from ...core.datamodel import Tag
|
21
22
|
from ...core.heart_rate import HeartRateZoneComputer
|
22
23
|
from ...core.paths import _activity_enriched_dir
|
23
24
|
from ..authenticator import Authenticator
|
@@ -395,6 +396,37 @@ def make_settings_blueprint(
|
|
395
396
|
strava_login_helper.save_strava_code(code)
|
396
397
|
return redirect(url_for(".strava"))
|
397
398
|
|
399
|
+
@blueprint.route("/tags")
|
400
|
+
@needs_authentication(authenticator)
|
401
|
+
def tags_list():
|
402
|
+
return render_template(
|
403
|
+
"settings/tags-list.html.j2",
|
404
|
+
tags=DB.session.scalars(sqlalchemy.select(Tag)).all(),
|
405
|
+
)
|
406
|
+
|
407
|
+
@blueprint.route("/tags/new", methods=["GET", "POST"])
|
408
|
+
@needs_authentication(authenticator)
|
409
|
+
def tags_new():
|
410
|
+
if request.method == "POST":
|
411
|
+
tag_str = request.form["tag"]
|
412
|
+
tag = Tag(tag=tag_str)
|
413
|
+
DB.session.add(tag)
|
414
|
+
DB.session.commit()
|
415
|
+
return redirect(url_for(".tags_list"))
|
416
|
+
else:
|
417
|
+
return render_template("settings/tags-new.html.j2")
|
418
|
+
|
419
|
+
@blueprint.route("/tags/edit/<int:id>", methods=["GET", "POST"])
|
420
|
+
@needs_authentication(authenticator)
|
421
|
+
def tags_edit(id: int):
|
422
|
+
tag = DB.session.get_one(Tag, id)
|
423
|
+
if request.method == "POST":
|
424
|
+
tag.tag = request.form["tag"]
|
425
|
+
DB.session.commit()
|
426
|
+
return redirect(url_for(".tags_list"))
|
427
|
+
else:
|
428
|
+
return render_template("settings/tags-edit.html.j2", tag=tag)
|
429
|
+
|
398
430
|
return blueprint
|
399
431
|
|
400
432
|
|
@@ -32,6 +32,21 @@
|
|
32
32
|
</select>
|
33
33
|
</div>
|
34
34
|
|
35
|
+
<div class="mb-3">
|
36
|
+
<label for="" class="form-label">Tags</label>
|
37
|
+
<div class="form-control">
|
38
|
+
{% for tag in tags %}
|
39
|
+
<div class="form-check form-check-inline">
|
40
|
+
<input class="form-check-input" type="checkbox" name="tag" value="{{ tag.id }}" id="tag_{{ tag.id }}" {%
|
41
|
+
if tag in activity.tags %} checked {% endif %}>
|
42
|
+
<label class="form-check-label" for="tag_{{ tag.id }}">
|
43
|
+
{{ tag.tag }}
|
44
|
+
</label>
|
45
|
+
</div>
|
46
|
+
{% endfor %}
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
|
35
50
|
<button type="submit" class="btn btn-primary">Save</button>
|
36
51
|
</form>
|
37
52
|
|
@@ -11,13 +11,22 @@
|
|
11
11
|
<div class="col-sm-12 col-md-4">
|
12
12
|
<dl>
|
13
13
|
<dt>Name</dt>
|
14
|
-
<dd>{{ activity
|
14
|
+
<dd>{{ activity.name }}</dd>
|
15
15
|
|
16
16
|
{% if activity.kind %}
|
17
17
|
<dt>Kind</dt>
|
18
18
|
<dd>{{ activity.kind.name }}</dd>
|
19
19
|
{% endif %}
|
20
20
|
|
21
|
+
{% if activity.tags %}
|
22
|
+
<dt>Tags</dt>
|
23
|
+
<dd>
|
24
|
+
{% for tag in activity.tags %}
|
25
|
+
<span class="badge text-bg-primary">{{ tag.tag }}</span>
|
26
|
+
{% endfor %}
|
27
|
+
</dd>
|
28
|
+
{% endif %}
|
29
|
+
|
21
30
|
<dt>Distance</dt>
|
22
31
|
<dd>{{ activity.distance_km|round(1) }} km</dd>
|
23
32
|
|
@@ -114,9 +123,11 @@
|
|
114
123
|
<div class="mb-3" style="padding-top: 10px;">
|
115
124
|
<form method="GET">
|
116
125
|
<label class="form-label">Line Color by</label>
|
117
|
-
<select class="form-select" aria-label="Line Color by" name="line_color_column"
|
126
|
+
<select class="form-select" aria-label="Line Color by" name="line_color_column"
|
127
|
+
onchange="this.form.submit()">
|
118
128
|
{% for name, column in line_color_columns_avail.items() %}
|
119
|
-
<option {% if name
|
129
|
+
<option {% if name==line_color_column %} selected {% endif %} value="{{ name }}">{{
|
130
|
+
column.display_name }}</option>
|
120
131
|
{% endfor %}
|
121
132
|
</select>
|
122
133
|
</form>
|
@@ -103,6 +103,15 @@
|
|
103
103
|
</div>
|
104
104
|
</div>
|
105
105
|
</div>
|
106
|
+
<div class="col">
|
107
|
+
<div class="card">
|
108
|
+
<div class="card-body">
|
109
|
+
<h5 class="card-title">Tags</h5>
|
110
|
+
<p class="card-text">You can assign tags to activities. Create and manage them here.</p>
|
111
|
+
<a href="{{ url_for('.tags_list') }}" class="btn btn-primary">Manage tags</a>
|
112
|
+
</div>
|
113
|
+
</div>
|
114
|
+
</div>
|
106
115
|
</div>
|
107
116
|
</div>
|
108
117
|
{% endblock %}
|
geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-edit.html.j2
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
{% extends "page.html.j2" %}
|
2
|
+
|
3
|
+
{% block container %}
|
4
|
+
|
5
|
+
<h1 class="mb-3">Edit Tag</h1>
|
6
|
+
|
7
|
+
<form method="POST">
|
8
|
+
<div class="mb-3">
|
9
|
+
<label for="tag" class="form-label">Tag</label>
|
10
|
+
<input type="text" class="form-control" id="tag" name="tag" value="{{ tag.tag }}" />
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<button type="submit" class="btn btn-primary">Save</button>
|
14
|
+
</form>
|
15
|
+
|
16
|
+
|
17
|
+
{% endblock %}
|
geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-list.html.j2
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
{% extends "page.html.j2" %}
|
2
|
+
|
3
|
+
{% block container %}
|
4
|
+
|
5
|
+
<h1 class="mb-3">Tags</h1>
|
6
|
+
|
7
|
+
<ul>
|
8
|
+
{% for tag in tags %}
|
9
|
+
<li>
|
10
|
+
<b>{{ tag.tag }}</b>
|
11
|
+
<a class="btn btn-sm btn-primary" href="{{ url_for('.tags_edit', id=tag.id) }}">Edit</a>
|
12
|
+
</li>
|
13
|
+
{% endfor %}
|
14
|
+
</ul>
|
15
|
+
|
16
|
+
|
17
|
+
<a class="btn btn-primary" href="{{ url_for('.tags_new') }}">New</a>
|
18
|
+
|
19
|
+
{% endblock %}
|
geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/settings/tags-new.html.j2
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
{% extends "page.html.j2" %}
|
2
|
+
|
3
|
+
{% block container %}
|
4
|
+
|
5
|
+
<h1 class="mb-3">Create Tag</h1>
|
6
|
+
|
7
|
+
<form method="POST">
|
8
|
+
<div class="mb-3">
|
9
|
+
<label for="tag" class="form-label">Tag</label>
|
10
|
+
<input type="text" class="form-control" id="tag" name="tag" />
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<button type="submit" class="btn btn-primary">Save</button>
|
14
|
+
</form>
|
15
|
+
|
16
|
+
|
17
|
+
{% endblock %}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "geo-activity-playground"
|
3
|
-
version = "0.
|
3
|
+
version = "0.42.0"
|
4
4
|
description = "Analysis of geo data activities like rides, runs or hikes."
|
5
5
|
authors = ["Martin Ueding <mu@martin-ueding.de>"]
|
6
6
|
license = "MIT"
|
@@ -59,6 +59,7 @@ types-requests = "^2.31.0.20240125"
|
|
59
59
|
types-tqdm = "^4.66.0.20240417"
|
60
60
|
types-typed-ast = "^1.5.8.7"
|
61
61
|
types-xmltodict = "^0.13.0.3"
|
62
|
+
pyright = "^1.1.399"
|
62
63
|
|
63
64
|
[build-system]
|
64
65
|
requires = ["poetry-core>=1.0.0"]
|
@@ -66,3 +67,7 @@ build-backend = "poetry.core.masonry.api"
|
|
66
67
|
|
67
68
|
[tool.mypy]
|
68
69
|
disable_error_code = "import-untyped"
|
70
|
+
|
71
|
+
|
72
|
+
[tool.pyright]
|
73
|
+
include = ['geo_activity_playground']
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|