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
@@ -18,11 +18,12 @@ from .explorer.blueprint import make_explorer_blueprint
|
|
18
18
|
from .heatmap.blueprint import make_heatmap_blueprint
|
19
19
|
from .search_controller import SearchController
|
20
20
|
from .square_planner.blueprint import make_square_planner_blueprint
|
21
|
-
from .
|
21
|
+
from .strava.blueprint import make_strava_blueprint
|
22
22
|
from .summary.blueprint import make_summary_blueprint
|
23
23
|
from .tile.blueprint import make_tile_blueprint
|
24
24
|
from .upload.blueprint import make_upload_blueprint
|
25
25
|
from geo_activity_playground.core.privacy_zones import PrivacyZone
|
26
|
+
from geo_activity_playground.webui.strava.controller import StravaController
|
26
27
|
|
27
28
|
|
28
29
|
def route_search(app: Flask, repository: ActivityRepository) -> None:
|
@@ -45,35 +46,10 @@ def route_start(app: Flask, repository: ActivityRepository) -> None:
|
|
45
46
|
return render_template("home.html.j2", **entry_controller.render())
|
46
47
|
|
47
48
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
def strava_connect():
|
53
|
-
return render_template(
|
54
|
-
"strava-connect.html.j2",
|
55
|
-
host=host,
|
56
|
-
port=port,
|
57
|
-
**strava_controller.action_connect()
|
58
|
-
)
|
59
|
-
|
60
|
-
@app.route("/strava/authorize")
|
61
|
-
def strava_authorize():
|
62
|
-
client_id = request.form["client_id"]
|
63
|
-
client_secret = request.form["client_secret"]
|
64
|
-
return redirect(
|
65
|
-
strava_controller.action_authorize(host, port, client_id, client_secret)
|
66
|
-
)
|
67
|
-
|
68
|
-
@app.route("/strava/callback")
|
69
|
-
def strava_callback():
|
70
|
-
code = request.args.get("code", type=str)
|
71
|
-
return render_template(
|
72
|
-
"strava-connect.html.j2",
|
73
|
-
host=host,
|
74
|
-
port=port,
|
75
|
-
**strava_controller.action_connect()
|
76
|
-
)
|
49
|
+
def route_settings(app: Flask) -> None:
|
50
|
+
@app.route("/settings")
|
51
|
+
def settings():
|
52
|
+
return render_template("settings.html.j2")
|
77
53
|
|
78
54
|
|
79
55
|
def get_secret_key():
|
@@ -99,7 +75,7 @@ def webui_main(
|
|
99
75
|
|
100
76
|
route_search(app, repository)
|
101
77
|
route_start(app, repository)
|
102
|
-
|
78
|
+
route_settings(app)
|
103
79
|
|
104
80
|
app.config["UPLOAD_FOLDER"] = "Activities"
|
105
81
|
app.secret_key = get_secret_key()
|
@@ -136,6 +112,10 @@ def webui_main(
|
|
136
112
|
make_summary_blueprint(repository),
|
137
113
|
url_prefix="/summary",
|
138
114
|
)
|
115
|
+
app.register_blueprint(
|
116
|
+
make_strava_blueprint(host, port),
|
117
|
+
url_prefix="/strava",
|
118
|
+
)
|
139
119
|
app.register_blueprint(make_tile_blueprint(), url_prefix="/tile")
|
140
120
|
app.register_blueprint(
|
141
121
|
make_upload_blueprint(repository, tile_visit_accessor, config),
|
@@ -13,12 +13,12 @@ class EntryController:
|
|
13
13
|
self._repository = repository
|
14
14
|
|
15
15
|
def render(self) -> dict:
|
16
|
-
result = {
|
17
|
-
|
16
|
+
result = {"latest_activities": []}
|
17
|
+
|
18
|
+
if len(self._repository):
|
19
|
+
result["distance_last_30_days_plot"] = distance_last_30_days_meta_plot(
|
18
20
|
self._repository.meta
|
19
|
-
)
|
20
|
-
"latest_activities": [],
|
21
|
-
}
|
21
|
+
)
|
22
22
|
|
23
23
|
for activity in itertools.islice(
|
24
24
|
self._repository.iter_activities(dropna=True), 15
|
@@ -83,6 +83,12 @@ class HeatmapController:
|
|
83
83
|
with work_tracker(
|
84
84
|
tile_count_cache_path.with_suffix(".json")
|
85
85
|
) as parsed_activities:
|
86
|
+
if parsed_activities - activity_ids:
|
87
|
+
logger.warning(
|
88
|
+
f"Resetting heatmap cache for {kind=}/{x=}/{y=}/{z=} because activities have been removed."
|
89
|
+
)
|
90
|
+
tile_counts = np.zeros(tile_pixels, dtype=np.int32)
|
91
|
+
parsed_activities.clear()
|
86
92
|
for activity_id in activity_ids:
|
87
93
|
if activity_id in parsed_activities:
|
88
94
|
continue
|
@@ -0,0 +1,78 @@
|
|
1
|
+
/*!
|
2
|
+
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
|
3
|
+
* Copyright 2011-2024 The Bootstrap Authors
|
4
|
+
* Licensed under the Creative Commons Attribution 3.0 Unported License.
|
5
|
+
*/
|
6
|
+
|
7
|
+
(() => {
|
8
|
+
'use strict'
|
9
|
+
|
10
|
+
const getStoredTheme = () => localStorage.getItem('theme')
|
11
|
+
const setStoredTheme = theme => localStorage.setItem('theme', theme)
|
12
|
+
|
13
|
+
const getPreferredTheme = () => {
|
14
|
+
const storedTheme = getStoredTheme()
|
15
|
+
if (storedTheme) {
|
16
|
+
return storedTheme
|
17
|
+
}
|
18
|
+
|
19
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
20
|
+
}
|
21
|
+
|
22
|
+
const setTheme = theme => {
|
23
|
+
if (theme === 'auto') {
|
24
|
+
document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
|
25
|
+
} else {
|
26
|
+
document.documentElement.setAttribute('data-bs-theme', theme)
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
setTheme(getPreferredTheme())
|
31
|
+
|
32
|
+
const showActiveTheme = (theme, focus = false) => {
|
33
|
+
const themeSwitcher = document.querySelector('#bd-theme')
|
34
|
+
|
35
|
+
if (!themeSwitcher) {
|
36
|
+
return
|
37
|
+
}
|
38
|
+
|
39
|
+
const themeSwitcherText = document.querySelector('#bd-theme-text')
|
40
|
+
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
|
41
|
+
|
42
|
+
document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
|
43
|
+
element.classList.remove('active')
|
44
|
+
element.setAttribute('aria-pressed', 'false')
|
45
|
+
})
|
46
|
+
|
47
|
+
btnToActive.classList.add('active')
|
48
|
+
btnToActive.setAttribute('aria-pressed', 'true')
|
49
|
+
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
|
50
|
+
themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
|
51
|
+
|
52
|
+
if (focus) {
|
53
|
+
themeSwitcher.focus()
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
58
|
+
const storedTheme = getStoredTheme()
|
59
|
+
if (storedTheme !== 'light' && storedTheme !== 'dark') {
|
60
|
+
setTheme(getPreferredTheme())
|
61
|
+
}
|
62
|
+
})
|
63
|
+
|
64
|
+
window.addEventListener('DOMContentLoaded', () => {
|
65
|
+
showActiveTheme(getPreferredTheme())
|
66
|
+
|
67
|
+
document.querySelectorAll('[data-bs-theme-value]')
|
68
|
+
.forEach(toggle => {
|
69
|
+
toggle.addEventListener('click', () => {
|
70
|
+
const theme = toggle.getAttribute('data-bs-theme-value')
|
71
|
+
setStoredTheme(theme)
|
72
|
+
setTheme(theme)
|
73
|
+
showActiveTheme(theme, true)
|
74
|
+
})
|
75
|
+
})
|
76
|
+
})
|
77
|
+
})()
|
78
|
+
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from flask import Blueprint
|
2
|
+
from flask import redirect
|
3
|
+
from flask import render_template
|
4
|
+
from flask import request
|
5
|
+
|
6
|
+
from .controller import StravaController
|
7
|
+
|
8
|
+
|
9
|
+
def make_strava_blueprint(host: str, port: int) -> Blueprint:
|
10
|
+
strava_controller = StravaController(host, port)
|
11
|
+
blueprint = Blueprint("strava", __name__, template_folder="templates")
|
12
|
+
|
13
|
+
@blueprint.route("/setup")
|
14
|
+
def setup():
|
15
|
+
return render_template(
|
16
|
+
"strava/client-id.html.j2", **strava_controller.set_client_id()
|
17
|
+
)
|
18
|
+
|
19
|
+
@blueprint.route("/post-client-id", methods=["POST"])
|
20
|
+
def post_client_id():
|
21
|
+
client_id = request.form["client_id"]
|
22
|
+
client_secret = request.form["client_secret"]
|
23
|
+
url = strava_controller.save_client_id(client_id, client_secret)
|
24
|
+
return redirect(url)
|
25
|
+
|
26
|
+
@blueprint.route("/callback")
|
27
|
+
def strava_callback():
|
28
|
+
code = request.args.get("code", type=str)
|
29
|
+
return render_template(
|
30
|
+
"strava/connected.html.j2", **strava_controller.save_code(code)
|
31
|
+
)
|
32
|
+
|
33
|
+
return blueprint
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import json
|
2
|
+
import urllib.parse
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from geo_activity_playground.core.paths import strava_dynamic_config_path
|
6
|
+
|
7
|
+
|
8
|
+
class StravaController:
|
9
|
+
def __init__(self, host: str, port: int) -> None:
|
10
|
+
self._host = host
|
11
|
+
self._port = port
|
12
|
+
|
13
|
+
self._client_secret: Optional[str] = None
|
14
|
+
|
15
|
+
def set_client_id(self) -> dict:
|
16
|
+
return {"host": self._host, "port": self._port}
|
17
|
+
|
18
|
+
def save_client_id(self, client_id: str, client_secret: str) -> str:
|
19
|
+
self._client_id = client_id
|
20
|
+
self._client_secret = client_secret
|
21
|
+
|
22
|
+
payload = {
|
23
|
+
"client_id": client_id,
|
24
|
+
"redirect_uri": f"http://{self._host}:{self._port}/strava/callback",
|
25
|
+
"response_type": "code",
|
26
|
+
"scope": "activity:read_all",
|
27
|
+
}
|
28
|
+
|
29
|
+
arg_string = "&".join(
|
30
|
+
f"{key}={urllib.parse.quote(value)}" for key, value in payload.items()
|
31
|
+
)
|
32
|
+
return f"https://www.strava.com/oauth/authorize?{arg_string}"
|
33
|
+
|
34
|
+
def save_code(self, code: str) -> dict:
|
35
|
+
self._code = code
|
36
|
+
|
37
|
+
with open(strava_dynamic_config_path(), "w") as f:
|
38
|
+
json.dump(
|
39
|
+
{
|
40
|
+
"client_id": self._client_id,
|
41
|
+
"client_secret": self._client_secret,
|
42
|
+
"code": self._code,
|
43
|
+
},
|
44
|
+
f,
|
45
|
+
indent=2,
|
46
|
+
sort_keys=True,
|
47
|
+
)
|
48
|
+
|
49
|
+
return {}
|
@@ -0,0 +1,36 @@
|
|
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-6">
|
9
|
+
<p>You can connect to Strava such that it automatically downloads your activities.</p>
|
10
|
+
|
11
|
+
<p>The Strava API has rather strict rate limiting. If you don't mind waiting a bit, you can just use the "client
|
12
|
+
ID" and "client secret" that are provided to use a pre-defined Strava app. In that case, just click on the
|
13
|
+
button. If you don't want to share the API limits with other people, go the <a
|
14
|
+
href="https://www.strava.com/settings/api">Strava API page</a> and create your own app. Then fill in
|
15
|
+
"client ID" and "client secret" in the form.</p>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="col-md-6">
|
19
|
+
<form action="/strava/post-client-id" method="POST">
|
20
|
+
<div class="mb-3">
|
21
|
+
<label for="client_id" class="form-label">Client ID</label>
|
22
|
+
<input type="text" class="form-control" id="client_id" name="client_id" value="131693" />
|
23
|
+
</div>
|
24
|
+
<div class="mb-3">
|
25
|
+
<label for="client_secret" class="form-label">Client Secret</label>
|
26
|
+
<input type="text" class="form-control" id="client_secret" name="client_secret"
|
27
|
+
value="0ccc0100a2c218512a7ef0cea3b0e322fb4b4365" />
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<input type="submit" value="Connect to Strava" />
|
31
|
+
</form>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
|
36
|
+
{% endblock %}
|
@@ -0,0 +1,14 @@
|
|
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">
|
9
|
+
<p>You're now connected to Strava. Please restart the webserver to start loading actvities.</p>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
|
14
|
+
{% endblock %}
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<div class="row mb-3">
|
5
5
|
</div>
|
6
6
|
|
7
|
+
{% if latest_activities %}
|
7
8
|
<div class="row mb-3">
|
8
9
|
<div class="col-md-9">
|
9
10
|
<h2>Last 30 days</h2>
|
@@ -63,5 +64,9 @@
|
|
63
64
|
{% endfor %}
|
64
65
|
</div>
|
65
66
|
{% endfor %}
|
67
|
+
{% else %}
|
68
|
+
<p>You don't have activities yet. Either put some files into a directory <tt>Activities</tt> or <a
|
69
|
+
href="{{ url_for('strava.setup') }}">set up Strava API</a>.</p>
|
70
|
+
{% endif %}
|
66
71
|
|
67
72
|
{% endblock %}
|
@@ -33,6 +33,9 @@
|
|
33
33
|
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
|
34
34
|
|
35
35
|
|
36
|
+
<script src="/static/bootstrap-dark-mode.js"></script>
|
37
|
+
|
38
|
+
|
36
39
|
<!-- Favicon. -->
|
37
40
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
38
41
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
@@ -59,36 +62,65 @@
|
|
59
62
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
60
63
|
|
61
64
|
<li class="nav-item">
|
62
|
-
<a class="nav-link
|
63
|
-
href="{{ url_for('summary.index') }}">Summary</a>
|
65
|
+
<a class="nav-link" aria-current="page" href="{{ url_for('summary.index') }}">Summary</a>
|
64
66
|
</li>
|
65
67
|
<li class="nav-item">
|
66
|
-
<a class="nav-link
|
67
|
-
href="{{ url_for('calendar.index') }}">Calendar</a>
|
68
|
+
<a class="nav-link" aria-current="page" href="{{ url_for('calendar.index') }}">Calendar</a>
|
68
69
|
</li>
|
69
70
|
<li class="nav-item">
|
70
|
-
<a class="nav-link
|
71
|
+
<a class="nav-link" aria-current="page"
|
71
72
|
href="{{ url_for('explorer.map', zoom=14) }}">Explorer</a>
|
72
73
|
</li>
|
73
74
|
<li class="nav-item">
|
74
|
-
<a class="nav-link
|
75
|
+
<a class="nav-link" aria-current="page"
|
75
76
|
href="{{ url_for('explorer.map', zoom=17) }}">Squadratinhos</a>
|
76
77
|
</li>
|
77
78
|
<li class="nav-item">
|
78
|
-
<a class="nav-link
|
79
|
-
href="{{ url_for('heatmap.index') }}">Heatmap</a>
|
79
|
+
<a class="nav-link" aria-current="page" href="{{ url_for('heatmap.index') }}">Heatmap</a>
|
80
80
|
</li>
|
81
81
|
<li class="nav-item">
|
82
|
-
<a class="nav-link
|
82
|
+
<a class="nav-link" aria-current="page"
|
83
83
|
href="{{ url_for('eddington.index') }}">Eddington</a>
|
84
84
|
</li>
|
85
85
|
<li class="nav-item">
|
86
|
-
<a class="nav-link
|
86
|
+
<a class="nav-link" aria-current="page"
|
87
87
|
href="{{ url_for('equipment.index') }}">Equipment</a>
|
88
88
|
</li>
|
89
89
|
<li class="nav-item">
|
90
|
-
<a class="nav-link
|
91
|
-
|
90
|
+
<a class="nav-link" aria-current="page" href="{{ url_for('upload.index') }}">Upload</a>
|
91
|
+
</li>
|
92
|
+
<li class="nav-item">
|
93
|
+
<a class="nav-link" aria-current="page" href="{{ url_for('settings') }}">Settings</a>
|
94
|
+
</li>
|
95
|
+
|
96
|
+
|
97
|
+
<li class="nav-item dropdown">
|
98
|
+
<button
|
99
|
+
class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center"
|
100
|
+
id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown"
|
101
|
+
data-bs-display="static" aria-label="Toggle theme (dark)">
|
102
|
+
<span id="bd-theme-text">Theme</span>
|
103
|
+
</button>
|
104
|
+
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
|
105
|
+
<li>
|
106
|
+
<button type="button" class="dropdown-item d-flex align-items-center"
|
107
|
+
data-bs-theme-value="light" aria-pressed="false">
|
108
|
+
☀️ Light
|
109
|
+
</button>
|
110
|
+
</li>
|
111
|
+
<li>
|
112
|
+
<button type="button" class="dropdown-item d-flex align-items-center active"
|
113
|
+
data-bs-theme-value="dark" aria-pressed="true">
|
114
|
+
🌙 Dark
|
115
|
+
</button>
|
116
|
+
</li>
|
117
|
+
<li>
|
118
|
+
<button type="button" class="dropdown-item d-flex align-items-center"
|
119
|
+
data-bs-theme-value="auto" aria-pressed="false">
|
120
|
+
⚙️ Auto
|
121
|
+
</button>
|
122
|
+
</li>
|
123
|
+
</ul>
|
92
124
|
</li>
|
93
125
|
</ul>
|
94
126
|
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{% extends "page.html.j2" %}
|
2
|
+
|
3
|
+
{% block container %}
|
4
|
+
<div class="row mb-3">
|
5
|
+
<div class="col">
|
6
|
+
<h1>Settings</h1>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class="row mb-3">
|
11
|
+
<div class="row row-cols-1 row-cols-md-3 g-2">
|
12
|
+
<div class="col">
|
13
|
+
<div class="card">
|
14
|
+
<div class="card-body">
|
15
|
+
<h5 class="card-title">Strava API</h5>
|
16
|
+
<p class="card-text">Connect to the Strava API to download activities from there.</p>
|
17
|
+
<a href="{{ url_for('strava.setup') }}" class="btn btn-primary">Set up Strava API</a>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
{% endblock %}
|
@@ -10,7 +10,9 @@ from flask import Response
|
|
10
10
|
from werkzeug.utils import secure_filename
|
11
11
|
|
12
12
|
from geo_activity_playground.core.activities import ActivityRepository
|
13
|
-
from geo_activity_playground.core.activities import
|
13
|
+
from geo_activity_playground.core.activities import build_activity_meta
|
14
|
+
from geo_activity_playground.core.enrichment import enrich_activities
|
15
|
+
from geo_activity_playground.core.paths import _strava_dynamic_config_path
|
14
16
|
from geo_activity_playground.explorer.tile_visits import compute_tile_evolution
|
15
17
|
from geo_activity_playground.explorer.tile_visits import compute_tile_visits
|
16
18
|
from geo_activity_playground.explorer.tile_visits import TileVisitAccessor
|
@@ -94,22 +96,16 @@ def scan_for_activities(
|
|
94
96
|
skip_strava: bool = False,
|
95
97
|
) -> None:
|
96
98
|
if pathlib.Path("Activities").exists():
|
97
|
-
import_from_directory(
|
98
|
-
repository,
|
99
|
-
config.get("kind", {}),
|
100
|
-
config.get("metadata_extraction_regexes", []),
|
101
|
-
)
|
99
|
+
import_from_directory(config.get("metadata_extraction_regexes", []))
|
102
100
|
if pathlib.Path("Strava Export").exists():
|
103
|
-
import_from_strava_checkout(
|
104
|
-
if "strava" in config and not skip_strava:
|
105
|
-
import_from_strava_api(
|
101
|
+
import_from_strava_checkout()
|
102
|
+
if (_strava_dynamic_config_path.exists() or "strava" in config) and not skip_strava:
|
103
|
+
import_from_strava_api()
|
106
104
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
)
|
111
|
-
sys.exit(1)
|
105
|
+
enrich_activities(config.get("kind", {}))
|
106
|
+
build_activity_meta()
|
107
|
+
repository.reload()
|
112
108
|
|
113
|
-
|
114
|
-
|
115
|
-
|
109
|
+
if len(repository) > 0:
|
110
|
+
compute_tile_visits(repository, tile_visit_accessor)
|
111
|
+
compute_tile_evolution(tile_visit_accessor)
|
{geo_activity_playground-0.24.2.dist-info → geo_activity_playground-0.26.0.dist-info}/RECORD
RENAMED
@@ -1,39 +1,39 @@
|
|
1
1
|
geo_activity_playground/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
geo_activity_playground/__main__.py,sha256=
|
2
|
+
geo_activity_playground/__main__.py,sha256=NQDFaa1BSIdare1oIdYO0cESf0kPVnEIE3J24jlsX_E,4021
|
3
3
|
geo_activity_playground/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
geo_activity_playground/core/activities.py,sha256=
|
5
|
-
geo_activity_playground/core/activity_parsers.py,sha256=pjYjnaAXsWfUNOoomYWOmmFZO5Qs076RWM-pqNdo7BA,10905
|
6
|
-
geo_activity_playground/core/cache_migrations.py,sha256=tkGA0h69-m-0Ek7JjvfVOX45YXLXkh_ZvC2TKB_fvbA,4281
|
4
|
+
geo_activity_playground/core/activities.py,sha256=I1lsn1gO_P9eHbZCZlkCO6Lvi5sqXq_-c-1aDv6uKMs,8081
|
7
5
|
geo_activity_playground/core/config.py,sha256=YjqCiEmIAa-GM1-JfBctMEsl8-I56pZyyDdTyPduOzw,477
|
8
6
|
geo_activity_playground/core/coordinates.py,sha256=tDfr9mlXhK6E_MMIJ0vYWVCoH0Lq8uyuaqUgaa8i0jg,966
|
7
|
+
geo_activity_playground/core/enrichment.py,sha256=wRVhrUCsvs2CcVhN-BQwxk_W_0E0AFp1_hncGzWNNvo,6435
|
9
8
|
geo_activity_playground/core/heatmap.py,sha256=bRLQHzmTEsQbX8XWeg85x_lRGk272UoYRiCnoxZ5da0,4189
|
10
|
-
geo_activity_playground/core/paths.py,sha256=
|
9
|
+
geo_activity_playground/core/paths.py,sha256=ohJN_xNLh303uc0ATpL4iH01xANIE86pILRaQi4e-RQ,1893
|
11
10
|
geo_activity_playground/core/privacy_zones.py,sha256=4TumHsVUN1uW6RG3ArqTXDykPVipF98DCxVBe7YNdO8,512
|
12
11
|
geo_activity_playground/core/similarity.py,sha256=Jo8jRViuORCxdIGvyaflgsQhwu9S_jn10a450FRL18A,3159
|
13
|
-
geo_activity_playground/core/tasks.py,sha256=
|
12
|
+
geo_activity_playground/core/tasks.py,sha256=22rIidyRR0eDqz9T7swJJSl7I96OeZ-T6xFQkh1-RsQ,2521
|
14
13
|
geo_activity_playground/core/test_tiles.py,sha256=zce1FxNfsSpOQt66jMehdQRVoNdl-oiFydx6iVBHZXM,764
|
15
14
|
geo_activity_playground/core/test_time_conversion.py,sha256=Sh6nZA3uCTOdZTZa3yOijtR0m74QtZu2mcWXsDNnyQI,984
|
16
15
|
geo_activity_playground/core/tiles.py,sha256=VxPu9vdfKnxDxaYo5JSYmka9Dt3TDxg0zo3cYVJXVHc,3359
|
17
16
|
geo_activity_playground/core/time_conversion.py,sha256=9J6aTlqJhWvsknQkoECNL-CIG-8BKs6ZatJJ9XJnTsg,367
|
18
17
|
geo_activity_playground/explorer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
18
|
geo_activity_playground/explorer/grid_file.py,sha256=k6j6KBEk2a2BY-onE8SV5TJsERGGyOrlY4as__meWpA,3304
|
20
|
-
geo_activity_playground/explorer/tile_visits.py,sha256=
|
19
|
+
geo_activity_playground/explorer/tile_visits.py,sha256=CLZ8bCUKc5YoxvNa23hGF9JtlinIl9Wbk9u2xN4bJpw,13457
|
21
20
|
geo_activity_playground/explorer/video.py,sha256=ROAmV9shfJyqTgnXVD41KFORiwnRgVpEWenIq4hMCRM,4389
|
22
21
|
geo_activity_playground/importers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
-
geo_activity_playground/importers/
|
24
|
-
geo_activity_playground/importers/
|
25
|
-
geo_activity_playground/importers/
|
22
|
+
geo_activity_playground/importers/activity_parsers.py,sha256=m2SpvGlTZ8F3gG6YB24_ZFrlOAbtqbfWi-GIYspeUco,10593
|
23
|
+
geo_activity_playground/importers/directory.py,sha256=YTYuroH-oYviL2a9B7No-6Fx4RrkhMqf60Yh-7dGats,5384
|
24
|
+
geo_activity_playground/importers/strava_api.py,sha256=ihy_ezq_gYUy1V4jbtg41N6K0ilYVOEiPZE07lSiUHU,8444
|
25
|
+
geo_activity_playground/importers/strava_checkout.py,sha256=mUKfCzBk0sMF6WEmAGelnwqGnonVO1UW_uZVAtxDJVQ,8576
|
26
26
|
geo_activity_playground/importers/test_directory.py,sha256=ljXokx7q0OgtHvEdHftcQYEmZJUDVv3OOF5opklxdT4,724
|
27
27
|
geo_activity_playground/importers/test_strava_api.py,sha256=4vX7wDr1a9aRh8myxNrIq6RwDBbP8ZeoXXPc10CAbW4,431
|
28
28
|
geo_activity_playground/webui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
29
|
geo_activity_playground/webui/activity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
30
|
geo_activity_playground/webui/activity/blueprint.py,sha256=gGMes5ycXi2rMixVYs4NQgzTU1Vttgu50prYAe3--Hs,1749
|
31
|
-
geo_activity_playground/webui/activity/controller.py,sha256=
|
31
|
+
geo_activity_playground/webui/activity/controller.py,sha256=BSmHwO2GLyMGiFRQ0BpTsHMKDWJbz5UHnwQ9HVULN4c,16679
|
32
32
|
geo_activity_playground/webui/activity/templates/activity/day.html.j2,sha256=r3qKl9uTzOko4R-ZzyYAZt1j61JSevYP4g0Yi06HHPg,2702
|
33
33
|
geo_activity_playground/webui/activity/templates/activity/lines.html.j2,sha256=5gB1aDjRgi_RventenRfC10_FtMT4ch_VuWvA9AMlBY,1121
|
34
34
|
geo_activity_playground/webui/activity/templates/activity/name.html.j2,sha256=RDLEt6ip8_ngmdLgaC5jg92Dk-F2umGwKkd8cWmvVko,2400
|
35
|
-
geo_activity_playground/webui/activity/templates/activity/show.html.j2,sha256=
|
36
|
-
geo_activity_playground/webui/app.py,sha256=
|
35
|
+
geo_activity_playground/webui/activity/templates/activity/show.html.j2,sha256=NOsMPUBy1UQM_YebtT6RQxLSgSGvCMetqi_mspJmUjQ,5229
|
36
|
+
geo_activity_playground/webui/app.py,sha256=a6RcsPH-n1Ru6RybkAPCRENL9KnPvxfPBJI9IzsEB5U,3980
|
37
37
|
geo_activity_playground/webui/calendar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
geo_activity_playground/webui/calendar/blueprint.py,sha256=rlnhgU2DWAcdLMRq7m77NzrM_aDyp4s3kuuQHuzjHhg,782
|
39
39
|
geo_activity_playground/webui/calendar/controller.py,sha256=QpSAkR2s1sbLSu6P_fNNTccgGglOzEH2PIv1XwKxeVY,2778
|
@@ -43,7 +43,7 @@ geo_activity_playground/webui/eddington/__init__.py,sha256=47DEQpj8HBSa-_TImW-5J
|
|
43
43
|
geo_activity_playground/webui/eddington/blueprint.py,sha256=evIvueLfDWVTxJ9pRguqmZ9-Pybd2WmBRst_-7vX2QA,551
|
44
44
|
geo_activity_playground/webui/eddington/controller.py,sha256=L4YssL088UMamp4qgzEtilzhaKGZsyfVUScuw-fmTjE,2888
|
45
45
|
geo_activity_playground/webui/eddington/templates/eddington/index.html.j2,sha256=XHKeUymQMS5x00PLOVlg-nSRCz_jHB2pvD8QunULWJ4,1839
|
46
|
-
geo_activity_playground/webui/entry_controller.py,sha256=
|
46
|
+
geo_activity_playground/webui/entry_controller.py,sha256=n9v4MriyL8kDR91LE9eeqc2tAvxyzFgoNMMXpr0qh4g,1906
|
47
47
|
geo_activity_playground/webui/equipment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
48
|
geo_activity_playground/webui/equipment/blueprint.py,sha256=YbOAsjk05BMeUlD6wGfxE1amvlLsFjG4HMJn5SBrVRU,551
|
49
49
|
geo_activity_playground/webui/equipment/controller.py,sha256=m1LNaGCNJnW97TlKT6x9NfQcMp6RKcZ8Q0I1FTUAvss,4037
|
@@ -54,7 +54,7 @@ geo_activity_playground/webui/explorer/controller.py,sha256=8d0FFrG55ZlPQ5seQC2D
|
|
54
54
|
geo_activity_playground/webui/explorer/templates/explorer/index.html.j2,sha256=OxNt2_VwH-cmVXJrDNfeD-dNB9IrwBjdhhQEqkXxHj0,6529
|
55
55
|
geo_activity_playground/webui/heatmap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
56
|
geo_activity_playground/webui/heatmap/blueprint.py,sha256=bjQu-HL3QN5UpJ6tHOifhcLGlPr_hIKvaRu78md4JqM,1470
|
57
|
-
geo_activity_playground/webui/heatmap/heatmap_controller.py,sha256=
|
57
|
+
geo_activity_playground/webui/heatmap/heatmap_controller.py,sha256=i376qEqTJrhezGsdPyKR8VsRY2N0JdEra7_kY7NmwW8,6822
|
58
58
|
geo_activity_playground/webui/heatmap/templates/heatmap/index.html.j2,sha256=YLeu6P4djl8G4qAXR6DhetseqrbOodN7aN4coocknc4,1875
|
59
59
|
geo_activity_playground/webui/search_controller.py,sha256=PzMf7b8tiJKZIZoPvQ9A2hOrzoKV9cS3jq05w2fK94c,532
|
60
60
|
geo_activity_playground/webui/square_planner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -65,6 +65,7 @@ geo_activity_playground/webui/static/android-chrome-192x192.png,sha256=yxZgo8Jw4
|
|
65
65
|
geo_activity_playground/webui/static/android-chrome-384x384.png,sha256=bgeqAdyvDZBMch7rVi3qSawf0Zr4Go0EG8Ws_B8NApY,49297
|
66
66
|
geo_activity_playground/webui/static/android-chrome-512x512.png,sha256=Uiv62gQpUjMOdp9d6exzd6IyOi5zgQdgjIVVWYw5m98,38891
|
67
67
|
geo_activity_playground/webui/static/apple-touch-icon.png,sha256=NsVMubJtVzslhql4GZlwTWm4cNRowgcEOT53RuZV190,16549
|
68
|
+
geo_activity_playground/webui/static/bootstrap-dark-mode.js,sha256=XfyhxIFgjDc6aEj0kYgKpG5zjS5gvyhWCJmNfUG4HJY,2622
|
68
69
|
geo_activity_playground/webui/static/browserconfig.xml,sha256=u5EvU6U1jKSDiXHW0i4rXrs0lT_tmS82otbJnvmccrk,253
|
69
70
|
geo_activity_playground/webui/static/favicon-16x16.png,sha256=Yy8lRjGB7itDaeUI_l_Toq3OO0gzgPGnqIfM3CqcQy0,1419
|
70
71
|
geo_activity_playground/webui/static/favicon-32x32.png,sha256=K52R99pLGgWHnjFPPkVieBm051Er-sTCiMvgLr9Alrg,2587
|
@@ -72,24 +73,28 @@ geo_activity_playground/webui/static/favicon.ico,sha256=uVNZlrF22zn1lcCS_9wAoWLh
|
|
72
73
|
geo_activity_playground/webui/static/mstile-150x150.png,sha256=j1ANUQJ1Xi1DR2sGqYZztob2ypfGw04eNtGpN9SxExA,11964
|
73
74
|
geo_activity_playground/webui/static/safari-pinned-tab.svg,sha256=OzoEVGY0igWRXM1NiM3SRKugdICBN7aB_XuxaC3Mu9Q,8371
|
74
75
|
geo_activity_playground/webui/static/site.webmanifest,sha256=4vYxdPMpwTdB8EmOvHkkYcjZ8Yrci3pOwwY3o_VwACA,440
|
75
|
-
geo_activity_playground/webui/
|
76
|
+
geo_activity_playground/webui/strava/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
|
+
geo_activity_playground/webui/strava/blueprint.py,sha256=Q2Wfxlg7bR2vjWZ3UpckPl9jWHwNB8hfP7SLBufgiUY,1055
|
78
|
+
geo_activity_playground/webui/strava/controller.py,sha256=Ye0R-nu5SwFdk2DAIEq7OE76XLgnRk9y8iJjLObbAUc,1437
|
79
|
+
geo_activity_playground/webui/strava/templates/strava/client-id.html.j2,sha256=m5gJk0VxcIn0VcROsOke5A5MbWXC5O1e1Lxc09MyN_g,1493
|
80
|
+
geo_activity_playground/webui/strava/templates/strava/connected.html.j2,sha256=TN6H8YPjG2zk8fodTaSaloTEJCXnpgTCIRX_uEVTiNI,274
|
76
81
|
geo_activity_playground/webui/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
82
|
geo_activity_playground/webui/summary/blueprint.py,sha256=kzQ6MDOycQKfDcVoEUmL7HYHJA_gu8DlzVHwO37-_jA,514
|
78
83
|
geo_activity_playground/webui/summary/controller.py,sha256=i6A9-S9j9Hm67FcZPzJpqMgxRVsXbDmJiVLGiRtZIqk,8805
|
79
84
|
geo_activity_playground/webui/summary/templates/summary/index.html.j2,sha256=rsII1eMY-xNugh8A9SecnEcDZqkEOWYIfiHAGroQYuM,4442
|
80
|
-
geo_activity_playground/webui/templates/home.html.j2,sha256=
|
81
|
-
geo_activity_playground/webui/templates/page.html.j2,sha256=
|
85
|
+
geo_activity_playground/webui/templates/home.html.j2,sha256=fp48MjBuO4QJfQz6YPOWH56IzStgaclx9XbwEKmUFHQ,2403
|
86
|
+
geo_activity_playground/webui/templates/page.html.j2,sha256=KwgUw7zOjWNVSZKM4BGWOaBbPhGZaaOXCvNV9pL-0R4,9160
|
82
87
|
geo_activity_playground/webui/templates/search.html.j2,sha256=FvNRoDfUlSzXjM_tqZY_fDhuhUDgbPaY73q56gdvF1A,1130
|
83
|
-
geo_activity_playground/webui/templates/
|
88
|
+
geo_activity_playground/webui/templates/settings.html.j2,sha256=-q9GflrG2t6kSt-NerBN5NV1gRp12JT3KgGp_aPaKT8,674
|
84
89
|
geo_activity_playground/webui/tile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
90
|
geo_activity_playground/webui/tile/blueprint.py,sha256=cK0o2Z3BrLycgF9zw0F8s9qF-JaYDbF5Gog-GXDtUZ8,943
|
86
91
|
geo_activity_playground/webui/tile/controller.py,sha256=PISh4vKs27b-LxFfTARtr5RAwHFresA1Kw1MDcERSRU,1221
|
87
92
|
geo_activity_playground/webui/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
88
93
|
geo_activity_playground/webui/upload/blueprint.py,sha256=2l5q1LYtjgLF_3CAyPvCLx-wMebp14OJvgZBzGILdmQ,801
|
89
|
-
geo_activity_playground/webui/upload/controller.py,sha256=
|
94
|
+
geo_activity_playground/webui/upload/controller.py,sha256=BWcSlLy_fVAodDlnXkxE4eIotC_UHrjldACrToA-iAQ,3975
|
90
95
|
geo_activity_playground/webui/upload/templates/upload/index.html.j2,sha256=hfXkEXaz_MkM46rU56423D6V6WtK-EAXPszSY-_-Tx8,1471
|
91
|
-
geo_activity_playground-0.
|
92
|
-
geo_activity_playground-0.
|
93
|
-
geo_activity_playground-0.
|
94
|
-
geo_activity_playground-0.
|
95
|
-
geo_activity_playground-0.
|
96
|
+
geo_activity_playground-0.26.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
|
97
|
+
geo_activity_playground-0.26.0.dist-info/METADATA,sha256=dFqZ5yCNUgsbZMxW55cZaI4Q_tbft6ifhGoaGgmImvc,1665
|
98
|
+
geo_activity_playground-0.26.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
99
|
+
geo_activity_playground-0.26.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
|
100
|
+
geo_activity_playground-0.26.0.dist-info/RECORD,,
|