DLNA renderers, app updates told like Librarian, acquisition without Lidarr, Collection and admin rework (M502–M505, M542) #156

Merged
bvandeusen merged 117 commits from dev into main 2026-10-26 12:32:33 -04:00
3 changed files with 14 additions and 7 deletions
Showing only changes of commit 7ef1fca90c - Show all commits
+2 -1
View File
@@ -30,7 +30,8 @@ const libraryMatchBatch = 25
// 1 tags, release, discography and search, checked by title and length // 1 tags, release, discography and search, checked by title and length
// 2 titles alone under the album's own name; a refusal names the track // 2 titles alone under the album's own name; a refusal names the track
// 3 a second copy of a track counts once; joining words count for nothing // 3 a second copy of a track counts once; joining words count for nothing
const libraryMatcher = 3 // 4 an album holding every track of an edition, and more, is that group
const libraryMatcher = 4
// listLibrary puts the library's albums on the wanted list as held, once // listLibrary puts the library's albums on the wanted list as held, once
// (operator, 2026-10-10: "make a record saying that the import has // (operator, 2026-10-10: "make a record saying that the import has
+4 -1
View File
@@ -277,9 +277,12 @@ func TestTrackAgreement(t *testing.T) {
if len(copies) != 2 { if len(copies) != 2 {
t.Errorf("a second copy of a track is read once: %+v", copies) t.Errorf("a second copy of a track is read once: %+v", copies)
} }
if agrees(3, 4) || !agrees(4, 5) || agrees(0, 0) { if agrees(3, 4, 0) || !agrees(4, 5, 0) || agrees(0, 0, 0) {
t.Error("agrees: 80% of the album's tracks, and an album has tracks") t.Error("agrees: 80% of the album's tracks, and an album has tracks")
} }
if !agrees(23, 43, 23) || agrees(2, 10, 2) || agrees(22, 43, 23) {
t.Error("agrees: a whole edition of three or more tracks, with more besides")
}
} }
// A refusal by an older matcher is matched again once the matching improves, // A refusal by an older matcher is matched again once the matching improves,
+8 -5
View File
@@ -170,9 +170,12 @@ func minutes(ms int) string {
return fmt.Sprintf("%d:%02d", sec/60, sec%60) return fmt.Sprintf("%d:%02d", sec/60, sec%60)
} }
// agrees: enough of the album's tracks agree for the edition to be it. // agrees: enough of the album's tracks agree for the edition to be it, or
func agrees(n, tracks int) bool { // the album holds every track of the edition and more besides (a folder
return tracks > 0 && n*10 >= tracks*matchAgreement // with the deluxe edition and its demos). A single or a two-track release
// is not taken on containment: too many albums hold its songs.
func agrees(n, tracks, edition int) bool {
return tracks > 0 && (n*10 >= tracks*matchAgreement || (edition >= 3 && n == edition))
} }
// sameTitle: the same words, not merely one holding the other. "And", // sameTitle: the same words, not merely one holding the other. "And",
@@ -243,7 +246,7 @@ func (s *Service) matchAlbum(ctx context.Context, a dbq.ListAlbumsToMatchRow, tr
if err := check(discography); err != nil { if err := check(discography); err != nil {
return albumMatch{}, err return albumMatch{}, err
} }
if !agrees(bestN, len(tracks)) { if !agrees(bestN, len(tracks), bestEdition) {
found, err := s.searchCandidates(ctx, a) found, err := s.searchCandidates(ctx, a)
if err != nil { if err != nil {
return albumMatch{}, err return albumMatch{}, err
@@ -252,7 +255,7 @@ func (s *Service) matchAlbum(ctx context.Context, a dbq.ListAlbumsToMatchRow, tr
return albumMatch{}, err return albumMatch{}, err
} }
} }
if agrees(bestN, len(tracks)) { if agrees(bestN, len(tracks), bestEdition) {
best.OK = true best.OK = true
return best, nil return best, nil
} }