Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions garmin_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from seleniumbase import Driver

from .endpoints import (
activities_search_url,
activity_detail_endpoints,
daily_graphql,
daily_rest,
Expand Down Expand Up @@ -930,13 +931,11 @@ def _process_batch(batch_result, cal_date=None):
full = self._fetch_batch(full_rest, full_gql)
_process_batch(full)

# 2b. Paginate through ALL activities
# 2b. Paginate remaining activities within the date range
page_start = 100
while True:
act_result = self._fetch_batch(
{
f"activities_page_{page_start}": f"/gc-api/activitylist-service/activities/search/activities?limit=100&start={page_start}"
},
{f"activities_page_{page_start}": activities_search_url(s_date, e_date, offset=page_start)},
{},
)
page_data = act_result.get(f"activities_page_{page_start}", {})
Expand Down Expand Up @@ -1034,9 +1033,7 @@ def _process_batch(batch_result, cal_date=None):

if not activity_ids and on_batch:
try:
act_data = self.api_fetch(
"/gc-api/activitylist-service/activities/search/activities?limit=1000&start=0"
)
act_data = self.api_fetch(activities_search_url(s_date, e_date, limit=1000))
if isinstance(act_data, list):
all_api_ids = [a.get("activityId") for a in act_data if a.get("activityId")]
activity_ids = [aid for aid in all_api_ids if aid not in (known_activity_ids or set())]
Expand Down
10 changes: 7 additions & 3 deletions garmin_client/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,17 @@ def profile_graphql(display_name: str) -> dict:
}


def activities_search_url(start_date: str, end_date: str, limit: int = 100, offset: int = 0) -> str:
"""Build the activities search URL with date filtering."""
return f"/gc-api/activitylist-service/activities/search/activities?limit={limit}&start={offset}&startDate={start_date}&endDate={end_date}"


def full_range_rest(display_name: str, start_date: str, end_date: str) -> dict:
"""REST endpoints that support full date ranges."""
dn = display_name
return {
# Note: this returns max ~20-100 activities per page. Pagination
# is handled in client.py fetch_all() to get ALL activities.
"activities": "/gc-api/activitylist-service/activities/search/activities?limit=100&start=0",
# Pagination is handled in client.py fetch_all().
"activities": activities_search_url(start_date, end_date),
"weight_range": f"/gc-api/weight-service/weight/dateRange?startDate={start_date}&endDate={end_date}",
"weight_latest": f"/gc-api/weight-service/weight/latest?date={end_date}",
"vo2max_trend": f"/gc-api/metrics-service/metrics/maxmet/daily/{start_date}/{end_date}",
Expand Down
9 changes: 8 additions & 1 deletion garmin_givemydata.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ def main():
help="Download FIT files only, skip health data sync",
)
fit_group.add_argument(
"--latest", action="store_true", help="Download only the latest FIT file (use with --fit-only)"
"--latest",
action="store_true",
help="Fetch only today's data (or download only the latest FIT file with --fit-only)",
)
fit_group.add_argument(
"--date", type=str, help="Download FIT file for a specific date YYYY-MM-DD (use with --fit-only)"
Expand Down Expand Up @@ -403,6 +405,11 @@ def main():
mode = "full"
start = (today - timedelta(days=365 * 10)).isoformat()
end = today.isoformat()
elif args.latest and not args.fit_only:
mode = "incremental"
start = today.isoformat()
end = today.isoformat()
print(f"Fetching latest data for {today.isoformat()}")
elif args.days:
mode = "range"
start = (today - timedelta(days=args.days)).isoformat()
Expand Down