diff --git a/internal/models/activity_metrics.go b/internal/models/activity_metrics.go new file mode 100644 index 0000000..73824c1 --- /dev/null +++ b/internal/models/activity_metrics.go @@ -0,0 +1,21 @@ +package models + +import "time" + +// ActivityMetrics contains all metrics extracted from activity files +type ActivityMetrics struct { + ActivityType string + StartTime time.Time + Duration time.Duration + Distance float64 // in meters + MaxHeartRate int + AvgHeartRate int + AvgPower int + Calories int + Steps int + ElevationGain float64 // in meters + ElevationLoss float64 // in meters + MinTemperature float64 // in °C + MaxTemperature float64 // in °C + AvgTemperature float64 // in °C +} diff --git a/internal/parser/activity.go b/internal/parser/activity.go index 232879a..4987dd1 100644 --- a/internal/parser/activity.go +++ b/internal/parser/activity.go @@ -1,28 +1,16 @@ package parser -import "time" +import ( + "time" + + "github.com/sstent/garminsync-go/internal/models" +) -// ActivityMetrics contains all metrics extracted from activity files -type ActivityMetrics struct { - ActivityType string - StartTime time.Time - Duration time.Duration - Distance float64 // in meters - MaxHeartRate int - AvgHeartRate int - AvgPower int - Calories int - Steps int - ElevationGain float64 // in meters - ElevationLoss float64 // in meters - MinTemperature float64 // in °C - MaxTemperature float64 // in °C - AvgTemperature float64 // in °C -} +// ActivityMetrics is now defined in internal/models // Parser defines the interface for activity file parsers type Parser interface { - ParseFile(filename string) (*ActivityMetrics, error) + ParseFile(filename string) (*models.ActivityMetrics, error) } // FileType represents supported file formats diff --git a/internal/parser/fit_parser.go b/internal/parser/fit_parser.go index d531c94..8580d6d 100644 --- a/internal/parser/fit_parser.go +++ b/internal/parser/fit_parser.go @@ -7,6 +7,7 @@ import ( "time" "github.com/tormoder/fit" + "github.com/sstent/garminsync-go/internal/models" ) type FITParser struct{} @@ -15,7 +16,7 @@ func NewFITParser() *FITParser { return &FITParser{} } -func (p *FITParser) ParseFile(filename string) (*ActivityMetrics, error) { +func (p *FITParser) ParseFile(filename string) (*models.ActivityMetrics, error) { file, err := os.Open(filename) if err != nil { return nil, err @@ -30,7 +31,7 @@ func (p *FITParser) ParseFile(filename string) (*ActivityMetrics, error) { return p.ParseData(data) } -func (p *FITParser) ParseData(data []byte) (*ActivityMetrics, error) { +func (p *FITParser) ParseData(data []byte) (*models.ActivityMetrics, error) { fitFile, err := fit.Decode(data) if err != nil { return nil, fmt.Errorf("failed to decode FIT file: %w", err) @@ -46,7 +47,7 @@ func (p *FITParser) ParseData(data []byte) (*ActivityMetrics, error) { } session := activity.Sessions[0] - metrics := &ActivityMetrics{} + metrics := &models.ActivityMetrics{} // Basic activity metrics metrics.StartTime = session.StartTime diff --git a/internal/sync/sync.go b/internal/sync/sync.go index b7483a2..e8d01de 100644 --- a/internal/sync/sync.go +++ b/internal/sync/sync.go @@ -3,13 +3,13 @@ package sync import ( "context" "fmt" - "io" "os" "path/filepath" "time" "github.com/sstent/garminsync-go/internal/database" "github.com/sstent/garminsync-go/internal/garmin" + "github.com/sstent/garminsync-go/internal/models" "github.com/sstent/garminsync-go/internal/parser" ) @@ -110,7 +110,7 @@ func (s *SyncService) syncActivity(activity *garmin.GarminActivity) error { } // Parse the file to extract additional metrics - metrics, err := parser.ParseFITData(fileData) + metrics, err := s.parseActivityFile(fileData, "fit") if err != nil { return fmt.Errorf("failed to parse activity file: %w", err) } @@ -135,6 +135,21 @@ func (s *SyncService) syncActivity(activity *garmin.GarminActivity) error { return nil } +func (s *SyncService) parseActivityFile(fileData []byte, fileType string) (*models.ActivityMetrics, error) { + switch fileType { + case "fit": + return parser.ParseFITData(fileData) + case "tcx": + // TODO: Implement TCX parsing + return nil, fmt.Errorf("TCX parsing not implemented yet") + case "gpx": + // TODO: Implement GPX parsing + return nil, fmt.Errorf("GPX parsing not implemented yet") + default: + return nil, fmt.Errorf("unsupported file type: %s", fileType) + } +} + func parseTime(timeStr string) time.Time { // Garmin time format: "2023-08-15 12:30:45" t, err := time.Parse("2006-01-02 15:04:05", timeStr)