Skip to content

Commit

Permalink
add configuration struct and more configuration options
Browse files Browse the repository at this point in the history
  • Loading branch information
BradLewis committed Aug 21, 2023
1 parent 16101b6 commit 50b4bdf
Show file tree
Hide file tree
Showing 19 changed files with 1,560 additions and 31 deletions.
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ APP_ENV="development"
# optional - use spotify images as a backup
SPOTIFY_CLIENT_ID="YOUR_API_KEY"
SPOTIFY_CLIENT_SECRET="YOUR_API_KEY"
# Collage configuration
ALBUM_MAX_IMAGES=400
ARTIST_MAX_IMAGES=100
TRACK_MAX_IMAGES=25
# Set the cutoffs for the image sizes.
# That is, if the number of images in the collage is less than this number,
# it will use the image size specified.
IMAGE_SIZE_CUTOFF_EXTRA_LARGE=100 # If less than 100 images, use the extra large images
IMAGE_SIZE_CUTOFF_LARGE=1000
IMAGE_SIZE_CUTOFF_MEDIUM=2000
7 changes: 0 additions & 7 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@ package main

import (
"github.com/SongStitch/song-stitch/internal/server"
"github.com/joho/godotenv"
"github.com/rs/zerolog/log"
)

func main() {
err := godotenv.Load()
if err != nil {
log.Info().Msg("Error loading .env file")
}

server.RunServer()
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/justinas/alice v1.2.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/rs/zerolog v1.29.1
github.com/sethvargo/go-envconfig v0.9.0
)

require (
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QX
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
Expand All @@ -52,6 +53,8 @@ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
Expand Down
29 changes: 18 additions & 11 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/rs/zerolog"

"github.com/SongStitch/song-stitch/internal/collages"
"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/generator"
)
Expand All @@ -24,9 +25,9 @@ type CollageRequest struct {
Period string `in:"query=period;default=7day" validate:"required,validatePeriod"`
Height uint `in:"query=height;default=0" validate:"gte=0,lte=3000"`
Width uint `in:"query=width;default=0" validate:"gte=0,lte=3000"`
Rows int `in:"query=rows;default=3" validate:"required,gte=1,lte=20"`
Rows int `in:"query=rows;default=3" validate:"required"`
FontSize int `in:"query=fontsize;default=12" validate:"gte=8,lte=30"`
Columns int `in:"query=columns;default=3" validate:"required,gte=1,lte=20"`
Columns int `in:"query=columns;default=3" validate:"required"`
DisplayAlbum bool `in:"query=album;default=false"`
DisplayTrack bool `in:"query=track;default=false"`
PlayCount bool `in:"query=playcount;default=false"`
Expand All @@ -37,18 +38,24 @@ type CollageRequest struct {
}

func generateCollage(ctx context.Context, request *CollageRequest) (*image.Image, *bytes.Buffer, error) {
config := config.GetConfig()

count := request.Rows * request.Columns
imageSize := "extralarge"
imageDimension := 300
if count > 100 && count <= 1000 {
imageSize = "large"
imageDimension = 174
} else if count > 1000 && count <= 2000 {
imageSize = "medium"
imageDimension = 64
} else if count > 2000 {

var imageSize string
var imageDimension int
if count > config.ImageSizeCutoffs.Medium {
imageSize = "small"
imageDimension = 3
} else if count > config.ImageSizeCutoffs.Large {
imageSize = "medium"
imageDimension = 64
} else if count > config.ImageSizeCutoffs.ExtraLarge {
imageSize = "large"
imageDimension = 174
} else {
imageSize = "extralarge"
imageDimension = 300
}

displayOptions := generator.DisplayOptions{
Expand Down
17 changes: 10 additions & 7 deletions internal/clients/lastfm/lastfm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"net/http"
"net/url"
"os"
"path"
"regexp"
"strconv"
Expand All @@ -17,6 +16,7 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/rs/zerolog"

"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/models"
)
Expand Down Expand Up @@ -65,8 +65,9 @@ func cleanError(err error) error {
}

func GetLastFmResponse[T LastFMResponse](ctx context.Context, collageType constants.CollageType, username string, period constants.Period, count int) (*T, error) {
endpoint := os.Getenv("LASTFM_ENDPOINT")
key := os.Getenv("LASTFM_API_KEY")
config := config.GetConfig()
endpoint := config.LastFM.Endpoint
apiKey := config.LastFM.APIKey

// Image URLs stop getting returned by the API at around 500
const maxPerPage = 500
Expand Down Expand Up @@ -97,7 +98,7 @@ func GetLastFmResponse[T LastFMResponse](ctx context.Context, collageType consta
q.Set("period", string(period))
q.Set("limit", strconv.Itoa(limit))
q.Set("page", strconv.Itoa(page))
q.Set("api_key", key)
q.Set("api_key", apiKey)
q.Set("format", "json")
u.RawQuery = q.Encode()

Expand Down Expand Up @@ -171,8 +172,10 @@ type GetTrackInfoResponse struct {
}

func GetTrackInfo(trackName string, artistName string, imageSize string) (*models.TrackInfo, error) {
endpoint := os.Getenv("LASTFM_ENDPOINT")
key := os.Getenv("LASTFM_API_KEY")
config := config.GetConfig()
endpoint := config.LastFM.Endpoint
apiKey := config.LastFM.APIKey

u, err := url.Parse(endpoint)
if err != nil {
panic(err)
Expand All @@ -182,7 +185,7 @@ func GetTrackInfo(trackName string, artistName string, imageSize string) (*model
q.Set("track", trackName)
q.Set("artist", artistName)
q.Set("method", "track.getInfo")
q.Set("api_key", key)
q.Set("api_key", apiKey)
q.Set("format", "json")
u.RawQuery = q.Encode()

Expand Down
8 changes: 5 additions & 3 deletions internal/clients/spotify/spotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"

"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/models"
"github.com/rs/zerolog"
Expand All @@ -31,8 +31,9 @@ type Token struct {
}

func (t *Token) Refresh() error {
client_id := os.Getenv("SPOTIFY_CLIENT_ID")
client_secret := os.Getenv("SPOTIFY_CLIENT_SECRET")
config := config.GetConfig()
client_id := config.Spotify.ClientId
client_secret := config.Spotify.ClientSecret

if client_id == "" || client_secret == "" {
return errors.New("spotify credentials not set")
Expand Down Expand Up @@ -104,6 +105,7 @@ func GetSpotifyClient() (*SpotifyClient, error) {
}

func InitSpotifyClient(log zerolog.Logger) {
log.Info().Msg("initializing spotify client...")
token := &Token{
client: http.DefaultClient,
endpoint: "https://accounts.spotify.com/api/token",
Expand Down
4 changes: 3 additions & 1 deletion internal/collages/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/SongStitch/song-stitch/internal/cache"
"github.com/SongStitch/song-stitch/internal/clients/lastfm"
"github.com/SongStitch/song-stitch/internal/clients/spotify"
"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/generator"
"github.com/SongStitch/song-stitch/internal/models"
Expand Down Expand Up @@ -59,7 +60,8 @@ func (a *LastFMTopAlbums) GetTotalFetched() int {
}

func GenerateCollageForAlbum(ctx context.Context, username string, period constants.Period, count int, imageSize string, displayOptions generator.DisplayOptions) (*image.Image, *bytes.Buffer, error) {
if count > 400 {
config := config.GetConfig()
if count > config.MaxImages.Albums {
return nil, nil, constants.ErrTooManyImages
}
albums, err := getAlbums(ctx, username, period, count, imageSize)
Expand Down
4 changes: 3 additions & 1 deletion internal/collages/artist.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/SongStitch/song-stitch/internal/cache"
"github.com/SongStitch/song-stitch/internal/clients/lastfm"
"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/generator"
)
Expand Down Expand Up @@ -53,7 +54,8 @@ func (a *LastFMTopArtists) GetTotalFetched() int {
}

func GenerateCollageForArtist(ctx context.Context, username string, period constants.Period, count int, imageSize string, displayOptions generator.DisplayOptions) (*image.Image, *bytes.Buffer, error) {
if count > 100 {
config := config.GetConfig()
if count > config.MaxImages.Artists {
return nil, nil, constants.ErrTooManyImages
}
artists, err := getArtists(ctx, username, period, count, imageSize)
Expand Down
4 changes: 3 additions & 1 deletion internal/collages/track.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/SongStitch/song-stitch/internal/cache"
"github.com/SongStitch/song-stitch/internal/clients/lastfm"
"github.com/SongStitch/song-stitch/internal/clients/spotify"
"github.com/SongStitch/song-stitch/internal/config"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/SongStitch/song-stitch/internal/generator"
"github.com/SongStitch/song-stitch/internal/models"
Expand Down Expand Up @@ -61,7 +62,8 @@ func (t *LastFMTopTracks) GetTotalFetched() int {
}

func GenerateCollageForTrack(ctx context.Context, username string, period constants.Period, count int, imageSize string, displayOptions generator.DisplayOptions) (*image.Image, *bytes.Buffer, error) {
if count > 25 {
config := config.GetConfig()
if count > config.MaxImages.Tracks {
return nil, nil, constants.ErrTooManyImages
}
tracks, err := getTracks(ctx, username, period, count, imageSize)
Expand Down
45 changes: 45 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package config

import (
"context"

"github.com/sethvargo/go-envconfig"
)

type Config struct {
LastFM struct {
Endpoint string `env:"LASTFM_ENDPOINT,required"`
APIKey string `env:"LASTFM_API_KEY,required"`
}
Spotify struct {
ClientId string `env:"SPOTIFY_CLIENT_ID"`
ClientSecret string `env:"SPOTIFY_CLIENT_SECRET"`
}
MaxImages struct {
Albums int `env:"MAX_ALBUM_IMAGES,default=400"`
Artists int `env:"MAX_ARTIST_IMAGES,default=100"`
Tracks int `env:"MAX_TRACK_IMAGES,default=25"`
}
ImageSizeCutoffs struct {
ExtraLarge int `env:"IMAGE_SIZE_CUTOFF_EXTRA_LARGE,default=100"`
Large int `env:"IMAGE_SIZE_CUTOFF_LARGE,default=1000"`
Medium int `env:"IMAGE_SIZE_CUTOFF_MEDIUM,default=2000"`
}
}

var config *Config

func GetConfig() *Config {
return config
}

func InitConfig() error {
ctx := context.Background()

config = &Config{}

if err := envconfig.Process(ctx, config); err != nil {
return err
}
return nil
}
9 changes: 9 additions & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"time"

"github.com/ggicci/httpin"
"github.com/joho/godotenv"
"github.com/justinas/alice"
"github.com/rs/zerolog"
"github.com/rs/zerolog/hlog"

"github.com/SongStitch/song-stitch/internal/api"
"github.com/SongStitch/song-stitch/internal/clients/spotify"
"github.com/SongStitch/song-stitch/internal/config"
)

func getLogger() zerolog.Logger {
Expand All @@ -24,7 +26,14 @@ func getLogger() zerolog.Logger {
}

func RunServer() {
_ = godotenv.Load()
log := getLogger()

err := config.InitConfig()
if err != nil {
log.Fatal().Err(err).Msg("Failed to initialize config")
}

c := alice.New()
c = c.Append(hlog.NewHandler(log))
c = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
Expand Down
8 changes: 8 additions & 0 deletions vendor/github.com/sethvargo/go-envconfig/AUTHORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 50b4bdf

Please sign in to comment.