feat: a held album below the quality you settle for, or holding a video rip, stays wanted for a better copy, and the import replaces the old tracks with their likes and plays carried over (M502 #5524)
release / govulncheck (push) Successful in 15s
release / web (push) Successful in 1m23s
release / go (push) Successful in 1m41s
release / integration (push) Successful in 5m20s
release / android (push) Successful in 5m28s
release / Build signed APK (releases and dev) (push) Successful in 5m30s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 27s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 15s
release / web (push) Successful in 1m23s
release / go (push) Successful in 1m41s
release / integration (push) Successful in 5m20s
release / android (push) Successful in 5m28s
release / Build signed APK (releases and dev) (push) Successful in 5m30s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 27s
release / Verify release artifacts (tag releases only) (push) Skipped
- acquisition_settings.upgrade_until (default High quality lossy, Lidarr's cutoff, note #5527; "" is off), an "Upgrade until" row under Searching. - The wanted worker judges held albums hourly: tier per format from size per second (the scanner records no bitrate), the album's worst. Below the cutoff it is wanted for quality; a video rip among its tracks always. - The schedule searches upgrades weekly, after open wants; a release no better than the copy held is refused ("not_better"). - The import matches each file to the track it would replace (recording, then disc/track) and replaces it when it is a rip or the file is a better tier: over the same path in one rename, or filed beside it and the old track folded in (library.ReplaceTrack: file first, then foldTrackInto). Nothing better: the release is set aside. - Collection › Upgrades (Lidarr's Cutoff Unmet); Suspect sources says when a clean copy was looked for instead of Lidarr's search. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -251,3 +251,61 @@ func TestParseTorrent_FilesAndInfohash(t *testing.T) {
|
||||
t.Error("HTML parsed as a torrent")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTierOfFile(t *testing.T) {
|
||||
cases := []struct {
|
||||
format string
|
||||
kbps int
|
||||
want Tier
|
||||
ok bool
|
||||
}{
|
||||
{"flac", 900, TierLossless, true},
|
||||
{"FLAC", 2800, TierLosslessHiRes, true},
|
||||
{"m4a", 750, TierLossless, true},
|
||||
{"m4a", 256, TierLossyHigh, true},
|
||||
{"mp3", 320, TierLossyHigh, true},
|
||||
{"mp3", 245, TierLossyHigh, true}, // a V0, by size
|
||||
{"mp3", 192, TierLossyLow, true},
|
||||
{"mp3", 128, TierLossyPoor, true},
|
||||
{"mp3", 96, TierLossyTrash, true},
|
||||
{"opus", 160, TierLossyLow, true},
|
||||
{"wma", 192, TierUnknown, false},
|
||||
{"mp3", 0, TierLossyStandard, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got, ok := TierOfFile(c.format, c.kbps)
|
||||
if got != c.want || ok != c.ok {
|
||||
t.Errorf("TierOfFile(%q, %d) = %s, %v; want %s, %v", c.format, c.kbps, got, ok, c.want, c.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileKbpsAndWords(t *testing.T) {
|
||||
// 5 MB over 3:30 of audio is about 190 kbps.
|
||||
k := FileKbps(5_000_000, 210_000)
|
||||
if k != 190 {
|
||||
t.Fatalf("FileKbps = %d, want 190", k)
|
||||
}
|
||||
if got := HeldWords("mp3", TierLossyLow, 191); got != "MP3, about 192 kbps" {
|
||||
t.Errorf("HeldWords = %q", got)
|
||||
}
|
||||
if got := HeldWords("flac", TierLossless, 900); got != "FLAC" {
|
||||
t.Errorf("HeldWords = %q", got)
|
||||
}
|
||||
if FileKbps(0, 1000) != 0 || FileKbps(1000, 0) != 0 {
|
||||
t.Error("FileKbps with nothing to measure is 0")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeldCopy_TakesTheWorstFormat(t *testing.T) {
|
||||
h, ok := HeldCopy([]HeldFormat{
|
||||
{Format: "flac", Bytes: 300_000_000, Ms: 2_400_000},
|
||||
{Format: "mp3", Bytes: 4_800_000, Ms: 200_000}, // 192 kbps
|
||||
})
|
||||
if !ok || h.Tier != TierLossyLow || h.Words != "MP3, about 192 kbps" {
|
||||
t.Fatalf("HeldCopy = %+v, %v", h, ok)
|
||||
}
|
||||
if _, ok := HeldCopy([]HeldFormat{{Format: "wma", Bytes: 1, Ms: 1}}); ok {
|
||||
t.Error("a format the ladder can't place says nothing")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user