summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-05 15:02:09 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-05 15:02:09 +0200
commitb6ca97fe994c46737e0aa5c73e8b3d924ddaecd2 (patch)
tree76ed491b85468cb5812bf0d7efafe95fa1cf14f7
parent71c39ed9f8ce3563130cdfc5099e9d7df60845a9 (diff)
refactor: Remove obsolete Strava helpers and add mise tasks
-rw-r--r--.mise.toml27
-rw-r--r--README.md4
-rw-r--r--strava/strava.go11
-rw-r--r--strava/strava_test.go15
-rw-r--r--strava/sync.go21
-rw-r--r--strava/sync_test.go48
6 files changed, 36 insertions, 90 deletions
diff --git a/.mise.toml b/.mise.toml
new file mode 100644
index 0000000..69f2629
--- /dev/null
+++ b/.mise.toml
@@ -0,0 +1,27 @@
+[tools]
+go = "1.25.12"
+
+[tasks.generate]
+description = "Generate templ Go files"
+run = "go run github.com/a-h/templ/cmd/templ@v0.2.747 generate"
+
+[tasks.format]
+description = "Format Go sources"
+run = "go fmt ./..."
+
+[tasks.check]
+description = "Run generation, vet, and tests"
+depends = ["generate", "format"]
+run = "go vet ./... && go test ./..."
+
+[tasks.build]
+description = "Build the application"
+run = "go build -o biking_home ."
+
+[tasks.migrate]
+description = "Apply SQLite migrations"
+run = "DATABASE_URL=sqlite:biking_home.db go run github.com/amacneil/dbmate up"
+
+[tasks.dev]
+description = "Run the web server"
+run = "go run ."
diff --git a/README.md b/README.md
index a2a2889..611266c 100644
--- a/README.md
+++ b/README.md
@@ -116,8 +116,8 @@ flowchart TB
## Development
```bash
-go vet ./...
-go test ./...
+mise run check
+mise run build
```
## TODO
diff --git a/strava/strava.go b/strava/strava.go
index c7a84d0..7c555be 100644
--- a/strava/strava.go
+++ b/strava/strava.go
@@ -12,10 +12,9 @@ import (
)
const (
- AuthURL = "https://www.strava.com/oauth/authorize"
- TokenURL = "https://www.strava.com/oauth/token"
- APIURL = "https://www.strava.com/api/v3"
- LoginPort = 8787
+ AuthURL = "https://www.strava.com/oauth/authorize"
+ TokenURL = "https://www.strava.com/oauth/token"
+ APIURL = "https://www.strava.com/api/v3"
)
var (
@@ -29,10 +28,6 @@ type Token struct {
ExpiresAt time.Time
}
-func AuthorizeURL(clientID, redirectURI string) string {
- return AuthorizeURLWithState(clientID, redirectURI, "")
-}
-
func AuthorizeURLWithState(clientID, redirectURI, state string) string {
q := url.Values{}
q.Set("client_id", clientID)
diff --git a/strava/strava_test.go b/strava/strava_test.go
index 7120434..fdfa305 100644
--- a/strava/strava_test.go
+++ b/strava/strava_test.go
@@ -3,7 +3,6 @@ package strava
import (
"net/http"
"net/http/httptest"
- "net/url"
"testing"
"time"
@@ -11,20 +10,6 @@ import (
"github.com/stretchr/testify/require"
)
-func TestAuthorizeURL(t *testing.T) {
- u := AuthorizeURL("12345", "http://localhost:8787/callback")
- parsed, err := url.Parse(u)
- require.NoError(t, err)
- assert.Equal(t, "https", parsed.Scheme)
- assert.Equal(t, "www.strava.com", parsed.Host)
- assert.Equal(t, "/oauth/authorize", parsed.Path)
- q := parsed.Query()
- assert.Equal(t, "12345", q.Get("client_id"))
- assert.Equal(t, "http://localhost:8787/callback", q.Get("redirect_uri"))
- assert.Equal(t, "code", q.Get("response_type"))
- assert.Equal(t, "activity:read_all", q.Get("scope"))
-}
-
func TestExchangeCode(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
diff --git a/strava/sync.go b/strava/sync.go
index 2044f28..e798410 100644
--- a/strava/sync.go
+++ b/strava/sync.go
@@ -3,7 +3,6 @@ package strava
import (
"fmt"
"net/url"
- "os"
"strconv"
"time"
@@ -64,27 +63,23 @@ func (c *Client) list(from, to time.Time, types ...string) ([]Activity, error) {
return all, nil
}
-func (c *Client) ListActivities(after time.Time, types ...string) ([]Activity, error) {
- return c.list(after, time.Time{}, types...)
-}
-
func (c *Client) Get(id int64) (Activity, []byte, error) {
var activity Activity
if err := c.GetJSON(fmt.Sprintf("/activities/%d", id), &activity); err != nil {
return Activity{}, nil, kcore.Wrap(err, "failed to get Strava activity")
}
- latlng, altitude, seconds, err := c.ActivityStreams(id)
+ latlng, altitude, seconds, err := c.activityStreams(id)
if err != nil {
return Activity{}, nil, err
}
- gpxData, err := ActivityGPX(activity, latlng, altitude, seconds)
+ gpxData, err := activityGPX(activity, latlng, altitude, seconds)
if err != nil {
return Activity{}, nil, err
}
return activity, gpxData, nil
}
-func (c *Client) ActivityStreams(id int64) (latlng [][2]float64, altitude []float64, seconds []float64, err error) {
+func (c *Client) activityStreams(id int64) (latlng [][2]float64, altitude []float64, seconds []float64, err error) {
path := fmt.Sprintf("/activities/%d/streams?keys=latlng,altitude,time&key_by_type=true", id)
var streams struct {
LatLng *struct {
@@ -113,7 +108,7 @@ func (c *Client) ActivityStreams(id int64) (latlng [][2]float64, altitude []floa
return latlng, altitude, seconds, nil
}
-func ActivityGPX(activity Activity, latlng [][2]float64, altitude, seconds []float64) ([]byte, error) {
+func activityGPX(activity Activity, latlng [][2]float64, altitude, seconds []float64) ([]byte, error) {
points := make([]gpx.GPXPoint, len(latlng))
for i := range latlng {
point := gpx.GPXPoint{}
@@ -142,11 +137,3 @@ func ActivityGPX(activity Activity, latlng [][2]float64, altitude, seconds []flo
}
return xmlData, nil
}
-
-func WriteActivityGPX(file string, activity Activity, latlng [][2]float64, altitude, seconds []float64) error {
- xmlData, err := ActivityGPX(activity, latlng, altitude, seconds)
- if err != nil {
- return err
- }
- return os.WriteFile(file, xmlData, 0o644)
-}
diff --git a/strava/sync_test.go b/strava/sync_test.go
index 1ddf439..04f3c64 100644
--- a/strava/sync_test.go
+++ b/strava/sync_test.go
@@ -4,8 +4,6 @@ import (
"fmt"
"net/http"
"net/http/httptest"
- "os"
- "path/filepath"
"testing"
"time"
@@ -79,49 +77,3 @@ func TestGet(t *testing.T) {
require.NoError(t, err)
require.Len(t, parsed.Tracks[0].Segments[0].Points, 2)
}
-
-func TestActivityStreams(t *testing.T) {
- client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
- require.Equal(t, "/activities/42/streams", r.URL.Path)
- assert.Equal(t, "latlng,altitude,time", r.URL.Query().Get("keys"))
- w.Header().Set("Content-Type", "application/json")
- _, err := w.Write([]byte(`{
- "latlng":{"type":"latlng","data":[[43.0,5.0],[43.1,5.1],[43.2,5.2]]},
- "altitude":{"type":"altitude","data":[100,120,140]},
- "time":{"type":"time","data":[0,10,25]}
- }`))
- require.NoError(t, err)
- })
-
- latlng, altitude, seconds, err := client.ActivityStreams(42)
- require.NoError(t, err)
- require.Len(t, latlng, 3)
- assert.Equal(t, [2]float64{43.0, 5.0}, latlng[0])
- assert.Equal(t, []float64{100, 120, 140}, altitude)
- assert.Equal(t, []float64{0, 10, 25}, seconds)
-}
-
-func TestWriteActivityGPX(t *testing.T) {
- activity := Activity{ID: 42, Name: "Ride A", StartDate: time.Date(2026, 1, 1, 10, 0, 0, 0, time.UTC)}
- latlng := [][2]float64{{43.0, 5.0}, {43.1, 5.1}}
- altitude := []float64{100, 120}
- seconds := []float64{0, 10}
-
- file := filepath.Join(t.TempDir(), "activity_42.gpx")
- err := WriteActivityGPX(file, activity, latlng, altitude, seconds)
- require.NoError(t, err)
-
- data, err := os.ReadFile(file)
- require.NoError(t, err)
- parsed, err := gpx.ParseBytes(data)
- require.NoError(t, err)
- require.Len(t, parsed.Tracks, 1)
- require.Len(t, parsed.Tracks[0].Segments, 1)
- points := parsed.Tracks[0].Segments[0].Points
- require.Len(t, points, 2)
- assert.Equal(t, 43.0, points[0].Latitude)
- assert.Equal(t, 5.1, points[1].Longitude)
- assert.Equal(t, 100.0, points[0].Elevation.Value())
- assert.Equal(t, activity.StartDate.Add(10*time.Second), points[1].Timestamp)
- assert.Equal(t, "Ride A", parsed.Name)
-}