mirror of
https://github.com/sstent/garminsync-go.git
synced 2025-12-06 08:01:52 +00:00
66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
package parser
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/tormoder/fit"
|
|
"github.com/sstent/garminsync-go/internal/models"
|
|
)
|
|
|
|
// Parser handles FIT file parsing
|
|
type Parser struct{}
|
|
|
|
func NewParser() *Parser {
|
|
return &Parser{}
|
|
}
|
|
|
|
func (p *Parser) ParseFile(filename string) (*models.ActivityMetrics, error) {
|
|
file, err := os.Open(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return p.ParseData(data)
|
|
}
|
|
|
|
func (p *Parser) ParseData(data []byte) (*models.ActivityMetrics, error) {
|
|
fitFile, err := fit.Decode(bytes.NewReader(data))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to decode FIT file: %w", err)
|
|
}
|
|
|
|
activity, err := fitFile.Activity()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get activity from FIT: %w", err)
|
|
}
|
|
|
|
if len(activity.Sessions) == 0 {
|
|
return nil, fmt.Errorf("no sessions found in FIT file")
|
|
}
|
|
|
|
session := activity.Sessions[0]
|
|
metrics := &models.ActivityMetrics{
|
|
StartTime: session.StartTime,
|
|
Duration: time.Duration(session.TotalTimerTime) * time.Second,
|
|
Distance: float64(session.TotalDistance),
|
|
AvgHeartRate: int(session.AvgHeartRate),
|
|
MaxHeartRate: int(session.MaxHeartRate),
|
|
AvgPower: int(session.AvgPower),
|
|
Calories: int(session.TotalCalories),
|
|
ElevationGain: float64(session.TotalAscent),
|
|
ElevationLoss: float64(session.TotalDescent),
|
|
Steps: 0, // FIT sessions don't include steps
|
|
}
|
|
|
|
return metrics, nil
|
|
}
|