diff options
Diffstat (limited to 'web')
| -rw-r--r-- | web/server.go | 2 | ||||
| -rw-r--r-- | web/server_test.go | 13 | ||||
| -rw-r--r-- | web/sync.go | 33 |
3 files changed, 33 insertions, 15 deletions
diff --git a/web/server.go b/web/server.go index 06b4ace..bde45ca 100644 --- a/web/server.go +++ b/web/server.go @@ -29,7 +29,7 @@ type Server struct { type syncClient interface { List(from, to time.Time) ([]strava.Activity, error) - Get(id int64) (strava.Activity, []byte, error) + Get(id int64) (strava.Activity, []byte, []byte, error) } func NewServer(db *sql.DB, configPath string) *Server { diff --git a/web/server_test.go b/web/server_test.go index 7137031..e9444c7 100644 --- a/web/server_test.go +++ b/web/server_test.go @@ -53,6 +53,7 @@ type fakeSyncClient struct { type fakeSyncResult struct { activity strava.Activity data []byte + fitData []byte err error } @@ -60,12 +61,16 @@ func (c fakeSyncClient) List(time.Time, time.Time) ([]strava.Activity, error) { return c.activities, nil } -func (c fakeSyncClient) Get(id int64) (strava.Activity, []byte, error) { +func (c fakeSyncClient) Get(id int64) (strava.Activity, []byte, []byte, error) { result, ok := c.results[id] if !ok { - return strava.Activity{}, nil, fmt.Errorf("missing fake activity %d", id) + return strava.Activity{}, nil, nil, fmt.Errorf("missing fake activity %d", id) } - return result.activity, result.data, result.err + fitData := result.fitData + if fitData == nil && result.data != nil { + fitData = result.data + } + return result.activity, result.data, fitData, result.err } const emptyTrackGPX = `<?xml version="1.0"?><gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1"><trk><trkseg></trkseg></trk></gpx>` @@ -684,7 +689,7 @@ func (c countingSyncClient) List(from, to time.Time) ([]strava.Activity, error) return c.inner.List(from, to) } -func (c countingSyncClient) Get(id int64) (strava.Activity, []byte, error) { +func (c countingSyncClient) Get(id int64) (strava.Activity, []byte, []byte, error) { *c.getCalled = true return c.inner.Get(id) } diff --git a/web/sync.go b/web/sync.go index f6dc7da..8ed306f 100644 --- a/web/sync.go +++ b/web/sync.go @@ -78,7 +78,7 @@ func (s *Server) handleSync(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Content-Type", "text/event-stream") - progress, err := s.syncRides(client, appConfig.Storage.GPXDir, from, to, func(progress SyncProgress) error { + progress, err := s.syncRides(client, appConfig.Storage.RidesDir, from, to, func(progress SyncProgress) error { enrichProgressRateLimit(&progress, client) return writeSyncEvent(w, flusher, "progress", progress) }) @@ -104,7 +104,7 @@ func (s *Server) handleSync(w http.ResponseWriter, r *http.Request) { _ = writeSyncEvent(w, flusher, "complete", progress) } -func (s *Server) syncRides(client syncClient, gpxDir string, from, to time.Time, report func(SyncProgress) error) (SyncProgress, error) { +func (s *Server) syncRides(client syncClient, ridesDir string, from, to time.Time, report func(SyncProgress) error) (SyncProgress, error) { activities, err := client.List(from, to) if err != nil { if rateErr, ok := errors.AsType[*strava.RateLimitError](err); ok { @@ -117,8 +117,8 @@ func (s *Server) syncRides(client syncClient, gpxDir string, from, to time.Time, return progress, err } slog.Info("Started Strava sync", "from", from.Format(dateFormat), "to", to.Add(-24*time.Hour).Format(dateFormat), "total", progress.Total) - if err := os.MkdirAll(gpxDir, 0o755); err != nil { - return progress, fmt.Errorf("create GPX directory: %w", err) + if err := os.MkdirAll(ridesDir, 0o755); err != nil { + return progress, fmt.Errorf("create rides directory: %w", err) } for _, summary := range activities { externalID := fmt.Sprintf("strava:%d", summary.ID) @@ -146,15 +146,16 @@ func (s *Server) syncRides(client syncClient, gpxDir string, from, to time.Time, } continue } - activity, gpxData, err := client.Get(summary.ID) + activity, gpxData, fitData, err := client.Get(summary.ID) if err != nil { if rateErr, ok := errors.AsType[*strava.RateLimitError](err); ok { slog.Warn("Strava sync rate limited", "activity", summary.ID, "name", summary.Name, "retryAfter", rateErr.RetryAfter, "isDaily", rateErr.IsDaily, "completed", progress.Completed, "total", progress.Total) return progress, err } if errors.Is(err, strava.ErrNoTrackPoints) { - _ = os.Remove(filepath.Join(gpxDir, fmt.Sprintf("activity_%d.gpx", summary.ID))) - if saveErr := ride.Save(s.db, rideFromActivity(externalID, "", activity)); saveErr != nil { + _ = os.Remove(filepath.Join(ridesDir, fmt.Sprintf("activity_%d.gpx", summary.ID))) + _ = os.Remove(filepath.Join(ridesDir, fmt.Sprintf("activity_%d.fit", summary.ID))) + if saveErr := ride.Save(s.db, rideFromActivity(externalID, "", "", activity)); saveErr != nil { if reportErr := skipSyncActivity(&progress, report, summary, fmt.Errorf("save metadata: %w", saveErr)); reportErr != nil { return progress, reportErr } @@ -173,16 +174,27 @@ func (s *Server) syncRides(client syncClient, gpxDir string, from, to time.Time, } continue } - gpxPath := filepath.Join(gpxDir, fmt.Sprintf("activity_%d.gpx", activity.ID)) + gpxPath := filepath.Join(ridesDir, fmt.Sprintf("activity_%d.gpx", activity.ID)) + fitPath := filepath.Join(ridesDir, fmt.Sprintf("activity_%d.fit", activity.ID)) if err := os.WriteFile(gpxPath, gpxData, 0o644); err != nil { _ = os.Remove(gpxPath) + _ = os.Remove(fitPath) if reportErr := skipSyncActivity(&progress, report, summary, fmt.Errorf("write GPX: %w", err)); reportErr != nil { return progress, reportErr } continue } - if err := ride.Save(s.db, rideFromActivity(externalID, gpxPath, activity)); err != nil { + if err := os.WriteFile(fitPath, fitData, 0o644); err != nil { _ = os.Remove(gpxPath) + _ = os.Remove(fitPath) + if reportErr := skipSyncActivity(&progress, report, summary, fmt.Errorf("write FIT: %w", err)); reportErr != nil { + return progress, reportErr + } + continue + } + if err := ride.Save(s.db, rideFromActivity(externalID, gpxPath, fitPath, activity)); err != nil { + _ = os.Remove(gpxPath) + _ = os.Remove(fitPath) if reportErr := skipSyncActivity(&progress, report, summary, fmt.Errorf("save activity: %w", err)); reportErr != nil { return progress, reportErr } @@ -198,7 +210,7 @@ func (s *Server) syncRides(client syncClient, gpxDir string, from, to time.Time, return progress, nil } -func rideFromActivity(externalID, gpxPath string, activity strava.Activity) ride.StoredRide { +func rideFromActivity(externalID, gpxPath, fitPath string, activity strava.Activity) ride.StoredRide { activityType := activity.SportType if activityType == "" { activityType = activity.Type @@ -206,6 +218,7 @@ func rideFromActivity(externalID, gpxPath string, activity strava.Activity) ride return ride.StoredRide{ ExternalID: externalID, GPXPath: gpxPath, + FitPath: fitPath, Name: activity.Name, Type: activityType, StartDate: activity.StartDate, |
