geo-activity-playground 0.40.1__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.40.1 → geo_activity_playground-0.42.0}/PKG-INFO +2 -1
- geo_activity_playground-0.42.0/geo_activity_playground/alembic/versions/38882503dc7c_add_tags_to_activities.py +70 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/script.py.mako +0 -6
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/activities.py +21 -44
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/datamodel.py +121 -60
- {geo_activity_playground-0.40.1 → 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.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/tile_visits.py +1 -1
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/app.py +7 -3
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/activity_blueprint.py +38 -13
- geo_activity_playground-0.42.0/geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +86 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/calendar_blueprint.py +12 -4
- geo_activity_playground-0.42.0/geo_activity_playground/webui/blueprints/eddington_blueprints.py +253 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/entry_views.py +30 -15
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/explorer_blueprint.py +83 -9
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/settings_blueprint.py +32 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/summary_blueprint.py +102 -42
- geo_activity_playground-0.42.0/geo_activity_playground/webui/columns.py +37 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/edit.html.j2 +15 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/show.html.j2 +27 -5
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +42 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2 +150 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/elevation_eddington/index.html.j2 +150 -0
- geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/explorer/server-side.html.j2 +72 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/home.html.j2 +14 -5
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/page.html.j2 +10 -1
- {geo_activity_playground-0.40.1 → 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.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/summary/index.html.j2 +91 -2
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/pyproject.toml +6 -1
- geo_activity_playground-0.40.1/geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +0 -61
- geo_activity_playground-0.40.1/geo_activity_playground/webui/blueprints/eddington_blueprint.py +0 -194
- geo_activity_playground-0.40.1/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +0 -26
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/LICENSE +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/__main__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/README +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/env.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/script.py.mako +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/451e7836b53d_add_square_planner_bookmark.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/63d3b7f6f93c_initial_version.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/93cc82ad1b60_add_parametricplotspec.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/ab83b9d23127_add_upstream_id.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/b03491c593f6_add_crop_indices.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/alembic/versions/e02e27876deb_add_square_planner_bookmark_name.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/config.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/coordinates.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/heart_rate.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/meta_search.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/parametric_plot.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/paths.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/privacy_zones.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/raster_map.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/similarity.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/summary_stats.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/tasks.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_datamodel.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_meta_search.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_summary_stats.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_tiles.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/test_time_conversion.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/tiles.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/core/time_conversion.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/grid_file.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/explorer/video.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/heatmap_video.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/activity_parsers.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/csv_parser.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/directory.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/strava_api.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/strava_checkout.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_csv_parser.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_directory.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/importers/test_strava_api.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/authenticator.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/__init__.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/auth_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/equipment_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/heatmap_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/plot_builder_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/search_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/square_planner_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/tile_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/blueprints/upload_blueprint.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/flasher.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/plot_util.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/search_util.py +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/Leaflet.fullscreen.min.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/MarkerCluster.Default.css +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/MarkerCluster.css +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/android-chrome-192x192.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/android-chrome-512x512.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/apple-touch-icon.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap-dark-mode.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap.bundle.min.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/bootstrap.min.css +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/browserconfig.xml +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-16x16.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-32x32.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon-48x48.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon.ico +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/favicon.svg +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/fullscreen.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/fullscreen@2x.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/layers-2x.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/layers.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-icon-2x.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-icon.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/images/marker-shadow.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.css +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.fullscreen.css +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/leaflet.markercluster.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/mstile-150x150.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/site.webmanifest +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/table-sort.min.js +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega-embed@6 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega-lite@4 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/vega@5 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/web-app-manifest-192x192.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/static/web-app-manifest-512x512.png +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/day.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/lines.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/name.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/activity/trim.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/auth/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/calendar/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/calendar/month.html.j2 +0 -0
- /geo_activity_playground-0.40.1/geo_activity_playground/webui/templates/eddington/index.html.j2 → /geo_activity_playground-0.42.0/geo_activity_playground/webui/templates/eddington/distance.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/equipment/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/explorer/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/heatmap/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/plot_builder/edit.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/plot_builder/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/search/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/search_form.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/admin-password.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/color-schemes.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/heart-rate.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/manage-equipments.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/manage-kinds.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/metadata-extraction.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/privacy-zones.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/segmentation.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/sharepic.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/settings/strava.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/square_planner/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → geo_activity_playground-0.42.0}/geo_activity_playground/webui/templates/upload/index.html.j2 +0 -0
- {geo_activity_playground-0.40.1 → 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)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
from typing import Sequence
|
2
|
+
from typing import Union
|
3
|
+
|
4
|
+
import sqlalchemy as sa
|
5
|
+
from alembic import op
|
6
|
+
|
7
|
+
|
8
|
+
# revision identifiers, used by Alembic.
|
9
|
+
revision: str = "38882503dc7c"
|
10
|
+
down_revision: Union[str, None] = "93cc82ad1b60"
|
11
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
12
|
+
depends_on: Union[str, Sequence[str], None] = None
|
13
|
+
|
14
|
+
|
15
|
+
def upgrade() -> None:
|
16
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
17
|
+
op.create_table(
|
18
|
+
"tags",
|
19
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
20
|
+
sa.Column("tag", sa.String(), nullable=False),
|
21
|
+
sa.PrimaryKeyConstraint("id"),
|
22
|
+
sa.UniqueConstraint("tag"),
|
23
|
+
sa.UniqueConstraint("tag", name="tags_tag"),
|
24
|
+
)
|
25
|
+
op.create_table(
|
26
|
+
"activity_tag_association_table",
|
27
|
+
sa.Column("left_id", sa.Integer(), nullable=False),
|
28
|
+
sa.Column("right_id", sa.Integer(), nullable=False),
|
29
|
+
sa.ForeignKeyConstraint(
|
30
|
+
["left_id"],
|
31
|
+
["activities.id"],
|
32
|
+
),
|
33
|
+
sa.ForeignKeyConstraint(
|
34
|
+
["right_id"],
|
35
|
+
["tags.id"],
|
36
|
+
),
|
37
|
+
sa.PrimaryKeyConstraint("left_id", "right_id"),
|
38
|
+
)
|
39
|
+
with op.batch_alter_table("plot_specs", schema=None) as batch_op:
|
40
|
+
batch_op.alter_column("mark", existing_type=sa.VARCHAR(), nullable=False)
|
41
|
+
batch_op.alter_column("x", existing_type=sa.VARCHAR(), nullable=False)
|
42
|
+
batch_op.alter_column("y", existing_type=sa.VARCHAR(), nullable=False)
|
43
|
+
batch_op.alter_column("color", existing_type=sa.VARCHAR(), nullable=False)
|
44
|
+
batch_op.alter_column("shape", existing_type=sa.VARCHAR(), nullable=False)
|
45
|
+
batch_op.alter_column("size", existing_type=sa.VARCHAR(), nullable=False)
|
46
|
+
batch_op.alter_column("row", existing_type=sa.VARCHAR(), nullable=False)
|
47
|
+
batch_op.alter_column("opacity", existing_type=sa.VARCHAR(), nullable=False)
|
48
|
+
batch_op.alter_column("column", existing_type=sa.VARCHAR(), nullable=False)
|
49
|
+
batch_op.alter_column("facet", existing_type=sa.VARCHAR(), nullable=False)
|
50
|
+
|
51
|
+
# ### end Alembic commands ###
|
52
|
+
|
53
|
+
|
54
|
+
def downgrade() -> None:
|
55
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
56
|
+
with op.batch_alter_table("plot_specs", schema=None) as batch_op:
|
57
|
+
batch_op.alter_column("facet", existing_type=sa.VARCHAR(), nullable=True)
|
58
|
+
batch_op.alter_column("column", existing_type=sa.VARCHAR(), nullable=True)
|
59
|
+
batch_op.alter_column("opacity", existing_type=sa.VARCHAR(), nullable=True)
|
60
|
+
batch_op.alter_column("row", existing_type=sa.VARCHAR(), nullable=True)
|
61
|
+
batch_op.alter_column("size", existing_type=sa.VARCHAR(), nullable=True)
|
62
|
+
batch_op.alter_column("shape", existing_type=sa.VARCHAR(), nullable=True)
|
63
|
+
batch_op.alter_column("color", existing_type=sa.VARCHAR(), nullable=True)
|
64
|
+
batch_op.alter_column("y", existing_type=sa.VARCHAR(), nullable=True)
|
65
|
+
batch_op.alter_column("x", existing_type=sa.VARCHAR(), nullable=True)
|
66
|
+
batch_op.alter_column("mark", existing_type=sa.VARCHAR(), nullable=True)
|
67
|
+
|
68
|
+
op.drop_table("activity_tag_association_table")
|
69
|
+
op.drop_table("tags")
|
70
|
+
# ### end Alembic commands ###
|
@@ -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
|
|
@@ -16,21 +17,11 @@ from geo_activity_playground.core.datamodel import Activity
|
|
16
17
|
from geo_activity_playground.core.datamodel import ActivityMeta
|
17
18
|
from geo_activity_playground.core.datamodel import DB
|
18
19
|
from geo_activity_playground.core.datamodel import Kind
|
20
|
+
from geo_activity_playground.core.datamodel import query_activity_meta
|
19
21
|
|
20
22
|
logger = logging.getLogger(__name__)
|
21
23
|
|
22
24
|
|
23
|
-
def make_activity_meta() -> ActivityMeta:
|
24
|
-
return ActivityMeta(
|
25
|
-
calories=None,
|
26
|
-
commute=False,
|
27
|
-
consider_for_achievements=True,
|
28
|
-
equipment="Unknown",
|
29
|
-
kind="Unknown",
|
30
|
-
steps=None,
|
31
|
-
)
|
32
|
-
|
33
|
-
|
34
25
|
class ActivityRepository:
|
35
26
|
def __len__(self) -> int:
|
36
27
|
return len(self.get_activity_ids())
|
@@ -51,14 +42,14 @@ class ActivityRepository:
|
|
51
42
|
else:
|
52
43
|
return None
|
53
44
|
|
54
|
-
def get_activity_ids(self, only_achievements: bool = False) ->
|
45
|
+
def get_activity_ids(self, only_achievements: bool = False) -> Sequence[int]:
|
55
46
|
query = sqlalchemy.select(Activity.id)
|
56
47
|
if only_achievements:
|
57
48
|
query = query.where(Kind.consider_for_achievements)
|
58
|
-
result = DB.session.scalars(query).all()
|
49
|
+
result = DB.session.scalars(query.order_by(Activity.start)).all()
|
59
50
|
return result
|
60
51
|
|
61
|
-
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]:
|
62
53
|
query = sqlalchemy.select(Activity)
|
63
54
|
if drop_na:
|
64
55
|
query = query.where(Activity.start.is_not(None))
|
@@ -79,22 +70,8 @@ class ActivityRepository:
|
|
79
70
|
|
80
71
|
@property
|
81
72
|
def meta(self) -> pd.DataFrame:
|
82
|
-
|
83
|
-
|
84
|
-
df["date"] = df["start"].dt.date
|
85
|
-
df["year"] = [start.year for start in df["start"]]
|
86
|
-
df["month"] = [start.month for start in df["start"]]
|
87
|
-
df["day"] = [start.day for start in df["start"]]
|
88
|
-
df["week"] = [start.isocalendar().week for start in df["start"]]
|
89
|
-
df["day_of_week"] = df["start"].dt.day_of_week
|
90
|
-
df["iso_year"] = [start.isocalendar().year for start in df["start"]]
|
91
|
-
df["hours"] = [
|
92
|
-
elapsed_time.total_seconds() / 3600 for elapsed_time in df["elapsed_time"]
|
93
|
-
]
|
94
|
-
df["hours_moving"] = [
|
95
|
-
moving_time.total_seconds() / 3600 for moving_time in df["moving_time"]
|
96
|
-
]
|
97
|
-
df.index = df["id"]
|
73
|
+
df = query_activity_meta()
|
74
|
+
|
98
75
|
return df
|
99
76
|
|
100
77
|
|
@@ -114,8 +91,8 @@ def inter_quartile_range(values):
|
|
114
91
|
return np.quantile(values, 0.75) - np.quantile(values, 0.25)
|
115
92
|
|
116
93
|
|
117
|
-
def make_geojson_color_line(time_series: pd.DataFrame) -> str:
|
118
|
-
low, high,
|
94
|
+
def make_geojson_color_line(time_series: pd.DataFrame, column: str) -> str:
|
95
|
+
low, high, clamp_value = _make_value_clamp(time_series[column])
|
119
96
|
cmap = matplotlib.colormaps["viridis"]
|
120
97
|
features = [
|
121
98
|
geojson.Feature(
|
@@ -126,8 +103,8 @@ def make_geojson_color_line(time_series: pd.DataFrame) -> str:
|
|
126
103
|
]
|
127
104
|
),
|
128
105
|
properties={
|
129
|
-
|
130
|
-
"color": matplotlib.colors.to_hex(cmap(
|
106
|
+
column: (next_row[column] if np.isfinite(next_row[column]) else 0.0),
|
107
|
+
"color": matplotlib.colors.to_hex(cmap(clamp_value(next_row[column]))),
|
131
108
|
},
|
132
109
|
)
|
133
110
|
for _, group in time_series.groupby("segment_id")
|
@@ -137,21 +114,21 @@ def make_geojson_color_line(time_series: pd.DataFrame) -> str:
|
|
137
114
|
return geojson.dumps(feature_collection)
|
138
115
|
|
139
116
|
|
140
|
-
def
|
141
|
-
low, high,
|
117
|
+
def make_color_bar(time_series: pd.Series, format: str) -> dict[str, Any]:
|
118
|
+
low, high, clamp_value = _make_value_clamp(time_series)
|
142
119
|
cmap = matplotlib.colormaps["viridis"]
|
143
120
|
colors = [
|
144
|
-
(f"{
|
145
|
-
for
|
121
|
+
(f"{value:{format}}", matplotlib.colors.to_hex(cmap(clamp_value(value))))
|
122
|
+
for value in np.linspace(low, high, 10)
|
146
123
|
]
|
147
124
|
return {"low": low, "high": high, "colors": colors}
|
148
125
|
|
149
126
|
|
150
|
-
def
|
151
|
-
|
152
|
-
low = min(
|
127
|
+
def _make_value_clamp(values: pd.Series) -> tuple[float, float, Callable]:
|
128
|
+
values_without_na = values.dropna()
|
129
|
+
low = min(values_without_na)
|
153
130
|
high = min(
|
154
|
-
max(
|
155
|
-
np.median(
|
131
|
+
max(values_without_na),
|
132
|
+
np.median(values_without_na) + 1.5 * inter_quartile_range(values_without_na),
|
156
133
|
)
|
157
|
-
return low, high, lambda
|
134
|
+
return low, high, lambda value: min(max((value - low) / (high - low), 0.0), 1.0)
|
@@ -10,8 +10,10 @@ import pandas as pd
|
|
10
10
|
import sqlalchemy
|
11
11
|
import sqlalchemy as sa
|
12
12
|
from flask_sqlalchemy import SQLAlchemy
|
13
|
+
from sqlalchemy import Column
|
13
14
|
from sqlalchemy import ForeignKey
|
14
15
|
from sqlalchemy import String
|
16
|
+
from sqlalchemy import Table
|
15
17
|
from sqlalchemy.orm import DeclarativeBase
|
16
18
|
from sqlalchemy.orm import Mapped
|
17
19
|
from sqlalchemy.orm import mapped_column
|
@@ -53,6 +55,13 @@ class Base(DeclarativeBase):
|
|
53
55
|
|
54
56
|
DB = SQLAlchemy(model_class=Base)
|
55
57
|
|
58
|
+
activity_tag_association_table = Table(
|
59
|
+
"activity_tag_association_table",
|
60
|
+
Base.metadata,
|
61
|
+
Column("left_id", ForeignKey("activities.id"), primary_key=True),
|
62
|
+
Column("right_id", ForeignKey("tags.id"), primary_key=True),
|
63
|
+
)
|
64
|
+
|
56
65
|
|
57
66
|
class Activity(DB.Model):
|
58
67
|
__tablename__ = "activities"
|
@@ -104,8 +113,9 @@ class Activity(DB.Model):
|
|
104
113
|
)
|
105
114
|
kind: Mapped["Kind"] = relationship(back_populates="activities")
|
106
115
|
|
107
|
-
|
108
|
-
|
116
|
+
tags: Mapped[list["Tag"]] = relationship(
|
117
|
+
secondary=activity_tag_association_table, back_populates="activities"
|
118
|
+
)
|
109
119
|
|
110
120
|
def __str__(self) -> str:
|
111
121
|
return f"{self.start} {self.name}"
|
@@ -114,11 +124,15 @@ class Activity(DB.Model):
|
|
114
124
|
def average_speed_moving_kmh(self) -> Optional[float]:
|
115
125
|
if self.moving_time:
|
116
126
|
return self.distance_km / (self.moving_time.total_seconds() / 3_600)
|
127
|
+
else:
|
128
|
+
return None
|
117
129
|
|
118
130
|
@property
|
119
131
|
def average_speed_elapsed_kmh(self) -> Optional[float]:
|
120
132
|
if self.elapsed_time:
|
121
133
|
return self.distance_km / (self.elapsed_time.total_seconds() / 3_600)
|
134
|
+
else:
|
135
|
+
return None
|
122
136
|
|
123
137
|
@property
|
124
138
|
def raw_time_series(self) -> pd.DataFrame:
|
@@ -141,38 +155,85 @@ class Activity(DB.Model):
|
|
141
155
|
else:
|
142
156
|
return self.raw_time_series
|
143
157
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
158
|
+
|
159
|
+
class Tag(DB.Model):
|
160
|
+
__tablename__ = "tags"
|
161
|
+
__table_args__ = (sa.UniqueConstraint("tag", name="tags_tag"),)
|
162
|
+
|
163
|
+
id: Mapped[int] = mapped_column(primary_key=True)
|
164
|
+
tag: Mapped[str] = mapped_column(String, unique=True)
|
165
|
+
|
166
|
+
activities: Mapped[list[Activity]] = relationship(
|
167
|
+
secondary=activity_tag_association_table, back_populates="tags"
|
168
|
+
)
|
169
|
+
|
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
|
+
|
182
|
+
def query_activity_meta() -> pd.DataFrame:
|
183
|
+
rows = DB.session.execute(
|
184
|
+
sqlalchemy.select(
|
185
|
+
Activity.id,
|
186
|
+
Activity.name,
|
187
|
+
Activity.path,
|
188
|
+
Activity.distance_km,
|
189
|
+
Activity.start,
|
190
|
+
Activity.elapsed_time,
|
191
|
+
Activity.moving_time,
|
192
|
+
Activity.start_latitude,
|
193
|
+
Activity.start_longitude,
|
194
|
+
Activity.end_latitude,
|
195
|
+
Activity.end_longitude,
|
196
|
+
Activity.elevation_gain,
|
197
|
+
Activity.start_elevation,
|
198
|
+
Activity.end_elevation,
|
199
|
+
Activity.calories,
|
200
|
+
Activity.steps,
|
201
|
+
Activity.num_new_tiles_14,
|
202
|
+
Activity.num_new_tiles_17,
|
203
|
+
Kind.consider_for_achievements,
|
204
|
+
Equipment.name.label("equipment"),
|
205
|
+
Kind.name.label("kind"),
|
149
206
|
)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
end_elevation=self.end_elevation,
|
165
|
-
calories=self.calories,
|
166
|
-
steps=self.steps,
|
167
|
-
num_new_tiles_14=self.num_new_tiles_14,
|
168
|
-
num_new_tiles_17=self.num_new_tiles_17,
|
169
|
-
equipment=equipment,
|
170
|
-
kind=kind,
|
171
|
-
average_speed_moving_kmh=self.average_speed_moving_kmh,
|
172
|
-
average_speed_elapsed_kmh=self.average_speed_elapsed_kmh,
|
173
|
-
consider_for_achievements=consider_for_achievements,
|
207
|
+
.join(Activity.equipment)
|
208
|
+
.join(Activity.kind)
|
209
|
+
.order_by(Activity.start)
|
210
|
+
).all()
|
211
|
+
df = pd.DataFrame(rows)
|
212
|
+
|
213
|
+
for old, new in [
|
214
|
+
("elapsed_time", "average_speed_elapsed_kmh"),
|
215
|
+
("moving_time", "average_speed_moving_kmh"),
|
216
|
+
]:
|
217
|
+
df[new] = pd.NA
|
218
|
+
mask = df[old].dt.total_seconds() > 0
|
219
|
+
df.loc[mask, new] = df.loc[mask, "distance_km"] / (
|
220
|
+
df.loc[mask, old].dt.total_seconds() / 3_600
|
174
221
|
)
|
175
222
|
|
223
|
+
df["date"] = df["start"].dt.date
|
224
|
+
df["year"] = df["start"].dt.year
|
225
|
+
df["month"] = df["start"].dt.month
|
226
|
+
df["day"] = df["start"].dt.day
|
227
|
+
df["week"] = df["start"].dt.isocalendar().week
|
228
|
+
df["day_of_week"] = df["start"].dt.day_of_week
|
229
|
+
df["iso_year"] = df["start"].dt.isocalendar().year
|
230
|
+
df["hours"] = df["elapsed_time"].dt.total_seconds() / 3_600
|
231
|
+
df["hours_moving"] = df["moving_time"].dt.total_seconds() / 3_600
|
232
|
+
|
233
|
+
df.index = df["id"]
|
234
|
+
|
235
|
+
return df
|
236
|
+
|
176
237
|
|
177
238
|
class Equipment(DB.Model):
|
178
239
|
__tablename__ = "equipments"
|
@@ -195,6 +256,23 @@ class Equipment(DB.Model):
|
|
195
256
|
__table_args__ = (sa.UniqueConstraint("name", name="equipments_name"),)
|
196
257
|
|
197
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
|
+
|
198
276
|
class Kind(DB.Model):
|
199
277
|
__tablename__ = "kinds"
|
200
278
|
|
@@ -218,20 +296,6 @@ class Kind(DB.Model):
|
|
218
296
|
__table_args__ = (sa.UniqueConstraint("name", name="kinds_name"),)
|
219
297
|
|
220
298
|
|
221
|
-
class SquarePlannerBookmark(DB.Model):
|
222
|
-
__tablename__ = "square_planner_bookmarks"
|
223
|
-
|
224
|
-
id: Mapped[int] = mapped_column(primary_key=True)
|
225
|
-
|
226
|
-
zoom: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
227
|
-
x: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
228
|
-
y: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
229
|
-
size: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
230
|
-
name: Mapped[str] = mapped_column(sa.String, nullable=False)
|
231
|
-
|
232
|
-
__table_args__ = (sa.UniqueConstraint("zoom", "x", "y", "size", name="kinds_name"),)
|
233
|
-
|
234
|
-
|
235
299
|
def get_or_make_kind(name: str, config: Config) -> Kind:
|
236
300
|
kinds = DB.session.scalars(sqlalchemy.select(Kind).where(Kind.name == name)).all()
|
237
301
|
if kinds:
|
@@ -246,21 +310,18 @@ def get_or_make_kind(name: str, config: Config) -> Kind:
|
|
246
310
|
return kind
|
247
311
|
|
248
312
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
)
|
262
|
-
DB.session.add(equipment)
|
263
|
-
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"),)
|
264
325
|
|
265
326
|
|
266
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)
|
@@ -28,7 +28,7 @@ from .blueprints.activity_blueprint import make_activity_blueprint
|
|
28
28
|
from .blueprints.auth_blueprint import make_auth_blueprint
|
29
29
|
from .blueprints.bubble_chart_blueprint import make_bubble_chart_blueprint
|
30
30
|
from .blueprints.calendar_blueprint import make_calendar_blueprint
|
31
|
-
from .blueprints.
|
31
|
+
from .blueprints.eddington_blueprints import register_eddington_blueprint
|
32
32
|
from .blueprints.entry_views import register_entry_views
|
33
33
|
from .blueprints.equipment_blueprint import make_equipment_blueprint
|
34
34
|
from .blueprints.explorer_blueprint import make_explorer_blueprint
|
@@ -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"}
|
@@ -137,7 +137,11 @@ def web_ui_main(
|
|
137
137
|
"/eddington": register_eddington_blueprint(repository, search_query_history),
|
138
138
|
"/equipment": make_equipment_blueprint(repository, config),
|
139
139
|
"/explorer": make_explorer_blueprint(
|
140
|
-
authenticator,
|
140
|
+
authenticator,
|
141
|
+
tile_visit_accessor,
|
142
|
+
config_accessor,
|
143
|
+
tile_getter,
|
144
|
+
image_transforms,
|
141
145
|
),
|
142
146
|
"/heatmap": make_heatmap_blueprint(
|
143
147
|
repository, tile_visit_accessor, config_accessor(), search_query_history
|