garmin sync: fix same-day second activity skipped by date-only dedup
This commit is contained in:
@@ -133,18 +133,24 @@ def sync_activities(garmin, user_id: int, since: Optional[datetime],
|
||||
continue
|
||||
|
||||
# Slow-path dedup: activity imported via bulk export (no garmin_activity_id).
|
||||
# Check by start_time; stamp the ID so future syncs skip it in the fast path.
|
||||
act_start_str = act.get("startTimeLocal") or act.get("startTimeGMT") or ""
|
||||
# Match on the actual start instant (not just the date — two activities on
|
||||
# the same day are distinct), comparing GMT-to-GMT since FIT start_times are
|
||||
# stored in UTC. A small window absorbs sub-second/rounding differences.
|
||||
act_start_str = act.get("startTimeGMT") or ""
|
||||
if act_start_str:
|
||||
try:
|
||||
from datetime import datetime as _dt
|
||||
from datetime import datetime as _dt, timezone as _tz
|
||||
act_start = _dt.fromisoformat(act_start_str.replace("Z", "+00:00"))
|
||||
if act_start.tzinfo is None:
|
||||
act_start = act_start.replace(tzinfo=_tz.utc) # startTimeGMT is UTC
|
||||
window = timedelta(minutes=5)
|
||||
time_match = db.execute(
|
||||
select(Activity).where(
|
||||
Activity.user_id == user_id,
|
||||
func.date(Activity.start_time) == act_start.date(),
|
||||
Activity.start_time >= act_start - window,
|
||||
Activity.start_time <= act_start + window,
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
).scalars().first()
|
||||
if time_match:
|
||||
if not time_match.garmin_activity_id:
|
||||
time_match.garmin_activity_id = garmin_id
|
||||
|
||||
@@ -127,18 +127,24 @@ def sync_activities(garmin, user_id: int, since: Optional[datetime],
|
||||
continue
|
||||
|
||||
# Slow-path dedup: activity imported via bulk export (no garmin_activity_id).
|
||||
# Check by start_time; stamp the ID so future syncs skip it in the fast path.
|
||||
act_start_str = act.get("startTimeLocal") or act.get("startTimeGMT") or ""
|
||||
# Match on the actual start instant (not just the date — two activities on
|
||||
# the same day are distinct), comparing GMT-to-GMT since FIT start_times are
|
||||
# stored in UTC. A small window absorbs sub-second/rounding differences.
|
||||
act_start_str = act.get("startTimeGMT") or ""
|
||||
if act_start_str:
|
||||
try:
|
||||
from datetime import datetime as _dt
|
||||
from datetime import datetime as _dt, timezone as _tz
|
||||
act_start = _dt.fromisoformat(act_start_str.replace("Z", "+00:00"))
|
||||
if act_start.tzinfo is None:
|
||||
act_start = act_start.replace(tzinfo=_tz.utc) # startTimeGMT is UTC
|
||||
window = timedelta(minutes=5)
|
||||
time_match = db.execute(
|
||||
select(Activity).where(
|
||||
Activity.user_id == user_id,
|
||||
func.date(Activity.start_time) == act_start.date(),
|
||||
Activity.start_time >= act_start - window,
|
||||
Activity.start_time <= act_start + window,
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
).scalars().first()
|
||||
if time_match:
|
||||
if not time_match.garmin_activity_id:
|
||||
time_match.garmin_activity_id = garmin_id
|
||||
|
||||
Reference in New Issue
Block a user