83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
package export
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"rideaware/internal/user"
|
|
"rideaware/internal/workout"
|
|
)
|
|
|
|
type Service struct {
|
|
workoutRepo *workout.Repository
|
|
userRepo *user.Repository
|
|
}
|
|
|
|
func NewService() *Service {
|
|
return &Service{
|
|
workoutRepo: workout.NewRepository(),
|
|
userRepo: user.NewRepository(),
|
|
}
|
|
}
|
|
|
|
func (s *Service) ExportFIT(workoutID, userID uint) ([]byte, string, error) {
|
|
w, err := s.workoutRepo.GetWorkoutByID(workoutID, userID)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("workout not found: %w", err)
|
|
}
|
|
|
|
u, err := s.userRepo.GetUserByID(userID)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("user not found: %w", err)
|
|
}
|
|
|
|
ftp := 0
|
|
if u.Profile != nil {
|
|
ftp = u.Profile.FTP
|
|
}
|
|
if ftp <= 0 {
|
|
return nil, "", fmt.Errorf("FTP must be set in your profile before exporting FIT files")
|
|
}
|
|
|
|
data, err := EncodeFITWorkout(w, ftp)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
filename := sanitizeFilename(w.Title) + ".fit"
|
|
return data, filename, nil
|
|
}
|
|
|
|
func (s *Service) ExportZWO(workoutID, userID uint) ([]byte, string, error) {
|
|
w, err := s.workoutRepo.GetWorkoutByID(workoutID, userID)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("workout not found: %w", err)
|
|
}
|
|
|
|
data, err := GenerateZWO(w)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
filename := sanitizeFilename(w.Title) + ".zwo"
|
|
return data, filename, nil
|
|
}
|
|
|
|
func sanitizeFilename(name string) string {
|
|
if name == "" {
|
|
return "workout"
|
|
}
|
|
result := make([]byte, 0, len(name))
|
|
for _, c := range name {
|
|
switch {
|
|
case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9':
|
|
result = append(result, byte(c))
|
|
case c == ' ' || c == '-' || c == '_':
|
|
result = append(result, '_')
|
|
}
|
|
}
|
|
if len(result) == 0 {
|
|
return "workout"
|
|
}
|
|
return string(result)
|
|
}
|