diff --git a/db/migration/20200512104202_add_disc_subtitle.go b/db/migration/20200512104202_add_disc_subtitle.go new file mode 100644 index 000000000..eeed35823 --- /dev/null +++ b/db/migration/20200512104202_add_disc_subtitle.go @@ -0,0 +1,27 @@ +package migration + +import ( + "database/sql" + + "github.com/pressly/goose" +) + +func init() { + goose.AddMigration(Up20200512104202, Down20200512104202) +} + +func Up20200512104202(tx *sql.Tx) error { + _, err := tx.Exec(` +alter table media_file + add disc_subtitle varchar(255); + `) + if err != nil { + return err + } + notice(tx, "A full rescan will be performed to import disc subtitles") + return forceFullRescan(tx) +} + +func Down20200512104202(tx *sql.Tx) error { + return nil +} diff --git a/model/mediafile.go b/model/mediafile.go index e27144a81..4d70bee37 100644 --- a/model/mediafile.go +++ b/model/mediafile.go @@ -18,6 +18,7 @@ type MediaFile struct { HasCoverArt bool `json:"hasCoverArt"` TrackNumber int `json:"trackNumber"` DiscNumber int `json:"discNumber"` + DiscSubtitle string `json:"discSubtitle"` Year int `json:"year"` Size int `json:"size"` Suffix string `json:"suffix"` diff --git a/persistence/album_repository.go b/persistence/album_repository.go index eb7e99591..9fe15c017 100644 --- a/persistence/album_repository.go +++ b/persistence/album_repository.go @@ -108,10 +108,11 @@ func (r *albumRepository) GetRandom(options ...model.QueryOptions) (model.Albums func (r *albumRepository) Refresh(ids ...string) error { type refreshAlbum struct { model.Album - CurrentId string - HasCoverArt bool - SongArtists string - Years string + CurrentId string + HasCoverArt bool + SongArtists string + Years string + DiscSubtitles string } var albums []refreshAlbum sel := Select(`album_id as id, album as name, f.artist, f.album_artist, f.artist_id, f.album_artist_id, @@ -119,6 +120,7 @@ func (r *albumRepository) Refresh(ids ...string) error { f.order_album_name, f.order_album_artist_name, f.compilation, f.genre, max(f.year) as max_year, sum(f.duration) as duration, count(*) as song_count, a.id as current_id, f.id as cover_art_id, f.path as cover_art_path, f.has_cover_art, + group_concat(f.disc_subtitle, ' ') as disc_subtitles, group_concat(f.artist, ' ') as song_artists, group_concat(f.year, ' ') as years`). From("media_file f"). LeftJoin("album a on f.album_id = a.id"). @@ -151,7 +153,7 @@ func (r *albumRepository) Refresh(ids ...string) error { al.CreatedAt = time.Now() } al.FullText = getFullText(al.Name, al.Artist, al.AlbumArtist, al.SongArtists, - al.SortAlbumName, al.SortArtistName, al.SortAlbumArtistName) + al.SortAlbumName, al.SortArtistName, al.SortAlbumArtistName, al.DiscSubtitles) _, err := r.put(al.ID, al.Album) if err != nil { return err diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index f2956ead7..761eac565 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -43,7 +43,7 @@ func (r mediaFileRepository) Exists(id string) (bool, error) { func (r mediaFileRepository) Put(m *model.MediaFile) error { m.FullText = getFullText(m.Title, m.Album, m.Artist, m.AlbumArtist, - m.SortTitle, m.SortAlbumName, m.SortArtistName, m.SortAlbumArtistName) + m.SortTitle, m.SortAlbumName, m.SortArtistName, m.SortAlbumArtistName, m.DiscSubtitle) _, err := r.put(m.ID, m) return err } diff --git a/scanner/metadata_ffmpeg.go b/scanner/metadata_ffmpeg.go index b22cc69e3..e22a94377 100644 --- a/scanner/metadata_ffmpeg.go +++ b/scanner/metadata_ffmpeg.go @@ -40,6 +40,7 @@ func (m *Metadata) Genre() string { return m.getTag("genre") } func (m *Metadata) Year() int { return m.parseYear("date") } func (m *Metadata) TrackNumber() (int, int) { return m.parseTuple("track") } func (m *Metadata) DiscNumber() (int, int) { return m.parseTuple("tpa", "disc") } +func (m *Metadata) DiscSubtitle() string { return m.getTag("tsst", "discsubtitle", "setsubtitle") } func (m *Metadata) HasPicture() bool { return m.getTag("has_picture", "metadata_block_picture") != "" } func (m *Metadata) Comment() string { return m.getTag("comment") } func (m *Metadata) Compilation() bool { return m.parseBool("compilation") } diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go index 9a6d8add7..2a1eac3c9 100644 --- a/scanner/tag_scanner.go +++ b/scanner/tag_scanner.go @@ -258,6 +258,7 @@ func (s *TagScanner) toMediaFile(md *Metadata) model.MediaFile { mf.Year = md.Year() mf.TrackNumber, _ = md.TrackNumber() mf.DiscNumber, _ = md.DiscNumber() + mf.DiscSubtitle = md.DiscSubtitle() mf.Duration = md.Duration() mf.BitRate = md.BitRate() mf.Path = md.FilePath() diff --git a/ui/src/common/SongDetails.js b/ui/src/common/SongDetails.js index e0ea2bc10..99d9be634 100644 --- a/ui/src/common/SongDetails.js +++ b/ui/src/common/SongDetails.js @@ -14,6 +14,7 @@ const SongDetails = (props) => { const { record } = props const data = { path: , + discSubtitle: , albumArtist: , genre: , compilation: , @@ -22,6 +23,9 @@ const SongDetails = (props) => { updatedAt: , playCount: , } + if (!record.discSubtitle) { + delete data.discSubtitle + } if (record.playCount > 0) { data.playDate = }