Skip to content

Commit

Permalink
Merge pull request #12 from ColCarroll/updates
Browse files Browse the repository at this point in the history
More updates, some typing
  • Loading branch information
ColCarroll authored Nov 12, 2024
2 parents 56f99a1 + 24c1c82 commit dd64c55
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 43 deletions.
13 changes: 0 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ dependencies = [
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"black>=23.0.0",
"pytype>=2024.1.24",
"ruff>=0.1.0",
]
Expand All @@ -51,18 +50,6 @@ addopts = "-ra -q --cov=strava_calendar"
testpaths = ["strava_calendar"]
python_files = ["test_*.py"]

[tool.black]
line-length = 88
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.tox
| build
| dist
)/
'''

[tool.ruff]
line-length = 88
lint.select = [
Expand Down
3 changes: 0 additions & 3 deletions scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Install dev dependencies
pip install ".[dev]"

# Format code
black .

# Run type checking
pytype

Expand Down
70 changes: 43 additions & 27 deletions strava_calendar/data.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import datetime
import gzip
import json
import os
import pathlib
import zipfile
from collections.abc import Callable, Generator, Iterable
from typing import Any

import gpxpy
import tqdm
from fitparse import FitFile

CACHE = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".cache")
if not os.path.isdir(CACHE):
os.mkdir(CACHE)
CACHE = pathlib.Path(__file__).parent.resolve() / ".cache"
if not CACHE.is_dir():
CACHE.mkdir()


class StravaGPXFile:
Expand Down Expand Up @@ -67,7 +70,9 @@ def to_json(self):

class StravaFile(FitFile):
def __init__(self, file):
super().__init__(file)
# These two check being false should make things somewhat faster, at
# the expense of error messages, I think...
super().__init__(file, check_crc=False, check_developer_data=False)
self.session_data = self._get_session_data()

def _get_session_data(self):
Expand All @@ -79,7 +84,7 @@ def _get_session_data(self):
)
return {j["name"]: j["value"] for j in session_data[0].as_dict()["fields"]}

def location(self):
def location(self) -> dict[str, float]:
lat, long = (
self.session_data["start_position_lat"],
self.session_data["start_position_long"],
Expand All @@ -89,7 +94,7 @@ def location(self):
long *= 180.0 / 2**31
return {"lat": lat, "long": long}

def route(self):
def route(self) -> dict[str, list[float]]:
coords = [
[record.get_value("position_long"), record.get_value("position_lat")]
for record in self.get_messages("record")
Expand All @@ -101,7 +106,7 @@ def route(self):
long, lat = [], []
return {"lat": lat, "long": long}

def to_json(self):
def to_json(self) -> dict[str, Any]:
return {
"distance": self.session_data["total_distance"],
"elapsed_time": self.session_data["total_timer_time"],
Expand All @@ -113,7 +118,11 @@ def to_json(self):
}


def is_sport(sport="running"):
DataFile = StravaFile | StravaGPXFile
FilterFunc = Callable[[DataFile], bool]


def is_sport(sport: str = "running") -> FilterFunc:
# hardcode more paces if you are using GPX files...
if sport == "running":
# if not labelled, use 5min/mile -> 10min/mile
Expand All @@ -122,7 +131,7 @@ def is_sport(sport="running"):
else:
lo, hi = 0, 0

def filter_func(strava_file):
def filter_func(strava_file: DataFile) -> bool:
if strava_file.session_data["sport"] is None:
# if distance is 0 or False-y, just skip it.
if strava_file.session_data["distance"]:
Expand All @@ -138,21 +147,21 @@ def filter_func(strava_file):
return filter_func


def is_after(start_date):
def filter_func(strava_file):
def is_after(start_date: datetime.datetime) -> FilterFunc:
def filter_func(strava_file: DataFile) -> bool:
return strava_file.session_data["start_time"] >= start_date

return filter_func


def is_before(end_date):
def filter_func(strava_file):
def is_before(end_date: datetime.datetime) -> FilterFunc:
def filter_func(strava_file: DataFile) -> bool:
return strava_file.session_data["start_time"] < end_date

return filter_func


def get_files(zip_path):
def get_files(zip_path: pathlib.Path) -> Generator[tuple[bytes, str]]:
suffixes = (".fit.gz", ".gpx", ".gpx.gz")
with zipfile.ZipFile(zip_path) as run_zip:
good_files = []
Expand All @@ -169,7 +178,9 @@ def get_files(zip_path):
yield buff.read(), filename


def filter_files(zip_path, filters):
def filter_files(
zip_path: pathlib.Path, filters: Iterable[FilterFunc]
) -> Generator[DataFile]:
for data, fname in get_files(zip_path):
if fname.endswith(".fit.gz"):
strava_file = StravaFile(data)
Expand All @@ -179,25 +190,30 @@ def filter_files(zip_path, filters):
yield strava_file


def get_data(zip_path, sport, start_date, end_date):
def get_data(
zip_path: str | pathlib.Path,
sport: str,
start_date: datetime.datetime,
end_date: datetime.datetime,
):
zip_path: pathlib.Path = pathlib.Path(zip_path)
date_fmt = "%Y-%m-%d"
zip_fname = os.path.basename(zip_path)
filter_dir = os.path.join(CACHE, zip_fname)
if not os.path.isdir(filter_dir):
os.mkdir(filter_dir)
filename = os.path.join(
filter_dir,
f"{sport}_{start_date.strftime(date_fmt)}_{end_date.strftime(date_fmt)}.json",
filter_dir = CACHE / zip_path.path
if not filter_dir.is_dir():
filter_dir.mkdir()
filename = (
filter_dir
/ f"{sport}_{start_date.strftime(date_fmt)}_{end_date.strftime(date_fmt)}.json"
)
if not os.path.exists(filename):
if not filename.exists():
filters = [is_sport(sport), is_after(start_date), is_before(end_date)]
data = {"activities": []}
for strava_file in filter_files(zip_path, filters):
try:
data["activities"].append(strava_file.to_json())
except KeyError as e:
print(e)
with open(filename, "w") as buff:
with filename.open("w") as buff:
json.dump(data, buff)
with open(filename) as buff:
with filename.open() as buff:
return json.load(buff)
1 change: 1 addition & 0 deletions strava_calendar/test_data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from strava_calendar.data import * # noqa:F403


def test_placeholder():
pass
1 change: 1 addition & 0 deletions strava_calendar/test_plot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from strava_calendar.plot import * # noqa:F403


def test_placeholder():
pass
1 change: 1 addition & 0 deletions strava_calendar/test_strava_calendar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from strava_calendar.strava_calendar import * # noqa:F403


def test_placeholder():
pass

0 comments on commit dd64c55

Please sign in to comment.