Skip to content

Commit

Permalink
Add --date-start/end options to filter activities before processing
Browse files Browse the repository at this point in the history
This way, strava_gear can be used to build yearly statistics or tracking
usage since, for example, rewaxing a chain (although a better UX for
this can, and hopefully will, be implemented).

Closes: #16
Co-authored-by: Tomas Janousek <tomi@nomi.cz>
  • Loading branch information
gangitano-gsom and liskin committed May 13, 2024
1 parent 8d7cfbf commit d235c90
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ For a real life example, take a look at [my own rules.yaml](https://github.com/l
Show first/last usage of components [default: show-first-last]
--show-vert / --hide-vert Show vertical (elevation gain) [default: hide-vert]
--units [metric|imperial] Show data in metric or imperial [default: metric]
--date-start ISO8601 Filter activities: start at or after the specified date(time)
--date-end ISO8601 Filter activities: start before the specified date(time)
--help Show this message and exit.
<!-- end include -->
Expand Down
39 changes: 39 additions & 0 deletions src/strava_gear/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from datetime import datetime
from pathlib import Path
from typing import Dict
from typing import List
from typing import Optional
from typing import TextIO

Expand All @@ -10,11 +13,25 @@
from .input.activities import essential_columns
from .input.activities import read_input_csv
from .input.activities import read_strava_offline
from .input.date import parse_datetime
from .input.rules import read_rules
from .report import Units
from .report import reports


class DateTimeParam(click.ParamType):
name = "datetime"

def convert(self, value, _param, _ctx):
try:
return parse_datetime(value)
except ValueError as e:
self.fail(str(e) or "Could not parse datetime")

def get_metavar(self, _param):
return "ISO8601"


@click.command(context_settings={'max_content_width': 120})
@click.option(
'--rules', 'rules_input', type=click.File('r'),
Expand Down Expand Up @@ -58,6 +75,12 @@
'--units', type=click.Choice([u.name.lower() for u in Units]), default=Units.METRIC.name.lower(), show_default=True,
callback=lambda _ctx, _param, v: Units[v.upper()], # TODO: drop when Python 3.11 is the oldest supported
help="Show data in metric or imperial")
@click.option(
'--date-start', type=DateTimeParam(),
help="Filter activities: start at or after the specified date(time)")
@click.option(
'--date-end', type=DateTimeParam(),
help="Filter activities: start before the specified date(time)")
def cli(
rules_input: TextIO,
csv: Optional[TextIO],
Expand All @@ -69,11 +92,14 @@ def cli(
show_first_last: bool,
show_vert: bool,
units: Units,
date_start: Optional[datetime],
date_end: Optional[datetime]
):
if csv:
aliases, activities = read_input_csv(csv)
else:
aliases, activities = read_strava_offline(strava_database)
activities = activities_in_range(activities, date_start=date_start, date_end=date_end)
rules = read_rules(rules_input, aliases=aliases)
res = apply_rules(rules, activities)
reports[report](
Expand All @@ -85,3 +111,16 @@ def cli(
units=units,
)
warn_unknown_bikes(rules, activities)


def activities_in_range(
activities: List[Dict],
date_start: Optional[datetime],
date_end: Optional[datetime]
) -> List[Dict]:
return [
a
for a in activities
if not date_start or a['start_date'] >= date_start
if not date_end or a['start_date'] < date_end
]
27 changes: 24 additions & 3 deletions tests/csv.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Rules:
$ cat >rules.yaml <<END
> rules:
> - road:
> frame: fr
> chain: c1
> - since: 2023-01-01
> road:
Expand All @@ -32,10 +33,11 @@ Bikes report:
> END
bike,role,id,name,km,hour,first … last
road,chain,c3,c3,0.0,0.0,never
road,frame,fr,fr,3.0,3.0,2022-01-01 … 2023-02-01

Components report:

$ strava-gear --report components <<END
$ strava-gear --report components <<END | grep -v ^fr,
> name,gear_id,start_date,moving_time,distance,total_elevation_gain
> Ride 1,road,2022-01-01,3600,1000,10
> Ride 2,road,2023-01-01,3600,1000,10
Expand All @@ -50,7 +52,7 @@ Components report:

VirtualRide virtual hashtag:

$ strava-gear --report components <<END
$ strava-gear --report components <<END | grep -v ^fr,
> name,gear_id,start_date,moving_time,distance,total_elevation_gain,type
> Ride 1,road,2022-01-01,3600,1000,10,Ride
> Ride 2,road,2023-01-01,3600,1000,10,Ride
Expand All @@ -65,7 +67,7 @@ VirtualRide virtual hashtag:

Components report imperial:

$ strava-gear --report components --units imperial <<END
$ strava-gear --report components --units imperial <<END | grep -v ^fr,
> name,gear_id,start_date,moving_time,distance,total_elevation_gain
> Ride 1,road,2022-01-01,3600,1000,10
> Ride 2,road,2023-01-01,3600,1000,10
Expand All @@ -77,3 +79,22 @@ Components report imperial:
c1,c1,0.621371192237334,1.0,2022-01-01 … 2022-01-01
c2,c2,0.621371192237334,1.0,2023-01-01 … 2023-01-01
c4,c4,0.621371192237334,1.0,2023-02-01 … 2023-02-01

Date range:

$ strava-gear --date-start 2023-01-01 <<END | grep frame
> name,gear_id,start_date,moving_time,distance,total_elevation_gain
> Ride 1,road,2022-01-01,3600,1000,10
> Ride 2,road,2023-01-01,3600,1000,10
> Ride 3,road,2023-02-01,3600,1000,10
> END
road,frame,fr,fr,2.0,2.0,2023-01-01 … 2023-02-01

$ strava-gear --date-end 2023-02-01 <<END | grep frame
> name,gear_id,start_date,moving_time,distance,total_elevation_gain
> Ride 1,road,2022-01-01,3600,1000,10
> Ride 2,road,2023-01-01,3600,1000,10
> Ride 3,road,2023-02-01,3600,1000,10
> END
road,frame,fr,fr,2.0,2.0,2022-01-01 … 2023-01-01

2 changes: 2 additions & 0 deletions tests/readme/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@
Show first/last usage of components [default: show-first-last]
--show-vert / --hide-vert Show vertical (elevation gain) [default: hide-vert]
--units [metric|imperial] Show data in metric or imperial [default: metric]
--date-start ISO8601 Filter activities: start at or after the specified date(time)
--date-end ISO8601 Filter activities: start before the specified date(time)
--help Show this message and exit.

0 comments on commit d235c90

Please sign in to comment.