geo-activity-playground 1.3.0__py3-none-any.whl → 1.3.1__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.
@@ -1,5 +1,6 @@
1
1
  import datetime
2
2
  import logging
3
+ import uuid
3
4
  import zoneinfo
4
5
  from typing import Callable
5
6
 
@@ -268,6 +269,8 @@ def update_and_commit(
268
269
  activity: Activity, time_series: pd.DataFrame, config: Config
269
270
  ) -> None:
270
271
  changed = apply_enrichments(activity, time_series, config)
272
+ if not activity.time_series_uuid:
273
+ activity.time_series_uuid = str(uuid.uuid4())
271
274
  if changed:
272
275
  activity.replace_time_series(time_series)
273
276
  DB.session.add(activity)
@@ -27,6 +27,9 @@ def read_activity(path: pathlib.Path) -> tuple[Activity, pd.DataFrame]:
27
27
  suffixes = [s.lower() for s in path.suffixes]
28
28
  activity = Activity()
29
29
 
30
+ if len(suffixes) == 0:
31
+ raise ActivityParseError(f"File has no suffix, ignoring")
32
+
30
33
  if suffixes[-1] == ".gz":
31
34
  opener = gzip.open
32
35
  file_type = suffixes[-2]
@@ -132,7 +135,13 @@ def read_fit_activity(path: pathlib.Path, open) -> tuple[Activity, pd.DataFrame]
132
135
  factor = _fit_speed_unit_factor(
133
136
  fields["enhanced_speed"].units
134
137
  )
135
- row["speed"] = values["enhanced_speed"] * factor
138
+ try:
139
+ row["speed"] = values["enhanced_speed"] * factor
140
+ except TypeError as e:
141
+ # https://github.com/martin-ueding/geo-activity-playground/issues/301
142
+ raise ActivityParseError(
143
+ f'Cannot work with {values["enhanced_speed"]!r}, {factor!r}'
144
+ ) from e
136
145
  if "grade" in fields:
137
146
  row["grade"] = values["grade"]
138
147
  if "temperature" in fields:
@@ -38,13 +38,15 @@ def import_from_directory(
38
38
  and not path.suffix in config.ignore_suffixes
39
39
  ]
40
40
 
41
- for activity_path in activity_paths:
41
+ for i, activity_path in enumerate(activity_paths):
42
42
  with DB.session.no_autoflush:
43
43
  activity = DB.session.scalar(
44
44
  sqlalchemy.select(Activity).filter(Activity.path == str(activity_path))
45
45
  )
46
46
  if activity is None:
47
- import_from_file(activity_path, repository, tile_visit_accessor, config)
47
+ import_from_file(
48
+ activity_path, repository, tile_visit_accessor, config, i
49
+ )
48
50
 
49
51
 
50
52
  def import_from_file(
@@ -52,6 +54,7 @@ def import_from_file(
52
54
  repository: ActivityRepository,
53
55
  tile_visit_accessor: TileVisitAccessor,
54
56
  config: Config,
57
+ i: int,
55
58
  ) -> None:
56
59
  logger.info(f"Importing {path} …")
57
60
  try:
@@ -74,6 +77,10 @@ def import_from_file(
74
77
 
75
78
  meta_from_path = _get_metadata_from_path(path, config.metadata_extraction_regexes)
76
79
  activity.name = meta_from_path.get("name", activity.name)
80
+ if "equipment" in meta_from_path:
81
+ activity.equipment = get_or_make_equipment(meta_from_path["equipment"], config)
82
+ if "kind" in meta_from_path:
83
+ activity.kind = get_or_make_kind(meta_from_path["kind"])
77
84
  if activity.equipment is None:
78
85
  activity.equipment = get_or_make_equipment(
79
86
  meta_from_path.get("equipment", DEFAULT_UNKNOWN_NAME), config
@@ -85,7 +92,7 @@ def import_from_file(
85
92
 
86
93
  update_and_commit(activity, time_series, config)
87
94
 
88
- if len(repository) > 0:
95
+ if len(repository) > 0 and i % 50 == 0:
89
96
  compute_tile_visits_new(repository, tile_visit_accessor)
90
97
  compute_tile_evolution(tile_visit_accessor.tile_state, config)
91
98
  tile_visit_accessor.save()
@@ -25,6 +25,8 @@ from ..core.paths import strava_api_dir
25
25
  from ..core.paths import strava_last_activity_date_path
26
26
  from ..core.tasks import get_state
27
27
  from ..core.tasks import set_state
28
+ from ..explorer.tile_visits import compute_tile_evolution
29
+ from ..explorer.tile_visits import compute_tile_visits_new
28
30
  from ..explorer.tile_visits import TileVisitAccessor
29
31
 
30
32
 
@@ -3,6 +3,7 @@ import logging
3
3
  import pathlib
4
4
  import shutil
5
5
  import sys
6
+ import urllib.parse
6
7
  import zoneinfo
7
8
  from typing import Optional
8
9
 
@@ -266,7 +267,7 @@ def convert_strava_checkout(
266
267
  "-",
267
268
  f"{activity_date.hour:02d}-{activity_date.minute:02d}-{activity_date.second:02d}",
268
269
  " ",
269
- activity_name.replace("/", "_"),
270
+ urllib.parse.quote_plus(activity_name),
270
271
  ]
271
272
  + activity_file.suffixes
272
273
  )
@@ -131,6 +131,12 @@ def web_ui_main(
131
131
  old_path = TIME_SERIES_DIR() / f"{activity.id}.parquet"
132
132
  if old_path.exists() and not activity.time_series_path.exists():
133
133
  old_path.rename(activity.time_series_path)
134
+ if not activity.time_series_path.exists():
135
+ logger.error(
136
+ f"Time series for {activity.id=}, expected at {activity.time_series_path}, does not exist. Deleting activity."
137
+ )
138
+ DB.session.delete(activity)
139
+ DB.session.commit()
134
140
 
135
141
  if not skip_reload:
136
142
  thread = threading.Thread(
@@ -42,6 +42,8 @@
42
42
  <dt>Average elapsed speed</dt>
43
43
  <dd>{{ activity.average_speed_elapsed_kmh|round(1) }} km/h = {{
44
44
  (60/activity.average_speed_elapsed_kmh)|round(1) }} min/km</dd>
45
+ {% endif %}
46
+ {% if date is defined %}
45
47
  <dt>Start time</dt>
46
48
  <dd><a href="{{ url_for('activity.day', year=date.year, month=date.month, day=date.day) }}">{{ date }}</a>
47
49
  {{ time }} {{ activity.iana_timezone }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geo-activity-playground
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
@@ -41,6 +41,7 @@ Requires-Dist: shapely (>=2.0.5,<3.0.0)
41
41
  Requires-Dist: sqlalchemy (>=2.0.40,<3.0.0)
42
42
  Requires-Dist: stravalib (>=2.0,<3.0)
43
43
  Requires-Dist: tcxreader (>=0.4.5,<0.5.0)
44
+ Requires-Dist: tifffile (==2025.5.10)
44
45
  Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
45
46
  Requires-Dist: tqdm (>=4.64.0,<5.0.0)
46
47
  Requires-Dist: vegafusion-python-embed (>=1.4.3,<2.0.0)
@@ -22,7 +22,7 @@ geo_activity_playground/core/config.py,sha256=mmdMQ5iCLNGnAlriT1ETEVS-gM6Aq_9sg2
22
22
  geo_activity_playground/core/coordinates.py,sha256=rW_OmMRpTUyIsQwrT6mgT9Y6uPGuwqTo5XDDMS7mGuo,1140
23
23
  geo_activity_playground/core/copernicus_dem.py,sha256=U6pvUAymLCX4CpbQKvUoXRj8LYdlaQTKtEVlrlHH3kw,2934
24
24
  geo_activity_playground/core/datamodel.py,sha256=3LdTm7lqykeLM6KYviW9WamgnS61nGNl-NHSEQdwTXY,15765
25
- geo_activity_playground/core/enrichment.py,sha256=gb8amLAjpcEYTeseQl6U6kOy8o1p63pzvoOf2f7iryY,8597
25
+ geo_activity_playground/core/enrichment.py,sha256=TPA0PsWhz2D3R3PL-8WGr8TJIWvtfPoUIbya7X910qA,8701
26
26
  geo_activity_playground/core/export.py,sha256=ayOmhWL72263oP9NLIZRYCg_Db0GLUFhgNIL_MCrV-E,4435
27
27
  geo_activity_playground/core/heart_rate.py,sha256=-S3WAhS7AOywrw_Lk5jfuo_fu6zvZQ1VtjwEKSycWpU,1542
28
28
  geo_activity_playground/core/meta_search.py,sha256=nyvCuR7v0pd6KjA8W5Kr71bBafRdE_ol7uSFRJs4eAM,6662
@@ -51,16 +51,16 @@ geo_activity_playground/explorer/tile_visits.py,sha256=WK_H5fdy3S69BT4zZGP0R92qq
51
51
  geo_activity_playground/explorer/video.py,sha256=7j6Qv3HG6On7Tn7xh7Olwrx_fbQnfzS7CeRg3TEApHg,4397
52
52
  geo_activity_playground/heatmap_video.py,sha256=I8i1uVvbbPUXVtvLAROaLy58nQoUPnuMCZkERWNkQjg,3318
53
53
  geo_activity_playground/importers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- geo_activity_playground/importers/activity_parsers.py,sha256=HVkW4Ql5vVRPlrhHgJEWeCEc1yTEWQTgJ6rkKOPWAfQ,10955
54
+ geo_activity_playground/importers/activity_parsers.py,sha256=zWgLkHHd8rjWnKs-COBegpAUh7dXxYOJsQL_L2-Qc7M,11435
55
55
  geo_activity_playground/importers/csv_parser.py,sha256=O1pP5GLhWhnWcy2Lsrr9g17Zspuibpt-GtZ3ZS5eZF4,2143
56
- geo_activity_playground/importers/directory.py,sha256=kkutzFliffBjxj1GJrqhMp2cLeiAK6ZGE9Gi6Ptl-NY,3255
57
- geo_activity_playground/importers/strava_api.py,sha256=LG8M8NRSv3kK3npf9gSY20YcqzJ0xiQoVEv0oeDXbNY,8309
58
- geo_activity_playground/importers/strava_checkout.py,sha256=eDzjK0r3rMICSMBtfSlSwwkRxRthWjRUA5zAnblhmNQ,8910
56
+ geo_activity_playground/importers/directory.py,sha256=ucnB5sPBvXzLdaza2v8GVU75ArfGG4E7d5OXrCgoFq4,3562
57
+ geo_activity_playground/importers/strava_api.py,sha256=Fiqlc-VeuzsvgDcWt71JoPMri221cMjkeL4SH80gC5s,8426
58
+ geo_activity_playground/importers/strava_checkout.py,sha256=6RJoGRN3OdEXODeB8yzhT1OJglBGgsaZdNath1rzooA,8937
59
59
  geo_activity_playground/importers/test_csv_parser.py,sha256=nOTVTdlzIY0TDcbWp7xNyNaIO6Mkeu55hVziVl22QE4,1092
60
60
  geo_activity_playground/importers/test_directory.py,sha256=_fn_-y98ZyElbG0BRxAmGFdtGobUShPU86SdEOpuv-A,691
61
61
  geo_activity_playground/importers/test_strava_api.py,sha256=7b8bl5Rh2BctCmvTPEhCadxtUOq3mfzuadD6F5XxRio,398
62
62
  geo_activity_playground/webui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
- geo_activity_playground/webui/app.py,sha256=gvvzPpYTlC5KhMOdpvDtiH2jPyvsLMM9Wf4yWkCoyzc,10020
63
+ geo_activity_playground/webui/app.py,sha256=4dCfzxPk7KJTAwEXyw3NPiQQz-udvgECqeL8CtOj0Es,10334
64
64
  geo_activity_playground/webui/authenticator.py,sha256=dhREYOu_TCD_nzFNuSlHIbf5K6TmwKdXtr1wxD8fBcc,1491
65
65
  geo_activity_playground/webui/blueprints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  geo_activity_playground/webui/blueprints/activity_blueprint.py,sha256=kfI7GrQUm36GuSNWv8vYQEmT7bshDFrLkWchqesa_9k,26793
@@ -126,7 +126,7 @@ geo_activity_playground/webui/templates/activity/day.html.j2,sha256=CHEvxlZralCm
126
126
  geo_activity_playground/webui/templates/activity/edit.html.j2,sha256=r979JPqaZi_2ymTykxpkjdpw0D2tsB9VJaf7OaGPaME,1961
127
127
  geo_activity_playground/webui/templates/activity/lines.html.j2,sha256=_ZDg1ruW-9UMJfOudy1-uY_-IcSSaagq7tPCih5Bb8g,1079
128
128
  geo_activity_playground/webui/templates/activity/name.html.j2,sha256=RYbNGzPexa4gRUWRjw-C9nWvp5lI7agAZZCS3Du7nAs,2661
129
- geo_activity_playground/webui/templates/activity/show.html.j2,sha256=e-jMjZ4fBwK4-u0qZmbiN76ZqrptD4xrGYhxwaUQsEE,10913
129
+ geo_activity_playground/webui/templates/activity/show.html.j2,sha256=gE4RraLi-h63KvHO4oXLDWPcXN1FB6wqMxVKB75Zn0k,10974
130
130
  geo_activity_playground/webui/templates/activity/trim.html.j2,sha256=3oAXQab6QqWjGBC9KCvWNOVn8uRmxoDLj3hx_O63TXc,1836
131
131
  geo_activity_playground/webui/templates/auth/index.html.j2,sha256=wzA0uxpiT1ktDadgnjvFXc9iUGMFm9GhjDkavl3S1h4,646
132
132
  geo_activity_playground/webui/templates/bubble_chart/index.html.j2,sha256=yd7lWjtxxVmJZqCiXb0Y1gMEOQ7LQYJXEdpE7JB1OZY,1616
@@ -171,8 +171,8 @@ geo_activity_playground/webui/templates/summary/vega-chart.html.j2,sha256=mw8Hti
171
171
  geo_activity_playground/webui/templates/time_zone_fixer/index.html.j2,sha256=s9r6BJMXmd7kLSyjkvH4xLi6e01S5bpGRcMgMMJyCAE,1760
172
172
  geo_activity_playground/webui/templates/upload/index.html.j2,sha256=I1Ix8tDS3YBdi-HdaNfjkzYXVVCjfUTe5PFTnap1ydc,775
173
173
  geo_activity_playground/webui/templates/upload/reload.html.j2,sha256=YZWX5eDeNyqKJdQAywDBcU8DZBm22rRBbZqFjrFrCvQ,556
174
- geo_activity_playground-1.3.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
175
- geo_activity_playground-1.3.0.dist-info/METADATA,sha256=CWWk8dBKRARHREz5Ux11u0U_qtrwqIRHJC-toP7hsLM,2045
176
- geo_activity_playground-1.3.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
177
- geo_activity_playground-1.3.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
178
- geo_activity_playground-1.3.0.dist-info/RECORD,,
174
+ geo_activity_playground-1.3.1.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
175
+ geo_activity_playground-1.3.1.dist-info/METADATA,sha256=2H0luCrinp9PleOQHmimHifLY4cqlUuhAOFlHKmdgAc,2083
176
+ geo_activity_playground-1.3.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
177
+ geo_activity_playground-1.3.1.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
178
+ geo_activity_playground-1.3.1.dist-info/RECORD,,