Go back to the hardlink deduplicator (1da0132), keeping backups
Restores the code of 1da0132 ("Add a setting to hide the quarantine from
Plex") and removes everything added after it: the tag editor, album art,
organizing/naming, the step-by-step tune-up and library types.
Kept:
- Database backups (Settings -> Backups): scheduled, manual, download,
restore, and the optional backup before every action.
- The .env-driven docker-compose.yml for Arcane.
Databases that already ran the later migrations keep working: migrations
6-10 stay in the list (they only add columns) so numbering never goes
backwards, and Undo refuses History entries of removed features instead
of treating them as links.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7b180e26db
commit
e0617047f7
44 files changed
+103
-10456
No files matched your search
@@ -13,12 +13,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cdnutter/playlink/internal/art"
|
||||
"github.com/cdnutter/playlink/internal/fsops"
|
||||
"github.com/cdnutter/playlink/internal/meta"
|
||||
"github.com/cdnutter/playlink/internal/probe"
|
||||
"github.com/cdnutter/playlink/internal/store"
|
||||
"github.com/cdnutter/playlink/internal/tags"
|
||||
)
|
||||
|
||||
// DefaultExtensions are the audio file types considered by default.
|
||||
@@ -44,20 +41,7 @@ type Engine struct {
|
||||
// the same files.
|
||||
mu sync.Mutex
|
||||
|
||||
tagTools tags.Tools
|
||||
beforeAction func(ctx context.Context, reason string) error
|
||||
tagCache tagCache
|
||||
artClient *art.Client
|
||||
artStore *art.Store
|
||||
|
||||
meta *meta.Client
|
||||
|
||||
fixMu sync.Mutex
|
||||
fixPlans map[int64]*FixPlan // latest fixer check per pair
|
||||
fixSeq int64
|
||||
|
||||
plansMu sync.Mutex
|
||||
plans map[int64]*organizePlan // latest "rename now" preview per pair
|
||||
|
||||
jobsMu sync.Mutex
|
||||
jobs map[int64]*Job
|
||||
@@ -84,7 +68,6 @@ type Job struct {
|
||||
Error string `json:"error"`
|
||||
Results map[string]int `json:"results"`
|
||||
Skipped []string `json:"skipped"`
|
||||
Notes []string `json:"notes"`
|
||||
StartedAt int64 `json:"started_at"`
|
||||
FinishedAt int64 `json:"finished_at,omitempty"`
|
||||
|
||||
@@ -106,15 +89,6 @@ func (j *Job) tick() { j.update(func(j *Job) { j.Done++ }) }
|
||||
|
||||
func (j *Job) count(key string) { j.update(func(j *Job) { j.Results[key]++ }) }
|
||||
|
||||
// note records an informational line (e.g. which cover was chosen).
|
||||
func (j *Job) note(msg string) {
|
||||
j.update(func(j *Job) {
|
||||
if len(j.Notes) < 300 {
|
||||
j.Notes = append(j.Notes, msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (j *Job) skip(msg string) {
|
||||
j.update(func(j *Job) {
|
||||
j.Results["skipped"]++
|
||||
@@ -138,7 +112,6 @@ func (e *Engine) Job(pairID int64) *Job {
|
||||
cp.Results[k] = v
|
||||
}
|
||||
cp.Skipped = append([]string{}, j.Skipped...) // never nil: the UI expects an array
|
||||
cp.Notes = append([]string{}, j.Notes...)
|
||||
return &cp
|
||||
}
|
||||
|
||||
@@ -316,16 +289,6 @@ func (e *Engine) NormalizePair(p *store.Pair) ([]store.Warning, error) {
|
||||
if p.RetentionDays < 0 || p.ScanIntervalMinutes < 0 || p.SettleMinutes < 0 {
|
||||
return nil, errors.New("intervals must not be negative")
|
||||
}
|
||||
switch p.LibraryType {
|
||||
case "":
|
||||
p.LibraryType = LibraryMusic
|
||||
case LibraryMusic, LibrarySoundtracks:
|
||||
default:
|
||||
return nil, errors.New("library type must be music or soundtracks")
|
||||
}
|
||||
if err := normalizeOrganize(p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.ApproxThreshold == 0 {
|
||||
p.ApproxThreshold = 85
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user