diff --git a/go.mod b/go.mod index a4d9686..677b3ff 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/sentriz/gonic require ( cloud.google.com/go v0.37.1 // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853 // indirect - github.com/dhowden/tag v0.0.0-20181104225729-a9f04c2798ca + github.com/eaburns/bit v0.0.0-20131029213740-7bd5cd37375d // indirect github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect github.com/go-sql-driver/mysql v1.4.1 // indirect github.com/gobuffalo/genny v0.1.1 // indirect @@ -19,6 +19,7 @@ require ( github.com/karrick/godirwalk v1.8.0 github.com/lib/pq v1.0.0 // indirect github.com/mattn/go-sqlite3 v1.10.0 // indirect + github.com/mdlayher/taggolib v0.0.0-20140723044655-d71b09674cfe github.com/peterbourgon/ff v1.2.0 github.com/pkg/errors v0.8.1 github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be @@ -28,7 +29,4 @@ require ( golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b // indirect google.golang.org/appengine v1.5.0 // indirect - gopkg.in/axiomzen/null.v3 v3.2.4 - gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect - gopkg.in/pg.v4 v4.9.5 // indirect ) diff --git a/go.sum b/go.sum index c74e204..f6af258 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853 h1:tTngnoO/B6HQnJ+pK8tN7kEAhmhIfaJOutqq/A4/JTM= github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= -github.com/dhowden/tag v0.0.0-20181104225729-a9f04c2798ca h1:EsPh1VImRZ6OOhWtz/zzwTjxVQKcKIiqS5tYNdx2eCg= -github.com/dhowden/tag v0.0.0-20181104225729-a9f04c2798ca/go.mod h1:SniNVYuaD1jmdEEvi+7ywb1QFR7agjeTdGKyFb0p7Rw= +github.com/eaburns/bit v0.0.0-20131029213740-7bd5cd37375d h1:HB5J9+f1xpkYLgWQ/RqEcbp3SEufyOIMYLoyKNKiG7E= +github.com/eaburns/bit v0.0.0-20131029213740-7bd5cd37375d/go.mod h1:CHkHWWZ4kbGY6jEy1+qlitDaCtRgNvCOQdakj/1Yl/Q= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -132,6 +132,8 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mdlayher/taggolib v0.0.0-20140723044655-d71b09674cfe h1:WyohQTx/GamBIn8NQAH3JrnEk5Tj++eNmwJOexXxNIk= +github.com/mdlayher/taggolib v0.0.0-20140723044655-d71b09674cfe/go.mod h1:11hji841NkL7BD+0rOgSuBzQ7bxBHKUj7Tp01NFZTE0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -263,16 +265,10 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/axiomzen/null.v3 v3.2.4 h1:5VmJ9lSU0dBJjisXhuhRnGiIolhTjkmQQ0EBNE9Z5QY= -gopkg.in/axiomzen/null.v3 v3.2.4/go.mod h1:Vq8/79AVvSZVg5PdN4kNROnTff7WtSh0HOiBHfOvVNU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/pg.v4 v4.9.5 h1:bs21aaMPPPcUPhNtqGxN8EeYUFU10MsNrC7U9m/lJgU= -gopkg.in/pg.v4 v4.9.5/go.mod h1:cSUPtzgofjgARAbFCE5u6WDHGPgbR1sjUYcWQlKvpec= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/model/model.go b/model/model.go index 540e2e3..c555efd 100644 --- a/model/model.go +++ b/model/model.go @@ -24,13 +24,9 @@ type Track struct { Duration int `gorm:"not null" sql:"default: null"` Size int `gorm:"not null" sql:"default: null"` Bitrate int `gorm:"not null" sql:"default: null"` - TagDiscNumber int `sql:"default: null"` TagTitle string `sql:"default: null"` - TagTotalDiscs int `sql:"default: null"` - TagTotalTracks int `sql:"default: null"` TagTrackArtist string `sql:"default: null"` TagTrackNumber int `sql:"default: null"` - TagYear int `sql:"default: null"` } func (t *Track) Ext() string { @@ -74,15 +70,16 @@ type Play struct { type Album struct { IDBase CrudBase - LeftPath string `gorm:"unique_index:idx_left_path_right_path"` - RightPath string `gorm:"not null; unique_index:idx_left_path_right_path" sql:"default: null"` - Parent *Album - ParentID int `sql:"default: null; type:int REFERENCES albums(id) ON DELETE CASCADE"` - Cover string `sql:"default: null"` - TagArtist *Artist - TagArtistID int `gorm:"index" sql:"default: null; type:int REFERENCES artists(id) ON DELETE CASCADE"` - TagTitle string `gorm:"index" sql:"default: null"` - TagYear int `sql:"default: null"` - Tracks []*Track - IsNew bool `gorm:"-"` + LeftPath string `gorm:"unique_index:idx_left_path_right_path"` + RightPath string `gorm:"not null; unique_index:idx_left_path_right_path" sql:"default: null"` + Parent *Album + ParentID int `sql:"default: null; type:int REFERENCES albums(id) ON DELETE CASCADE"` + Cover string `sql:"default: null"` + TagArtist *Artist + TagArtistID int `gorm:"index" sql:"default: null; type:int REFERENCES artists(id) ON DELETE CASCADE"` + TagTitle string `gorm:"index" sql:"default: null"` + TagYear int `sql:"default: null"` + Tracks []*Track + ReceivedPaths bool `gorm:"-"` + ReceivedTags bool `gorm:"-"` } diff --git a/scanner/scanner.go b/scanner/scanner.go index 622141a..ccff3c6 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -9,7 +9,6 @@ import ( "sync/atomic" "time" - "github.com/dhowden/tag" "github.com/jinzhu/gorm" "github.com/karrick/godirwalk" "github.com/pkg/errors" @@ -42,6 +41,7 @@ type Scanner struct { musicPath string seenTracks map[int]struct{} seenTracksNew int + seenTracksErr int curFolders folderStack curCover string } @@ -108,10 +108,11 @@ func (s *Scanner) Start() error { if err != nil { return errors.Wrap(err, "walking filesystem") } - log.Printf("finished scan in %s, +%d/%d tracks\n", + log.Printf("finished scan in %s, +%d/%d tracks (%d err)\n", time.Since(start), s.seenTracksNew, len(s.seenTracks), + s.seenTracksErr, ) // // begin cleaning @@ -198,7 +199,7 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error { func (s *Scanner) callbackPost(fullPath string, info *godirwalk.Dirent) error { folder := s.curFolders.Pop() - if folder.IsNew { + if folder.ReceivedPaths { folder.ParentID = s.curFolderID() folder.Cover = s.curCover s.tx.Save(folder) @@ -209,19 +210,6 @@ func (s *Scanner) callbackPost(fullPath string, info *godirwalk.Dirent) error { return nil } -func readTags(path string) (tag.Metadata, error) { - trackData, err := os.Open(path) - if err != nil { - return nil, errors.Wrap(err, "reading track from disk") - } - defer trackData.Close() - tags, err := tag.ReadFrom(trackData) - if err != nil { - return nil, errors.Wrap(err, "reading tags from track") - } - return tags, nil -} - func (s *Scanner) handleFolder(it *item) error { folder := &model.Album{} defer s.curFolders.Push(folder) @@ -240,7 +228,7 @@ func (s *Scanner) handleFolder(it *item) error { folder.LeftPath = it.directory folder.RightPath = it.filename s.tx.Save(folder) - folder.IsNew = true + folder.ReceivedPaths = true return nil } @@ -248,11 +236,6 @@ func (s *Scanner) handleTrack(it *item) error { // // set track basics track := &model.Track{} - defer func() { - // id will will be found (the first early return) - // or created the tx.Save(track) - s.seenTracks[track.ID] = struct{}{} - }() err := s.tx. Where(model.Track{ AlbumID: s.curFolderID(), @@ -263,26 +246,26 @@ func (s *Scanner) handleTrack(it *item) error { if !gorm.IsRecordNotFoundError(err) && it.stat.ModTime().Before(track.UpdatedAt) { // we found the record but it hasn't changed + s.seenTracks[track.ID] = struct{}{} return nil } track.Filename = it.filename track.Size = int(it.stat.Size()) track.AlbumID = s.curFolderID() - track.Duration = -1 - track.Bitrate = -1 tags, err := readTags(it.fullPath) if err != nil { - return errors.Wrap(err, "reading tags") + // not returning the error here because we don't + // want the entire walk to stop if we can't read + // the tags of a single file + log.Printf("error reading tags `%s`: %v", it.relPath, err) + s.seenTracksErr++ + return nil } - trackNumber, totalTracks := tags.Track() - discNumber, totalDiscs := tags.Disc() - track.TagDiscNumber = discNumber - track.TagTotalDiscs = totalDiscs - track.TagTotalTracks = totalTracks - track.TagTrackNumber = trackNumber track.TagTitle = tags.Title() track.TagTrackArtist = tags.Artist() - track.TagYear = tags.Year() + track.TagTrackNumber = tags.TrackNumber() + track.Duration = tags.DurationSecs() // these two should be calculated + track.Bitrate = tags.Bitrate() // from the file instead of tags // // set album artist basics artist := &model.Artist{} @@ -296,14 +279,18 @@ func (s *Scanner) handleTrack(it *item) error { } track.ArtistID = artist.ID s.tx.Save(track) + s.seenTracks[track.ID] = struct{}{} s.seenTracksNew++ // // set album if this is the first track in the folder - if !s.curFolder().IsNew { + folder := s.curFolder() + if !folder.ReceivedPaths || folder.ReceivedTags { + // the folder hasn't been modified or already has it's tags return nil } - s.curFolder().TagTitle = tags.Album() - s.curFolder().TagYear = tags.Year() - s.curFolder().TagArtistID = artist.ID + folder.TagTitle = tags.Album() + folder.TagYear = tags.Year() + folder.TagArtistID = artist.ID + folder.ReceivedTags = true return nil } diff --git a/scanner/tags.go b/scanner/tags.go new file mode 100644 index 0000000..21a2a02 --- /dev/null +++ b/scanner/tags.go @@ -0,0 +1,55 @@ +package scanner + +import ( + "os" + "strconv" + "strings" + + "github.com/mdlayher/taggolib" + "github.com/pkg/errors" +) + +type tags struct { + taggolib.Parser +} + +func (t *tags) Year() int { + // for this one there could be multiple tags and a + // date separator. so do string(2019-6-6) -> int(2019) + // for the two options and pick the first + for _, name := range []string{"DATE", "YEAR"} { + tag := t.Tag(name) + if tag == "" { + continue + } + parts := strings.Split(tag, "-") + year, err := strconv.Atoi(parts[0]) + if err != nil { + continue + } + return year + } + return 0 +} + +func (t *tags) DurationSecs() int { + duration := int(t.Duration() / 1e9) + if duration == 0 { + return -1 + } + return duration +} + +func readTags(path string) (*tags, error) { + track, err := os.Open(path) + if err != nil { + return nil, errors.Wrap(err, "reading disk") + } + defer track.Close() + parser, err := taggolib.New(track) + if err != nil { + return nil, errors.Wrap(err, "parsing") + } + newTags := &tags{parser} + return newTags, nil +} diff --git a/server/handler/construct_sub_by_folder.go b/server/handler/construct_sub_by_folder.go index bc4b2ec..f197c8a 100644 --- a/server/handler/construct_sub_by_folder.go +++ b/server/handler/construct_sub_by_folder.go @@ -19,20 +19,20 @@ func newAlbumByFolder(f *model.Album) *subsonic.Album { } func newTCAlbumByFolder(f *model.Album, parent *model.Album) *subsonic.TrackChild { - child := &subsonic.TrackChild{ - CoverID: f.ID, - ID: f.ID, - IsDir: true, - Title: f.RightPath, + trCh := &subsonic.TrackChild{ + ID: f.ID, + IsDir: true, + Title: f.RightPath, + ParentID: f.ParentID, } - if parent != nil { - child.ParentID = parent.ID + if f.Cover != "" { + trCh.CoverID = f.ID } - return child + return trCh } func newTCTrackByFolder(t *model.Track, parent *model.Album) *subsonic.TrackChild { - return &subsonic.TrackChild{ + trCh := &subsonic.TrackChild{ ID: t.ID, Album: t.Album.RightPath, ContentType: t.MIME(), @@ -47,11 +47,15 @@ func newTCTrackByFolder(t *model.Track, parent *model.Album) *subsonic.TrackChil t.Filename, ), ParentID: parent.ID, - CoverID: parent.ID, - Duration: 0, + Duration: t.Duration, + Bitrate: t.Bitrate, IsDir: false, Type: "music", } + if parent.Cover != "" { + trCh.CoverID = parent.ID + } + return trCh } func newArtistByFolder(f *model.Album) *subsonic.Artist { diff --git a/server/handler/construct_sub_by_tags.go b/server/handler/construct_sub_by_tags.go index b285c3e..c748f5b 100644 --- a/server/handler/construct_sub_by_tags.go +++ b/server/handler/construct_sub_by_tags.go @@ -9,11 +9,13 @@ import ( func newAlbumByTags(a *model.Album, artist *model.Artist) *subsonic.Album { ret := &subsonic.Album{ - CoverID: a.ID, Created: a.CreatedAt, ID: a.ID, Name: a.TagTitle, } + if a.Cover != "" { + ret.CoverID = a.ID + } if artist != nil { ret.Artist = artist.Name ret.ArtistID = artist.ID @@ -22,7 +24,7 @@ func newAlbumByTags(a *model.Album, artist *model.Artist) *subsonic.Album { } func newTrackByTags(t *model.Track, album *model.Album) *subsonic.TrackChild { - return &subsonic.TrackChild{ + ret := &subsonic.TrackChild{ ID: t.ID, ContentType: t.MIME(), Suffix: t.Ext(), @@ -40,9 +42,14 @@ func newTrackByTags(t *model.Track, album *model.Album) *subsonic.TrackChild { Album: album.TagTitle, AlbumID: album.ID, ArtistID: album.TagArtist.ID, - CoverID: album.ID, + Duration: t.Duration, + Bitrate: t.Bitrate, Type: "music", } + if album.Cover != "" { + ret.CoverID = album.ID + } + return ret } func newArtistByTags(a *model.Artist) *subsonic.Artist { diff --git a/server/handler/handler_sub_common.go b/server/handler/handler_sub_common.go index c6b89c0..5905175 100644 --- a/server/handler/handler_sub_common.go +++ b/server/handler/handler_sub_common.go @@ -78,7 +78,7 @@ func (c *Controller) GetCoverArt(w http.ResponseWriter, r *http.Request) { } folder := &model.Album{} err = c.DB. - Select("id, path, cover"). + Select("id, left_path, right_path, cover"). First(folder, id). Error if gorm.IsRecordNotFoundError(err) { @@ -91,8 +91,8 @@ func (c *Controller) GetCoverArt(w http.ResponseWriter, r *http.Request) { } absPath := path.Join( c.MusicPath, - folder.RightPath, folder.LeftPath, + folder.RightPath, folder.Cover, ) http.ServeFile(w, r, absPath) diff --git a/server/handler/test_data/db b/server/handler/test_data/db index 8249c95..194561a 100644 Binary files a/server/handler/test_data/db and b/server/handler/test_data/db differ diff --git a/server/handler/test_data/test_get_album_list_random b/server/handler/test_data/test_get_album_list_random index b8427e9..b48a5e3 100644 --- a/server/handler/test_data/test_get_album_list_random +++ b/server/handler/test_data/test_get_album_list_random @@ -4,15 +4,6 @@ "version": "1.9.0", "albumList": { "album": [ - { - "id": 3, - "coverArt": 3, - "artist": "A Certain Ratio", - "title": "(1994) The Graveyard and the Ballroom", - "parent": 2, - "isDir": true, - "created": "0001-01-01T00:00:00Z" - }, { "id": 11, "coverArt": 11, @@ -22,6 +13,15 @@ "isDir": true, "created": "0001-01-01T00:00:00Z" }, + { + "id": 7, + "coverArt": 7, + "artist": "13th Floor Lowervators", + "title": "(1966) The Psychedelic Sounds of the 13th Floor Elevators", + "parent": 5, + "isDir": true, + "created": "0001-01-01T00:00:00Z" + }, { "id": 4, "coverArt": 4, @@ -32,19 +32,19 @@ "created": "0001-01-01T00:00:00Z" }, { - "id": 6, - "coverArt": 6, - "artist": "13th Floor Lowervators", - "title": "(1967) Easter Nowhere", - "parent": 5, + "id": 3, + "coverArt": 3, + "artist": "A Certain Ratio", + "title": "(1994) The Graveyard and the Ballroom", + "parent": 2, "isDir": true, "created": "0001-01-01T00:00:00Z" }, { - "id": 7, - "coverArt": 7, + "id": 6, + "coverArt": 6, "artist": "13th Floor Lowervators", - "title": "(1966) The Psychedelic Sounds of the 13th Floor Elevators", + "title": "(1967) Easter Nowhere", "parent": 5, "isDir": true, "created": "0001-01-01T00:00:00Z" diff --git a/server/handler/test_data/test_get_album_list_two_alpha_artist b/server/handler/test_data/test_get_album_list_two_alpha_artist index e6e10a1..dde3bdc 100644 --- a/server/handler/test_data/test_get_album_list_two_alpha_artist +++ b/server/handler/test_data/test_get_album_list_two_alpha_artist @@ -10,7 +10,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "Easter Everywhere", - "created": "2019-06-05T16:00:10.556862345+01:00" + "created": "2019-06-06T16:38:39.306600701+01:00" }, { "id": 7, @@ -18,7 +18,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" }, { "id": 3, @@ -26,15 +26,14 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00" + "created": "2019-06-06T16:38:39.298724062+01:00" }, { "id": 4, - "coverArt": 4, "artistId": 1, "artist": "A Certain Ratio", "name": "To Each...", - "created": "2019-06-05T16:00:10.553065063+01:00" + "created": "2019-06-06T16:38:39.303278797+01:00" }, { "id": 11, @@ -42,7 +41,7 @@ "artistId": 3, "artist": "Anikas", "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "created": "2019-06-06T16:38:39.31657693+01:00" } ] } diff --git a/server/handler/test_data/test_get_album_list_two_alpha_name b/server/handler/test_data/test_get_album_list_two_alpha_name index 1f0b097..0257551 100644 --- a/server/handler/test_data/test_get_album_list_two_alpha_name +++ b/server/handler/test_data/test_get_album_list_two_alpha_name @@ -10,7 +10,7 @@ "artistId": 3, "artist": "Anikas", "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "created": "2019-06-06T16:38:39.31657693+01:00" }, { "id": 6, @@ -18,7 +18,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "Easter Everywhere", - "created": "2019-06-05T16:00:10.556862345+01:00" + "created": "2019-06-06T16:38:39.306600701+01:00" }, { "id": 3, @@ -26,7 +26,7 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00" + "created": "2019-06-06T16:38:39.298724062+01:00" }, { "id": 7, @@ -34,15 +34,14 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" }, { "id": 4, - "coverArt": 4, "artistId": 1, "artist": "A Certain Ratio", "name": "To Each...", - "created": "2019-06-05T16:00:10.553065063+01:00" + "created": "2019-06-06T16:38:39.303278797+01:00" } ] } diff --git a/server/handler/test_data/test_get_album_list_two_newest b/server/handler/test_data/test_get_album_list_two_newest index 9648a8a..d1c062a 100644 --- a/server/handler/test_data/test_get_album_list_two_newest +++ b/server/handler/test_data/test_get_album_list_two_newest @@ -10,7 +10,7 @@ "artistId": 3, "artist": "Anikas", "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "created": "2019-06-06T16:38:39.31657693+01:00" }, { "id": 7, @@ -18,7 +18,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" }, { "id": 6, @@ -26,15 +26,14 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "Easter Everywhere", - "created": "2019-06-05T16:00:10.556862345+01:00" + "created": "2019-06-06T16:38:39.306600701+01:00" }, { "id": 4, - "coverArt": 4, "artistId": 1, "artist": "A Certain Ratio", "name": "To Each...", - "created": "2019-06-05T16:00:10.553065063+01:00" + "created": "2019-06-06T16:38:39.303278797+01:00" }, { "id": 3, @@ -42,7 +41,7 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00" + "created": "2019-06-06T16:38:39.298724062+01:00" } ] } diff --git a/server/handler/test_data/test_get_album_list_two_random b/server/handler/test_data/test_get_album_list_two_random index e5b8c87..ecff8b8 100644 --- a/server/handler/test_data/test_get_album_list_two_random +++ b/server/handler/test_data/test_get_album_list_two_random @@ -5,20 +5,12 @@ "albumList2": { "album": [ { - "id": 4, - "coverArt": 4, - "artistId": 1, - "artist": "A Certain Ratio", - "name": "To Each...", - "created": "2019-06-05T16:00:10.553065063+01:00" - }, - { - "id": 11, - "coverArt": 11, - "artistId": 3, - "artist": "Anikas", - "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "id": 6, + "coverArt": 6, + "artistId": 2, + "artist": "13th Floor Elevators", + "name": "Easter Everywhere", + "created": "2019-06-06T16:38:39.306600701+01:00" }, { "id": 3, @@ -26,7 +18,14 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00" + "created": "2019-06-06T16:38:39.298724062+01:00" + }, + { + "id": 4, + "artistId": 1, + "artist": "A Certain Ratio", + "name": "To Each...", + "created": "2019-06-06T16:38:39.303278797+01:00" }, { "id": 7, @@ -34,15 +33,15 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" }, { - "id": 6, - "coverArt": 6, - "artistId": 2, - "artist": "13th Floor Elevators", - "name": "Easter Everywhere", - "created": "2019-06-05T16:00:10.556862345+01:00" + "id": 11, + "coverArt": 11, + "artistId": 3, + "artist": "Anikas", + "name": "Anika", + "created": "2019-06-06T16:38:39.31657693+01:00" } ] } diff --git a/server/handler/test_data/test_get_album_with_cover b/server/handler/test_data/test_get_album_with_cover index 652d725..cd94224 100644 --- a/server/handler/test_data/test_get_album_with_cover +++ b/server/handler/test_data/test_get_album_with_cover @@ -8,16 +8,18 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00", + "created": "2019-06-06T16:38:39.298724062+01:00", "song": [ { "album": "The Graveyard and the Ballroom", "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 922, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.552108331+01:00", + "created": "2019-06-06T16:38:39.302489659+01:00", + "duration": 174, "id": 12, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/01.14 Do the Du (casse).flac", @@ -32,9 +34,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 916, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.550632503+01:00", + "created": "2019-06-06T16:38:39.301301007+01:00", + "duration": 142, "id": 8, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/02.14 Faceless.flac", @@ -49,9 +53,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 957, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.549864008+01:00", + "created": "2019-06-06T16:38:39.300698509+01:00", + "duration": 174, "id": 6, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/03.14 Crippled Child.flac", @@ -66,9 +72,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 961, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.551742258+01:00", + "created": "2019-06-06T16:38:39.302194015+01:00", + "duration": 201, "id": 11, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/04.14 Choir.flac", @@ -83,9 +91,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 924, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.548393601+01:00", + "created": "2019-06-06T16:38:39.299490189+01:00", + "duration": 210, "id": 2, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/05.14 Flight.flac", @@ -100,9 +110,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 961, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.552469878+01:00", + "created": "2019-06-06T16:38:39.302789079+01:00", + "duration": 131, "id": 13, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/06.14 I Feel.flac", @@ -117,9 +129,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 929, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.552842449+01:00", + "created": "2019-06-06T16:38:39.303072046+01:00", + "duration": 148, "id": 14, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/07.14 Strain.flac", @@ -134,9 +148,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 898, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.549504916+01:00", + "created": "2019-06-06T16:38:39.300381932+01:00", + "duration": 217, "id": 5, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/08.14 All Night Party.flac", @@ -151,9 +167,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 877, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.549134887+01:00", + "created": "2019-06-06T16:38:39.300087164+01:00", + "duration": 235, "id": 4, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/09.14 Oceans.flac", @@ -168,9 +186,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 888, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.551373999+01:00", + "created": "2019-06-06T16:38:39.301890876+01:00", + "duration": 212, "id": 10, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/10.14 The Choir.flac", @@ -185,9 +205,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 916, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.550996621+01:00", + "created": "2019-06-06T16:38:39.301604638+01:00", + "duration": 205, "id": 9, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/11.14 The Fox.flac", @@ -202,9 +224,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 900, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.55027053+01:00", + "created": "2019-06-06T16:38:39.301006358+01:00", + "duration": 144, "id": 7, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/12.14 Suspect.flac", @@ -219,9 +243,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 877, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.547986038+01:00", + "created": "2019-06-06T16:38:39.299163755+01:00", + "duration": 332, "id": 1, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/13.14 Flight.flac", @@ -236,9 +262,11 @@ "albumId": 3, "artist": "A Certain Ratio", "artistId": 1, + "bitRate": 893, "contentType": "audio/x-flac", "coverArt": 3, - "created": "2019-06-05T16:00:10.548763765+01:00", + "created": "2019-06-06T16:38:39.299791782+01:00", + "duration": 213, "id": 3, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/14.14 Genotype_Phenotype.flac", diff --git a/server/handler/test_data/test_get_album_without_cover b/server/handler/test_data/test_get_album_without_cover index 0b9b94f..309f458 100644 --- a/server/handler/test_data/test_get_album_without_cover +++ b/server/handler/test_data/test_get_album_without_cover @@ -4,8 +4,7 @@ "version": "1.9.0", "album": { "id": 2, - "coverArt": 2, - "created": "2019-06-05T16:00:10.547172057+01:00" + "created": "2019-06-06T16:38:39.298507437+01:00" } } } diff --git a/server/handler/test_data/test_get_artist_id_one b/server/handler/test_data/test_get_artist_id_one index 279a8a6..1ece5d9 100644 --- a/server/handler/test_data/test_get_artist_id_one +++ b/server/handler/test_data/test_get_artist_id_one @@ -12,15 +12,14 @@ "artistId": 1, "artist": "A Certain Ratio", "name": "The Graveyard and the Ballroom", - "created": "2019-06-05T16:00:10.54747823+01:00" + "created": "2019-06-06T16:38:39.298724062+01:00" }, { "id": 4, - "coverArt": 4, "artistId": 1, "artist": "A Certain Ratio", "name": "To Each...", - "created": "2019-06-05T16:00:10.553065063+01:00" + "created": "2019-06-06T16:38:39.303278797+01:00" } ] } diff --git a/server/handler/test_data/test_get_artist_id_three b/server/handler/test_data/test_get_artist_id_three index 2cb1d18..10fbb5c 100644 --- a/server/handler/test_data/test_get_artist_id_three +++ b/server/handler/test_data/test_get_artist_id_three @@ -12,7 +12,7 @@ "artistId": 3, "artist": "Anikas", "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "created": "2019-06-06T16:38:39.31657693+01:00" } ] } diff --git a/server/handler/test_data/test_get_artist_id_two b/server/handler/test_data/test_get_artist_id_two index 50ebb3b..e314709 100644 --- a/server/handler/test_data/test_get_artist_id_two +++ b/server/handler/test_data/test_get_artist_id_two @@ -12,7 +12,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "Easter Everywhere", - "created": "2019-06-05T16:00:10.556862345+01:00" + "created": "2019-06-06T16:38:39.306600701+01:00" }, { "id": 7, @@ -20,7 +20,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" } ] } diff --git a/server/handler/test_data/test_get_music_directory_with_tracks b/server/handler/test_data/test_get_music_directory_with_tracks index b954d3a..35a5a40 100644 --- a/server/handler/test_data/test_get_music_directory_with_tracks +++ b/server/handler/test_data/test_get_music_directory_with_tracks @@ -10,9 +10,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 922, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 174, "id": 12, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/01.14 Do the Du (casse).flac", @@ -25,9 +27,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 916, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 142, "id": 8, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/02.14 Faceless.flac", @@ -40,9 +44,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 957, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 174, "id": 6, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/03.14 Crippled Child.flac", @@ -55,9 +61,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 961, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 201, "id": 11, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/04.14 Choir.flac", @@ -70,9 +78,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 924, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 210, "id": 2, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/05.14 Flight.flac", @@ -85,9 +95,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 961, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 131, "id": 13, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/06.14 I Feel.flac", @@ -100,9 +112,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 929, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 148, "id": 14, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/07.14 Strain.flac", @@ -115,9 +129,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 898, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 217, "id": 5, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/08.14 All Night Party.flac", @@ -130,9 +146,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 877, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 235, "id": 4, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/09.14 Oceans.flac", @@ -145,9 +163,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 888, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 212, "id": 10, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/10.14 The Choir.flac", @@ -160,9 +180,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 916, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 205, "id": 9, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/11.14 The Fox.flac", @@ -175,9 +197,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 900, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 144, "id": 7, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/12.14 Suspect.flac", @@ -190,9 +214,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 877, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 332, "id": 1, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/13.14 Flight.flac", @@ -205,9 +231,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 893, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 213, "id": 3, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/14.14 Genotype_Phenotype.flac", diff --git a/server/handler/test_data/test_get_music_directory_without_tracks b/server/handler/test_data/test_get_music_directory_without_tracks index 4702d84..325fb24 100644 --- a/server/handler/test_data/test_get_music_directory_without_tracks +++ b/server/handler/test_data/test_get_music_directory_without_tracks @@ -16,7 +16,6 @@ "title": "(1994) The Graveyard and the Ballroom" }, { - "coverArt": 4, "created": "0001-01-01T00:00:00Z", "id": 4, "isDir": true, diff --git a/server/handler/test_data/test_search_three_q_13 b/server/handler/test_data/test_search_three_q_13 index 5f848ed..c70a7c2 100644 --- a/server/handler/test_data/test_search_three_q_13 +++ b/server/handler/test_data/test_search_three_q_13 @@ -16,7 +16,7 @@ "artistId": 2, "artist": "13th Floor Elevators", "name": "The Psychedelic Sounds of the 13th Floor Elevators", - "created": "2019-06-05T16:00:10.560355528+01:00" + "created": "2019-06-06T16:38:39.309763889+01:00" } ] } diff --git a/server/handler/test_data/test_search_three_q_ani b/server/handler/test_data/test_search_three_q_ani index 69e491b..bf21ecf 100644 --- a/server/handler/test_data/test_search_three_q_ani +++ b/server/handler/test_data/test_search_three_q_ani @@ -16,7 +16,7 @@ "artistId": 3, "artist": "Anikas", "name": "Anika", - "created": "2019-06-05T16:00:10.565661506+01:00" + "created": "2019-06-06T16:38:39.31657693+01:00" } ] } diff --git a/server/handler/test_data/test_search_two_q_13 b/server/handler/test_data/test_search_two_q_13 index f9f8334..db2f5a2 100644 --- a/server/handler/test_data/test_search_two_q_13 +++ b/server/handler/test_data/test_search_two_q_13 @@ -24,9 +24,11 @@ { "album": "(1994) The Graveyard and the Ballroom", "artist": "A Certain Ratio", + "bitRate": 877, "contentType": "audio/x-flac", "coverArt": 3, "created": "0001-01-01T00:00:00Z", + "duration": 332, "id": 1, "parent": 3, "path": "A Certain Ratio/(1994) The Graveyard and the Ballroom/13.14 Flight.flac", @@ -39,9 +41,11 @@ { "album": "(1966) The Psychedelic Sounds of the 13th Floor Elevators", "artist": "13th Floor Elevators", + "bitRate": 245, "contentType": "audio/mpeg", "coverArt": 7, "created": "0001-01-01T00:00:00Z", + "duration": 154, "id": 35, "parent": 7, "path": "13th Floor Lowervators/(1966) The Psychedelic Sounds of the 13th Floor Elevators/13.21 Before You Accuse Me.mp3",