diff --git a/api/api.go b/api/api.go
index a4a05747f..c6b0a5def 100644
--- a/api/api.go
+++ b/api/api.go
@@ -64,6 +64,7 @@ func (api *Router) routes() http.Handler {
H(r, "getMusicFolders", c.GetMusicFolders)
H(r, "getIndexes", c.GetIndexes)
H(r, "getArtists", c.GetArtists)
+ H(r, "getGenres", c.GetGenres)
reqParams := r.With(requiredParams("id"))
H(reqParams, "getMusicDirectory", c.GetMusicDirectory)
H(reqParams, "getArtist", c.GetArtist)
diff --git a/api/browsing.go b/api/browsing.go
index 7c21ac663..6ecc09f99 100644
--- a/api/browsing.go
+++ b/api/browsing.go
@@ -151,6 +151,18 @@ func (c *BrowsingController) GetSong(w http.ResponseWriter, r *http.Request) (*r
return response, nil
}
+func (c *BrowsingController) GetGenres(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
+ genres, err := c.browser.GetGenres()
+ if err != nil {
+ log.Error(r, err)
+ return nil, NewError(responses.ErrorGeneric, "Internal Error")
+ }
+
+ response := NewResponse()
+ response.Genres = ToGenres(genres)
+ return response, nil
+}
+
func (c *BrowsingController) buildDirectory(d *engine.DirectoryInfo) *responses.Directory {
dir := &responses.Directory{
Id: d.Id,
diff --git a/api/helpers.go b/api/helpers.go
index 33924961e..a8bdfabae 100644
--- a/api/helpers.go
+++ b/api/helpers.go
@@ -9,6 +9,7 @@ import (
"github.com/cloudsonic/sonic-server/api/responses"
"github.com/cloudsonic/sonic-server/engine"
+ "github.com/cloudsonic/sonic-server/model"
"github.com/cloudsonic/sonic-server/utils"
)
@@ -185,3 +186,11 @@ func ToChild(entry engine.Entry) responses.Child {
child.SongCount = entry.SongCount
return child
}
+
+func ToGenres(genres model.Genres) *responses.Genres {
+ response := make([]responses.Genre, len(genres))
+ for i, g := range genres {
+ response[i] = responses.Genre(g)
+ }
+ return &responses.Genres{Genre: response}
+}
diff --git a/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match JSON b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match JSON
new file mode 100644
index 000000000..08a4fb50c
--- /dev/null
+++ b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","genres":{"genre":[{"value":"Rock","songCount":1000,"albumCount":100},{"value":"Reggae","songCount":500,"albumCount":50},{"value":"Pop","songCount":0,"albumCount":0}]}}
diff --git a/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match XML b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match XML
new file mode 100644
index 000000000..e99952d47
--- /dev/null
+++ b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres with data should match XML
@@ -0,0 +1 @@
+RockReggaePop
diff --git a/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match JSON b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match JSON
new file mode 100644
index 000000000..f7f97bf4e
--- /dev/null
+++ b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","genres":{}}
diff --git a/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match XML b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match XML
new file mode 100644
index 000000000..1d0c9e4b7
--- /dev/null
+++ b/api/responses/.snapshots/responses-snapshotMatcher-Match-Responses Genres without data should match XML
@@ -0,0 +1 @@
+
diff --git a/api/responses/responses.go b/api/responses/responses.go
index a699f76d7..50e79e788 100644
--- a/api/responses/responses.go
+++ b/api/responses/responses.go
@@ -26,6 +26,7 @@ type Subsonic struct {
NowPlaying *NowPlaying `xml:"nowPlaying,omitempty" json:"nowPlaying,omitempty"`
Song *Child `xml:"song,omitempty" json:"song,omitempty"`
RandomSongs *Songs `xml:"randomSongs,omitempty" json:"randomSongs,omitempty"`
+ Genres *Genres `xml:"genres,omitempty" json:"genres,omitempty"`
// ID3
Artist *Indexes `xml:"artists,omitempty" json:"artists,omitempty"`
@@ -259,3 +260,13 @@ type User struct {
VideoConversionRole bool `xml:"videoConversionRole,attr" json:"videoConversionRole"`
Folder []int `xml:"folder,omitempty" json:"folder,omitempty"`
}
+
+type Genre struct {
+ Name string `xml:",chardata" json:"value,omitempty"`
+ SongCount int `xml:"songCount,attr" json:"songCount"`
+ AlbumCount int `xml:"albumCount,attr" json:"albumCount"`
+}
+
+type Genres struct {
+ Genre []Genre `xml:"genre,omitempty" json:"genre,omitempty"`
+}
diff --git a/api/responses/responses_test.go b/api/responses/responses_test.go
index 4fb0ab819..230999210 100644
--- a/api/responses/responses_test.go
+++ b/api/responses/responses_test.go
@@ -248,4 +248,36 @@ var _ = Describe("Responses", func() {
})
})
})
+
+ Describe("Genres", func() {
+ BeforeEach(func() {
+ response.Genres = &Genres{}
+ })
+
+ Context("without data", func() {
+ It("should match XML", func() {
+ Expect(xml.Marshal(response)).To(MatchSnapshot())
+ })
+ It("should match JSON", func() {
+ Expect(json.Marshal(response)).To(MatchSnapshot())
+ })
+ })
+
+ Context("with data", func() {
+ BeforeEach(func() {
+ genres := make([]Genre, 3)
+ genres[0] = Genre{SongCount: 1000, AlbumCount: 100, Name: "Rock"}
+ genres[1] = Genre{SongCount: 500, AlbumCount: 50, Name: "Reggae"}
+ genres[2] = Genre{SongCount: 0, AlbumCount: 0, Name: "Pop"}
+ response.Genres.Genre = genres
+ })
+
+ It("should match XML", func() {
+ Expect(xml.Marshal(response)).To(MatchSnapshot())
+ })
+ It("should match JSON", func() {
+ Expect(json.Marshal(response)).To(MatchSnapshot())
+ })
+ })
+ })
})
diff --git a/engine/browser.go b/engine/browser.go
index 8b12c4b6a..6222b86ab 100644
--- a/engine/browser.go
+++ b/engine/browser.go
@@ -3,7 +3,9 @@ package engine
import (
"context"
"fmt"
+ "sort"
"strconv"
+ "strings"
"time"
"github.com/cloudsonic/sonic-server/log"
@@ -18,11 +20,12 @@ type Browser interface {
Artist(ctx context.Context, id string) (*DirectoryInfo, error)
Album(ctx context.Context, id string) (*DirectoryInfo, error)
GetSong(id string) (*Entry, error)
+ GetGenres() (model.Genres, error)
}
func NewBrowser(pr model.PropertyRepository, fr model.MediaFolderRepository, ir model.ArtistIndexRepository,
- ar model.ArtistRepository, alr model.AlbumRepository, mr model.MediaFileRepository) Browser {
- return &browser{pr, fr, ir, ar, alr, mr}
+ ar model.ArtistRepository, alr model.AlbumRepository, mr model.MediaFileRepository, gr model.GenreRepository) Browser {
+ return &browser{pr, fr, ir, ar, alr, mr, gr}
}
type browser struct {
@@ -32,6 +35,7 @@ type browser struct {
artistRepo model.ArtistRepository
albumRepo model.AlbumRepository
mfileRepo model.MediaFileRepository
+ genreRepo model.GenreRepository
}
func (b *browser) MediaFolders() (model.MediaFolders, error) {
@@ -114,6 +118,19 @@ func (b *browser) GetSong(id string) (*Entry, error) {
return &entry, nil
}
+func (b *browser) GetGenres() (model.Genres, error) {
+ genres, err := b.genreRepo.GetAll()
+ for i, g := range genres {
+ if strings.TrimSpace(g.Name) == "" {
+ genres[i].Name = ""
+ }
+ }
+ sort.Slice(genres, func(i, j int) bool {
+ return genres[i].Name < genres[j].Name
+ })
+ return genres, err
+}
+
func (b *browser) buildArtistDir(a *model.Artist, albums model.Albums) *DirectoryInfo {
dir := &DirectoryInfo{
Id: a.ID,
diff --git a/engine/browser_test.go b/engine/browser_test.go
new file mode 100644
index 000000000..30e1b8047
--- /dev/null
+++ b/engine/browser_test.go
@@ -0,0 +1,49 @@
+package engine
+
+import (
+ "errors"
+
+ "github.com/cloudsonic/sonic-server/model"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Browser", func() {
+ var repo *mockGenreRepository
+ var b Browser
+
+ BeforeSuite(func() {
+ repo = &mockGenreRepository{data: model.Genres{
+ {Name: "Rock", SongCount: 1000, AlbumCount: 100},
+ {Name: "", SongCount: 13, AlbumCount: 13},
+ {Name: "Electronic", SongCount: 4000, AlbumCount: 40},
+ }}
+ b = &browser{genreRepo: repo}
+ })
+
+ It("returns sorted data", func() {
+ Expect(b.GetGenres()).To(Equal(model.Genres{
+ {Name: "", SongCount: 13, AlbumCount: 13},
+ {Name: "Electronic", SongCount: 4000, AlbumCount: 40},
+ {Name: "Rock", SongCount: 1000, AlbumCount: 100},
+ }))
+ })
+
+ It("bubbles up errors", func() {
+ repo.err = errors.New("generic error")
+ _, err := b.GetGenres()
+ Expect(err).ToNot(BeNil())
+ })
+})
+
+type mockGenreRepository struct {
+ data model.Genres
+ err error
+}
+
+func (r *mockGenreRepository) GetAll() (model.Genres, error) {
+ if r.err != nil {
+ return nil, r.err
+ }
+ return r.data, nil
+}
diff --git a/engine/engine_suite_test.go b/engine/engine_suite_test.go
new file mode 100644
index 000000000..68f00f6a8
--- /dev/null
+++ b/engine/engine_suite_test.go
@@ -0,0 +1,15 @@
+package engine
+
+import (
+ "testing"
+
+ "github.com/cloudsonic/sonic-server/log"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestPersistence(t *testing.T) {
+ log.SetLevel(log.LevelCritical)
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Persistence Suite")
+}
diff --git a/model/genres.go b/model/genres.go
new file mode 100644
index 000000000..44f153ac8
--- /dev/null
+++ b/model/genres.go
@@ -0,0 +1,13 @@
+package model
+
+type Genre struct {
+ Name string
+ SongCount int
+ AlbumCount int
+}
+
+type Genres []Genre
+
+type GenreRepository interface {
+ GetAll() (Genres, error)
+}
diff --git a/persistence/album_repository.go b/persistence/album_repository.go
index e545aece8..7e7b5473f 100644
--- a/persistence/album_repository.go
+++ b/persistence/album_repository.go
@@ -23,7 +23,7 @@ type Album struct {
SongCount int ``
Duration int ``
Rating int `orm:"index"`
- Genre string ``
+ Genre string `orm:"index"`
StarredAt time.Time `orm:"null"`
CreatedAt time.Time `orm:"null"`
UpdatedAt time.Time `orm:"null"`
diff --git a/persistence/album_repository_test.go b/persistence/album_repository_test.go
index 6d1986fc2..b125c92b5 100644
--- a/persistence/album_repository_test.go
+++ b/persistence/album_repository_test.go
@@ -20,37 +20,37 @@ var _ = Describe("AlbumRepository", func() {
It("returns all records sorted", func() {
Expect(repo.GetAll(model.QueryOptions{SortBy: "Name"})).To(Equal(model.Albums{
- {ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
- {ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
- {ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
+ albumAbbeyRoad,
+ albumRadioactivity,
+ albumSgtPeppers,
}))
})
It("returns all records sorted desc", func() {
Expect(repo.GetAll(model.QueryOptions{SortBy: "Name", Desc: true})).To(Equal(model.Albums{
- {ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
- {ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
- {ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
+ albumSgtPeppers,
+ albumRadioactivity,
+ albumAbbeyRoad,
}))
})
It("paginates the result", func() {
Expect(repo.GetAll(model.QueryOptions{Offset: 1, Size: 1})).To(Equal(model.Albums{
- {ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
+ albumAbbeyRoad,
}))
})
})
Describe("GetAllIds", func() {
It("returns all records", func() {
- Expect(repo.GetAllIds()).To(Equal([]string{"1", "2", "3"}))
+ Expect(repo.GetAllIds()).To(ConsistOf("1", "2", "3"))
})
})
Describe("GetStarred", func() {
It("returns all starred records", func() {
Expect(repo.GetStarred(model.QueryOptions{})).To(Equal(model.Albums{
- {ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
+ albumRadioactivity,
}))
})
})
@@ -58,8 +58,8 @@ var _ = Describe("AlbumRepository", func() {
Describe("FindByArtist", func() {
It("returns all records from a given ArtistID", func() {
Expect(repo.FindByArtist("1")).To(Equal(model.Albums{
- {ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
- {ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
+ albumAbbeyRoad,
+ albumSgtPeppers,
}))
})
})
diff --git a/persistence/genre_repository.go b/persistence/genre_repository.go
new file mode 100644
index 000000000..0d99ef594
--- /dev/null
+++ b/persistence/genre_repository.go
@@ -0,0 +1,59 @@
+package persistence
+
+import (
+ "strconv"
+
+ "github.com/astaxie/beego/orm"
+ "github.com/cloudsonic/sonic-server/model"
+)
+
+type genreRepository struct{}
+
+func NewGenreRepository() model.GenreRepository {
+ return &genreRepository{}
+}
+
+func (r genreRepository) GetAll() (model.Genres, error) {
+ o := Db()
+ genres := make(map[string]model.Genre)
+
+ // Collect SongCount
+ var res []orm.Params
+ _, err := o.Raw("select genre, count(*) as c from media_file group by genre").Values(&res)
+ if err != nil {
+ return nil, err
+ }
+ for _, r := range res {
+ name := r["genre"].(string)
+ count := r["c"].(string)
+ g, ok := genres[name]
+ if !ok {
+ g = model.Genre{Name: name}
+ }
+ g.SongCount, _ = strconv.Atoi(count)
+ genres[name] = g
+ }
+
+ // Collect AlbumCount
+ _, err = o.Raw("select genre, count(*) as c from album group by genre").Values(&res)
+ if err != nil {
+ return nil, err
+ }
+ for _, r := range res {
+ name := r["genre"].(string)
+ count := r["c"].(string)
+ g, ok := genres[name]
+ if !ok {
+ g = model.Genre{Name: name}
+ }
+ g.AlbumCount, _ = strconv.Atoi(count)
+ genres[name] = g
+ }
+
+ // Build response
+ result := model.Genres{}
+ for _, g := range genres {
+ result = append(result, g)
+ }
+ return result, err
+}
diff --git a/persistence/genre_repository_test.go b/persistence/genre_repository_test.go
new file mode 100644
index 000000000..24a9756a2
--- /dev/null
+++ b/persistence/genre_repository_test.go
@@ -0,0 +1,22 @@
+package persistence
+
+import (
+ "github.com/cloudsonic/sonic-server/model"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("GenreRepository", func() {
+ var repo model.GenreRepository
+
+ BeforeEach(func() {
+ repo = NewGenreRepository()
+ })
+
+ It("returns all records", func() {
+ genres, err := repo.GetAll()
+ Expect(err).To(BeNil())
+ Expect(genres).To(ContainElement(model.Genre{Name: "Rock", AlbumCount: 2, SongCount: 2}))
+ Expect(genres).To(ContainElement(model.Genre{Name: "Electronic", AlbumCount: 1, SongCount: 2}))
+ })
+})
diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go
index 183a6cc69..184cf6836 100644
--- a/persistence/mediafile_repository.go
+++ b/persistence/mediafile_repository.go
@@ -24,7 +24,7 @@ type MediaFile struct {
Suffix string ``
Duration int ``
BitRate int ``
- Genre string ``
+ Genre string `orm:"index"`
Compilation bool ``
PlayCount int `orm:"index"`
PlayDate time.Time `orm:"null"`
diff --git a/persistence/persistence_suite_test.go b/persistence/persistence_suite_test.go
index fc2dca324..89a763e7c 100644
--- a/persistence/persistence_suite_test.go
+++ b/persistence/persistence_suite_test.go
@@ -16,19 +16,38 @@ func TestPersistence(t *testing.T) {
RunSpecs(t, "Persistence Suite")
}
-var testAlbums = model.Albums{
- {ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
- {ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
- {ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
-}
+var artistSaaraSaara = model.Artist{ID: "1", Name: "Saara Saara", AlbumCount: 2}
+var artistKraftwerk = model.Artist{ID: "2", Name: "Kraftwerk"}
+var artistBeatles = model.Artist{ID: "3", Name: "The Beatles"}
var testArtists = model.Artists{
- {ID: "1", Name: "Saara Saara", AlbumCount: 2},
- {ID: "2", Name: "Kraftwerk"},
- {ID: "3", Name: "The Beatles"},
+ artistSaaraSaara,
+ artistKraftwerk,
+ artistBeatles,
+}
+
+var albumSgtPeppers = model.Album{ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1", Genre: "Rock"}
+var albumAbbeyRoad = model.Album{ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1", Genre: "Rock"}
+var albumRadioactivity = model.Album{ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true, Genre: "Electronic"}
+var testAlbums = model.Albums{
+ albumSgtPeppers,
+ albumAbbeyRoad,
+ albumRadioactivity,
+}
+
+var songDayInALife = model.MediaFile{ID: "1", Title: "A Day In A Life", ArtistID: "3", AlbumID: "1", Genre: "Rock"}
+var songComeTogether = model.MediaFile{ID: "2", Title: "Come Together", ArtistID: "3", AlbumID: "2", Genre: "Rock"}
+var songRadioactivity = model.MediaFile{ID: "3", Title: "Radioactivity", ArtistID: "2", AlbumID: "3", Genre: "Electronic"}
+var songAntenna = model.MediaFile{ID: "4", Title: "Antenna", ArtistID: "2", AlbumID: "3", Genre: "Electronic"}
+var testSongs = model.MediaFiles{
+ songDayInALife,
+ songComeTogether,
+ songRadioactivity,
+ songAntenna,
}
var _ = Describe("Initialize test DB", func() {
BeforeSuite(func() {
+ //log.SetLevel(log.LevelTrace)
//conf.Sonic.DbPath, _ = ioutil.TempDir("", "cloudsonic_tests")
//os.MkdirAll(conf.Sonic.DbPath, 0700)
conf.Sonic.DbPath = ":memory:"
@@ -44,5 +63,12 @@ var _ = Describe("Initialize test DB", func() {
panic(err)
}
}
+ mediaFileRepository := NewMediaFileRepository()
+ for _, s := range testSongs {
+ err := mediaFileRepository.Put(&s)
+ if err != nil {
+ panic(err)
+ }
+ }
})
})
diff --git a/persistence/wire_provider.go b/persistence/wire_provider.go
index 51f49bf6c..2390b983c 100644
--- a/persistence/wire_provider.go
+++ b/persistence/wire_provider.go
@@ -14,4 +14,5 @@ var Set = wire.NewSet(
NewPlaylistRepository,
NewNowPlayingRepository,
NewMediaFolderRepository,
+ NewGenreRepository,
)
diff --git a/wire_gen.go b/wire_gen.go
index eb8e0fdd8..eeaef8f4e 100644
--- a/wire_gen.go
+++ b/wire_gen.go
@@ -41,7 +41,8 @@ func CreateSubsonicAPIRouter() *api.Router {
artistRepository := repositories.ArtistRepository
albumRepository := repositories.AlbumRepository
mediaFileRepository := repositories.MediaFileRepository
- browser := engine.NewBrowser(propertyRepository, mediaFolderRepository, artistIndexRepository, artistRepository, albumRepository, mediaFileRepository)
+ genreRepository := repositories.GenreRepository
+ browser := engine.NewBrowser(propertyRepository, mediaFolderRepository, artistIndexRepository, artistRepository, albumRepository, mediaFileRepository, genreRepository)
cover := engine.NewCover(mediaFileRepository, albumRepository)
nowPlayingRepository := repositories.NowPlayingRepository
listGenerator := engine.NewListGenerator(albumRepository, mediaFileRepository, nowPlayingRepository)
@@ -65,6 +66,7 @@ func createPersistenceProvider() *Repositories {
nowPlayingRepository := persistence.NewNowPlayingRepository()
playlistRepository := persistence.NewPlaylistRepository()
propertyRepository := persistence.NewPropertyRepository()
+ genreRepository := persistence.NewGenreRepository()
repositories := &Repositories{
AlbumRepository: albumRepository,
ArtistRepository: artistRepository,
@@ -75,6 +77,7 @@ func createPersistenceProvider() *Repositories {
NowPlayingRepository: nowPlayingRepository,
PlaylistRepository: playlistRepository,
PropertyRepository: propertyRepository,
+ GenreRepository: genreRepository,
}
return repositories
}
@@ -91,9 +94,10 @@ type Repositories struct {
NowPlayingRepository model.NowPlayingRepository
PlaylistRepository model.PlaylistRepository
PropertyRepository model.PropertyRepository
+ GenreRepository model.GenreRepository
}
var allProviders = wire.NewSet(itunesbridge.NewItunesControl, engine.Set, scanner_legacy.Set, api.NewRouter, wire.FieldsOf(new(*Repositories), "AlbumRepository", "ArtistRepository", "CheckSumRepository",
"ArtistIndexRepository", "MediaFileRepository", "MediaFolderRepository", "NowPlayingRepository",
- "PlaylistRepository", "PropertyRepository"), createPersistenceProvider,
+ "PlaylistRepository", "PropertyRepository", "GenreRepository"), createPersistenceProvider,
)
diff --git a/wire_injectors.go b/wire_injectors.go
index 99170dc82..326e9787a 100644
--- a/wire_injectors.go
+++ b/wire_injectors.go
@@ -13,6 +13,7 @@ import (
"github.com/google/wire"
)
+// TODO Can we remove this indirection?
type Repositories struct {
AlbumRepository model.AlbumRepository
ArtistRepository model.ArtistRepository
@@ -23,6 +24,7 @@ type Repositories struct {
NowPlayingRepository model.NowPlayingRepository
PlaylistRepository model.PlaylistRepository
PropertyRepository model.PropertyRepository
+ GenreRepository model.GenreRepository
}
var allProviders = wire.NewSet(
@@ -32,7 +34,7 @@ var allProviders = wire.NewSet(
api.NewRouter,
wire.FieldsOf(new(*Repositories), "AlbumRepository", "ArtistRepository", "CheckSumRepository",
"ArtistIndexRepository", "MediaFileRepository", "MediaFolderRepository", "NowPlayingRepository",
- "PlaylistRepository", "PropertyRepository"),
+ "PlaylistRepository", "PropertyRepository", "GenreRepository"),
createPersistenceProvider,
)