Rename host library to master throughout
The two libraries are now "master" and "slave" everywhere: UI text, API JSON fields (master_root, rel_master, master_size, ...), Go identifiers, database columns, quality verdicts, quarantine subfolders and docs. Existing databases are upgraded by a new migration that renames the columns in place and rewrites stored "host" values, so pairs, history, cached verdicts and restorable quarantine entries carry over. Network "host" usages (SplitHostPort, the Origin/Host check) are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d06b6d546d
commit
5b088bb4a6
19 files changed
+339
-326
No files matched your search
@@ -1,7 +1,7 @@
|
||||
# playlink
|
||||
|
||||
Deduplicate music libraries with hardlinks. playlink finds songs that exist in both a **host** library (e.g. your full `Albums`) and a
|
||||
**slave** library (e.g. a curated `Singles` library) and replaces the slave copy with a hardlink to the host copy. Each song then takes
|
||||
Deduplicate music libraries with hardlinks. playlink finds songs that exist in both a **master** library (e.g. your full `Albums`) and a
|
||||
**slave** library (e.g. a curated `Singles` library) and replaces the slave copy with a hardlink to the master copy. Each song then takes
|
||||
up disk space only once, while both libraries keep looking exactly the same to Plex, Navidrome, Jellyfin and other media servers.
|
||||
|
||||
It ships as a single Go binary with an embedded React web UI and SQLite state, packaged as a small Docker image, in the style of
|
||||
@@ -26,15 +26,15 @@ path on both sides. The fallbacks below catch small differences, and a scan warn
|
||||
**Manual review** shows both files side by side and ranks their quality: lossless beats lossy, then bit depth and sample rate, then
|
||||
codec-weighted bitrate (Opus and AAC count for more per kbps than MP3). You then have three choices:
|
||||
|
||||
- **Link to host copy.** The default. The host is kept because it belongs to a complete album. If the host is *lower* quality, playlink
|
||||
- **Link to master copy.** The default. The master is kept because it belongs to a complete album. If the master is *lower* quality, playlink
|
||||
warns you and asks for explicit confirmation.
|
||||
- **Use slave copy as host.** The override. The slave's better file replaces the host file, the old host file is quarantined, and both
|
||||
- **Use slave copy as master.** The override. The slave's better file replaces the master file, the old master file is quarantined, and both
|
||||
libraries share the better file.
|
||||
- **Ignore.** The pair is hidden from review until you un-ignore it.
|
||||
|
||||
**Build mode** covers the "start fresh" workflow. Point the slave at an empty folder, browse the host library, tick the
|
||||
**Build mode** covers the "start fresh" workflow. Point the slave at an empty folder, browse the master library, tick the
|
||||
folders or songs you want, and playlink hardlinks them in at the same relative path. **Remove** deletes slave files, but only ones that are hardlinks of the
|
||||
host file.
|
||||
master file.
|
||||
|
||||
## Safety model
|
||||
|
||||
@@ -52,10 +52,10 @@ playlink is built so that no user data is ever lost, even if it crashes or loses
|
||||
expires, or until you purge it.
|
||||
- **Every operation can be undone.** An identical link is undone by writing an independent, verified copy back. A quarantined file is
|
||||
undone by restoring the original.
|
||||
- **Removal is limited to hardlinks.** Build/Remove only deletes a slave file that shares an inode with the host file, so the last
|
||||
- **Removal is limited to hardlinks.** Build/Remove only deletes a slave file that shares an inode with the master file, so the last
|
||||
copy of any data is never deleted.
|
||||
- **Paths are confined.** Libraries and the quarantine must be inside `PLAYLINK_ALLOWED_ROOTS`. Symlinks are never followed or
|
||||
replaced, `..` is rejected, and host and slave may not overlap.
|
||||
replaced, `..` is rejected, and master and slave may not overlap.
|
||||
- **Mutations are serialized.** Only one filesystem mutation runs at a time, and only one job runs per pair.
|
||||
- **Auto-link is conservative.** It only acts on files with the *exact* same path, and it skips files modified within the settle time
|
||||
(default 10 minutes) so it never touches a download in progress.
|
||||
@@ -83,7 +83,7 @@ services:
|
||||
|
||||
Then open `http://<server>:7480`, create your account, and add a pair:
|
||||
|
||||
- Host: `/data/Music/Albums`
|
||||
- Master: `/data/Music/Albums`
|
||||
- Slave: `/data/Music/Instances/cdnutter/Singles`
|
||||
|
||||
Run a scan, check the Review tab, and turn off dry run once the planned actions in Activity look right.
|
||||
|
||||
Reference in new issue
Block a user