geo-activity-playground 0.24.2__py3-none-any.whl → 0.26.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.
- geo_activity_playground/__main__.py +0 -2
- geo_activity_playground/core/activities.py +71 -149
- geo_activity_playground/core/enrichment.py +164 -0
- geo_activity_playground/core/paths.py +34 -15
- geo_activity_playground/core/tasks.py +27 -4
- geo_activity_playground/explorer/tile_visits.py +78 -42
- geo_activity_playground/{core → importers}/activity_parsers.py +7 -14
- geo_activity_playground/importers/directory.py +36 -27
- geo_activity_playground/importers/strava_api.py +45 -38
- geo_activity_playground/importers/strava_checkout.py +24 -16
- geo_activity_playground/webui/activity/controller.py +2 -2
- geo_activity_playground/webui/activity/templates/activity/show.html.j2 +2 -0
- geo_activity_playground/webui/app.py +11 -31
- geo_activity_playground/webui/entry_controller.py +5 -5
- geo_activity_playground/webui/heatmap/heatmap_controller.py +6 -0
- geo_activity_playground/webui/static/bootstrap-dark-mode.js +78 -0
- geo_activity_playground/webui/strava/__init__.py +0 -0
- geo_activity_playground/webui/strava/blueprint.py +33 -0
- geo_activity_playground/webui/strava/controller.py +49 -0
- geo_activity_playground/webui/strava/templates/strava/client-id.html.j2 +36 -0
- geo_activity_playground/webui/strava/templates/strava/connected.html.j2 +14 -0
- geo_activity_playground/webui/templates/home.html.j2 +5 -0
- geo_activity_playground/webui/templates/page.html.j2 +44 -12
- geo_activity_playground/webui/templates/settings.html.j2 +24 -0
- geo_activity_playground/webui/upload/controller.py +13 -17
- {geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/METADATA +1 -1
- {geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/RECORD +30 -25
- geo_activity_playground/core/cache_migrations.py +0 -133
- geo_activity_playground/webui/strava_controller.py +0 -27
- geo_activity_playground/webui/templates/strava-connect.html.j2 +0 -30
- {geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/LICENSE +0 -0
- {geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/WHEEL +0 -0
- {geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/entry_points.txt +0 -0
@@ -1,133 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import logging
|
3
|
-
import pathlib
|
4
|
-
import shutil
|
5
|
-
|
6
|
-
import pandas as pd
|
7
|
-
from tqdm import tqdm
|
8
|
-
|
9
|
-
from geo_activity_playground.core.paths import activities_path
|
10
|
-
from geo_activity_playground.core.paths import activity_timeseries_dir
|
11
|
-
from geo_activity_playground.core.tasks import work_tracker_path
|
12
|
-
|
13
|
-
logger = logging.getLogger(__name__)
|
14
|
-
|
15
|
-
|
16
|
-
def delete_activities_per_tile() -> None:
|
17
|
-
paths = [
|
18
|
-
pathlib.Path("Cache/activities-per-tile.pickle"),
|
19
|
-
pathlib.Path("Cache/activities-per-tile-task.json"),
|
20
|
-
]
|
21
|
-
for path in paths:
|
22
|
-
path.unlink(missing_ok=True)
|
23
|
-
|
24
|
-
|
25
|
-
def delete_work_tracker(name: str):
|
26
|
-
work_tracker_path(name).unlink(missing_ok=True)
|
27
|
-
|
28
|
-
|
29
|
-
def reset_time_series_embellishment() -> None:
|
30
|
-
pathlib.Path("Cache/work-tracker-embellish-time-series.pickle").unlink(
|
31
|
-
missing_ok=True
|
32
|
-
)
|
33
|
-
|
34
|
-
|
35
|
-
def delete_tile_visits() -> None:
|
36
|
-
paths = [
|
37
|
-
pathlib.Path("Cache/activities-per-tile.pickle"),
|
38
|
-
pathlib.Path("Cache/tile-evolution-state.pickle"),
|
39
|
-
pathlib.Path("Cache/tile-history.pickle"),
|
40
|
-
pathlib.Path("Cache/tile-visits.pickle"),
|
41
|
-
pathlib.Path("Cache/work-tracker-parse-activity-files.pickle"),
|
42
|
-
pathlib.Path("Cache/work-tracker-tile-visits.pickle"),
|
43
|
-
]
|
44
|
-
for path in paths:
|
45
|
-
path.unlink(missing_ok=True)
|
46
|
-
|
47
|
-
|
48
|
-
def delete_heatmap_cache() -> None:
|
49
|
-
path = pathlib.Path("Cache/Heatmap")
|
50
|
-
if path.exists():
|
51
|
-
shutil.rmtree(path)
|
52
|
-
|
53
|
-
|
54
|
-
def delete_activity_metadata() -> None:
|
55
|
-
delete_work_tracker("parse-activity-files")
|
56
|
-
activities_path().unlink(missing_ok=True)
|
57
|
-
|
58
|
-
|
59
|
-
def convert_distances_to_km() -> None:
|
60
|
-
if activities_path().exists():
|
61
|
-
activities = pd.read_parquet(activities_path())
|
62
|
-
if not "distance_km" in activities.columns:
|
63
|
-
activities["distance_km"] = activities["distance"] / 1000
|
64
|
-
for col in ["distance", "distance/km"]:
|
65
|
-
if col in activities.columns:
|
66
|
-
del activities[col]
|
67
|
-
activities.to_parquet(activities_path())
|
68
|
-
|
69
|
-
for time_series_path in tqdm(
|
70
|
-
list(activity_timeseries_dir().glob("*.parquet")),
|
71
|
-
desc="Convert m to km",
|
72
|
-
):
|
73
|
-
time_series = pd.read_parquet(time_series_path)
|
74
|
-
if "distance" in time_series.columns:
|
75
|
-
time_series["distance_km"] = time_series["distance"] / 1000
|
76
|
-
for col in ["distance", "distance/km"]:
|
77
|
-
if col in time_series.columns:
|
78
|
-
del time_series[col]
|
79
|
-
time_series.to_parquet(time_series_path)
|
80
|
-
|
81
|
-
|
82
|
-
def add_consider_for_achievements() -> None:
|
83
|
-
activities_path = pathlib.Path("Cache/activities.parquet")
|
84
|
-
if activities_path.exists():
|
85
|
-
df = pd.read_parquet(activities_path)
|
86
|
-
if "consider_for_achievements" not in df.columns:
|
87
|
-
df["consider_for_achievements"] = True
|
88
|
-
else:
|
89
|
-
df.loc[
|
90
|
-
df["consider_for_achievements"].isna(), "consider_for_achievements"
|
91
|
-
] = True
|
92
|
-
df.to_parquet("Cache/activities.parquet")
|
93
|
-
|
94
|
-
|
95
|
-
def delete_everything() -> None:
|
96
|
-
if pathlib.Path("Cache").exists():
|
97
|
-
shutil.rmtree("Cache")
|
98
|
-
|
99
|
-
|
100
|
-
def apply_cache_migrations() -> None:
|
101
|
-
logger.info("Apply cache migration if needed …")
|
102
|
-
cache_status_file = pathlib.Path("Cache/status.json")
|
103
|
-
if cache_status_file.exists():
|
104
|
-
with open(cache_status_file) as f:
|
105
|
-
cache_status = json.load(f)
|
106
|
-
else:
|
107
|
-
cache_status = {"num_applied_migrations": 0}
|
108
|
-
|
109
|
-
migrations = [
|
110
|
-
delete_activities_per_tile,
|
111
|
-
reset_time_series_embellishment,
|
112
|
-
delete_tile_visits,
|
113
|
-
delete_heatmap_cache,
|
114
|
-
delete_activity_metadata,
|
115
|
-
delete_activity_metadata,
|
116
|
-
convert_distances_to_km,
|
117
|
-
delete_activity_metadata,
|
118
|
-
delete_tile_visits,
|
119
|
-
delete_heatmap_cache,
|
120
|
-
add_consider_for_achievements,
|
121
|
-
delete_tile_visits,
|
122
|
-
delete_heatmap_cache,
|
123
|
-
delete_tile_visits,
|
124
|
-
delete_everything,
|
125
|
-
]
|
126
|
-
|
127
|
-
for migration in migrations[cache_status["num_applied_migrations"] :]:
|
128
|
-
logger.info(f"Applying cache migration {migration.__name__} …")
|
129
|
-
migration()
|
130
|
-
cache_status["num_applied_migrations"] += 1
|
131
|
-
cache_status_file.parent.mkdir(exist_ok=True, parents=True)
|
132
|
-
with open(cache_status_file, "w") as f:
|
133
|
-
json.dump(cache_status, f)
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import urllib.parse
|
2
|
-
from typing import Optional
|
3
|
-
|
4
|
-
|
5
|
-
class StravaController:
|
6
|
-
def __init__(self) -> None:
|
7
|
-
self._client_secret: Optional[str] = None
|
8
|
-
|
9
|
-
def action_connect(self) -> dict:
|
10
|
-
return {}
|
11
|
-
|
12
|
-
def action_authorize(
|
13
|
-
self, host: str, port: int, client_id: str, client_secret: str
|
14
|
-
) -> str:
|
15
|
-
self._client_secret = client_secret
|
16
|
-
|
17
|
-
payload = {
|
18
|
-
"client_id": client_id,
|
19
|
-
"redirect_uri": f"http://{host}:{port}/strava/callback",
|
20
|
-
"response_type": "code",
|
21
|
-
"scope": "activity:read_all",
|
22
|
-
}
|
23
|
-
|
24
|
-
arg_string = "&".join(
|
25
|
-
f"{key}={urllib.parse.quote(value)}" for key, value in payload.items()
|
26
|
-
)
|
27
|
-
return f"https://www.strava.com/oauth/authorize?{arg_string}"
|
@@ -1,30 +0,0 @@
|
|
1
|
-
{% extends "page.html.j2" %}
|
2
|
-
|
3
|
-
{% block container %}
|
4
|
-
|
5
|
-
<h1 class="mb-3">Strava Connect</h1>
|
6
|
-
|
7
|
-
<div class="row mb-3">
|
8
|
-
<div class="col-md-4">
|
9
|
-
<form action="/strava/authorize" method="POST">
|
10
|
-
<div class="mb-3">
|
11
|
-
<label for="client_id" class="form-label">Client ID</label>
|
12
|
-
<input type="text" class="form-control" id="client_id" name="client_id" placeholder="814722" />
|
13
|
-
</div>
|
14
|
-
<div class="mb-3">
|
15
|
-
<label for="client_secret" class="form-label">Client Secret</label>
|
16
|
-
<input type="text" class="form-control" id="client_secret" name="client_secret"
|
17
|
-
placeholder="ed9d766e135d95c79dbfca4379d09661a72ebdfd" />
|
18
|
-
</div>
|
19
|
-
|
20
|
-
|
21
|
-
<input type="hidden" name="redirect_uri" value="http://{{ host }}:{{ port }}/strava/callback" />
|
22
|
-
<input type="hidden" name="response_type" value="code" />
|
23
|
-
<input type="hidden" name="scope" value="activity:read_all" />
|
24
|
-
<input type="submit" value="Connect to Strava" />
|
25
|
-
</form>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
|
30
|
-
{% endblock %}
|
{geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/LICENSE
RENAMED
File without changes
|
File without changes
|
File without changes
|