From 72fef2e3b2a6d3f2655709c2d85d13fa3947eee3 Mon Sep 17 00:00:00 2001 From: froge Date: Wed, 12 Feb 2025 14:31:19 +1000 Subject: [PATCH] Run go fmt --- auth.go | 48 ++++++++++++++++++++++---------------------- auth_test.go | 2 +- database.go | 40 ++++++++++++++++++------------------- main.go | 40 ++++++++++++++++++------------------- routes.go | 50 +++++++++++++++++++++++----------------------- routes_test.go | 10 +++++----- utils.go | 54 +++++++++++++++++++++++++------------------------- 7 files changed, 122 insertions(+), 122 deletions(-) diff --git a/auth.go b/auth.go index 0f3b884..f1a491f 100644 --- a/auth.go +++ b/auth.go @@ -1,27 +1,27 @@ package main import ( - "github.com/gin-gonic/gin" - "encoding/base64" - "encoding/json" - "net/http" - "log/slog" - "strings" - "time" - "fmt" - "io" + "encoding/base64" + "encoding/json" + "fmt" + "github.com/gin-gonic/gin" + "io" + "log/slog" + "net/http" + "strings" + "time" ) // Used to unmarshal response data into type safe struct type SpotifyToken struct { AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresIn int `json:"expires_in"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` } // Makes a HTTP request to grab a short lived access token from Spotify func getSpotifyToken(clientID string, clientSecret string) (SpotifyToken, error) { - + // See spotify API docs for details on parameters/urls required here // https://developer.spotify.com/documentation/web-api/tutorials/client-credentials-flow spotifyAuthURL := "https://accounts.spotify.com/api/token" @@ -43,7 +43,7 @@ func getSpotifyToken(clientID string, clientSecret string) (SpotifyToken, error) if err != nil { slog.Error("[GOMUSIC] Failed to send authentication request to spotify", "Error", err) return SpotifyToken{}, fmt.Errorf("Failed to authenticate with spotify: %w", err) - + } else if resp.StatusCode != 200 { slog.Error("[GOMUSIC] Failed to authenticate with spotify", "Error", resp.Status) return SpotifyToken{}, fmt.Errorf("Failed to authenticate with spotify: %s", resp.Status) @@ -56,13 +56,13 @@ func getSpotifyToken(clientID string, clientSecret string) (SpotifyToken, error) // Close this immediately since it's unused now resp.Body.Close() - var spotifyToken SpotifyToken + var spotifyToken SpotifyToken err = json.Unmarshal(respData, &spotifyToken) if err != nil { slog.Error("[GOMUSIC] Failed to parse spotify authentication response", "Error", err) return SpotifyToken{}, fmt.Errorf("Failed to parse spotify JSON response: %w", err) } - + return spotifyToken, nil } @@ -72,7 +72,7 @@ func spotifyAuth(clientID string, clientSecret string) gin.HandlerFunc { // Short lived spotify access tokens during execution spotifyToken, err := getSpotifyToken(clientID, clientSecret) if err != nil { - slog.Error("[GOMUSIC] Failed to get spotify access token", "Error", err) + slog.Error("[GOMUSIC] Failed to get spotify access token", "Error", err) } // Calculate the future expiry time @@ -81,14 +81,14 @@ func spotifyAuth(clientID string, clientSecret string) gin.HandlerFunc { return func(c *gin.Context) { if time.Now().After(expireTime) { - // Token expired so we grab a new one - slog.Info("[GOMUSIC] Replacing expired Spotify access token") - spotifyToken, err = getSpotifyToken(clientID, clientSecret) - if err != nil { - slog.Error("[GOMUSIC] Failed to get new spotify access token", "Error", err) - } - expDuration := time.Duration(spotifyToken.ExpiresIn) * time.Second - expireTime = time.Now().Add(expDuration) + // Token expired so we grab a new one + slog.Info("[GOMUSIC] Replacing expired Spotify access token") + spotifyToken, err = getSpotifyToken(clientID, clientSecret) + if err != nil { + slog.Error("[GOMUSIC] Failed to get new spotify access token", "Error", err) + } + expDuration := time.Duration(spotifyToken.ExpiresIn) * time.Second + expireTime = time.Now().Add(expDuration) } // Pass the authorization header into context diff --git a/auth_test.go b/auth_test.go index d3c9bd6..fcb69cf 100644 --- a/auth_test.go +++ b/auth_test.go @@ -1,8 +1,8 @@ package main import ( - "testing" "github.com/stretchr/testify/assert" + "testing" ) func TestgetSpotifyAuthURL(t *testing.T) { diff --git a/database.go b/database.go index 1c398b0..31f4da2 100644 --- a/database.go +++ b/database.go @@ -1,26 +1,26 @@ package main import ( - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "log/slog" "fmt" -) + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "log/slog" +) type ArtistProfile struct { - gorm.Model - SpotifyID string `gorm:"unique"` - Name string - Popularity int - Genres []Genre `gorm:"many2many:artist_genres;"` + gorm.Model + SpotifyID string `gorm:"unique"` + Name string + Popularity int + Genres []Genre `gorm:"many2many:artist_genres;"` } type Genre struct { - gorm.Model - Name string `gorm:"unique"` + gorm.Model + Name string `gorm:"unique"` } -func setupTestDatabase(name string) *gorm.DB { +func setupTestDatabase(name string) *gorm.DB { slog.Info("[GOMUSIC] Setting up new test database in memory") // Open a named DB instance so each test has a clean environment dbName := fmt.Sprintf("file:%s?mode=memory&cache=shared", name) @@ -30,18 +30,18 @@ func setupTestDatabase(name string) *gorm.DB { } // Run model migrations here to keep DB consistent - db.AutoMigrate(&ArtistProfile{}, &Genre{}) + db.AutoMigrate(&ArtistProfile{}, &Genre{}) return db } -func setupDatabase() *gorm.DB { +func setupDatabase() *gorm.DB { slog.Info("[GOMUSIC] Setting up database and running auto migrations") db, err := gorm.Open(sqlite.Open("gomusic.db"), &gorm.Config{}) - if err != nil { - panic("Failed to open database") - } + if err != nil { + panic("Failed to open database") + } - // Run model migrations here to keep DB consistent - db.AutoMigrate(&ArtistProfile{}, &Genre{}) - return db + // Run model migrations here to keep DB consistent + db.AutoMigrate(&ArtistProfile{}, &Genre{}) + return db } diff --git a/main.go b/main.go index d0d3482..da817ba 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,11 @@ package main import ( - "github.com/gin-gonic/gin" - "gorm.io/gorm" - "log/slog" - "os" -) + "github.com/gin-gonic/gin" + "gorm.io/gorm" + "log/slog" + "os" +) // Environment type is used with route methods // So that we can easily inject/contain context data like DB connections @@ -18,27 +18,27 @@ var spotifyClientID = os.Getenv("SPOTIFY_ID") var spotifyClientSecret = os.Getenv("SPOTIFY_TOKEN") func setupRouter(env *Env, spotifyID string, spotifySecret string) *gin.Engine { - var r *gin.Engine = gin.Default() + var r *gin.Engine = gin.Default() r.Use(spotifyAuth(spotifyID, spotifySecret)) - r.GET("/alive", env.alive) - r.GET("/artists/:artistID", env.getArtistByID) - r.GET("/artists", env.getArtistByName) - return r + r.GET("/alive", env.alive) + r.GET("/artists/:artistID", env.getArtistByID) + r.GET("/artists", env.getArtistByName) + return r } func main() { - // If the auth/ID variables are empty something is probably misconfigured - if spotifyClientID == "" { - slog.Warn("[GOMUSIC] No Spotify ID configured in 'SPOTIFY_ID' environment variable") - } - if spotifyClientSecret == "" { - slog.Warn("[GOMUSIC] No Spotify secret configured in 'SPOTIFY_SECRET' environment variable") - } + // If the auth/ID variables are empty something is probably misconfigured + if spotifyClientID == "" { + slog.Warn("[GOMUSIC] No Spotify ID configured in 'SPOTIFY_ID' environment variable") + } + if spotifyClientSecret == "" { + slog.Warn("[GOMUSIC] No Spotify secret configured in 'SPOTIFY_SECRET' environment variable") + } db := setupDatabase() env := &Env{db: db} - + // Router/middleware and server setup - r := setupRouter(env, spotifyClientID, spotifyClientSecret) - r.Run(":8000") + r := setupRouter(env, spotifyClientID, spotifyClientSecret) + r.Run(":8000") } diff --git a/routes.go b/routes.go index 8559dff..6642a41 100644 --- a/routes.go +++ b/routes.go @@ -1,60 +1,60 @@ package main -import ( - "github.com/gin-gonic/gin" - "gorm.io/gorm/clause" - "net/http" - "log/slog" +import ( "fmt" + "github.com/gin-gonic/gin" + "gorm.io/gorm/clause" + "log/slog" + "net/http" ) func (env *Env) alive(c *gin.Context) { - c.String(http.StatusOK, "yes!") + c.String(http.StatusOK, "yes!") } func (env *Env) getArtistByID(c *gin.Context) { - artistID := c.Params.ByName("artistID") - spotifyAuthToken := c.GetString("spotifyAuthToken") - - if artistID == "" || spotifyAuthToken == "Bearer " { + artistID := c.Params.ByName("artistID") + spotifyAuthToken := c.GetString("spotifyAuthToken") + + if artistID == "" || spotifyAuthToken == "Bearer " { c.JSON(http.StatusBadRequest, gin.H{"Error": "Could not find required parameters and/or required authentication tokens"}) return - } + } spotifyResponse, err := getSpotifyArtistData(artistID, spotifyAuthToken) if err != nil { statusCode := err.(*ResponseError).StatusCode switch statusCode { - case 404: - c.JSON(http.StatusNotFound, gin.H{"Error": "This artist does not exist"}) - return - case 400: - c.JSON(http.StatusBadRequest, gin.H{"Error": "Bad request"}) - return + case 404: + c.JSON(http.StatusNotFound, gin.H{"Error": "This artist does not exist"}) + return + case 400: + c.JSON(http.StatusBadRequest, gin.H{"Error": "Bad request"}) + return } slog.Error("[GOMUSIC] Failed to request latest spotify data from API", "Error", err) c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request the latest data from spotify API"}) return } - + // Update DB here var genreList []Genre for _, val := range spotifyResponse.Genres { - genreList = append(genreList, Genre {Name: val}) + genreList = append(genreList, Genre{Name: val}) } artistProfile := ArtistProfile{ - SpotifyID: spotifyResponse.ID, - Name: spotifyResponse.Name, + SpotifyID: spotifyResponse.ID, + Name: spotifyResponse.Name, Popularity: spotifyResponse.Popularity, - Genres: genreList, + Genres: genreList, } // Create new record // Otherwise update values when artist with this SpotifyID already exists // Basically upsert dbResult := env.db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "spotify_id"}}, + Columns: []clause.Column{{Name: "spotify_id"}}, UpdateAll: true, }).Create(&artistProfile) @@ -62,8 +62,8 @@ func (env *Env) getArtistByID(c *gin.Context) { slog.Error("[GOMUSIC] Failed to store response in local database", "Error", err) } - // Send back our response data - c.JSON(http.StatusOK, spotifyResponse) + // Send back our response data + c.JSON(http.StatusOK, spotifyResponse) } func (env *Env) getArtistByName(c *gin.Context) { diff --git a/routes_test.go b/routes_test.go index 7865917..3f87e77 100644 --- a/routes_test.go +++ b/routes_test.go @@ -1,12 +1,12 @@ package main import ( - "net/http" "encoding/json" - "net/http/httptest" - "github.com/stretchr/testify/assert" - "testing" "fmt" + "github.com/stretchr/testify/assert" + "net/http" + "net/http/httptest" + "testing" ) func TestAliveRoute(t *testing.T) { @@ -49,7 +49,7 @@ func TestGetArtistByIDRoute(t *testing.T) { if dbResult.Error != nil { assert.Fail(t, "Failed to retrieve new info from test database") } - + assert.Equal(t, "Pitbull", artist.Name) assert.Equal(t, "0TnOYISbd1XYRBk9myaseg", artist.SpotifyID) } diff --git a/utils.go b/utils.go index dd915b1..e32a4d9 100644 --- a/utils.go +++ b/utils.go @@ -1,22 +1,22 @@ package main import ( - "fmt" - "errors" - "net/http" "encoding/json" + "errors" + "fmt" + "net/http" ) type SpotifyResponse struct { - ID string - Name string - Popularity int - Genres []string + ID string + Name string + Popularity int + Genres []string } type ResponseError struct { StatusCode int - Err error + Err error } func (r ResponseError) Error() string { @@ -28,44 +28,44 @@ func (r ResponseError) Error() string { func getSpotifyArtistData(artistID string, spotifyAuthToken string) (SpotifyResponse, error) { artistEndpoint := fmt.Sprintf("https://api.spotify.com/v1/artists/%s", artistID) - req, err := http.NewRequest("GET", artistEndpoint, nil) - if err != nil { + req, err := http.NewRequest("GET", artistEndpoint, nil) + if err != nil { respErr := &ResponseError{ StatusCode: 500, - Err: errors.New("Failed to build request"), + Err: errors.New("Failed to build request"), } return SpotifyResponse{}, respErr - } - req.Header.Add("Authorization", spotifyAuthToken) + } + req.Header.Add("Authorization", spotifyAuthToken) - // Send off request - resp, err := http.DefaultClient.Do(req) - if err != nil { + // Send off request + resp, err := http.DefaultClient.Do(req) + if err != nil { respErr := &ResponseError{ StatusCode: 500, - Err: errors.New("Failed to send request to spotify"), + Err: errors.New("Failed to send request to spotify"), } return SpotifyResponse{}, respErr } else if resp.StatusCode != 200 { respErr := &ResponseError{ StatusCode: resp.StatusCode, - Err: errors.New("Failed to get artist data from spotify API"), + Err: errors.New("Failed to get artist data from spotify API"), } return SpotifyResponse{}, respErr - } - + } + var spotifyResponse SpotifyResponse err = json.NewDecoder(resp.Body).Decode(&spotifyResponse) - if err != nil { + if err != nil { respErr := &ResponseError{ StatusCode: 500, - Err: errors.New("Failed to decode response body"), + Err: errors.New("Failed to decode response body"), } - return SpotifyResponse{}, respErr - } - - // Close this immediately since it's unused now - resp.Body.Close() + return SpotifyResponse{}, respErr + } + + // Close this immediately since it's unused now + resp.Body.Close() // After all the above checks we assume this response is populated // If errors arise we can do extra validation here