Add database backups and two-digit disc numbers
Disc numbers: the organizer writes two-digit disc numbers by default
(Disc 01, 01-04 Title, {disc}), with an option for the plain style
(Disc 2, 2-04). Migration 8 adds the per-pair setting.
Backups (Settings -> Backups), similar to Sonarr:
- A backup is a zip with a consistent snapshot of the database (VACUUM
INTO, safe while running) and backup.json. Configurable folder,
schedule (off/1/3/7/14 days) and retention for scheduled backups;
manual backups are kept until deleted. List, download, delete.
- Restore from a listed backup or an uploaded zip: validated first
(integrity check, playlink tables, not a newer schema), staged next to
the live database, then the server restarts; at startup the staged
database is swapped in and the previous one kept as
playlink.db.pre-restore-<time>. Refused while a job runs. Backup names
are validated, so downloads/deletes cannot reach other files.
- Optional backup before every action in live mode: once per action the
user starts (link, promote, bulk, build/remove, tag edit, folder
renames, undo, purge) and before scans auto-link or auto-organize,
never per file and never in dry run. If the backup fails the action
does not run. The newest 10 action backups are kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
96ea856dfd
commit
49fc32096a
18 files changed
+1235
-47
No files matched your search
@@ -42,8 +42,9 @@ type Engine struct {
|
||||
// the same files.
|
||||
mu sync.Mutex
|
||||
|
||||
tagTools tags.Tools
|
||||
tagCache tagCache
|
||||
tagTools tags.Tools
|
||||
beforeAction func(ctx context.Context, reason string) error
|
||||
tagCache tagCache
|
||||
|
||||
jobsMu sync.Mutex
|
||||
jobs map[int64]*Job
|
||||
@@ -358,3 +359,19 @@ func sortedKeys(m map[string]fsops.Info) []string {
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// SetBeforeAction installs the hook that backs up the database before an
|
||||
// action in live mode.
|
||||
func (e *Engine) SetBeforeAction(f func(ctx context.Context, reason string) error) {
|
||||
e.beforeAction = f
|
||||
}
|
||||
|
||||
// BeforeAction runs the pre-action backup, once per user action (not per
|
||||
// file). It does nothing in dry run, where no files change. An error means
|
||||
// the action must not run.
|
||||
func (e *Engine) BeforeAction(ctx context.Context, reason string) error {
|
||||
if e.beforeAction == nil || e.st.DryRun(ctx) {
|
||||
return nil
|
||||
}
|
||||
return e.beforeAction(ctx, reason)
|
||||
}
|
||||
Reference in new issue
Block a user