checkpoint 3

This commit is contained in:
2025-08-25 05:43:38 -07:00
parent 1727435561
commit 8f0325f766
4 changed files with 49 additions and 24 deletions

View File

@@ -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
}

View File

@@ -1,28 +1,16 @@
package parser package parser
import "time" import (
"time"
"github.com/sstent/garminsync-go/internal/models"
)
// ActivityMetrics contains all metrics extracted from activity files // ActivityMetrics is now defined in internal/models
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
}
// Parser defines the interface for activity file parsers // Parser defines the interface for activity file parsers
type Parser interface { type Parser interface {
ParseFile(filename string) (*ActivityMetrics, error) ParseFile(filename string) (*models.ActivityMetrics, error)
} }
// FileType represents supported file formats // FileType represents supported file formats

View File

@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/tormoder/fit" "github.com/tormoder/fit"
"github.com/sstent/garminsync-go/internal/models"
) )
type FITParser struct{} type FITParser struct{}
@@ -15,7 +16,7 @@ func NewFITParser() *FITParser {
return &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) file, err := os.Open(filename)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -30,7 +31,7 @@ func (p *FITParser) ParseFile(filename string) (*ActivityMetrics, error) {
return p.ParseData(data) 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) fitFile, err := fit.Decode(data)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode FIT file: %w", err) 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] session := activity.Sessions[0]
metrics := &ActivityMetrics{} metrics := &models.ActivityMetrics{}
// Basic activity metrics // Basic activity metrics
metrics.StartTime = session.StartTime metrics.StartTime = session.StartTime

View File

@@ -3,13 +3,13 @@ package sync
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
"github.com/sstent/garminsync-go/internal/database" "github.com/sstent/garminsync-go/internal/database"
"github.com/sstent/garminsync-go/internal/garmin" "github.com/sstent/garminsync-go/internal/garmin"
"github.com/sstent/garminsync-go/internal/models"
"github.com/sstent/garminsync-go/internal/parser" "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 // Parse the file to extract additional metrics
metrics, err := parser.ParseFITData(fileData) metrics, err := s.parseActivityFile(fileData, "fit")
if err != nil { if err != nil {
return fmt.Errorf("failed to parse activity file: %w", err) return fmt.Errorf("failed to parse activity file: %w", err)
} }
@@ -135,6 +135,21 @@ func (s *SyncService) syncActivity(activity *garmin.GarminActivity) error {
return nil 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 { func parseTime(timeStr string) time.Time {
// Garmin time format: "2023-08-15 12:30:45" // Garmin time format: "2023-08-15 12:30:45"
t, err := time.Parse("2006-01-02 15:04:05", timeStr) t, err := time.Parse("2006-01-02 15:04:05", timeStr)