geo-activity-playground 0.27.1__py3-none-any.whl → 0.29.0__py3-none-any.whl

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 (40) hide show
  1. geo_activity_playground/__main__.py +1 -2
  2. geo_activity_playground/core/activities.py +3 -3
  3. geo_activity_playground/core/config.py +4 -0
  4. geo_activity_playground/core/paths.py +10 -0
  5. geo_activity_playground/core/tasks.py +7 -6
  6. geo_activity_playground/explorer/tile_visits.py +168 -133
  7. geo_activity_playground/webui/activity/controller.py +51 -14
  8. geo_activity_playground/webui/activity/templates/activity/show.html.j2 +37 -9
  9. geo_activity_playground/webui/app.py +20 -22
  10. geo_activity_playground/webui/auth/blueprint.py +27 -0
  11. geo_activity_playground/webui/auth/templates/auth/index.html.j2 +21 -0
  12. geo_activity_playground/webui/authenticator.py +46 -0
  13. geo_activity_playground/webui/entry_controller.py +8 -4
  14. geo_activity_playground/webui/equipment/controller.py +2 -1
  15. geo_activity_playground/webui/explorer/controller.py +4 -3
  16. geo_activity_playground/webui/explorer/templates/explorer/index.html.j2 +2 -0
  17. geo_activity_playground/webui/heatmap/heatmap_controller.py +20 -6
  18. geo_activity_playground/webui/plot_util.py +9 -0
  19. geo_activity_playground/webui/search/blueprint.py +20 -0
  20. geo_activity_playground/webui/settings/blueprint.py +101 -1
  21. geo_activity_playground/webui/settings/controller.py +43 -0
  22. geo_activity_playground/webui/settings/templates/settings/admin-password.html.j2 +19 -0
  23. geo_activity_playground/webui/settings/templates/settings/color-schemes.html.j2 +33 -0
  24. geo_activity_playground/webui/settings/templates/settings/index.html.j2 +27 -0
  25. geo_activity_playground/webui/settings/templates/settings/sharepic.html.j2 +22 -0
  26. geo_activity_playground/webui/square_planner/controller.py +1 -1
  27. geo_activity_playground/webui/summary/blueprint.py +3 -2
  28. geo_activity_playground/webui/summary/controller.py +20 -13
  29. geo_activity_playground/webui/templates/home.html.j2 +1 -1
  30. geo_activity_playground/webui/templates/page.html.j2 +57 -29
  31. geo_activity_playground/webui/upload/blueprint.py +7 -0
  32. geo_activity_playground/webui/upload/controller.py +4 -8
  33. geo_activity_playground/webui/upload/templates/upload/index.html.j2 +15 -31
  34. {geo_activity_playground-0.27.1.dist-info → geo_activity_playground-0.29.0.dist-info}/METADATA +3 -4
  35. {geo_activity_playground-0.27.1.dist-info → geo_activity_playground-0.29.0.dist-info}/RECORD +39 -32
  36. geo_activity_playground/webui/search_controller.py +0 -19
  37. /geo_activity_playground/webui/{templates/search.html.j2 → search/templates/search/index.html.j2} +0 -0
  38. {geo_activity_playground-0.27.1.dist-info → geo_activity_playground-0.29.0.dist-info}/LICENSE +0 -0
  39. {geo_activity_playground-0.27.1.dist-info → geo_activity_playground-0.29.0.dist-info}/WHEEL +0 -0
  40. {geo_activity_playground-0.27.1.dist-info → geo_activity_playground-0.29.0.dist-info}/entry_points.txt +0 -0
@@ -11,6 +11,24 @@
11
11
 
12
12
  <div class="row mb-3">
13
13
  <div class="row row-cols-1 row-cols-md-3 g-3">
14
+ <div class="col">
15
+ <div class="card">
16
+ <div class="card-body">
17
+ <h5 class="card-title">Admin password</h5>
18
+ <p class="card-text">Running a public instance and want to protect it?</p>
19
+ <a href="{{ url_for('.admin_password') }}" class="btn btn-primary">Set up admin password</a>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <div class="col">
24
+ <div class="card">
25
+ <div class="card-body">
26
+ <h5 class="card-title">Color schemes</h5>
27
+ <p class="card-text">Don't like the colors in the plots?</p>
28
+ <a href="{{ url_for('.color_schemes') }}" class="btn btn-primary">Set up color schemes</a>
29
+ </div>
30
+ </div>
31
+ </div>
14
32
  <div class="col">
15
33
  <div class="card">
16
34
  <div class="card-body">
@@ -60,6 +78,15 @@
60
78
  </div>
61
79
  </div>
62
80
  </div>
81
+ <div class="col">
82
+ <div class="card">
83
+ <div class="card-body">
84
+ <h5 class="card-title">Share picture</h5>
85
+ <p class="card-text">Select which metadata shall be displayed on share pictures.</p>
86
+ <a href="{{ url_for('.sharepic') }}" class="btn btn-primary">Set up share picture</a>
87
+ </div>
88
+ </div>
89
+ </div>
63
90
  <div class="col">
64
91
  <div class="card">
65
92
  <div class="card-body">
@@ -0,0 +1,22 @@
1
+ {% extends "page.html.j2" %}
2
+
3
+ {% block container %}
4
+
5
+ <h1 class="mb-3">Share Picture</h1>
6
+
7
+ <p>What data fields shall be displayed on the share picture?</p>
8
+
9
+ <form method="POST">
10
+ {% for name, label, checked in names %}
11
+ <div class="form-check form-check-inline form-switch">
12
+ <input class="form-check-input" type="checkbox" role="switch" id="{{ name }}" name="name" value="{{ name }}"
13
+ {{ 'checked' if checked else '' }} />
14
+ <label class="form-check-label" for="{{ name }}">{{ label }}</label>
15
+ </div>
16
+ {% endfor %}
17
+ <div class="clearfix mb-3"></div>
18
+ <button type="submit" class="btn btn-primary">Save</button>
19
+ </form>
20
+
21
+
22
+ {% endblock %}
@@ -18,7 +18,7 @@ class SquarePlannerController:
18
18
  self._repository = repository
19
19
  self._tile_visit_accessor = tile_visit_accessor
20
20
 
21
- self._tile_visits = self._tile_visit_accessor.visits
21
+ self._tile_visits = self._tile_visit_accessor.tile_state["tile_visits"]
22
22
 
23
23
  def action_planner(
24
24
  self, zoom: int, square_x: int, square_y: int, square_size: int
@@ -3,10 +3,11 @@ from flask import render_template
3
3
 
4
4
  from ...core.activities import ActivityRepository
5
5
  from .controller import SummaryController
6
+ from geo_activity_playground.core.config import Config
6
7
 
7
8
 
8
- def make_summary_blueprint(repository: ActivityRepository) -> Blueprint:
9
- summary_controller = SummaryController(repository)
9
+ def make_summary_blueprint(repository: ActivityRepository, config: Config) -> Blueprint:
10
+ summary_controller = SummaryController(repository, config)
10
11
  blueprint = Blueprint("summary", __name__, template_folder="templates")
11
12
 
12
13
  @blueprint.route("/")
@@ -8,14 +8,18 @@ import pandas as pd
8
8
 
9
9
  from geo_activity_playground.core.activities import ActivityRepository
10
10
  from geo_activity_playground.core.activities import make_geojson_from_time_series
11
+ from geo_activity_playground.core.config import Config
12
+ from geo_activity_playground.webui.plot_util import make_kind_scale
11
13
 
12
14
 
13
15
  class SummaryController:
14
- def __init__(self, repository: ActivityRepository) -> None:
16
+ def __init__(self, repository: ActivityRepository, config: Config) -> None:
15
17
  self._repository = repository
18
+ self._config = config
16
19
 
17
20
  @functools.cache
18
21
  def render(self) -> dict:
22
+ kind_scale = make_kind_scale(self._repository.meta, self._config)
19
23
  df = embellished_activities(self._repository.meta)
20
24
  df = df.loc[df["consider_for_achievements"]]
21
25
 
@@ -27,14 +31,14 @@ class SummaryController:
27
31
  )
28
32
 
29
33
  return {
30
- "plot_distance_heatmap": plot_distance_heatmap(df),
31
- "plot_monthly_distance": plot_monthly_distance(df),
32
- "plot_yearly_distance": plot_yearly_distance(year_kind_total),
34
+ "plot_distance_heatmap": plot_distance_heatmap(df, self._config),
35
+ "plot_monthly_distance": plot_monthly_distance(df, kind_scale),
36
+ "plot_yearly_distance": plot_yearly_distance(year_kind_total, kind_scale),
33
37
  "plot_year_cumulative": plot_year_cumulative(df),
34
38
  "tabulate_year_kind_mean": tabulate_year_kind_mean(df)
35
39
  .reset_index()
36
40
  .to_dict(orient="split"),
37
- "plot_weekly_distance": plot_weekly_distance(df),
41
+ "plot_weekly_distance": plot_weekly_distance(df, kind_scale),
38
42
  "nominations": [
39
43
  (
40
44
  self._repository.get_activity_by_id(activity_id),
@@ -108,7 +112,7 @@ def embellished_activities(meta: pd.DataFrame) -> pd.DataFrame:
108
112
  return df
109
113
 
110
114
 
111
- def plot_distance_heatmap(meta: pd.DataFrame) -> str:
115
+ def plot_distance_heatmap(meta: pd.DataFrame, config: Config) -> str:
112
116
  return (
113
117
  alt.Chart(
114
118
  meta.loc[
@@ -129,7 +133,10 @@ def plot_distance_heatmap(meta: pd.DataFrame) -> str:
129
133
  scale=alt.Scale(reverse=True),
130
134
  title="Year and month",
131
135
  ),
132
- alt.Color("sum(distance_km)", scale=alt.Scale(scheme="viridis")),
136
+ alt.Color(
137
+ "sum(distance_km)",
138
+ scale=alt.Scale(scheme=config.color_scheme_for_counts),
139
+ ),
133
140
  [
134
141
  alt.Tooltip("yearmonthdate(start)", title="Date"),
135
142
  alt.Tooltip(
@@ -142,7 +149,7 @@ def plot_distance_heatmap(meta: pd.DataFrame) -> str:
142
149
  )
143
150
 
144
151
 
145
- def plot_monthly_distance(meta: pd.DataFrame) -> str:
152
+ def plot_monthly_distance(meta: pd.DataFrame, kind_scale: alt.Scale) -> str:
146
153
  return (
147
154
  alt.Chart(
148
155
  meta.loc[
@@ -159,7 +166,7 @@ def plot_monthly_distance(meta: pd.DataFrame) -> str:
159
166
  .encode(
160
167
  alt.X("month(start)", title="Month"),
161
168
  alt.Y("sum(distance_km)", title="Distance / km"),
162
- alt.Color("kind", scale=alt.Scale(scheme="category10"), title="Kind"),
169
+ alt.Color("kind", scale=kind_scale, title="Kind"),
163
170
  alt.Column("year(start):O", title="Year"),
164
171
  )
165
172
  .resolve_axis(x="independent")
@@ -167,14 +174,14 @@ def plot_monthly_distance(meta: pd.DataFrame) -> str:
167
174
  )
168
175
 
169
176
 
170
- def plot_yearly_distance(year_kind_total: pd.DataFrame) -> str:
177
+ def plot_yearly_distance(year_kind_total: pd.DataFrame, kind_scale: alt.Scale) -> str:
171
178
  return (
172
179
  alt.Chart(year_kind_total, title="Total Distance per Year")
173
180
  .mark_bar()
174
181
  .encode(
175
182
  alt.X("year:O", title="Year"),
176
183
  alt.Y("distance_km", title="Distance / km"),
177
- alt.Color("kind", title="Kind"),
184
+ alt.Color("kind", scale=kind_scale, title="Kind"),
178
185
  [
179
186
  alt.Tooltip("year:O", title="Year"),
180
187
  alt.Tooltip("kind", title="Kind"),
@@ -231,7 +238,7 @@ def tabulate_year_kind_mean(df: pd.DataFrame) -> pd.DataFrame:
231
238
  return year_kind_mean_distance
232
239
 
233
240
 
234
- def plot_weekly_distance(df: pd.DataFrame) -> str:
241
+ def plot_weekly_distance(df: pd.DataFrame, kind_scale: alt.Scale) -> str:
235
242
  week_kind_total_distance = (
236
243
  df[["year", "week", "kind", "distance_km"]]
237
244
  .groupby(["year", "week", "kind"])
@@ -261,7 +268,7 @@ def plot_weekly_distance(df: pd.DataFrame) -> str:
261
268
  .encode(
262
269
  alt.X("year_week", title="Year and Week"),
263
270
  alt.Y("distance_km", title="Distance / km"),
264
- alt.Color("kind", title="Kind"),
271
+ alt.Color("kind", scale=kind_scale, title="Kind"),
265
272
  [
266
273
  alt.Tooltip("year_week", title="Year and Week"),
267
274
  alt.Tooltip("kind", title="Kind"),
@@ -12,7 +12,7 @@
12
12
  </div>
13
13
  <div class="col-md-3">
14
14
  <h2>Search activities</h2>
15
- <form method="post" action="/search">
15
+ <form method="post" action="{{ url_for('search.index') }}">
16
16
  <input type="search" name="name" />
17
17
  <input type="submit" class="button" />
18
18
  </form>
@@ -52,7 +52,7 @@
52
52
  <div class="container">
53
53
  <nav class="navbar navbar-expand-lg bg-body-secondary mb-3">
54
54
  <div class="container-fluid">
55
- <a class="navbar-brand" href="{{ url_for('index') }}">Geo Actvitity Playground</a>
55
+ <a class="navbar-brand" href="{{ url_for('index') }}">Geo Activity Playground</a>
56
56
  <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
57
57
  data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
58
58
  aria-expanded="false" aria-label="Toggle navigation">
@@ -62,42 +62,70 @@
62
62
  <ul class="navbar-nav me-auto mb-2 mb-lg-0">
63
63
 
64
64
  {% if num_activities > 0 %}
65
- <li class="nav-item">
66
- <a class="nav-link" aria-current="page" href="{{ url_for('summary.index') }}">Summary</a>
67
- </li>
68
- <li class="nav-item">
69
- <a class="nav-link" aria-current="page" href="{{ url_for('calendar.index') }}">Calendar</a>
65
+ <li class="nav-item dropdown">
66
+ <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
67
+ aria-expanded="false">
68
+ Activities
69
+ </a>
70
+ <ul class="dropdown-menu">
71
+ <li><a class="dropdown-item" href="{{ url_for('calendar.index') }}">Calendar</a></li>
72
+ {# <li><a class="dropdown-item" href="{{ url_for('search.index') }}">Search</a></li> #}
73
+ </ul>
70
74
  </li>
71
- <li class="nav-item">
72
- <a class="nav-link" aria-current="page"
73
- href="{{ url_for('explorer.map', zoom=14) }}">Explorer</a>
75
+
76
+ <li class="nav-item dropdown">
77
+ <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
78
+ aria-expanded="false">
79
+ Statistics
80
+ </a>
81
+ <ul class="dropdown-menu">
82
+ <li><a class="dropdown-item" href="{{ url_for('summary.index') }}">Summary
83
+ Statistics</a>
84
+ </li>
85
+ <li><a class="dropdown-item" href="{{ url_for('eddington.index') }}">Eddington
86
+ Number</a>
87
+ </li>
88
+ <li><a class="dropdown-item" href="{{ url_for('equipment.index') }}">Equipment</a></li>
89
+ </ul>
74
90
  </li>
75
- <li class="nav-item">
76
- <a class="nav-link" aria-current="page"
77
- href="{{ url_for('explorer.map', zoom=17) }}">Squadratinhos</a>
91
+
92
+ <li class="nav-item dropdown">
93
+ <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
94
+ aria-expanded="false">
95
+ Explorer
96
+ </a>
97
+ <ul class="dropdown-menu">
98
+ <li><a class="dropdown-item" href="{{ url_for('explorer.map', zoom=14) }}">Explorer
99
+ Tiles (Zoom 14)</a></li>
100
+ <li><a class="dropdown-item" href="{{ url_for('explorer.map', zoom=17) }}">Squadratinhos
101
+ (Zoom 17)</a></li>
102
+ </ul>
78
103
  </li>
104
+
79
105
  <li class="nav-item">
80
106
  <a class="nav-link" aria-current="page" href="{{ url_for('heatmap.index') }}">Heatmap</a>
81
107
  </li>
82
- <li class="nav-item">
83
- <a class="nav-link" aria-current="page"
84
- href="{{ url_for('eddington.index') }}">Eddington</a>
85
- </li>
86
- <li class="nav-item">
87
- <a class="nav-link" aria-current="page"
88
- href="{{ url_for('equipment.index') }}">Equipment</a>
89
- </li>
90
108
  {% endif %}
91
- <li class="nav-item">
92
- <a class="nav-link" aria-current="page" href="{{ url_for('upload.index') }}">Upload</a>
93
- </li>
94
- <li class="nav-item">
95
- <a class="nav-link" aria-current="page" href="{{ url_for('upload.reload') }}">Refresh</a>
96
- </li>
97
- <li class="nav-item">
98
- <a class="nav-link" aria-current="page" href="{{ url_for('settings.index') }}">Settings</a>
99
- </li>
100
109
 
110
+ <li class="nav-item dropdown">
111
+ <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
112
+ aria-expanded="false">
113
+ Admin
114
+ </a>
115
+ <ul class="dropdown-menu">
116
+ <li><a class="dropdown-item" href="{{ url_for('upload.index') }}">Upload Activities</a>
117
+ </li>
118
+ <li><a class="dropdown-item" href="{{ url_for('upload.reload') }}">Scan New
119
+ Activities</a>
120
+ </li>
121
+
122
+ <li>
123
+ <hr class="dropdown-divider">
124
+ </li>
125
+
126
+ <li><a class="dropdown-item" href="{{ url_for('settings.index') }}">Settings</a></li>
127
+ </ul>
128
+ </li>
101
129
 
102
130
  <li class="nav-item dropdown">
103
131
  <button
@@ -5,32 +5,39 @@ from ...core.activities import ActivityRepository
5
5
  from ...explorer.tile_visits import TileVisitAccessor
6
6
  from .controller import UploadController
7
7
  from geo_activity_playground.core.config import Config
8
+ from geo_activity_playground.webui.authenticator import Authenticator
9
+ from geo_activity_playground.webui.authenticator import needs_authentication
8
10
 
9
11
 
10
12
  def make_upload_blueprint(
11
13
  repository: ActivityRepository,
12
14
  tile_visit_accessor: TileVisitAccessor,
13
15
  config: Config,
16
+ authenticator: Authenticator,
14
17
  ) -> Blueprint:
15
18
  blueprint = Blueprint("upload", __name__, template_folder="templates")
16
19
 
17
20
  upload_controller = UploadController(repository, tile_visit_accessor, config)
18
21
 
19
22
  @blueprint.route("/")
23
+ @needs_authentication(authenticator)
20
24
  def index():
21
25
  return render_template(
22
26
  "upload/index.html.j2", **upload_controller.render_form()
23
27
  )
24
28
 
25
29
  @blueprint.route("/receive", methods=["POST"])
30
+ @needs_authentication(authenticator)
26
31
  def receive():
27
32
  return upload_controller.receive()
28
33
 
29
34
  @blueprint.route("/refresh")
35
+ @needs_authentication(authenticator)
30
36
  def reload():
31
37
  return render_template("upload/reload.html.j2")
32
38
 
33
39
  @blueprint.route("/execute-reload")
40
+ @needs_authentication(authenticator)
34
41
  def execute_reload():
35
42
  return upload_controller.execute_reload()
36
43
 
@@ -14,7 +14,7 @@ from geo_activity_playground.core.activities import build_activity_meta
14
14
  from geo_activity_playground.core.config import Config
15
15
  from geo_activity_playground.core.enrichment import enrich_activities
16
16
  from geo_activity_playground.explorer.tile_visits import compute_tile_evolution
17
- from geo_activity_playground.explorer.tile_visits import compute_tile_visits
17
+ from geo_activity_playground.explorer.tile_visits import compute_tile_visits_new
18
18
  from geo_activity_playground.explorer.tile_visits import TileVisitAccessor
19
19
  from geo_activity_playground.importers.directory import get_file_hash
20
20
  from geo_activity_playground.importers.directory import import_from_directory
@@ -45,7 +45,6 @@ class UploadController:
45
45
  directories.sort()
46
46
  return {
47
47
  "directories": directories,
48
- "has_upload": self._config.upload_password,
49
48
  }
50
49
 
51
50
  def receive(self) -> Response:
@@ -54,10 +53,6 @@ class UploadController:
54
53
  flash("No file could be found. Did you select a file?", "warning")
55
54
  return redirect("/upload")
56
55
 
57
- if request.form["password"] != self._config.upload_password:
58
- flash("Incorrect upload password!", "danger")
59
- return redirect("/upload")
60
-
61
56
  file = request.files["file"]
62
57
  # If the user does not select a file, the browser submits an
63
58
  # empty file without a filename.
@@ -120,5 +115,6 @@ def scan_for_activities(
120
115
  repository.reload()
121
116
 
122
117
  if len(repository) > 0:
123
- compute_tile_visits(repository, tile_visit_accessor)
124
- compute_tile_evolution(tile_visit_accessor, config)
118
+ compute_tile_visits_new(repository, tile_visit_accessor)
119
+ compute_tile_evolution(tile_visit_accessor.tile_state, config)
120
+ tile_visit_accessor.save()
@@ -1,37 +1,21 @@
1
1
  {% extends "page.html.j2" %}
2
2
 
3
3
  {% block container %}
4
- <div class="row mb-1">
5
- <div class="col">
6
- <h1>Upload Activity</h1>
4
+ <h1>Upload Activity</h1>
7
5
 
8
- {% if has_upload %}
9
- <form method="post" enctype="multipart/form-data" action="{{ url_for(".receive") }}">
10
- <div class="mb-3">
11
- <label for="file1" class="form-label">Activity file</label>
12
- <input type="file" name="file" id="file1" class="form-control">
13
- </div>
14
- <div class="mb-3">
15
- <label for="directory" class="form-label">Target directory</label>
16
- <select name="directory" id="directory" class="form-select" aria-label="Default select example">
17
- {% for directory in directories %}
18
- <option>{{ directory }}</option>
19
- {% endfor %}
20
- </select>
21
- </div>
22
- <div class="mb-3">
23
- <label for="password" class="form-label">Password</label>
24
- <input type="password" name="password" id="password" class="form-control">
25
- </div>
26
- <button type="submit" class="btn btn-primary">Upload</button>
27
- </form>
28
- {% else %}
29
- <p>You don't have an upload password set. In order to use this feature, add the following to your configuration
30
- file:</p>
31
- <code><pre>[upload]
32
- password = "your unique password here"</pre></code>
33
- {% endif %}
6
+ <form method="post" enctype="multipart/form-data" action="{{ url_for('.receive') }}">
7
+ <div class="mb-3">
8
+ <label for="file1" class="form-label">Activity file</label>
9
+ <input type="file" name="file" id="file1" class="form-control">
34
10
  </div>
35
- </div>
36
-
11
+ <div class="mb-3">
12
+ <label for="directory" class="form-label">Target directory</label>
13
+ <select name="directory" id="directory" class="form-select" aria-label="Default select example">
14
+ {% for directory in directories %}
15
+ <option>{{ directory }}</option>
16
+ {% endfor %}
17
+ </select>
18
+ </div>
19
+ <button type="submit" class="btn btn-primary">Upload</button>
20
+ </form>
37
21
  {% endblock %}
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geo-activity-playground
3
- Version: 0.27.1
3
+ Version: 0.29.0
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
7
7
  Author-email: mu@martin-ueding.de
8
- Requires-Python: >=3.9,<3.13
8
+ Requires-Python: >=3.10,<3.13
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.9
12
11
  Classifier: Programming Language :: Python :: 3.10
13
12
  Classifier: Programming Language :: Python :: 3.11
14
13
  Classifier: Programming Language :: Python :: 3.12
@@ -30,7 +29,7 @@ Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
30
29
  Requires-Dist: requests (>=2.28.1,<3.0.0)
31
30
  Requires-Dist: scipy (>=1.8.1,<2.0.0)
32
31
  Requires-Dist: shapely (>=2.0.5,<3.0.0)
33
- Requires-Dist: stravalib (>=1.3.3,<2.0.0)
32
+ Requires-Dist: stravalib (>=2.0,<3.0)
34
33
  Requires-Dist: tcxreader (>=0.4.5,<0.5.0)
35
34
  Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
36
35
  Requires-Dist: tqdm (>=4.64.0,<5.0.0)
@@ -1,23 +1,23 @@
1
1
  geo_activity_playground/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- geo_activity_playground/__main__.py,sha256=0feB3cw3-U9q0Dkrn5co76gTPpwGRWyfI5mfWNSZ_lU,4063
2
+ geo_activity_playground/__main__.py,sha256=MBZn9K1m3PofiPNTtpsSTVCyB_Gz95TjVP-nb9v_-JE,3989
3
3
  geo_activity_playground/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- geo_activity_playground/core/activities.py,sha256=Z81Itv3qrokxE1-YnPrDJ0QteyBZYjQYvTP-tHvR9j4,6606
5
- geo_activity_playground/core/config.py,sha256=Ogv_nPJD3ihlgBDZsCv5XsWAUXIKKhzWR6cu-KMNMWU,4414
4
+ geo_activity_playground/core/activities.py,sha256=yDjf3aVOC3LvnAwAvQUl_e7S3NXq_vKgccq0hGuFdLI,6609
5
+ geo_activity_playground/core/config.py,sha256=DsjZhiq2BZs94rjd7zgt_KTZIjVfxfntiEQZhgq8NeA,4617
6
6
  geo_activity_playground/core/coordinates.py,sha256=tDfr9mlXhK6E_MMIJ0vYWVCoH0Lq8uyuaqUgaa8i0jg,966
7
7
  geo_activity_playground/core/enrichment.py,sha256=CwZhW-svgPAYbdx3n9kvKlTgcsiCaeuJfSRCC4JxX6g,7411
8
8
  geo_activity_playground/core/heart_rate.py,sha256=IwMt58TpjOYqpAxtsj07zP2ttpN_J3GZeiv-qGhYyJc,1598
9
9
  geo_activity_playground/core/heatmap.py,sha256=bRLQHzmTEsQbX8XWeg85x_lRGk272UoYRiCnoxZ5da0,4189
10
- geo_activity_playground/core/paths.py,sha256=AiYUJv46my_FGYbHZmSs5ZrqeE65GNdWEMmXZgunZrk,2150
10
+ geo_activity_playground/core/paths.py,sha256=BZYuIg1LVHjuWLKB0Iz6Cevlq-XSalpCes_ClFuXa0s,2410
11
11
  geo_activity_playground/core/privacy_zones.py,sha256=4TumHsVUN1uW6RG3ArqTXDykPVipF98DCxVBe7YNdO8,512
12
12
  geo_activity_playground/core/similarity.py,sha256=Jo8jRViuORCxdIGvyaflgsQhwu9S_jn10a450FRL18A,3159
13
- geo_activity_playground/core/tasks.py,sha256=k_DHzY--V5EHqMh-aNFh-VsLiQntvAsGbmK5zZJ0YPI,2909
13
+ geo_activity_playground/core/tasks.py,sha256=aMDBWJqp6ek2ao6G6Xa8GOSZbcQqXoWL74SGRowRPIk,2942
14
14
  geo_activity_playground/core/test_tiles.py,sha256=zce1FxNfsSpOQt66jMehdQRVoNdl-oiFydx6iVBHZXM,764
15
15
  geo_activity_playground/core/test_time_conversion.py,sha256=Sh6nZA3uCTOdZTZa3yOijtR0m74QtZu2mcWXsDNnyQI,984
16
16
  geo_activity_playground/core/tiles.py,sha256=KpzD-h3kNzZ2ieLt6f2xHilSF3lHyfaEXPnrGvlIAz0,3379
17
17
  geo_activity_playground/core/time_conversion.py,sha256=9J6aTlqJhWvsknQkoECNL-CIG-8BKs6ZatJJ9XJnTsg,367
18
18
  geo_activity_playground/explorer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  geo_activity_playground/explorer/grid_file.py,sha256=k6j6KBEk2a2BY-onE8SV5TJsERGGyOrlY4as__meWpA,3304
20
- geo_activity_playground/explorer/tile_visits.py,sha256=p0MK0V4fHhroR-FN8S9m5nW0vT7uO39Euo-_mOw0Q8k,13586
20
+ geo_activity_playground/explorer/tile_visits.py,sha256=VaenegdPQ51vXxvn2oQXj8-3A7t8ihMhkgV8HpAqEuI,14133
21
21
  geo_activity_playground/explorer/video.py,sha256=ROAmV9shfJyqTgnXVD41KFORiwnRgVpEWenIq4hMCRM,4389
22
22
  geo_activity_playground/importers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  geo_activity_playground/importers/activity_parsers.py,sha256=m2SpvGlTZ8F3gG6YB24_ZFrlOAbtqbfWi-GIYspeUco,10593
@@ -31,12 +31,15 @@ geo_activity_playground/importers/test_strava_api.py,sha256=4vX7wDr1a9aRh8myxNrI
31
31
  geo_activity_playground/webui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  geo_activity_playground/webui/activity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  geo_activity_playground/webui/activity/blueprint.py,sha256=upQzZa5sKApj_Fmu6PziFDboi7SBL5Zsi-tNSSNPlEE,1759
34
- geo_activity_playground/webui/activity/controller.py,sha256=VJrbUD2oofESV2imNr7LBrx6jhSA8miuwnrERPsUuQc,17573
34
+ geo_activity_playground/webui/activity/controller.py,sha256=PJIZ7pFqpUyWDrintnnlW6Hxj7DbdPswARozws6TE30,18861
35
35
  geo_activity_playground/webui/activity/templates/activity/day.html.j2,sha256=r3qKl9uTzOko4R-ZzyYAZt1j61JSevYP4g0Yi06HHPg,2702
36
36
  geo_activity_playground/webui/activity/templates/activity/lines.html.j2,sha256=5gB1aDjRgi_RventenRfC10_FtMT4ch_VuWvA9AMlBY,1121
37
37
  geo_activity_playground/webui/activity/templates/activity/name.html.j2,sha256=RDLEt6ip8_ngmdLgaC5jg92Dk-F2umGwKkd8cWmvVko,2400
38
- geo_activity_playground/webui/activity/templates/activity/show.html.j2,sha256=3g-Hab06uWBPJo6DmTk4lM2OlozE1EyrQK6RgTgTuwU,5521
39
- geo_activity_playground/webui/app.py,sha256=xKPP0WDyHMAbkpJsuEz53skIjOMRBMvueD6LpRdYJE0,4119
38
+ geo_activity_playground/webui/activity/templates/activity/show.html.j2,sha256=W77M1S7RQOGY3Vg9LRT5mFnefuMWUKKU1Vd-ZKxUoKg,6552
39
+ geo_activity_playground/webui/app.py,sha256=foON49jw8klBJ3GF70DDjgz-_KRDPFvC31_mScaqDXk,4255
40
+ geo_activity_playground/webui/auth/blueprint.py,sha256=Lx-ZvMnfHLC1CMre1xPQI3k_pCtQoZvgRhtmafULzoE,812
41
+ geo_activity_playground/webui/auth/templates/auth/index.html.j2,sha256=ILQ5HvTEYc3OrtOAIFt1VrqWorVD70V9DC342znmP70,579
42
+ geo_activity_playground/webui/authenticator.py,sha256=k278OEVuOfAmTGT4F2X4pqSTwwkK_FA87EIhAeysEqc,1416
40
43
  geo_activity_playground/webui/calendar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
44
  geo_activity_playground/webui/calendar/blueprint.py,sha256=rlnhgU2DWAcdLMRq7m77NzrM_aDyp4s3kuuQHuzjHhg,782
42
45
  geo_activity_playground/webui/calendar/controller.py,sha256=QpSAkR2s1sbLSu6P_fNNTccgGglOzEH2PIv1XwKxeVY,2778
@@ -46,32 +49,37 @@ geo_activity_playground/webui/eddington/__init__.py,sha256=47DEQpj8HBSa-_TImW-5J
46
49
  geo_activity_playground/webui/eddington/blueprint.py,sha256=evIvueLfDWVTxJ9pRguqmZ9-Pybd2WmBRst_-7vX2QA,551
47
50
  geo_activity_playground/webui/eddington/controller.py,sha256=ly7JSkSS79kO4CL_xugB62uRuuWKVqOjbN-pheelv94,2910
48
51
  geo_activity_playground/webui/eddington/templates/eddington/index.html.j2,sha256=XHKeUymQMS5x00PLOVlg-nSRCz_jHB2pvD8QunULWJ4,1839
49
- geo_activity_playground/webui/entry_controller.py,sha256=n9v4MriyL8kDR91LE9eeqc2tAvxyzFgoNMMXpr0qh4g,1906
52
+ geo_activity_playground/webui/entry_controller.py,sha256=kTEToBtR1T4l30cV3HkCK3KO2hVYfb22BSgcWLdLEXQ,2164
50
53
  geo_activity_playground/webui/equipment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
54
  geo_activity_playground/webui/equipment/blueprint.py,sha256=_NIhRJuJNbXpEd_nEPo01AqnUqPgo1vawFn7E3yoeng,636
52
- geo_activity_playground/webui/equipment/controller.py,sha256=_iLkQeeu7UYMg7FGNemTrhm8e0pf409f9aUXnGfNsCI,4022
55
+ geo_activity_playground/webui/equipment/controller.py,sha256=Sx9i2RCK7m4W6FgpDfRMewcH64VBQfUhHJdTSCwMqOU,4079
53
56
  geo_activity_playground/webui/equipment/templates/equipment/index.html.j2,sha256=FEfxB4XwVYELAOdjVlSlprjJH_kLmE-pNWEEXdPqc6I,1778
54
57
  geo_activity_playground/webui/explorer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
58
  geo_activity_playground/webui/explorer/blueprint.py,sha256=EKnBs8llqT6Wy1uac18dF2epp3TebF9p3iGlSbj6Vl0,2337
56
- geo_activity_playground/webui/explorer/controller.py,sha256=M3FdPLrcP9GZiCjuRVY0ug1DtTqLvIbEDCzRHf6QuOE,11555
57
- geo_activity_playground/webui/explorer/templates/explorer/index.html.j2,sha256=cm9pWY0vB84DtkTH-LBvSzfLU1FnmxQ2ECyw3Bl7dTo,6945
59
+ geo_activity_playground/webui/explorer/controller.py,sha256=PAVyewO5ZY8BM1-EwtiqZuU-u63BJYuAKNNEDNutJkw,11669
60
+ geo_activity_playground/webui/explorer/templates/explorer/index.html.j2,sha256=u2htecx-XwINRiINHFN6EZDaRXVtiape1OCUZexTBU8,7049
58
61
  geo_activity_playground/webui/heatmap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
62
  geo_activity_playground/webui/heatmap/blueprint.py,sha256=bjQu-HL3QN5UpJ6tHOifhcLGlPr_hIKvaRu78md4JqM,1470
60
- geo_activity_playground/webui/heatmap/heatmap_controller.py,sha256=i376qEqTJrhezGsdPyKR8VsRY2N0JdEra7_kY7NmwW8,6822
63
+ geo_activity_playground/webui/heatmap/heatmap_controller.py,sha256=Q17Ay8hbU5ZlUiz2a9S-ULWrnNGWQHvTTV3kDY5FhNc,7411
61
64
  geo_activity_playground/webui/heatmap/templates/heatmap/index.html.j2,sha256=YLeu6P4djl8G4qAXR6DhetseqrbOodN7aN4coocknc4,1875
62
- geo_activity_playground/webui/search_controller.py,sha256=PzMf7b8tiJKZIZoPvQ9A2hOrzoKV9cS3jq05w2fK94c,532
63
- geo_activity_playground/webui/settings/blueprint.py,sha256=1u16oRlauOSPVBGBzjf08Ja9jxbqEKnwcDISWl7CmJU,4113
64
- geo_activity_playground/webui/settings/controller.py,sha256=ixuYgpMGggg9kmcIVTgL2gzAPhYjMpqWEPxS7YXlmnA,7902
65
+ geo_activity_playground/webui/plot_util.py,sha256=pTTQoqOCkLVjkgOit7mbry28kMruZIL8amZozSzEpxQ,283
66
+ geo_activity_playground/webui/search/blueprint.py,sha256=b3TCIplY60MWE2_VsKHuoV1LAgNwd_T5ft5t0CKALFI,642
67
+ geo_activity_playground/webui/search/templates/search/index.html.j2,sha256=FvNRoDfUlSzXjM_tqZY_fDhuhUDgbPaY73q56gdvF1A,1130
68
+ geo_activity_playground/webui/settings/blueprint.py,sha256=u5VGzVoRRA9Am5WqC1VGod4L-k839_9qVlecKO9sRUE,7593
69
+ geo_activity_playground/webui/settings/controller.py,sha256=v14oKvI1QzWn0g41Sm4NA_g9q4SUVZ_bO9SUOZuPAaY,9121
70
+ geo_activity_playground/webui/settings/templates/settings/admin-password.html.j2,sha256=VYwddpObD1RpeTH5Dm4y7VtmT7kwURDCIjxyzJeq08c,495
71
+ geo_activity_playground/webui/settings/templates/settings/color-schemes.html.j2,sha256=CaFbYkkU1yGTOlAzGq97u3tVgS79RIo7PEmiVjuZiBc,1226
65
72
  geo_activity_playground/webui/settings/templates/settings/equipment-offsets.html.j2,sha256=ltaYwFe8S8Mi72ddmIp1vwqlu8MEXXjBGfbpN2WBTC4,1728
66
73
  geo_activity_playground/webui/settings/templates/settings/heart-rate.html.j2,sha256=UPT3MegRgSeff36lhCo0l3ZwhqNSIg5gM6h2s32GkCY,4255
67
- geo_activity_playground/webui/settings/templates/settings/index.html.j2,sha256=26VEC_MbdIyd7vbFokDFtJelcuK3YFb1_3WaFLGv_bk,3183
74
+ geo_activity_playground/webui/settings/templates/settings/index.html.j2,sha256=-ZSlR6htaeMMOf4ISUSzWPu5BUhYODuAmcWPN0ZoBno,4443
68
75
  geo_activity_playground/webui/settings/templates/settings/kinds-without-achievements.html.j2,sha256=IdUfXon1Pu8zX3NirKb28ypshLHOvZRpz2T4bJrzrak,1067
69
76
  geo_activity_playground/webui/settings/templates/settings/metadata-extraction.html.j2,sha256=Ppa8O-zRJznbeCsF4YQj37_HM9nOW8fyTi66jvWvHmA,2285
70
77
  geo_activity_playground/webui/settings/templates/settings/privacy-zones.html.j2,sha256=7BxFvCaVJOEqbImyK5vxCmhh-NGSFaRa9ARhqjZeYJ0,3093
78
+ geo_activity_playground/webui/settings/templates/settings/sharepic.html.j2,sha256=qZkfEpd4CtKKMaSSVadqvNEgMRYLV-0X-pw5-nJvukk,678
71
79
  geo_activity_playground/webui/settings/templates/settings/strava.html.j2,sha256=FrXgT-m1PgvsQWo9kMKpk8QenKeifSDBCZFqKgsHRxQ,1827
72
80
  geo_activity_playground/webui/square_planner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
81
  geo_activity_playground/webui/square_planner/blueprint.py,sha256=r2VkSM547chX85g6c1BQ8NC-tkdqGdYp-2ZALBiiDTc,1320
74
- geo_activity_playground/webui/square_planner/controller.py,sha256=wYcNEviDgqyYxSrnwMD_5LnYXIazVH9plGX8RxG6oco,3464
82
+ geo_activity_playground/webui/square_planner/controller.py,sha256=vV7Wd4Kt1YPOI-UVoqLtIqUb3nke9PJQwWynlA31Lto,3483
75
83
  geo_activity_playground/webui/square_planner/templates/square_planner/index.html.j2,sha256=aIB0ql5qW4HXfp0ENksYYOk9vTgBitwyHJX5W7bqkeY,6512
76
84
  geo_activity_playground/webui/static/android-chrome-192x192.png,sha256=yxZgo8Jw4hrgOgrn3tvi9G0AXWGFD29kjCuxC07WoT4,17610
77
85
  geo_activity_playground/webui/static/android-chrome-384x384.png,sha256=bgeqAdyvDZBMch7rVi3qSawf0Zr4Go0EG8Ws_B8NApY,49297
@@ -86,22 +94,21 @@ geo_activity_playground/webui/static/mstile-150x150.png,sha256=j1ANUQJ1Xi1DR2sGq
86
94
  geo_activity_playground/webui/static/safari-pinned-tab.svg,sha256=OzoEVGY0igWRXM1NiM3SRKugdICBN7aB_XuxaC3Mu9Q,8371
87
95
  geo_activity_playground/webui/static/site.webmanifest,sha256=4vYxdPMpwTdB8EmOvHkkYcjZ8Yrci3pOwwY3o_VwACA,440
88
96
  geo_activity_playground/webui/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- geo_activity_playground/webui/summary/blueprint.py,sha256=kzQ6MDOycQKfDcVoEUmL7HYHJA_gu8DlzVHwO37-_jA,514
90
- geo_activity_playground/webui/summary/controller.py,sha256=ZOrwfrKjpc8hecUYImBvesKXZi06obfR1yhQkVTeWzw,8981
97
+ geo_activity_playground/webui/summary/blueprint.py,sha256=tfA2aPF19yKwkQOb5lPQBySoQYYhTn49Iuh0SYvsGP8,593
98
+ geo_activity_playground/webui/summary/controller.py,sha256=cWn5szA1o5Vjht0DyhRwBjmwqJryrLcmm4FUdmVpUoo,9443
91
99
  geo_activity_playground/webui/summary/templates/summary/index.html.j2,sha256=rsII1eMY-xNugh8A9SecnEcDZqkEOWYIfiHAGroQYuM,4442
92
- geo_activity_playground/webui/templates/home.html.j2,sha256=FjEwr9kt_3qu_evIHpa7F_oGAINN8W2Z1T_j56ugJ5c,2406
93
- geo_activity_playground/webui/templates/page.html.j2,sha256=sqerdJLOIcgMtQy533kHPD9uVIxF3v6ItLQSjuoCqlI,9589
94
- geo_activity_playground/webui/templates/search.html.j2,sha256=FvNRoDfUlSzXjM_tqZY_fDhuhUDgbPaY73q56gdvF1A,1130
100
+ geo_activity_playground/webui/templates/home.html.j2,sha256=eIPNyLHhUNVTITDbn6nR82-ZJA5Dp4SY41cZTjymZDU,2428
101
+ geo_activity_playground/webui/templates/page.html.j2,sha256=HN7s4i4kR3laMFkToktjwmTQiTHdrY3nqKcCVO9nKdA,11088
95
102
  geo_activity_playground/webui/tile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
103
  geo_activity_playground/webui/tile/blueprint.py,sha256=cK0o2Z3BrLycgF9zw0F8s9qF-JaYDbF5Gog-GXDtUZ8,943
97
104
  geo_activity_playground/webui/tile/controller.py,sha256=PISh4vKs27b-LxFfTARtr5RAwHFresA1Kw1MDcERSRU,1221
98
105
  geo_activity_playground/webui/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
- geo_activity_playground/webui/upload/blueprint.py,sha256=qU6ZKOrhB8DA8GSbOECVu2fPKd2VtBFp0mEFzjJAgIA,1083
100
- geo_activity_playground/webui/upload/controller.py,sha256=8Xv9JMeTyPe6mhYiDBW_nv9W_Hp7yz4Cgv_lXbM_JfY,4271
101
- geo_activity_playground/webui/upload/templates/upload/index.html.j2,sha256=hfXkEXaz_MkM46rU56423D6V6WtK-EAXPszSY-_-Tx8,1471
106
+ geo_activity_playground/webui/upload/blueprint.py,sha256=xX9scEmleN_dL03jfhWRh5yI1WsFyhxUFiS_Ul2HWy4,1428
107
+ geo_activity_playground/webui/upload/controller.py,sha256=disRtrlvPiqsIFt9UaAokgtRtXCvosg7bXkAnN_qaxk,4102
108
+ geo_activity_playground/webui/upload/templates/upload/index.html.j2,sha256=I1Ix8tDS3YBdi-HdaNfjkzYXVVCjfUTe5PFTnap1ydc,775
102
109
  geo_activity_playground/webui/upload/templates/upload/reload.html.j2,sha256=YZWX5eDeNyqKJdQAywDBcU8DZBm22rRBbZqFjrFrCvQ,556
103
- geo_activity_playground-0.27.1.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
104
- geo_activity_playground-0.27.1.dist-info/METADATA,sha256=Wm7WbQhD76zAw6Vf127jOm7ZeYPy0hllY9DZTKeh8oE,1665
105
- geo_activity_playground-0.27.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
106
- geo_activity_playground-0.27.1.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
107
- geo_activity_playground-0.27.1.dist-info/RECORD,,
110
+ geo_activity_playground-0.29.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
111
+ geo_activity_playground-0.29.0.dist-info/METADATA,sha256=692u7MhLYbWTJR5OSwKqyS8sZDG3oq3TNZQyPIsHVlk,1612
112
+ geo_activity_playground-0.29.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
113
+ geo_activity_playground-0.29.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
114
+ geo_activity_playground-0.29.0.dist-info/RECORD,,