Load cover art from file directory
This commit adds support for loading cover art from media file directories, according to configured filename priorities (of which an additional, special choice of `embedded` is given). Cover art paths are resolved during scanning and stored in the database as part of the `album.cover_art_path` column; if embedded cover art is matched, this will default to the path of the media file itself, and if no cover art is matched at all. Similarly, the `album.cover_art_id` column will default to a reference to `media_file.id` if embedded cover art is wanted, but if an external cover art file is matched, this will instead be set to a reference to the `album.id` value itself, prefixed with the `al-` constant. Stored cover art paths are once again resolved and matched against configuration when covers are requested; that is, any change in configuration between scanning and requesting cover art may not return correct data until a re-scan is complete. Tests will be added in future commits.
This commit is contained in:
committed by
Deluan Quintão
parent
6563897692
commit
08cd28af2d
@@ -2,6 +2,8 @@ package persistence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -9,6 +11,7 @@ import (
|
||||
|
||||
. "github.com/Masterminds/squirrel"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/deluan/navidrome/conf"
|
||||
"github.com/deluan/navidrome/consts"
|
||||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/model"
|
||||
@@ -137,9 +140,15 @@ func (r *albumRepository) Refresh(ids ...string) error {
|
||||
toInsert := 0
|
||||
toUpdate := 0
|
||||
for _, al := range albums {
|
||||
if !al.HasCoverArt {
|
||||
al.CoverArtId = ""
|
||||
if !al.HasCoverArt || !strings.HasPrefix(conf.Server.CoverArtPriority, "embedded") {
|
||||
if path := getCoverFromPath(al.CoverArtPath, al.HasCoverArt); path != "" {
|
||||
al.CoverArtId = "al-" + al.ID
|
||||
al.CoverArtPath = path
|
||||
} else if !al.HasCoverArt {
|
||||
al.CoverArtId = ""
|
||||
}
|
||||
}
|
||||
|
||||
if al.Compilation {
|
||||
al.AlbumArtist = consts.VariousArtists
|
||||
al.AlbumArtistID = consts.VariousArtistsID
|
||||
@@ -184,6 +193,42 @@ func getMinYear(years string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetCoverFromPath accepts a path to a file, and returns a path to an eligible cover image from the
|
||||
// file's directory (as configured with CoverArtPriority). If no cover file is found, among
|
||||
// available choices, or an error occurs, an empty string is returned. If HasEmbeddedCover is true,
|
||||
// and 'embedded' is matched among eligible choices, GetCoverFromPath will return early with an
|
||||
// empty path.
|
||||
func getCoverFromPath(path string, hasEmbeddedCover bool) string {
|
||||
n, err := os.Open(filepath.Dir(path))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
defer n.Close()
|
||||
names, err := n.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, p := range strings.Split(conf.Server.CoverArtPriority, ",") {
|
||||
pat := strings.ToLower(strings.TrimSpace(p))
|
||||
if pat == "embedded" {
|
||||
if hasEmbeddedCover {
|
||||
return ""
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
if ok, _ := filepath.Match(pat, strings.ToLower(name)); ok {
|
||||
return filepath.Join(filepath.Dir(path), name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (r *albumRepository) purgeEmpty() error {
|
||||
del := Delete(r.tableName).Where("id not in (select distinct(album_id) from media_file)")
|
||||
c, err := r.executeSQL(del)
|
||||
|
||||
Reference in New Issue
Block a user