geo-activity-playground 1.8.3__tar.gz → 1.9.1__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.
Files changed (180) hide show
  1. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/PKG-INFO +1 -1
  2. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/activities.py +1 -1
  3. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/enrichment.py +6 -2
  4. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/parametric_plot.py +10 -10
  5. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/summary_stats.py +2 -2
  6. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/explorer/tile_visits.py +2 -0
  7. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/activity_parsers.py +26 -3
  8. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/strava_api.py +4 -0
  9. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/activity_blueprint.py +6 -6
  10. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +2 -2
  11. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/calendar_blueprint.py +2 -2
  12. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/eddington_blueprints.py +5 -10
  13. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/entry_views.py +3 -3
  14. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/equipment_blueprint.py +5 -5
  15. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/explorer_blueprint.py +5 -3
  16. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/plot_builder_blueprint.py +1 -1
  17. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/summary_blueprint.py +2 -2
  18. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/upload_blueprint.py +15 -13
  19. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/day.html.j2 +1 -1
  20. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/show.html.j2 +1 -1
  21. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/search/index.html.j2 +2 -2
  22. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/upload/index.html.j2 +1 -1
  23. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/pyproject.toml +1 -1
  24. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/LICENSE +0 -0
  25. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/__init__.py +0 -0
  26. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/__main__.py +0 -0
  27. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/README +0 -0
  28. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/env.py +0 -0
  29. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/script.py.mako +0 -0
  30. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/0f02b92c4f94_add_tag_color.py +0 -0
  31. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/38882503dc7c_add_tags_to_activities.py +0 -0
  32. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/451e7836b53d_add_square_planner_bookmark.py +0 -0
  33. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/63d3b7f6f93c_initial_version.py +0 -0
  34. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/85fe0348e8a2_add_time_series_uuid_field.py +0 -0
  35. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/93cc82ad1b60_add_parametricplotspec.py +0 -0
  36. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/ab83b9d23127_add_upstream_id.py +0 -0
  37. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/b03491c593f6_add_crop_indices.py +0 -0
  38. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/da2cba03b71d_add_photos.py +0 -0
  39. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/dc8073871da7_add_plotspec_group_by.py +0 -0
  40. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/e02e27876deb_add_square_planner_bookmark_name.py +0 -0
  41. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/f2f50843be2d_make_all_fields_in_activity_nullable.py +0 -0
  42. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/alembic/versions/script.py.mako +0 -0
  43. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/__init__.py +0 -0
  44. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/config.py +0 -0
  45. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/coordinates.py +0 -0
  46. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/copernicus_dem.py +0 -0
  47. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/datamodel.py +0 -0
  48. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/export.py +0 -0
  49. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/heart_rate.py +0 -0
  50. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/meta_search.py +0 -0
  51. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/missing_values.py +0 -0
  52. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/paths.py +0 -0
  53. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/photos.py +0 -0
  54. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/privacy_zones.py +0 -0
  55. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/raster_map.py +0 -0
  56. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/similarity.py +0 -0
  57. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/tasks.py +0 -0
  58. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_datamodel.py +0 -0
  59. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_meta_search.py +0 -0
  60. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_missing_values.py +0 -0
  61. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_pandas_timezone.py +0 -0
  62. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_summary_stats.py +0 -0
  63. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_tiles.py +0 -0
  64. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_time_zone_from_location.py +0 -0
  65. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_time_zone_import.py +0 -0
  66. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/test_timezone_sqlalchemy.py +0 -0
  67. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/tiles.py +0 -0
  68. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/core/time_conversion.py +0 -0
  69. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/explorer/__init__.py +0 -0
  70. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/explorer/grid_file.py +0 -0
  71. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/explorer/video.py +0 -0
  72. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/heatmap_video.py +0 -0
  73. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/__init__.py +0 -0
  74. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/csv_parser.py +0 -0
  75. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/directory.py +0 -0
  76. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/strava_checkout.py +0 -0
  77. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/test_csv_parser.py +0 -0
  78. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/test_directory.py +0 -0
  79. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/importers/test_strava_api.py +0 -0
  80. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/__init__.py +0 -0
  81. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/app.py +0 -0
  82. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/authenticator.py +0 -0
  83. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/__init__.py +0 -0
  84. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/auth_blueprint.py +0 -0
  85. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/export_blueprint.py +0 -0
  86. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/hall_of_fame_blueprint.py +0 -0
  87. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/heatmap_blueprint.py +0 -0
  88. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/photo_blueprint.py +0 -0
  89. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/search_blueprint.py +0 -0
  90. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/settings_blueprint.py +0 -0
  91. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/square_planner_blueprint.py +0 -0
  92. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/tile_blueprint.py +0 -0
  93. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/blueprints/time_zone_fixer_blueprint.py +0 -0
  94. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/columns.py +0 -0
  95. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/flasher.py +0 -0
  96. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/plot_util.py +0 -0
  97. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/search_util.py +0 -0
  98. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/activity-trim.js +0 -0
  99. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/bootstrap/bootstrap-dark-mode.js +0 -0
  100. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/bootstrap/bootstrap.bundle.min.js +0 -0
  101. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/bootstrap/bootstrap.min.css +0 -0
  102. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/android-chrome-192x192.png +0 -0
  103. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/android-chrome-512x512.png +0 -0
  104. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/apple-touch-icon.png +0 -0
  105. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/browserconfig.xml +0 -0
  106. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/favicon-16x16.png +0 -0
  107. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/favicon-32x32.png +0 -0
  108. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/favicon-48x48.png +0 -0
  109. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/favicon.ico +0 -0
  110. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/favicon.svg +0 -0
  111. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/mstile-150x150.png +0 -0
  112. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/site.webmanifest +0 -0
  113. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/web-app-manifest-192x192.png +0 -0
  114. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/favicons/web-app-manifest-512x512.png +0 -0
  115. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/images/layers-2x.png +0 -0
  116. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/images/layers.png +0 -0
  117. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/images/marker-icon-2x.png +0 -0
  118. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/images/marker-icon.png +0 -0
  119. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/images/marker-shadow.png +0 -0
  120. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/Leaflet.fullscreen.min.js +0 -0
  121. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/MarkerCluster.Default.css +0 -0
  122. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/MarkerCluster.css +0 -0
  123. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/fullscreen.png +0 -0
  124. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/fullscreen@2x.png +0 -0
  125. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/images/layers-2x.png +0 -0
  126. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/images/layers.png +0 -0
  127. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/leaflet.css +0 -0
  128. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/leaflet.fullscreen.css +0 -0
  129. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/leaflet.js +0 -0
  130. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/leaflet/leaflet.markercluster.js +0 -0
  131. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/server-side-explorer.js +0 -0
  132. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/table-sort.min.js +0 -0
  133. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/vega/vega-embed@6.js +0 -0
  134. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/vega/vega-lite@4.js +0 -0
  135. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/static/vega/vega@5.js +0 -0
  136. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/edit.html.j2 +0 -0
  137. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/lines.html.j2 +0 -0
  138. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/name.html.j2 +0 -0
  139. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/activity/trim.html.j2 +0 -0
  140. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/auth/index.html.j2 +0 -0
  141. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +0 -0
  142. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/calendar/index.html.j2 +0 -0
  143. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/calendar/month.html.j2 +0 -0
  144. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/eddington/distance.html.j2 +0 -0
  145. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2 +0 -0
  146. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/elevation_eddington/index.html.j2 +0 -0
  147. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/equipment/index.html.j2 +0 -0
  148. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/explorer/server-side.html.j2 +0 -0
  149. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/export/index.html.j2 +0 -0
  150. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/hall_of_fame/index.html.j2 +0 -0
  151. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/heatmap/index.html.j2 +0 -0
  152. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/home.html.j2 +0 -0
  153. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/page.html.j2 +0 -0
  154. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/photo/map.html.j2 +0 -0
  155. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/photo/new.html.j2 +0 -0
  156. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/plot-macros.html.j2 +0 -0
  157. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/plot_builder/edit.html.j2 +0 -0
  158. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/plot_builder/import-spec.html.j2 +0 -0
  159. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/plot_builder/index.html.j2 +0 -0
  160. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/search_form.html.j2 +0 -0
  161. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/admin-password.html.j2 +0 -0
  162. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/color-schemes.html.j2 +0 -0
  163. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/heart-rate.html.j2 +0 -0
  164. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/index.html.j2 +0 -0
  165. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/manage-equipments.html.j2 +0 -0
  166. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/manage-kinds.html.j2 +0 -0
  167. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/metadata-extraction.html.j2 +0 -0
  168. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/privacy-zones.html.j2 +0 -0
  169. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/segmentation.html.j2 +0 -0
  170. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/sharepic.html.j2 +0 -0
  171. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/strava.html.j2 +0 -0
  172. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/tags-edit.html.j2 +0 -0
  173. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/tags-list.html.j2 +0 -0
  174. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/tags-new.html.j2 +0 -0
  175. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/settings/tile-source.html.j2 +0 -0
  176. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/square_planner/index.html.j2 +0 -0
  177. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/summary/index.html.j2 +0 -0
  178. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/summary/vega-chart.html.j2 +0 -0
  179. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/geo_activity_playground/webui/templates/time_zone_fixer/index.html.j2 +0 -0
  180. {geo_activity_playground-1.8.3 → geo_activity_playground-1.9.1}/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: 1.8.3
3
+ Version: 1.9.1
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
@@ -40,7 +40,7 @@ class ActivityRepository:
40
40
  sqlalchemy.select(Activity).order_by(Activity.start)
41
41
  ).all()
42
42
  if result:
43
- return result[-1].start
43
+ return result[-1].start_local_tz
44
44
  else:
45
45
  return None
46
46
 
@@ -183,14 +183,18 @@ def enrichment_distance(
183
183
  if "speed" not in time_series.columns:
184
184
  time_series["speed"] = (
185
185
  time_series["distance_km"].diff()
186
- / (time_series["time"].diff().dt.total_seconds() + 1e-3)
186
+ / time_series["time"].diff().dt.total_seconds()
187
187
  * 3600
188
188
  )
189
+ # Division by zero causes infinity. We replace these with NaN and interpolate the values instead.
190
+ time_series["speed"] = time_series["speed"].replace([np.inf, -np.inf], np.nan)
191
+ time_series.interpolate(inplace=True)
192
+
189
193
  changed = True
190
194
 
191
195
  potential_jumps = (time_series["speed"] > 40) & (time_series["speed"].diff() > 10)
192
196
  if np.any(potential_jumps):
193
- time_series.replace(time_series.loc[~potential_jumps])
197
+ time_series.replace(time_series.loc[~potential_jumps], inplace=True)
194
198
  changed = True
195
199
 
196
200
  if "segment_id" not in time_series.columns:
@@ -17,7 +17,7 @@ CONTINUOUS_VARIABLES = {
17
17
  "distance_km_cumsum": "Cumulative Distance / km",
18
18
  "sum(distance_km)": "Total distance / km",
19
19
  "mean(distance_km)": "Average distance / km",
20
- "start": "Date",
20
+ "start_local": "Date",
21
21
  "hours": "Elapsed time / h",
22
22
  "hours_moving": "Moving time / h",
23
23
  "calories": "Energy / kcal",
@@ -40,17 +40,17 @@ DISCRETE_VARIABLES = {
40
40
  "equipment": "Equipment",
41
41
  "kind": "Activity kind",
42
42
  "consider_for_achievements": "Consider for achievements",
43
- "year(start):O": "Year",
43
+ "year(start_local):O": "Year",
44
44
  "iso_year:O": "ISO Year",
45
- "yearquarter(start)": "Year, Quarter",
46
- "yearquartermonth(start)": "Year, Quarter, Month",
47
- "yearmonth(start)": "Year, Month",
48
- "quarter(start)": "Quarter",
49
- "quartermonth(start)": "Quarter, Month",
50
- "month(start)": "Month",
45
+ "yearquarter(start_local)": "Year, Quarter",
46
+ "yearquartermonth(start_local)": "Year, Quarter, Month",
47
+ "yearmonth(start_local)": "Year, Month",
48
+ "quarter(start_local)": "Quarter",
49
+ "quartermonth(start_local)": "Quarter, Month",
50
+ "month(start_local)": "Month",
51
51
  "week:O": "ISO Week",
52
- "date(start)": "Day of month",
53
- "weekday(start)": "Day of week",
52
+ "date(start_local)": "Day of month",
53
+ "weekday(start_local)": "Day of week",
54
54
  "iso_day:O": "ISO Day",
55
55
  }
56
56
  GROUP_BY_VARIABLES = {
@@ -10,8 +10,8 @@ def get_equipment_use_table(
10
10
  lambda group: pd.Series(
11
11
  {
12
12
  "total_distance_km": group["distance_km"].sum(),
13
- "first_use": group["start"].min(skipna=True),
14
- "last_use": group["start"].max(skipna=True),
13
+ "first_use": group["start_local"].min(skipna=True),
14
+ "last_use": group["start_local"].max(skipna=True),
15
15
  },
16
16
  ),
17
17
  include_groups=False,
@@ -240,6 +240,8 @@ def _process_activity(
240
240
  zip(activity_tiles["tile_x"], activity_tiles["tile_y"]),
241
241
  ):
242
242
  if activity.kind.consider_for_achievements:
243
+ if time is not None and time.tz is None:
244
+ time = time.tz_localize("UTC")
243
245
  if tile not in tile_state["tile_visits"][zoom]:
244
246
  new_tile_history_soa["activity_id"].append(activity_id)
245
247
  new_tile_history_soa["time"].append(time)
@@ -202,9 +202,32 @@ def read_gpx_activity(path: pathlib.Path, open) -> pd.DataFrame:
202
202
  time = dateutil.parser.parse(str(point.time))
203
203
  else:
204
204
  time = None
205
- points.append((time, point.latitude, point.longitude, point.elevation))
206
-
207
- df = pd.DataFrame(points, columns=["time", "latitude", "longitude", "elevation"])
205
+ row = {
206
+ "time": time,
207
+ "latitude": point.latitude,
208
+ "longitude": point.longitude,
209
+ "elevation": point.elevation,
210
+ }
211
+ if point.extensions:
212
+ for ext in point.extensions:
213
+ if (
214
+ ext.tag
215
+ == "{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}TrackPointExtension"
216
+ ):
217
+ for datum in ext:
218
+ if (
219
+ datum.tag
220
+ == "{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}hr"
221
+ ):
222
+ row["heartrate"] = int(datum.text)
223
+ if (
224
+ datum.tag
225
+ == "{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}cad"
226
+ ):
227
+ row["cadence"] = int(datum.text)
228
+
229
+ points.append(row)
230
+ df = pd.DataFrame(points)
208
231
  # Some files don't have elevation information. In these cases we remove the column.
209
232
  if not df["elevation"].any():
210
233
  del df["elevation"]
@@ -117,6 +117,9 @@ def try_import_strava(
117
117
  for strava_activity in tqdm(
118
118
  client.get_activities(after=get_after), desc="Downloading Strava activities"
119
119
  ):
120
+ logger.info(
121
+ f"Examining Strava activity with ID {strava_activity.id} and name '{strava_activity.name}' …"
122
+ )
120
123
  if (
121
124
  strava_end
122
125
  and strava_activity.start_date is not None
@@ -195,6 +198,7 @@ def try_import_strava(
195
198
  activity.moving_time = detailed_activity.moving_time
196
199
 
197
200
  update_and_commit(activity, time_series, config)
201
+ logger.info(f"Added activity '{activity.name}' from Strava.")
198
202
  compute_tile_visits_new(repository, tile_visit_accessor)
199
203
  compute_tile_evolution(tile_visit_accessor.tile_state, config)
200
204
  tile_visit_accessor.save()
@@ -207,7 +207,7 @@ def make_activity_blueprint(
207
207
  @blueprint.route("/day/<int:year>/<int:month>/<int:day>")
208
208
  def day(year: int, month: int, day: int) -> ResponseReturnValue:
209
209
  meta = repository.meta
210
- selection = meta["start"].dt.date == datetime.date(year, month, day)
210
+ selection = meta["start_local"].dt.date == datetime.date(year, month, day)
211
211
  activities_that_day = meta.loc[selection]
212
212
 
213
213
  time_series = [
@@ -258,7 +258,7 @@ def make_activity_blueprint(
258
258
  @blueprint.route("/day-sharepic/<int:year>/<int:month>/<int:day>/sharepic.png")
259
259
  def day_sharepic(year: int, month: int, day: int) -> ResponseReturnValue:
260
260
  meta = repository.meta
261
- selection = meta["start"].dt.date == datetime.date(year, month, day)
261
+ selection = meta["start_local"].dt.date == datetime.date(year, month, day)
262
262
  activities_that_day = meta.loc[selection]
263
263
 
264
264
  time_series = [
@@ -583,7 +583,7 @@ def name_tick_plot(meta: pd.DataFrame) -> str:
583
583
  alt.Chart(meta, title="Repetitions")
584
584
  .mark_tick()
585
585
  .encode(
586
- alt.X("start", title="Date"),
586
+ alt.X("start_local", title="Date"),
587
587
  )
588
588
  .to_json(format="vega")
589
589
  )
@@ -693,8 +693,8 @@ def make_sharepic(
693
693
  facts = {
694
694
  "distance_km": f"\n{activity.distance_km:.1f} km",
695
695
  }
696
- if activity.start:
697
- facts["start"] = f"{activity.start.date()}"
696
+ if activity.start_local_tz:
697
+ facts["start"] = f"{activity.start_local_tz.date()}"
698
698
  if activity.elapsed_time:
699
699
  facts["elapsed_time"] = re.sub(r"^0 days ", "", f"{activity.elapsed_time}")
700
700
  if activity.kind:
@@ -744,7 +744,7 @@ def make_day_sharepic(
744
744
  [0, img.height - footer_height, img.width, img.height], fill=(0, 0, 0, 180)
745
745
  )
746
746
 
747
- date = activities.iloc[0]["start"].date()
747
+ date = activities.iloc[0]["start_local"].date()
748
748
  distance_km = activities["distance_km"].sum()
749
749
  elapsed_time: pd.Timedelta = activities["elapsed_time"].sum()
750
750
  elapsed_time = elapsed_time.round("s")
@@ -25,7 +25,7 @@ def make_bubble_chart_blueprint(repository) -> Blueprint:
25
25
  # Prepare the bubble chart data
26
26
  bubble_data = activities[
27
27
  [
28
- "start",
28
+ "start_local",
29
29
  "kind",
30
30
  "activity_id",
31
31
  column_distance.name,
@@ -33,7 +33,7 @@ def make_bubble_chart_blueprint(repository) -> Blueprint:
33
33
  ]
34
34
  ].rename(
35
35
  columns={
36
- "start": "date",
36
+ "start_local": "date",
37
37
  "kind": "activity",
38
38
  "activity_id": "id",
39
39
  }
@@ -55,7 +55,7 @@ def make_calendar_blueprint(repository: ActivityRepository) -> Blueprint:
55
55
 
56
56
  filtered = meta.loc[
57
57
  (meta["year"] == year) & (meta["month"] == month)
58
- ].sort_values("start")
58
+ ].sort_values("start_local")
59
59
 
60
60
  weeks = collections.defaultdict(dict)
61
61
  day_of_month = collections.defaultdict(dict)
@@ -67,7 +67,7 @@ def make_calendar_blueprint(repository: ActivityRepository) -> Blueprint:
67
67
  date += datetime.timedelta(days=1)
68
68
 
69
69
  for index, row in filtered.iterrows():
70
- iso = row["start"].isocalendar()
70
+ iso = row["start_local"].isocalendar()
71
71
  weeks[iso.week][iso.weekday].append(
72
72
  {
73
73
  "name": row["name"],
@@ -64,22 +64,19 @@ def _render_eddington_template(
64
64
 
65
65
  query = search_query_from_form(request.args)
66
66
  search_query_history.register_query(query)
67
- activities = apply_search_query(query).dropna(subset=["start", column_name]).copy()
67
+ activities = (
68
+ apply_search_query(query).dropna(subset=["start_local", column_name]).copy()
69
+ )
68
70
 
69
71
  assert (
70
72
  len(activities) > 0
71
73
  ), "The filter has selected zero elements, that cannot work here."
72
74
 
73
- activities["year"] = [start.year for start in activities["start"]]
74
- activities["date"] = [start.date() for start in activities["start"]]
75
- activities["isoyear"] = [start.isocalendar().year for start in activities["start"]]
76
- activities["isoweek"] = [start.isocalendar().week for start in activities["start"]]
77
-
78
75
  en_per_day, eddington_df_per_day = _get_values_per_group(
79
76
  activities.groupby("date"), column_name, divisor
80
77
  )
81
78
  en_per_week, eddington_df_per_week = _get_values_per_group(
82
- activities.groupby(["isoyear", "isoweek"]), column_name, divisor
79
+ activities.groupby(["iso_year", "week"]), column_name, divisor
83
80
  )
84
81
 
85
82
  return render_template(
@@ -207,9 +204,7 @@ def _get_eddington_number(elevation_gains: pd.Series, divisor: int) -> int:
207
204
  def _get_yearly_eddington(
208
205
  meta: pd.DataFrame, columnName: str, divisor: int
209
206
  ) -> dict[int, int]:
210
- meta = meta.dropna(subset=["start", columnName]).copy()
211
- meta["year"] = [start.year for start in meta["start"]]
212
- meta["date"] = [start.date() for start in meta["start"]]
207
+ meta = meta.dropna(subset=["start_local", columnName]).copy()
213
208
 
214
209
  yearly_eddington = meta.groupby("year").apply(
215
210
  lambda group: _get_eddington_number(
@@ -64,18 +64,18 @@ def _last_30_days_meta_plot(
64
64
  )
65
65
  return (
66
66
  alt.Chart(
67
- meta.loc[meta["start"] > before_30_days],
67
+ meta.loc[meta["start_local"] > before_30_days],
68
68
  width=700,
69
69
  height=200,
70
70
  title=f"{column.display_name} per day",
71
71
  )
72
72
  .mark_bar()
73
73
  .encode(
74
- alt.X("yearmonthdate(start)", title="Date"),
74
+ alt.X("yearmonthdate(start_local)", title="Date"),
75
75
  alt.Y(f"sum({column.name})", title=f"{column.name} / {column.unit}"),
76
76
  alt.Color("kind", scale=kind_scale, title="Kind"),
77
77
  [
78
- alt.Tooltip("yearmonthdate(start)", title="Date"),
78
+ alt.Tooltip("yearmonthdate(start_local)", title="Date"),
79
79
  alt.Tooltip("kind", title="Kind"),
80
80
  alt.Tooltip(
81
81
  f"sum({column.name})",
@@ -22,9 +22,9 @@ def make_equipment_blueprint(
22
22
  )
23
23
 
24
24
  # Prepare data for the stacked area chart
25
- activities = repository.meta.dropna(subset=["start"])
25
+ activities = repository.meta.dropna(subset=["start_local"])
26
26
  activities["month"] = (
27
- activities["start"].dt.to_period("M").apply(lambda r: r.start_time)
27
+ activities["start_local"].dt.to_period("M").apply(lambda r: r.start_time)
28
28
  )
29
29
  monthly_data = (
30
30
  activities.groupby(["month", "equipment"])
@@ -58,7 +58,7 @@ def make_equipment_blueprint(
58
58
  selection = repository.meta.loc[repository.meta["equipment"] == equipment]
59
59
  total_distances = pd.DataFrame(
60
60
  {
61
- "time": selection["start"],
61
+ "time": selection["start_local"],
62
62
  "total_distance_km": selection["distance_km"].cumsum(),
63
63
  }
64
64
  )
@@ -95,7 +95,7 @@ def make_equipment_blueprint(
95
95
  )
96
96
  .mark_bar()
97
97
  .encode(
98
- alt.X("year(start):O", title="Year"),
98
+ alt.X("year(start_local):O", title="Year"),
99
99
  alt.Y("sum(distance_km)", title="Distance / km"),
100
100
  alt.Color(
101
101
  "kind",
@@ -103,7 +103,7 @@ def make_equipment_blueprint(
103
103
  title="Kind",
104
104
  ),
105
105
  tooltip=[
106
- alt.Tooltip("year(start):O", title="Year"),
106
+ alt.Tooltip("year(start_local):O", title="Year"),
107
107
  alt.Tooltip(
108
108
  "sum(distance_km):Q", title="Distance / km", format=".0f"
109
109
  ),
@@ -173,7 +173,7 @@ def make_explorer_blueprint(
173
173
  return redirect(url_for(".map", zoom=zoom))
174
174
 
175
175
  @blueprint.route(
176
- "/<int:zoom>/<float:north>/<float:east>/<float:south>/<float:west>/missing.<suffix>"
176
+ "/<int:zoom>/<float(signed=True):north>/<float(signed=True):east>/<float(signed=True):south>/<float(signed=True):west>/missing.<suffix>"
177
177
  )
178
178
  def download_missing(
179
179
  zoom: int, north: float, east: float, south: float, west: float, suffix: str
@@ -198,7 +198,7 @@ def make_explorer_blueprint(
198
198
  )
199
199
 
200
200
  @blueprint.route(
201
- "/<int:zoom>/<float:north>/<float:east>/<float:south>/<float:west>/explored.<suffix>"
201
+ "/<int:zoom>/<float(signed=True):north>/<float(signed=True):east>/<float(signed=True):south>/<float(signed=True):west>/explored.<suffix>"
202
202
  )
203
203
  def download_explored(
204
204
  zoom: int, north: float, east: float, south: float, west: float, suffix: str
@@ -424,7 +424,9 @@ def make_explorer_blueprint(
424
424
  pl.imsave(f, result, format="png")
425
425
  return Response(bytes(f.getbuffer()), mimetype="image/png")
426
426
 
427
- @blueprint.route("/<int:zoom>/info/<float:latitude>/<float:longitude>")
427
+ @blueprint.route(
428
+ "/<int:zoom>/info/<float(signed=True):latitude>/<float(signed=True):longitude>"
429
+ )
428
430
  def info(zoom: int, latitude: float, longitude: float) -> dict:
429
431
  tile_visits = tile_visit_accessor.tile_state["tile_visits"][zoom]
430
432
  evolution_state = tile_visit_accessor.tile_state["evolution_state"][zoom]
@@ -42,7 +42,7 @@ def make_plot_builder_blueprint(
42
42
  spec = PlotSpec(
43
43
  name="My New Plot",
44
44
  mark="bar",
45
- x="year(start):O",
45
+ x="year(start_local):O",
46
46
  y="sum(distance_km)",
47
47
  color="kind",
48
48
  )
@@ -164,7 +164,7 @@ def heatmap_per_day(df: pd.DataFrame, column: ColumnDescription) -> str:
164
164
  def _filter_past_year(df: pd.DataFrame) -> pd.DataFrame:
165
165
  now = datetime.datetime.combine(datetime.date.today(), datetime.time.min)
166
166
  start = now - datetime.timedelta(days=365)
167
- return df.loc[df["start"] >= start]
167
+ return df.loc[df["start_local"] >= start]
168
168
 
169
169
 
170
170
  def make_summary_blueprint(
@@ -181,7 +181,7 @@ def make_summary_blueprint(
181
181
  df = apply_search_query(query)
182
182
 
183
183
  kind_scale = make_kind_scale(repository.meta, config)
184
- df_without_nan = df.loc[~pd.isna(df["start"])]
184
+ df_without_nan = df.loc[~pd.isna(df["start_local"])]
185
185
 
186
186
  return render_template(
187
187
  "summary/index.html.j2",
@@ -8,6 +8,7 @@ from flask import flash
8
8
  from flask import redirect
9
9
  from flask import render_template
10
10
  from flask import request
11
+ from flask import Response
11
12
  from flask import url_for
12
13
 
13
14
  from ...core.activities import ActivityRepository
@@ -59,8 +60,9 @@ def make_upload_blueprint(
59
60
  if file.filename == "":
60
61
  flash("No selected file", "warning")
61
62
  return redirect("/upload")
62
- if file:
63
+ for file in request.files.getlist("file"):
63
64
  filename = file.filename
65
+ assert filename is not None
64
66
  target_path = pathlib.Path(request.form["directory"]) / filename
65
67
  assert target_path.suffix in [
66
68
  ".csv",
@@ -79,18 +81,18 @@ def make_upload_blueprint(
79
81
  )
80
82
  return redirect(url_for(".index"))
81
83
  file.save(target_path)
82
- scan_for_activities(
83
- repository,
84
- tile_visit_accessor,
85
- config,
86
- skip_strava=True,
87
- )
88
- latest_activity = DB.session.scalar(
89
- sqlalchemy.select(Activity).order_by(Activity.id.desc()).limit(1)
90
- )
91
- assert latest_activity is not None
92
- flash(f"Activity was saved with ID {latest_activity.id}.", "success")
93
- return redirect(f"/activity/{latest_activity.id}")
84
+ scan_for_activities(
85
+ repository,
86
+ tile_visit_accessor,
87
+ config,
88
+ skip_strava=True,
89
+ )
90
+ latest_activity = DB.session.scalar(
91
+ sqlalchemy.select(Activity).order_by(Activity.id.desc()).limit(1)
92
+ )
93
+ assert latest_activity is not None
94
+ flash(f"Activity was saved with ID {latest_activity.id}.", "success")
95
+ return redirect(f"/activity/{latest_activity.id}")
94
96
 
95
97
  @blueprint.route("/refresh")
96
98
  @needs_authentication(authenticator)
@@ -50,7 +50,7 @@
50
50
  <td><span style="color: {{ activity['color'] }};">█</span> <a
51
51
  href="{{ url_for('activity.show', id=activity.id) }}">{{
52
52
  activity.name }}</a></td>
53
- <td>{{ activity.start|dt }}</td>
53
+ <td>{{ activity.start_local|dt }}</td>
54
54
  <td>{{ activity.distance_km | round(1) }}</td>
55
55
  <td>{{ activity.elapsed_time|td }}</td>
56
56
  <td>{{ activity.average_speed_moving_kmh|round(1) }}</td>
@@ -308,7 +308,7 @@
308
308
  <tbody>
309
309
  {% for other_activity in similar_activites %}
310
310
  <tr>
311
- <td><a href="{{ url_for('.show', id=other_activity.id) }}">{{ other_activity.start|dt
311
+ <td><a href="{{ url_for('.show', id=other_activity.id) }}">{{ other_activity.start_local|dt
312
312
  }}</a></td>
313
313
  <td>{{ other_activity.distance_km | round(1) }}</td>
314
314
  <td>{{ other_activity.elapsed_time|td }}</td>
@@ -25,8 +25,8 @@
25
25
  <tr>
26
26
  <td><a href="{{ url_for('activity.show', id=activity['id']) }}">{{ activity['name'] }}</a></td>
27
27
  <td>
28
- {% if activity['start'] is defined %}
29
- {{ activity['start']|dt }}
28
+ {% if activity['start_local'] is defined %}
29
+ {{ activity['start_local']|dt }} {{ activity.iana_timezone }}
30
30
  {% endif %}
31
31
  </td>
32
32
  <td>{{ '%.1f' % activity["distance_km"] }} km</td>
@@ -6,7 +6,7 @@
6
6
  <form method="post" enctype="multipart/form-data" action="{{ url_for('.receive') }}">
7
7
  <div class="mb-3">
8
8
  <label for="file1" class="form-label">Activity file</label>
9
- <input type="file" name="file" id="file1" class="form-control">
9
+ <input type="file" name="file" id="file1" class="form-control" multiple>
10
10
  </div>
11
11
  <div class="mb-3">
12
12
  <label for="directory" class="form-label">Target directory</label>
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "geo-activity-playground"
3
- version = "1.8.3"
3
+ version = "1.9.1"
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"