Skip to content

Commit

Permalink
fix(scanner): gracefully handle multi value tag delim splits with adj…
Browse files Browse the repository at this point in the history
…acent delimiters

closes #448

Co-authored-by: Chris Hayes <[email protected]>
  • Loading branch information
sentriz and shinterro committed Jan 2, 2024
1 parent 59d2bd9 commit eb79cec
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
18 changes: 11 additions & 7 deletions scanner/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"regexp"
"slices"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -319,7 +320,7 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
return fmt.Errorf("%w: %w", err, ErrReadingTags)
}

genreNames := parseMulti(trags, s.multiValueSettings[Genre], tagcommon.MustGenres, tagcommon.MustGenre)
genreNames := ParseMulti(s.multiValueSettings[Genre], tagcommon.MustGenres(trags), tagcommon.MustGenre(trags))
genreIDs, err := populateGenres(tx, genreNames)
if err != nil {
return fmt.Errorf("populate genres: %w", err)
Expand All @@ -331,7 +332,7 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
return fmt.Errorf("delete artist appearances: %w", err)
}

albumArtistNames := parseMulti(trags, s.multiValueSettings[AlbumArtist], tagcommon.MustAlbumArtists, tagcommon.MustAlbumArtist)
albumArtistNames := ParseMulti(s.multiValueSettings[AlbumArtist], tagcommon.MustAlbumArtists(trags), tagcommon.MustAlbumArtist(trags))
var albumArtistIDs []int
for _, albumArtistName := range albumArtistNames {
albumArtist, err := populateArtist(tx, albumArtistName)
Expand Down Expand Up @@ -364,7 +365,7 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
return fmt.Errorf("populate track genres: %w", err)
}

trackArtistNames := parseMulti(trags, s.multiValueSettings[Artist], tagcommon.MustArtists, tagcommon.MustArtist)
trackArtistNames := ParseMulti(s.multiValueSettings[Artist], tagcommon.MustArtists(trags), tagcommon.MustArtist(trags))
var trackArtistIDs []int
for _, trackArtistName := range trackArtistNames {
trackArtist, err := populateArtist(tx, trackArtistName)
Expand Down Expand Up @@ -704,19 +705,22 @@ type MultiValueSetting struct {
Delim string
}

func parseMulti(parser tagcommon.Info, setting MultiValueSetting, getMulti func(tagcommon.Info) []string, get func(tagcommon.Info) string) []string {
func ParseMulti(setting MultiValueSetting, values []string, value string) []string {
var parts []string
switch setting.Mode {
case Multi:
parts = getMulti(parser)
parts = values
case Delim:
parts = strings.Split(get(parser), setting.Delim)
parts = strings.Split(value, setting.Delim)
default:
parts = []string{get(parser)}
parts = []string{value}
}
for i := range parts {
parts[i] = strings.TrimSpace(parts[i])
}
parts = slices.DeleteFunc(parts, func(s string) bool {
return s == ""
})
return parts
}

Expand Down
16 changes: 16 additions & 0 deletions scanner/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,3 +810,19 @@ func TestPrefixOverlap(t *testing.T) {
require.NoError(t, m.DB().Model(db.Album{}).Where("root_dir LIKE ?", `%/tagged`).Count(&tagged).Error)
require.Greater(t, tagged, 1)
}

// https://github.com/sentriz/gonic/pull/448
func TestParseMultiDoubleDelim(t *testing.T) {
t.Parallel()

setting := scanner.MultiValueSetting{
Mode: scanner.Delim,
Delim: `/`,
}

values := scanner.ParseMulti(setting, nil, `DON'T//BE//⚜⚜⚜`)
require.Len(t, values, 3)
require.Equal(t, `DON'T`, values[0])
require.Equal(t, `BE`, values[1])
require.Equal(t, `⚜⚜⚜`, values[2])
}
6 changes: 5 additions & 1 deletion server/ctrlsubsonic/handlers_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,11 @@ func getMusicFolder(musicPaths []MusicPath, p params.Params) string {
}

func lowerUDecOrHash(in string) string {
lower := unicode.ToLower(rune(in[0]))
inRunes := []rune(in)
if len(inRunes) == 0 {
return ""
}
lower := unicode.ToLower(inRunes[0])
if !unicode.IsLetter(lower) {
return "#"
}
Expand Down

0 comments on commit eb79cec

Please sign in to comment.