geo-activity-playground 0.44.0__tar.gz → 1.0.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.
Files changed (164) hide show
  1. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/PKG-INFO +2 -1
  2. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/config.py +1 -0
  3. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/datamodel.py +6 -0
  4. geo_activity_playground-1.0.0/geo_activity_playground/core/export.py +129 -0
  5. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/meta_search.py +2 -2
  6. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/directory.py +3 -2
  7. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/strava_checkout.py +2 -1
  8. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/app.py +3 -1
  9. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/authenticator.py +4 -2
  10. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/auth_blueprint.py +3 -0
  11. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/eddington_blueprints.py +17 -8
  12. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/entry_views.py +5 -3
  13. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/equipment_blueprint.py +1 -1
  14. geo_activity_playground-1.0.0/geo_activity_playground/webui/blueprints/explorer_blueprint.py +534 -0
  15. geo_activity_playground-1.0.0/geo_activity_playground/webui/blueprints/export_blueprint.py +30 -0
  16. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/settings_blueprint.py +64 -1
  17. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/upload_blueprint.py +16 -3
  18. geo_activity_playground-1.0.0/geo_activity_playground/webui/static/server-side-explorer.js +55 -0
  19. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/auth/index.html.j2 +1 -0
  20. geo_activity_playground-1.0.0/geo_activity_playground/webui/templates/explorer/server-side.html.j2 +77 -0
  21. geo_activity_playground-1.0.0/geo_activity_playground/webui/templates/export/index.html.j2 +39 -0
  22. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/home.html.j2 +2 -0
  23. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/page.html.j2 +3 -6
  24. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/summary/index.html.j2 +2 -0
  25. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/pyproject.toml +2 -1
  26. geo_activity_playground-0.44.0/geo_activity_playground/webui/blueprints/explorer_blueprint.py +0 -422
  27. geo_activity_playground-0.44.0/geo_activity_playground/webui/templates/explorer/index.html.j2 +0 -148
  28. geo_activity_playground-0.44.0/geo_activity_playground/webui/templates/explorer/server-side.html.j2 +0 -72
  29. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/LICENSE +0 -0
  30. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/__init__.py +0 -0
  31. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/__main__.py +0 -0
  32. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/README +0 -0
  33. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/env.py +0 -0
  34. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/script.py.mako +0 -0
  35. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/0f02b92c4f94_add_tag_color.py +0 -0
  36. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/38882503dc7c_add_tags_to_activities.py +0 -0
  37. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/451e7836b53d_add_square_planner_bookmark.py +0 -0
  38. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/63d3b7f6f93c_initial_version.py +0 -0
  39. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/93cc82ad1b60_add_parametricplotspec.py +0 -0
  40. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/ab83b9d23127_add_upstream_id.py +0 -0
  41. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/b03491c593f6_add_crop_indices.py +0 -0
  42. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/da2cba03b71d_add_photos.py +0 -0
  43. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/e02e27876deb_add_square_planner_bookmark_name.py +0 -0
  44. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/alembic/versions/script.py.mako +0 -0
  45. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/__init__.py +0 -0
  46. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/activities.py +0 -0
  47. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/coordinates.py +0 -0
  48. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/enrichment.py +0 -0
  49. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/heart_rate.py +0 -0
  50. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/missing_values.py +0 -0
  51. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/parametric_plot.py +0 -0
  52. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/paths.py +0 -0
  53. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/privacy_zones.py +0 -0
  54. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/raster_map.py +0 -0
  55. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/similarity.py +0 -0
  56. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/summary_stats.py +0 -0
  57. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/tasks.py +0 -0
  58. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_datamodel.py +0 -0
  59. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_meta_search.py +0 -0
  60. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_missing_values.py +0 -0
  61. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_summary_stats.py +0 -0
  62. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_tiles.py +0 -0
  63. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/test_time_conversion.py +0 -0
  64. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/tiles.py +0 -0
  65. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/core/time_conversion.py +0 -0
  66. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/explorer/__init__.py +0 -0
  67. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/explorer/grid_file.py +0 -0
  68. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/explorer/tile_visits.py +0 -0
  69. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/explorer/video.py +0 -0
  70. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/heatmap_video.py +0 -0
  71. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/__init__.py +0 -0
  72. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/activity_parsers.py +0 -0
  73. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/csv_parser.py +0 -0
  74. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/strava_api.py +0 -0
  75. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/test_csv_parser.py +0 -0
  76. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/test_directory.py +0 -0
  77. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/importers/test_strava_api.py +0 -0
  78. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/__init__.py +0 -0
  79. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/__init__.py +0 -0
  80. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/activity_blueprint.py +0 -0
  81. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +0 -0
  82. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/calendar_blueprint.py +0 -0
  83. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/heatmap_blueprint.py +0 -0
  84. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/photo_blueprint.py +0 -0
  85. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/plot_builder_blueprint.py +0 -0
  86. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/search_blueprint.py +0 -0
  87. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/square_planner_blueprint.py +0 -0
  88. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/summary_blueprint.py +0 -0
  89. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/blueprints/tile_blueprint.py +0 -0
  90. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/columns.py +0 -0
  91. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/flasher.py +0 -0
  92. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/plot_util.py +0 -0
  93. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/search_util.py +0 -0
  94. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/Leaflet.fullscreen.min.js +0 -0
  95. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/MarkerCluster.Default.css +0 -0
  96. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/MarkerCluster.css +0 -0
  97. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/android-chrome-192x192.png +0 -0
  98. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/android-chrome-512x512.png +0 -0
  99. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/apple-touch-icon.png +0 -0
  100. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/bootstrap-dark-mode.js +0 -0
  101. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/bootstrap.bundle.min.js +0 -0
  102. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/bootstrap.min.css +0 -0
  103. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/browserconfig.xml +0 -0
  104. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/favicon-16x16.png +0 -0
  105. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/favicon-32x32.png +0 -0
  106. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/favicon-48x48.png +0 -0
  107. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/favicon.ico +0 -0
  108. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/favicon.svg +0 -0
  109. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/fullscreen.png +0 -0
  110. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/fullscreen@2x.png +0 -0
  111. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/images/layers-2x.png +0 -0
  112. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/images/layers.png +0 -0
  113. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/images/marker-icon-2x.png +0 -0
  114. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/images/marker-icon.png +0 -0
  115. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/images/marker-shadow.png +0 -0
  116. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/leaflet.css +0 -0
  117. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/leaflet.fullscreen.css +0 -0
  118. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/leaflet.js +0 -0
  119. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/leaflet.markercluster.js +0 -0
  120. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/mstile-150x150.png +0 -0
  121. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/site.webmanifest +0 -0
  122. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/table-sort.min.js +0 -0
  123. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/vega-embed@6 +0 -0
  124. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/vega-lite@4 +0 -0
  125. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/vega@5 +0 -0
  126. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/web-app-manifest-192x192.png +0 -0
  127. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/static/web-app-manifest-512x512.png +0 -0
  128. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/day.html.j2 +0 -0
  129. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/edit.html.j2 +0 -0
  130. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/lines.html.j2 +0 -0
  131. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/name.html.j2 +0 -0
  132. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/show.html.j2 +0 -0
  133. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/activity/trim.html.j2 +0 -0
  134. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +0 -0
  135. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/calendar/index.html.j2 +0 -0
  136. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/calendar/month.html.j2 +0 -0
  137. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/eddington/distance.html.j2 +0 -0
  138. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2 +0 -0
  139. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/elevation_eddington/index.html.j2 +0 -0
  140. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/equipment/index.html.j2 +0 -0
  141. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/heatmap/index.html.j2 +0 -0
  142. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/photo/map.html.j2 +0 -0
  143. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/photo/new.html.j2 +0 -0
  144. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/plot_builder/edit.html.j2 +0 -0
  145. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/plot_builder/index.html.j2 +0 -0
  146. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/search/index.html.j2 +0 -0
  147. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/search_form.html.j2 +0 -0
  148. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/admin-password.html.j2 +0 -0
  149. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/color-schemes.html.j2 +0 -0
  150. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/heart-rate.html.j2 +0 -0
  151. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/index.html.j2 +0 -0
  152. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/manage-equipments.html.j2 +0 -0
  153. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/manage-kinds.html.j2 +0 -0
  154. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/metadata-extraction.html.j2 +0 -0
  155. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/privacy-zones.html.j2 +0 -0
  156. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/segmentation.html.j2 +0 -0
  157. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/sharepic.html.j2 +0 -0
  158. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/strava.html.j2 +0 -0
  159. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/tags-edit.html.j2 +0 -0
  160. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/tags-list.html.j2 +0 -0
  161. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/settings/tags-new.html.j2 +0 -0
  162. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/square_planner/index.html.j2 +0 -0
  163. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.0}/geo_activity_playground/webui/templates/upload/index.html.j2 +0 -0
  164. {geo_activity_playground-0.44.0 → geo_activity_playground-1.0.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.44.0
3
+ Version: 1.0.0
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
@@ -28,6 +28,7 @@ Requires-Dist: gpxpy (>=1.5.0,<2.0.0)
28
28
  Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
29
29
  Requires-Dist: matplotlib (>=3.10.1,<4.0.0)
30
30
  Requires-Dist: numpy (>=2.2.3,<3.0.0)
31
+ Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
31
32
  Requires-Dist: pandas (>=2.2.3,<3.0.0)
32
33
  Requires-Dist: pyarrow (>=19.0.1,<20.0.0)
33
34
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
@@ -38,6 +38,7 @@ class Config:
38
38
  privacy_zones: dict[str, list[list[float]]] = dataclasses.field(
39
39
  default_factory=dict
40
40
  )
41
+ reliable_elevation_measurements: bool = True
41
42
  sharepic_suppressed_fields: list[str] = dataclasses.field(default_factory=list)
42
43
  strava_client_id: int = 131693
43
44
  strava_client_secret: str = "0ccc0100a2c218512a7ef0cea3b0e322fb4b4365"
@@ -29,6 +29,9 @@ from .paths import TIME_SERIES_DIR
29
29
  logger = logging.getLogger(__name__)
30
30
 
31
31
 
32
+ DEFAULT_UNKNOWN_NAME = "Unknown"
33
+
34
+
32
35
  class ActivityMeta(TypedDict):
33
36
  average_speed_elapsed_kmh: float
34
37
  average_speed_moving_kmh: float
@@ -226,6 +229,9 @@ def query_activity_meta(clauses: list = []) -> pd.DataFrame:
226
229
  .order_by(Activity.start)
227
230
  ).all()
228
231
  df = pd.DataFrame(rows)
232
+ # If the search yields only activities without time information, the dtype isn't derived correctly.
233
+ df["start"] = pd.to_datetime(df["start"])
234
+ df["elapsed_time"] = pd.to_timedelta(df["elapsed_time"])
229
235
 
230
236
  if len(df):
231
237
  for old, new in [
@@ -0,0 +1,129 @@
1
+ import io
2
+ import zipfile
3
+ from typing import IO
4
+
5
+ import geojson
6
+ import gpxpy.gpx
7
+ import pandas as pd
8
+ import sqlalchemy
9
+ from tqdm import tqdm
10
+
11
+ from .datamodel import Activity
12
+ from .datamodel import DB
13
+ from .datamodel import query_activity_meta
14
+
15
+
16
+ def export_all(meta_format: str, activity_format: str) -> bytes:
17
+ meta = query_activity_meta()
18
+ buffer = io.BytesIO()
19
+ with zipfile.ZipFile(buffer, "x") as zf:
20
+ with zf.open(f"activities.{meta_format}", mode="w") as f:
21
+ match meta_format:
22
+ case "csv":
23
+ export_meta_as_csv(meta, f)
24
+ case "json":
25
+ export_meta_as_json(meta, f)
26
+ case "ods":
27
+ export_meta_as_xlsx(meta, f)
28
+ case "parquet":
29
+ export_meta_as_parquet(meta, f)
30
+ case "xlsx":
31
+ export_meta_as_xlsx(meta, f)
32
+ case _:
33
+ raise ValueError(
34
+ f"Format {meta_format} is not supported for metadata."
35
+ )
36
+ if activity_format:
37
+ zf.mkdir("activities")
38
+ for activity in tqdm(
39
+ DB.session.scalars(sqlalchemy.select(Activity)).all(),
40
+ desc="Export activity time series",
41
+ ):
42
+ with zf.open(
43
+ f"activities/{activity.id}.{activity_format}", mode="w"
44
+ ) as f:
45
+ match activity_format:
46
+ case "csv":
47
+ export_activity_as_csv(activity, f)
48
+ case "geojson":
49
+ export_activity_as_geojson(activity, f)
50
+ case "gpx":
51
+ export_activity_as_gpx(activity, f)
52
+ case "ods":
53
+ export_activity_as_xlsx(activity, f)
54
+ case "parquet":
55
+ export_activity_as_parquet(activity, f)
56
+ case "xlsx":
57
+ export_activity_as_xlsx(activity, f)
58
+ case _:
59
+ raise ValueError(
60
+ f"Format {activity_format} is not supported for activity time series."
61
+ )
62
+ return bytes(buffer.getbuffer())
63
+
64
+
65
+ def export_meta_as_csv(meta: pd.DataFrame, target: IO[bytes]) -> None:
66
+ meta.to_csv(target, index=False)
67
+
68
+
69
+ def export_meta_as_json(meta: pd.DataFrame, target: IO[bytes]) -> None:
70
+ buffer = io.StringIO()
71
+ meta.to_json(buffer, index=False)
72
+ target.write(buffer.getvalue().encode())
73
+
74
+
75
+ def export_meta_as_parquet(meta: pd.DataFrame, target: IO[bytes]) -> None:
76
+ meta.to_parquet(target, index=False)
77
+
78
+
79
+ def export_meta_as_xlsx(meta: pd.DataFrame, target: IO[bytes]) -> None:
80
+ meta.to_excel(target, index=False)
81
+
82
+
83
+ def export_activity_as_csv(activity: Activity, target: IO[bytes]) -> None:
84
+ activity.time_series.to_csv(target, index=False)
85
+
86
+
87
+ def export_activity_as_geojson(activity: Activity, target: IO[bytes]) -> None:
88
+ ts = activity.time_series
89
+ result = geojson.MultiLineString(
90
+ coordinates=[
91
+ [(lon, lat) for lat, lon in zip(group["latitude"], group["longitude"])]
92
+ for segment_id, group in ts.groupby("segment_id")
93
+ ]
94
+ )
95
+ buffer = io.StringIO()
96
+ geojson.dump(result, buffer)
97
+ target.write(buffer.getvalue().encode())
98
+
99
+
100
+ def export_activity_as_gpx(activity: Activity, target: IO[bytes]) -> None:
101
+ g = gpxpy.gpx.GPX()
102
+
103
+ gpx_track = gpxpy.gpx.GPXTrack()
104
+ g.tracks.append(gpx_track)
105
+
106
+ ts = activity.time_series
107
+ for segment_id, group in ts.groupby("segment_id"):
108
+ gpx_segment = gpxpy.gpx.GPXTrackSegment()
109
+ gpx_track.segments.append(gpx_segment)
110
+
111
+ for index, row in group.iterrows():
112
+ gpx_segment.points.append(
113
+ gpxpy.gpx.GPXTrackPoint(
114
+ row["latitude"],
115
+ row["longitude"],
116
+ elevation=row.get("elevation", None),
117
+ time=row.get("time", None),
118
+ )
119
+ )
120
+
121
+ target.write(g.to_xml().encode())
122
+
123
+
124
+ def export_activity_as_parquet(activity: Activity, target: IO[bytes]) -> None:
125
+ activity.time_series.to_parquet(target, index=False)
126
+
127
+
128
+ def export_activity_as_xlsx(activity: Activity, target: IO[bytes]) -> None:
129
+ activity.time_series.to_excel(target, index=False)
@@ -120,7 +120,7 @@ class SearchQuery:
120
120
  variables.append(("distance_km_max", self.distance_km_max))
121
121
 
122
122
  return "&".join(
123
- f"{key}={urllib.parse.quote_plus(value)}" for key, value in variables
123
+ f"{key}={urllib.parse.quote_plus(str(value))}" for key, value in variables
124
124
  )
125
125
 
126
126
 
@@ -158,7 +158,7 @@ def apply_search_query(
158
158
  )
159
159
 
160
160
  if search_query.start_begin:
161
- filter_clauses.append(Activity.start <= search_query.start_begin)
161
+ filter_clauses.append(Activity.start >= search_query.start_begin)
162
162
  if search_query.start_end:
163
163
  filter_clauses.append(Activity.start < search_query.start_end)
164
164
 
@@ -10,6 +10,7 @@ from tqdm import tqdm
10
10
 
11
11
  from ..core.config import Config
12
12
  from ..core.datamodel import ActivityMeta
13
+ from ..core.datamodel import DEFAULT_UNKNOWN_NAME
13
14
  from ..core.paths import activity_extracted_dir
14
15
  from ..core.paths import activity_extracted_meta_dir
15
16
  from ..core.paths import activity_extracted_time_series_dir
@@ -84,8 +85,8 @@ def import_from_directory(
84
85
  # https://stackoverflow.com/a/74718395/653152
85
86
  name=path.name.removesuffix("".join(path.suffixes)),
86
87
  path=str(path),
87
- kind="Unknown",
88
- equipment="Unknown",
88
+ kind=DEFAULT_UNKNOWN_NAME,
89
+ equipment=DEFAULT_UNKNOWN_NAME,
89
90
  consider_for_achievements=True,
90
91
  )
91
92
  activity_meta.update(activity_meta_from_file)
@@ -13,6 +13,7 @@ import pandas as pd
13
13
  from tqdm import tqdm
14
14
 
15
15
  from ..core.datamodel import ActivityMeta
16
+ from ..core.datamodel import DEFAULT_UNKNOWN_NAME
16
17
  from ..core.paths import activity_extracted_meta_dir
17
18
  from ..core.paths import activity_extracted_time_series_dir
18
19
  from ..core.paths import strava_last_activity_date_path
@@ -277,7 +278,7 @@ def convert_strava_checkout(
277
278
  nan_as_none(row["Activity Gear"])
278
279
  or nan_as_none(row["Bike"])
279
280
  or nan_as_none(row["Gear"])
280
- or ""
281
+ or DEFAULT_UNKNOWN_NAME
281
282
  )
282
283
  activity_file = checkout_path / row["Filename"]
283
284
 
@@ -38,6 +38,7 @@ from .blueprints.eddington_blueprints import register_eddington_blueprint
38
38
  from .blueprints.entry_views import register_entry_views
39
39
  from .blueprints.equipment_blueprint import make_equipment_blueprint
40
40
  from .blueprints.explorer_blueprint import make_explorer_blueprint
41
+ from .blueprints.export_blueprint import make_export_blueprint
41
42
  from .blueprints.heatmap_blueprint import make_heatmap_blueprint
42
43
  from .blueprints.photo_blueprint import make_photo_blueprint
43
44
  from .blueprints.plot_builder_blueprint import make_plot_builder_blueprint
@@ -160,6 +161,7 @@ def web_ui_main(
160
161
  tile_getter,
161
162
  image_transforms,
162
163
  ),
164
+ "/export": make_export_blueprint(authenticator),
163
165
  "/heatmap": make_heatmap_blueprint(
164
166
  repository, tile_visit_accessor, config_accessor(), search_query_history
165
167
  ),
@@ -175,7 +177,7 @@ def web_ui_main(
175
177
  "/summary": make_summary_blueprint(repository, config, search_query_history),
176
178
  "/tile": make_tile_blueprint(image_transforms, tile_getter),
177
179
  "/upload": make_upload_blueprint(
178
- repository, tile_visit_accessor, config_accessor(), authenticator
180
+ repository, tile_visit_accessor, config_accessor(), authenticator, flasher
179
181
  ),
180
182
  }
181
183
 
@@ -3,8 +3,10 @@ from typing import Callable
3
3
 
4
4
  from flask import flash
5
5
  from flask import redirect
6
+ from flask import request
6
7
  from flask import session
7
8
  from flask import url_for
9
+ from flask.typing import RouteCallable
8
10
 
9
11
  from ..core.config import Config
10
12
 
@@ -32,14 +34,14 @@ class Authenticator:
32
34
 
33
35
 
34
36
  def needs_authentication(authenticator: Authenticator) -> Callable:
35
- def decorator(route: Callable) -> Callable:
37
+ def decorator(route: RouteCallable) -> RouteCallable:
36
38
  @functools.wraps(route)
37
39
  def wrapped_route(*args, **kwargs):
38
40
  if authenticator.is_authenticated():
39
41
  return route(*args, **kwargs)
40
42
  else:
41
43
  flash("You need to be logged in to view that site.", category="Warning")
42
- return redirect(url_for("auth.index"))
44
+ return redirect(url_for("auth.index", redirect=request.url))
43
45
 
44
46
  return wrapped_route
45
47
 
@@ -14,9 +14,12 @@ def make_auth_blueprint(authenticator: Authenticator) -> Blueprint:
14
14
  def index():
15
15
  if request.method == "POST":
16
16
  authenticator.authenticate(request.form["password"])
17
+ if redirect_to := request.form["redirect"]:
18
+ return redirect(redirect_to)
17
19
  return render_template(
18
20
  "auth/index.html.j2",
19
21
  is_authenticated=authenticator.is_authenticated(),
22
+ redirect=request.args.get("redirect", ""),
20
23
  )
21
24
 
22
25
  @blueprint.route("/logout")
@@ -26,7 +26,12 @@ def register_eddington_blueprint(
26
26
  @blueprint.route("/")
27
27
  def distance():
28
28
  return _render_eddington_template(
29
- repository, request, search_query_history, "distance", column_distance, [1]
29
+ repository,
30
+ request,
31
+ search_query_history,
32
+ "distance",
33
+ column_distance,
34
+ [1],
30
35
  )
31
36
 
32
37
  @blueprint.route("/elevation_gain")
@@ -64,6 +69,10 @@ def _render_eddington_template(
64
69
  .copy()
65
70
  )
66
71
 
72
+ assert (
73
+ len(activities) > 0
74
+ ), "The filter has selected zero elements, that cannot work here."
75
+
67
76
  activities["year"] = [start.year for start in activities["start"]]
68
77
  activities["date"] = [start.date() for start in activities["start"]]
69
78
  activities["isoyear"] = [start.isocalendar().year for start in activities["start"]]
@@ -111,24 +120,24 @@ def _render_eddington_template(
111
120
  )
112
121
 
113
122
 
114
- def _get_values_per_group(grouped, columnName, divisor) -> tuple[int, pd.DataFrame]:
123
+ def _get_values_per_group(grouped, column_name, divisor) -> tuple[int, pd.DataFrame]:
115
124
  sum_per_group = grouped.apply(
116
- lambda group: int(sum(group[columnName])), include_groups=False
125
+ lambda group: int(sum(group[column_name])), include_groups=False
117
126
  )
118
127
  counts = dict(zip(*np.unique(sorted(sum_per_group), return_counts=True)))
119
128
  eddington = pd.DataFrame(
120
- {columnName: d, "count": counts.get(d, 0)}
129
+ {column_name: d, "count": counts.get(d, 0)}
121
130
  for d in range(max(counts.keys()) + 1)
122
131
  )
123
132
  eddington["total"] = eddington["count"][::-1].cumsum()[::-1]
124
- eddington[f"{columnName}_div"] = eddington[columnName] // divisor
133
+ eddington[f"{column_name}_div"] = eddington[column_name] // divisor
125
134
  en = (
126
- eddington.loc[eddington["total"] >= eddington[f"{columnName}_div"]][
127
- "total"
135
+ eddington.loc[eddington["total"] >= eddington[f"{column_name}_div"]][
136
+ f"{column_name}_div"
128
137
  ].iloc[-1]
129
138
  * divisor
130
139
  )
131
- eddington["missing"] = eddington[f"{columnName}_div"] - eddington["total"]
140
+ eddington["missing"] = eddington[f"{column_name}_div"] - eddington["total"]
132
141
 
133
142
  return en, eddington
134
143
 
@@ -31,9 +31,11 @@ def register_entry_views(
31
31
  context["distance_last_30_days_plot"] = _last_30_days_meta_plot(
32
32
  repository.meta, kind_scale, column_distance
33
33
  )
34
- context["elevation_gain_last_30_days_plot"] = _last_30_days_meta_plot(
35
- repository.meta, kind_scale, column_elevation_gain
36
- )
34
+
35
+ if config.reliable_elevation_measurements:
36
+ context["elevation_gain_last_30_days_plot"] = _last_30_days_meta_plot(
37
+ repository.meta, kind_scale, column_elevation_gain
38
+ )
37
39
 
38
40
  context["latest_activities"] = collections.defaultdict(list)
39
41
  for activity in DB.session.scalars(
@@ -21,7 +21,7 @@ def make_equipment_blueprint(
21
21
  )
22
22
 
23
23
  # Prepare data for the stacked area chart
24
- activities = repository.meta
24
+ activities = repository.meta.dropna(subset=["start"])
25
25
  activities["month"] = (
26
26
  activities["start"].dt.to_period("M").apply(lambda r: r.start_time)
27
27
  )