A website inspired by Last.fm that will keep track of your listening statistics
lastfm music statistics
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update user service to receive artist repos in constructor. Add default insert en select functions for user repo. Update server start function to be more clean.

oscar345 118b13b6 4c15334a

+96 -21
+49
internal/repo/db/user.go
··· 1 + package db 2 + 3 + import ( 4 + "context" 5 + "database/sql" 6 + 7 + "github.com/oscar345/keeptrack/internal/models" 8 + "github.com/oscar345/keeptrack/internal/repo" 9 + "github.com/oscar345/keeptrack/pkg/database" 10 + ) 11 + 12 + type UserRepoDB struct { 13 + db *sql.DB 14 + } 15 + 16 + var _ repo.UserRepo = (*UserRepoDB)(nil) 17 + 18 + func NewUserRepoDB(db *sql.DB) *UserRepoDB { 19 + return &UserRepoDB{ 20 + db: db, 21 + } 22 + } 23 + 24 + func (repo *UserRepoDB) Create(ctx context.Context, user models.User) (int, error) { 25 + values := map[string]any{ 26 + "name": user.Name, 27 + "email": user.Email, 28 + "password": user.Password, 29 + } 30 + 31 + return database.Insert(ctx, repo.db, "users", values) 32 + } 33 + 34 + func (repo *UserRepoDB) GetByID(ctx context.Context, id string) (models.User, error) { 35 + const statement = /*sql*/ ` 36 + SELECT 37 + users.id, users.name, users.email, users.password 38 + FROM users 39 + WHERE users.id = ? 40 + ` 41 + 42 + return database.QueryOne(ctx, repo.db, statement, []any{id}, func(r *sql.Rows) (models.User, error) { 43 + var user models.User 44 + if err := r.Scan(&user.ID, &user.Name, &user.Email, &user.Password); err != nil { 45 + return models.User{}, err 46 + } 47 + return user, nil 48 + }) 49 + }
+1 -1
internal/repo/repo.go
··· 41 41 } 42 42 43 43 type UserRepo interface { 44 - Create(ctx context.Context, user models.User) error 44 + Create(ctx context.Context, user models.User) (int, error) 45 45 GetByID(ctx context.Context, id string) (models.User, error) 46 46 } 47 47
+29 -12
internal/server/server.go
··· 43 43 }) 44 44 defer statisticsDB.Close() 45 45 46 - artistRepo := db.NewArtistRepoDB(musicbrainzDB) 47 - artistScrobbleRepo := db.NewArtistScrobbleRepoDB(statisticsDB) 48 - artistImageFetcher := image.NewArtistImageFetcherFanArtTV(s.config.Services.FanartTV.APIKey) 49 - 50 - storage := storagesvc.NewDiskStorage("/public", s.config.Storage.Disk.Path) 51 - 52 - mediaProvider := providers.NewMediaProvider(storage, artistImageFetcher) 53 - 54 - artistService := services.NewArtistService( 55 - artistRepo, artistScrobbleRepo, artistImageFetcher, mediaProvider, storage, 56 - ) 46 + services := s.services(musicbrainzDB, statisticsDB) 57 47 58 48 router := router. 59 - New(artistService, s.config). 49 + New(services.Artist, services.User, s.config). 60 50 Router() 61 51 62 52 server := http.Server{ ··· 67 57 68 58 return server.ListenAndServe() 69 59 } 60 + 61 + type Services struct { 62 + Artist services.ArtistService 63 + User services.UserService 64 + } 65 + 66 + func (s *Server) services(musicbrainzDB *sql.DB, statisticsDB *sql.DB) Services { 67 + artistRepo := db.NewArtistRepoDB(musicbrainzDB) 68 + artistScrobbleRepo := db.NewArtistScrobbleRepoDB(statisticsDB) 69 + artistImageFetcher := image.NewArtistImageFetcherFanArtTV(s.config.Services.FanartTV.APIKey) 70 + 71 + userRepo := db.NewUserRepoDB(musicbrainzDB) 72 + userFollowRepo := db.NewUserFollowRepoDB(musicbrainzDB) 73 + 74 + storage := storagesvc.NewDiskStorage("/public", s.config.Storage.Disk.Path) 75 + 76 + mediaProvider := providers.NewMediaProvider(storage, artistImageFetcher) 77 + 78 + return Services{ 79 + Artist: services.NewArtistService( 80 + artistRepo, artistScrobbleRepo, artistImageFetcher, mediaProvider, storage, 81 + ), 82 + User: services.NewUserService( 83 + userRepo, userFollowRepo, artistRepo, artistScrobbleRepo, mediaProvider, 84 + ), 85 + } 86 + }
+13 -4
internal/services/user.go
··· 19 19 mediaProvider *providers.MediaProvider 20 20 } 21 21 22 - func NewUserService(userRepo repo.UserRepo, userFollowRepo repo.UserFollowRepo) *UserService { 23 - return &UserService{ 24 - userRepo: userRepo, 25 - userFollowRepo: userFollowRepo, 22 + func NewUserService( 23 + userRepo repo.UserRepo, 24 + userFollowRepo repo.UserFollowRepo, 25 + artistRepo repo.ArtistRepo, 26 + artistScrobbleRepo repo.ArtistScrobbleRepo, 27 + mediaProvider *providers.MediaProvider, 28 + ) UserService { 29 + return UserService{ 30 + userRepo: userRepo, 31 + userFollowRepo: userFollowRepo, 32 + artistRepo: artistRepo, 33 + artistScrobbleRepo: artistScrobbleRepo, 34 + mediaProvider: mediaProvider, 26 35 } 27 36 } 28 37
+4 -4
internal/web/router/router.go
··· 20 20 ) 21 21 22 22 type Server struct { 23 - chi *chi.Mux 24 23 artistService services.ArtistService 24 + userService services.UserService 25 25 config *config.Config 26 26 } 27 27 28 28 func New( 29 29 artistService services.ArtistService, 30 + userService services.UserService, 30 31 config *config.Config, 31 32 ) *Server { 32 33 return &Server{ 33 34 artistService: artistService, 35 + userService: userService, 34 36 config: config, 35 37 } 36 38 } ··· 79 81 }) 80 82 81 83 r.Get("/library/artists", func(w http.ResponseWriter, r *http.Request) { 82 - artists, page, err := s.artistService.ListArtistByCount(r.Context(), filters.ArtistCount{ 83 - UserID: 1, 84 - }) 84 + artists, page, err := s.userService.ListArtistsByCount(r.Context(), 1, filters.ArtistCount{}) 85 85 86 86 if err != nil { 87 87 http.Error(w, err.Error(), http.StatusInternalServerError)