mirror of
https://github.com/sstent/go-garth.git
synced 2026-02-07 06:51:44 +00:00
feat: Implement Phase 1C.2: Multi-Format Support
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -57,6 +60,7 @@ var (
|
|||||||
// Flags for downloadActivitiesCmd
|
// Flags for downloadActivitiesCmd
|
||||||
downloadFormat string
|
downloadFormat string
|
||||||
outputDir string
|
outputDir string
|
||||||
|
downloadOriginal bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -72,8 +76,9 @@ func init() {
|
|||||||
activitiesCmd.AddCommand(getActivitiesCmd)
|
activitiesCmd.AddCommand(getActivitiesCmd)
|
||||||
|
|
||||||
activitiesCmd.AddCommand(downloadActivitiesCmd)
|
activitiesCmd.AddCommand(downloadActivitiesCmd)
|
||||||
downloadActivitiesCmd.Flags().StringVar(&downloadFormat, "format", "gpx", "Download format (gpx, tcx, csv)")
|
downloadActivitiesCmd.Flags().StringVar(&downloadFormat, "format", "gpx", "Download format (gpx, tcx, fit, csv)")
|
||||||
downloadActivitiesCmd.Flags().StringVar(&outputDir, "output-dir", ".", "Output directory for downloaded files")
|
downloadActivitiesCmd.Flags().StringVar(&outputDir, "output-dir", ".", "Output directory for downloaded files")
|
||||||
|
downloadActivitiesCmd.Flags().BoolVar(&downloadOriginal, "original", false, "Download original uploaded file")
|
||||||
|
|
||||||
activitiesCmd.AddCommand(searchActivitiesCmd)
|
activitiesCmd.AddCommand(searchActivitiesCmd)
|
||||||
searchActivitiesCmd.Flags().StringP("query", "q", "", "Query string to search for activities")
|
searchActivitiesCmd.Flags().StringP("query", "q", "", "Query string to search for activities")
|
||||||
@@ -180,9 +185,49 @@ func runDownloadActivity(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("not logged in: %w", err)
|
return fmt.Errorf("not logged in: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if downloadFormat == "csv" {
|
||||||
|
activityDetail, err := garminClient.GetActivity(activityID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get activity details for CSV export: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := fmt.Sprintf("%d.csv", activityID)
|
||||||
|
outputPath := filename
|
||||||
|
if outputDir != "" {
|
||||||
|
outputPath = filepath.Join(outputDir, filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(outputPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create CSV file: %w", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
writer := csv.NewWriter(file)
|
||||||
|
defer writer.Flush()
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
writer.Write([]string{"ActivityID", "ActivityName", "ActivityType", "StartTime", "Distance(km)", "Duration(s)", "Description"})
|
||||||
|
|
||||||
|
// Write data
|
||||||
|
writer.Write([]string{
|
||||||
|
fmt.Sprintf("%d", activityDetail.ActivityID),
|
||||||
|
activityDetail.ActivityName,
|
||||||
|
activityDetail.ActivityType,
|
||||||
|
activityDetail.Starttime.Format("2006-01-02 15:04:05"),
|
||||||
|
fmt.Sprintf("%.2f", activityDetail.Distance/1000),
|
||||||
|
fmt.Sprintf("%.0f", activityDetail.Duration),
|
||||||
|
activityDetail.Description,
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Printf("Activity %d summary exported to %s\n", activityID, outputPath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
opts := garmin.DownloadOptions{
|
opts := garmin.DownloadOptions{
|
||||||
Format: downloadFormat,
|
Format: downloadFormat,
|
||||||
OutputDir: outputDir,
|
OutputDir: outputDir,
|
||||||
|
Original: downloadOriginal,
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Downloading activity %d in %s format to %s...\n", activityID, downloadFormat, outputDir)
|
fmt.Printf("Downloading activity %d in %s format to %s...\n", activityID, downloadFormat, outputDir)
|
||||||
|
|||||||
@@ -331,9 +331,13 @@ func (c *Client) Upload(filePath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Download retrieves a file from Garmin Connect
|
// Download retrieves a file from Garmin Connect
|
||||||
func (c *Client) Download(activityID string, filePath string) error {
|
func (c *Client) Download(activityID string, format string, filePath string) error {
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("activityId", activityID)
|
params.Add("activityId", activityID)
|
||||||
|
// Add format parameter if provided and not empty
|
||||||
|
if format != "" {
|
||||||
|
params.Add("format", format)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := c.ConnectAPI("/download-service/export", "GET", params, nil)
|
resp, err := c.ConnectAPI("/download-service/export", "GET", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
14
phase1.md
14
phase1.md
@@ -306,16 +306,16 @@ func (c *Client) DownloadActivity(id string, opts *DownloadOptions) error {
|
|||||||
**Duration: 2 days**
|
**Duration: 2 days**
|
||||||
|
|
||||||
**Tasks:**
|
**Tasks:**
|
||||||
- [ ] Implement TCX format download
|
- [x] Implement TCX format download
|
||||||
- [ ] Implement FIT format download (if available)
|
- [x] Implement FIT format download (if available)
|
||||||
- [ ] Add CSV export for activity summaries
|
- [x] Add CSV export for activity summaries
|
||||||
- [ ] Format validation and conversion
|
- [x] Format validation and conversion
|
||||||
- [ ] Add format-specific options
|
- [x] Add format-specific options
|
||||||
|
|
||||||
**Deliverables:**
|
**Deliverables:**
|
||||||
- [ ] Support for GPX, TCX, and CSV formats
|
- [x] Support for GPX, TCX, and CSV formats
|
||||||
- [ ] Format auto-detection
|
- [ ] Format auto-detection
|
||||||
- [ ] Format-specific download options
|
- [x] Format-specific download options
|
||||||
|
|
||||||
#### 1C.3: Batch Download Features
|
#### 1C.3: Batch Download Features
|
||||||
**Duration: 1 day**
|
**Duration: 1 day**
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func (c *Client) DownloadActivity(activityID int, opts activities.DownloadOption
|
|||||||
outputPath = filepath.Join(opts.OutputDir, filename)
|
outputPath = filepath.Join(opts.OutputDir, filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Client.Download(fmt.Sprintf("%d", activityID), outputPath)
|
return c.Client.Download(fmt.Sprintf("%d", activityID), opts.Format, outputPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchActivities searches for activities by a query string
|
// SearchActivities searches for activities by a query string
|
||||||
|
|||||||
Reference in New Issue
Block a user