From efe8280e234e3edab377ce98bbc7878ef307febd Mon Sep 17 00:00:00 2001
From: Broque Thomas <26755000+Nezreka@users.noreply.github.com>
Date: Sat, 18 Apr 2026 17:35:20 -0700
Subject: [PATCH] =?UTF-8?q?Rebrand=20folder=20terminology:=20Download?=
=?UTF-8?q?=E2=86=92Input,=20Transfer=E2=86=92Output,=20Staging=E2=86=92Im?=
=?UTF-8?q?port?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
All user-facing labels, docs, help text, tooltips, error messages, and debug
info output updated. Backend config keys, variable names, actual path values,
and Docker volume mounts are completely unchanged — zero functional impact.
---
README.md | 12 ++--
docker-compose.yml | 4 +-
web_server.py | 28 ++++-----
webui/index.html | 24 ++++----
webui/static/docs.js | 112 +++++++++++++++++------------------
webui/static/helper.js | 38 ++++++------
webui/static/script.js | 26 ++++----
webui/static/setup-wizard.js | 10 ++--
8 files changed, 127 insertions(+), 127 deletions(-)
diff --git a/README.md b/README.md
index bacabd48..6d1c30c9 100644
--- a/README.md
+++ b/README.md
@@ -280,9 +280,9 @@ Open SoulSync at `http://localhost:8008` and go to Settings.
**Download Source**: Choose your preferred source (Soulseek, Deezer, Tidal, Qobuz, HiFi, YouTube, or Hybrid)
**Paths**:
-- **Download Path**: Container path to slskd's download folder (e.g., `/app/downloads`)
-- **Transfer Path**: Where organized music goes (e.g., `/app/Transfer`)
-- **Staging Path**: Optional import folder (e.g., `/app/Staging`)
+- **Input Folder**: Container path to slskd's download folder (e.g., `/app/downloads`)
+- **Output Folder**: Where organized music goes (e.g., `/app/Transfer`)
+- **Import Folder**: Optional folder for importing existing music (e.g., `/app/Staging`)
**Media Server** (optional): Use your machine's actual IP (not `localhost` — that means inside the container)
@@ -293,9 +293,9 @@ Open SoulSync at `http://localhost:8008` and go to Settings.
| Config | `/app/config` | Your config folder |
| Logs | `/app/logs` | Your logs folder |
| Database | `/app/data` | Named volume (recommended) |
-| Downloads | `/app/downloads` | Same folder slskd downloads to |
-| Transfer | `/app/Transfer` | Where organized music goes |
-| Staging | `/app/Staging` | Optional import folder |
+| Input | `/app/downloads` | Same folder slskd downloads to |
+| Output | `/app/Transfer` | Where organized music goes |
+| Import | `/app/Staging` | Optional folder for importing music |
**Important:** Use a named volume for the database (`soulsync_database:/app/data`). Direct host path mounts to `/app/data` can overwrite Python module files.
diff --git a/docker-compose.yml b/docker-compose.yml
index cafa2e54..a2d8a0d4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -39,13 +39,13 @@ services:
# Use named volume for database persistence (separate from host database)
# NOTE: Changed from /app/database to /app/data to avoid overwriting Python package
- soulsync_database:/app/data
- # IMPORTANT: Mount host paths that your download/transfer folders live on.
+ # IMPORTANT: Mount host paths that your input/output folders live on.
# Replace these examples with your actual paths:
# Linux/Mac: - /path/to/your/downloads:/host/downloads:rw
# WSL: - /mnt/d/Music:/host/music:rw
# You can add as many mounts as needed for your setup.
# - /path/to/downloads:/host/downloads:rw
- # - /path/to/transfer:/host/transfer:rw
+ # - /path/to/music-library:/host/music:rw
# Optional: Mount your music library for Plex/Jellyfin/Navidrome access
# - /path/to/your/music:/music:ro
extra_hosts:
diff --git a/web_server.py b/web_server.py
index 240a2c1d..af156f14 100644
--- a/web_server.py
+++ b/web_server.py
@@ -1727,7 +1727,7 @@ def _register_automation_handlers():
log_line=f'Empty directories: removed {dirs_removed}', log_type='success' if dirs_removed else 'info')
# --- 4. Sweep empty staging directories ---
- _update_automation_progress(automation_id, phase='Sweeping staging folder...', progress=60)
+ _update_automation_progress(automation_id, phase='Sweeping import folder...', progress=60)
staging_path = _get_staging_path()
s_removed = 0
if os.path.isdir(staging_path):
@@ -4454,9 +4454,9 @@ def run_service_test(service, test_config):
count += 1
if count > 100:
break # Don't count everything, just confirm files exist
- return True, f"SoulSync standalone ready! Transfer folder: {transfer_path} ({count}+ audio files)"
+ return True, f"SoulSync standalone ready! Output folder: {transfer_path} ({count}+ audio files)"
else:
- return False, f"Transfer folder not found: {transfer_path}"
+ return False, f"Output folder not found: {transfer_path}"
elif service == "soulseek":
if soulseek_client is None:
return False, "Download orchestrator failed to initialize. Check server logs for startup errors."
@@ -6852,7 +6852,7 @@ def get_automation_blocks():
{"type": "clean_completed_downloads", "label": "Clean Completed Downloads", "icon": "check-square",
"description": "Clear completed downloads and empty directories", "available": True},
{"type": "full_cleanup", "label": "Full Cleanup", "icon": "trash",
- "description": "Clear quarantine, download queue, staging folder, and search history in one sweep", "available": True},
+ "description": "Clear quarantine, download queue, import folder, and search history in one sweep", "available": True},
{"type": "deep_scan_library", "label": "Deep Scan Library", "icon": "search",
"description": "Full library comparison without losing enrichment data", "available": True},
{"type": "run_script", "label": "Run Script", "icon": "terminal",
@@ -22516,7 +22516,7 @@ def get_version_info():
},
{
"title": "Auto-Import",
- "description": "Background staging folder watcher that automatically identifies and imports music into your library",
+ "description": "Background import folder watcher that automatically identifies and imports music into your library",
"features": [
"• Recursive scan — any folder depth (Artist/Album/tracks, Album/tracks, loose files)",
"• Single file support — loose audio files identified via tags, filename, or AcoustID",
@@ -22526,7 +22526,7 @@ def get_version_info():
"• Expandable track match details with per-track confidence scores",
"• Race condition fix prevents duplicate processing during multi-track albums",
],
- "usage_note": "Enable on the Import page Auto tab. Set your staging folder in Settings."
+ "usage_note": "Enable on the Import page Auto tab. Set your import folder in Settings."
},
{
"title": "Wishlist Nebula",
@@ -22982,7 +22982,7 @@ _OLD_V22_NOTES = """
"title": "Fix Library Maintenance Path Fixes Failing Silently",
"description": "Path mismatch fixes now use fresh config and report errors to the UI",
"features": [
- "• Transfer folder path is re-read from config before each fix attempt",
+ "• Output folder path is re-read from config before each fix attempt",
"• Fix failure reasons are now shown in the toast notification",
"• Bulk fix failures are logged individually with finding ID and error details"
]
@@ -23428,9 +23428,9 @@ _OLD_V2_NOTES = r"""
},
{
"title": "Staging Folder Pre-Download Check",
- "description": "Check your staging folder for existing files before downloading",
+ "description": "Check your import folder for existing files before downloading",
"features": [
- "• Before searching Soulseek/YouTube, checks the staging folder for a matching file",
+ "• Before searching Soulseek/YouTube, checks the import folder for a matching file",
"• Tag-based matching (Mutagen) with filename parsing fallback",
"• On match, copies the file to transfer and runs normal post-processing",
"• Staging scan cached per batch — only scans once for the entire download"
@@ -24499,9 +24499,9 @@ def _resume_workers_after_scan():
def _run_soulsync_deep_scan():
"""Deep scan for SoulSync standalone mode.
- 1. Scans the Transfer folder for all audio files
+ 1. Scans the output folder for all audio files
2. Compares against soulsync DB records (by file_path)
- 3. Untracked files → moved to Staging for auto-import processing
+ 3. Untracked files → moved to import folder for auto-import processing
4. Stale DB records (file gone) → removed from DB
"""
try:
@@ -24510,7 +24510,7 @@ def _run_soulsync_deep_scan():
staging_path = docker_resolve_path(config_manager.get('import.staging_path', './Staging'))
if not os.path.isdir(transfer_path):
- _db_update_error_callback(f"Transfer folder not found: {transfer_path}")
+ _db_update_error_callback(f"Output folder not found: {transfer_path}")
return
print(f"[SoulSync Deep Scan] Starting — Transfer: {transfer_path}")
@@ -26851,8 +26851,8 @@ def _run_duplicate_cleaner():
if not transfer_folder or not os.path.exists(transfer_folder):
with duplicate_cleaner_lock:
duplicate_cleaner_state["status"] = "error"
- duplicate_cleaner_state["phase"] = "Transfer folder not configured or does not exist"
- duplicate_cleaner_state["error_message"] = "Please configure Transfer folder in settings"
+ duplicate_cleaner_state["phase"] = "Output folder not configured or does not exist"
+ duplicate_cleaner_state["error_message"] = "Please configure output folder in settings"
print(f"[Duplicate Cleaner] Transfer folder not found: {transfer_folder}")
return
diff --git a/webui/index.html b/webui/index.html
index 39384333..5de14518 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -4422,7 +4422,7 @@
-
+
Files in this folder are your library. Configure the path in the Paths section.
Download Source — Connect at least one download source: Soulseek (slskd), YouTube, Tidal, Qobuz, HiFi, or Deezer. Soulseek offers the best quality selection; the others work as alternatives or fallbacks in Hybrid mode.
Media Server — Connect Plex, Jellyfin, or Navidrome so SoulSync knows where your library lives and can trigger scans.
Spotify (Recommended) — Connect Spotify for the richest metadata. Create an app at developer.spotify.com, enter your Client ID and Secret, then click Authenticate.
-
Download Path — Set your download and transfer paths in the Download Settings section. The transfer path should point to your media server's monitored folder.
+
Input Path — Set your input and output paths in the Download Settings section. The output path should point to your media server's monitored folder.
You can start using SoulSync with just one download source. Spotify and other services add metadata enrichment but aren't strictly required — iTunes/Apple Music and Deezer are always available as free fallbacks.
@@ -105,7 +105,7 @@ const DOCS_SECTIONS = [
Artists — Search artists, manage your watchlist, scan for new releases
Automations — Create scheduled tasks and event-driven workflows
Library — Browse and manage your music collection with standard or enhanced views
-
Import — Import music files from a staging folder with album/track matching
+
Import — Import music files from an import folder with album/track matching
Settings — Configure services, download preferences, quality profiles, and more
1. You search for music in SoulSync and click download
- 2. SoulSync tells slskd to download the file → slskd saves it to its download folder
- 3. SoulSync detects the completed download in the Download Path
+ 2. SoulSync tells slskd to download the file → slskd saves it to its input folder
+ 3. SoulSync detects the completed download in the Input Path 4. Post-processing runs: AcoustID verification → metadata tagging → cover art embedding → lyrics fetch 5. File is renamed and organized (e.g., Artist/Album/01 - Title.flac)
- 6. File is moved from Download Path → Transfer Path
+ 6. File is moved from Input Path → Output Path 7. Media server scan is triggered → file appears in your library
- If any step fails, the pipeline stops. The most common failure point is Step 3 — SoulSync can't find the file because the Download Path doesn't match where slskd actually saved it.
+ If any step fails, the pipeline stops. The most common failure point is Step 3 — SoulSync can't find the file because the Input Path doesn't match where slskd actually saved it.
Docker Setup: The Full Picture
@@ -163,31 +163,31 @@ const DOCS_SECTIONS = [
/app/downloads/ ← same files as /mnt/data/slskd-downloads/ /app/Transfer/ ← same files as /mnt/media/music/
SoulSync Settings (what you enter in the app)
- Download Path: /app/downloads
- Transfer Path: /app/Transfer
+ Input Path: /app/downloads
+ Output Path: /app/Transfer
The #1 Mistake: Not Configuring App Settings
Many users set up their docker-compose volumes correctly but never open SoulSync Settings to configure the paths. The app defaults may not match your volume mounts. You must go to Settings → Download Settings and verify that:
-
Download Path matches where slskd puts completed files inside the container (usually /app/downloads)
-
Transfer Path matches where you mounted your media library inside the container (usually /app/Transfer)
+
Input Path matches where slskd puts completed files inside the container (usually /app/downloads)
+
Output Path matches where you mounted your media library inside the container (usually /app/Transfer)
⚠️
"I set up my docker-compose but nothing transfers" — this almost always means the app settings weren't configured. Docker-compose makes the folders accessible. The app settings tell SoulSync where to look. Both are required.
-
The #2 Mistake: Download Path Doesn't Match slskd
-
The Download Path in SoulSync must point to the exact same physical folder where slskd saves its completed downloads. If they don't match, SoulSync can't find the files and post-processing fails silently.
+
The #2 Mistake: Input Path Doesn't Match slskd
+
The Input Path in SoulSync must point to the exact same physical folder where slskd saves its completed downloads. If they don't match, SoulSync can't find the files and post-processing fails silently.
ℹ️
- Both SoulSync and slskd must see the same download folder.
+ Both SoulSync and slskd must see the same input folder.
slskd container:
• slskd downloads to /downloads/complete inside its own container
• slskd docker-compose: - /mnt/data/slskd-downloads:/downloads/complete
The key: both containers mount the same host folder (/mnt/data/slskd-downloads). The container-internal paths can be different — that's fine. What matters is they point to the same physical directory on your server.
@@ -205,18 +205,18 @@ const DOCS_SECTIONS = [
-
Transfer Path = Media Server's Music Folder
-
Your Transfer Path must ultimately point to the same physical directory your media server monitors. This is how new music appears in Plex/Jellyfin/Navidrome.
+
Output Path = Media Server's Music Folder
+
Your Output Path must ultimately point to the same physical directory your media server monitors. This is how new music appears in Plex/Jellyfin/Navidrome.
💡
Example with Plex:
• Plex monitors /mnt/media/music on the host
• SoulSync docker-compose: - /mnt/media/music:/app/Transfer:rw
- • SoulSync Settings: Transfer Path = /app/Transfer
Go through every item. If you miss any single one, the pipeline will break:
-
slskd download folder is mounted in SoulSync's container — Both containers must mount the same host directory. The host paths (left side of :) must be identical.
-
Media server's music folder is mounted as Transfer — Mount the folder your Plex/Jellyfin/Navidrome monitors as /app/Transfer with :rw permissions.
-
SoulSync Settings are configured — Open Settings → Download Settings. Set Download Path to /app/downloads and Transfer Path to /app/Transfer (or whatever container paths you used on the right side of :).
+
slskd input folder is mounted in SoulSync's container — Both containers must mount the same host directory. The host paths (left side of :) must be identical.
+
Media server's music folder is mounted as Output — Mount the folder your Plex/Jellyfin/Navidrome monitors as /app/Transfer with :rw permissions.
+
SoulSync Settings are configured — Open Settings → Download Settings. Set Input Path to /app/downloads and Output Path to /app/Transfer (or whatever container paths you used on the right side of :).
slskd URL and API key are set — In Settings → Soulseek, enter your slskd URL (e.g., http://slskd:5030 or http://host.docker.internal:5030) and API key.
PUID/PGID match your host user — Run id on your host. Set those values in docker-compose environment variables. Both slskd and SoulSync should use the same PUID/PGID.
Test with one track — Download a single track. Watch the logs. If it downloads but doesn't transfer, the paths are wrong.
@@ -259,7 +259,7 @@ const DOCS_SECTIONS = [
If paths are correct but files still won't transfer, it's usually a permissions issue. SoulSync needs read + write access to all three folders.
Set PUID and PGID in your docker-compose to match the user that owns your music folders (run id on your host to find your UID/GID — usually 1000/1000)
-
Ensure the Transfer folder is writable: chmod -R 755 /mnt/media/music (use your actual host path)
+
Ensure the output folder is writable: chmod -R 755 /mnt/media/music (use your actual host path)
If using multiple containers (slskd + SoulSync), both must use the same PUID/PGID so file permissions are compatible
NFS/CIFS/network mounts may need additional permissions — test with a local folder first to isolate the issue
@@ -270,7 +270,7 @@ const DOCS_SECTIONS = [
Verify downloads are visible:docker exec soulsync-webui ls -la /app/downloads — you should see slskd's downloaded files here. If empty or "No such file or directory", your volume mount is wrong.
Verify Transfer is writable:docker exec soulsync-webui touch /app/Transfer/test.txt && echo "OK" — then check that test.txt appears in your media server's music folder on the host. Clean up after: rm /mnt/media/music/test.txt
Verify permissions:docker exec soulsync-webui id — the uid and gid should match your PUID/PGID values.
-
Verify app settings: Open SoulSync Settings → Download Settings. Confirm the Download Path and Transfer Path show container paths (like /app/downloads), not host paths.
+
Verify app settings: Open SoulSync Settings → Download Settings. Confirm the Input Path and Output Path show container paths (like /app/downloads), not host paths.
Test a single download: Search for a track, download it, and watch the logs. Enable DEBUG logging in Settings for full detail. Check logs/app.log for any path errors.
@@ -278,13 +278,13 @@ const DOCS_SECTIONS = [
Symptom
Likely Cause
Fix
-
Files download but never transfer
App settings not configured — docker-compose volumes are set but SoulSync Settings still have defaults or wrong paths
Open Settings → Download Settings and set Download Path + Transfer Path to your container-side mount paths.
-
Post-processing log is empty
SoulSync can't find the downloaded file at the expected path — the Download Path in Settings doesn't match where slskd actually saves files inside the container
Run docker exec soulsync-webui ls /app/downloads to see what's actually there. The Download Path in Settings must match this path exactly.
-
Same tracks downloading multiple times
Post-processing fails so SoulSync thinks the track was never downloaded successfully. On resume, it tries again.
Fix the folder paths first. Once post-processing works, files move to Transfer and SoulSync knows they exist.
-
Files not renamed properly
Post-processing isn't running (path mismatch) or file organization is disabled in Settings
Verify File Organization is enabled in Settings → Processing & Organization. Fix Download Path first.
-
Permission denied in logs
Container user can't write to the Transfer folder on the host
Set PUID/PGID to match the host user that owns the music folder. Run chmod -R 755 on the Transfer host folder.
-
Media server doesn't see new files
Transfer Path doesn't map to the folder your media server monitors
Ensure the host path in your SoulSync volume mount (/mnt/media/music:/app/Transfer) is the same folder Plex/Jellyfin/Navidrome watches.
-
slskd downloads work fine on their own but not through SoulSync
slskd's download folder and SoulSync's Download Path point to different physical locations
Both containers must mount the same host directory. Check the left side of : in both docker-compose volume entries — they must match.
+
Files download but never transfer
App settings not configured — docker-compose volumes are set but SoulSync Settings still have defaults or wrong paths
Open Settings → Download Settings and set Input Path + Output Path to your container-side mount paths.
+
Post-processing log is empty
SoulSync can't find the downloaded file at the expected path — the Input Path in Settings doesn't match where slskd actually saves files inside the container
Run docker exec soulsync-webui ls /app/downloads to see what's actually there. The Input Path in Settings must match this path exactly.
+
Same tracks downloading multiple times
Post-processing fails so SoulSync thinks the track was never downloaded successfully. On resume, it tries again.
Fix the folder paths first. Once post-processing works, files move to the output folder and SoulSync knows they exist.
+
Files not renamed properly
Post-processing isn't running (path mismatch) or file organization is disabled in Settings
Verify File Organization is enabled in Settings → Processing & Organization. Fix Input Path first.
+
Permission denied in logs
Container user can't write to the output folder on the host
Set PUID/PGID to match the host user that owns the music folder. Run chmod -R 755 on the output host folder.
+
Media server doesn't see new files
Output Path doesn't map to the folder your media server monitors
Ensure the host path in your SoulSync volume mount (/mnt/media/music:/app/Transfer) is the same folder Plex/Jellyfin/Navidrome watches.
+
slskd downloads work fine on their own but not through SoulSync
slskd's download folder and SoulSync's Input Path point to different physical locations
Both containers must mount the same host directory. Check the left side of : in both docker-compose volume entries — they must match.
💡
Still stuck? Enable DEBUG logging in Settings, download a single track, and check logs/app.log. The post-processing log will show exactly where the file pipeline breaks — whether it's a path not found, permission denied, or verification failure. If the post-processing log is empty, the issue is almost certainly a path mismatch (SoulSync never found the file to process).
@@ -392,7 +392,7 @@ const DOCS_SECTIONS = [
How to: Download an Album
Goal: Find an album and download it to your library with full metadata, cover art, and proper file organization.
-
Prerequisites: At least one download source connected (Soulseek, YouTube, Tidal, or Qobuz). Download and Transfer paths configured.
+
Prerequisites: At least one download source connected (Soulseek, YouTube, Tidal, or Qobuz). Input and Output paths configured.
Open Search — Click the Search page in the sidebar (make sure Enhanced Search is active)
Type the album name — Results appear in a categorized dropdown: Artists, Albums, Singles & EPs, Tracks
@@ -401,7 +401,7 @@ const DOCS_SECTIONS = [
Click Download — SoulSync searches for each track, downloads, tags, and organizes the files automatically
${docsImg('wf-download-album.gif', 'Downloading an album')}
-
Result: Tracks appear in your Transfer folder as Artist/Album/01 - Title.flac and your media server is notified to scan.
+
Result: Tracks appear in your output folder as Artist/Album/01 - Title.flac and your media server is notified to scan.
💡
If a track fails to download, click the retry icon or use the candidate selector to pick an alternative source file from a different user.
@@ -432,7 +432,7 @@ const DOCS_SECTIONS = [
How to: Import Existing Music
Goal: Bring music files you already have into SoulSync with proper metadata and organization.
-
Place files in your staging folder — Put album folders (e.g., Artist - Album/) in the Staging path configured in Settings
+
Place files in your import folder — Put album folders (e.g., Artist - Album/) in the Import Path configured in Settings
Go to the Import page — SoulSync detects the files and suggests album matches
Search for the correct album — If the auto-suggestion is wrong, search Spotify/iTunes for the right album
Match tracks — Drag-and-drop files onto the correct track slots, or click Auto-Match
@@ -450,7 +450,7 @@ const DOCS_SECTIONS = [
Click Test Connection — Verify the connection is working. A green checkmark confirms success
${docsImg('wf-media-server.gif', 'Connecting media server')}
-
💡
Make sure your Transfer Path points to the same folder your media server monitors. This is how new downloads automatically appear in your library.
+
💡
Make sure your Output Path points to the same folder your media server monitors. This is how new downloads automatically appear in your library.
`
},
@@ -576,7 +576,7 @@ const DOCS_SECTIONS = [
Job
What It Does
Track Number Repair
Fixes missing or incorrect track numbers by comparing against official tracklists
-
Orphan File Detector
Finds audio files in your transfer folder not tracked in the database. Can move to staging or delete.
+
Orphan File Detector
Finds audio files in your output folder not tracked in the database. Can move to import folder or delete.
Dead File Cleaner
Removes database entries pointing to files that no longer exist on disk
Duplicate Detector
Identifies duplicate tracks by fingerprint or metadata match
AcoustID Scanner
Batch audio fingerprint verification across your library
@@ -834,7 +834,7 @@ const DOCS_SECTIONS = [
AcoustID Fingerprint Verification — If AcoustID is configured, the downloaded file is fingerprinted and compared against the expected track. Title and artist are fuzzy-matched (title ≥ 70% similarity, artist ≥ 60%). Files that fail verification are quarantined instead of added to your library. Note: AcoustID is skipped for streaming sources (Tidal, Qobuz, Deezer, HiFi) since files are downloaded by exact track ID. However, streaming search results are still verified by artist and title matching before download to prevent wrong-track matches (e.g. same title, different artist).
Metadata Tagging — The file is tagged with official metadata: title, artist, album artist, album, track number, disc number, year, genre, and composer. Tags are written using Mutagen (supports MP3, FLAC, OGG, M4A).
Cover Art Embedding — Album artwork is downloaded from the metadata source and embedded directly into the audio file.
-
File Organization — The file is renamed and moved to your transfer path following customizable templates. Separate templates for albums, singles, and playlists are configured in Settings. Available variables include $artist, $album, $title, $track, $year, $quality, and $albumtype (resolves to Album, Single, EP, or Compilation). For multi-disc albums, a Disc N/ subfolder is automatically created when the album has more than one disc (or use $disc for zero-padded "01" or $discnum for unpadded "1" in your template for manual control).
+
File Organization — The file is renamed and moved to your output path following customizable templates. Separate templates for albums, singles, and playlists are configured in Settings. Available variables include $artist, $album, $title, $track, $year, $quality, and $albumtype (resolves to Album, Single, EP, or Compilation). For multi-disc albums, a Disc N/ subfolder is automatically created when the album has more than one disc (or use $disc for zero-padded "01" or $discnum for unpadded "1" in your template for manual control).
Lyrics (LRC) — Synced lyrics are fetched from the LRClib API and saved as .lrc sidecar files alongside the audio file. Compatible media players (foobar2000, MusicBee, Plex, etc.) will display time-synced lyrics automatically. Falls back to plain-text lyrics if synced versions aren't available.
Lossy Copy — If enabled in settings, a lower-bitrate copy is created alongside the original (useful for mobile device syncing).
Media Server Scan — Your media server (Plex/Jellyfin) is notified to scan for the new file. Navidrome auto-detects changes.
@@ -1111,8 +1111,8 @@ const DOCS_SECTIONS = [
Backup Database
Create a timestamped database backup
Refresh Beatport Cache
Scrape Beatport homepage and warm the data cache
Clean Search History
Remove old searches from Soulseek (keeps 50 most recent)
-
Clean Completed Downloads
Clear completed downloads and empty directories from the download folder
-
Full Cleanup
Clear quarantine, download queue, staging folder, and search history in one sweep
+
Clean Completed Downloads
Clear completed downloads and empty directories from the input folder
+
Full Cleanup
Clear quarantine, download queue, import folder, and search history in one sweep
Notify Only
No action — just trigger notifications
@@ -1250,7 +1250,7 @@ const DOCS_SECTIONS = [
Library Issues
The Issues page tracks problems detected in your library by the repair worker. Issues are categorized by type and severity:
-
Orphan files — Audio files in your transfer folder not tracked in the database
+
Orphan files — Audio files in your output folder not tracked in the database
Dead references — Database entries pointing to files that no longer exist on disk
Duplicate tracks — Multiple copies of the same track detected by fingerprint or metadata
Missing cover art — Albums or tracks without embedded artwork
Set your staging folder path in Settings → Download Settings. Place audio files you want to import into this folder. SoulSync scans the folder and detects albums from the file structure.
+
Set your import folder path in Settings → Download Settings. Place audio files you want to import into this folder. SoulSync scans the folder and detects albums from the file structure.
Place albums in subfolders (e.g., Artist - Album/) and loose singles at the root level.
The import page header shows the total files in staging and their combined size.
Files not showing up? Check that your staging folder path is correct in Settings and that the folder has read permissions. Docker users: make sure the staging volume mount is configured in your docker-compose.yml.
+
💡
Files not showing up? Check that your import folder path is correct in Settings and that the folder has read permissions. Docker users: make sure the import volume mount is configured in your docker-compose.yml.
Import Workflow
-
Place audio files in your staging folder
+
Place audio files in your import folder
Navigate to the Import page — SoulSync detects and suggests album matches
Search for the correct album on Spotify/iTunes if the suggestion is wrong
Match tracks — Drag-and-drop staged files onto album track slots, or let auto-match attempt it
@@ -1304,7 +1304,7 @@ const DOCS_SECTIONS = [
Drag & Drop — Manually drag staged files onto the correct album track slots
Conflict Detection — Highlights when a file matches multiple tracks or when tracks are unmatched
-
After matching, the import process tags files with the official metadata (title, artist, album, track number, cover art) and moves them to your transfer path following the standard file organization template.
+
After matching, the import process tags files with the official metadata (title, artist, album, track number, cover art) and moves them to your output path following the standard file organization template.
Import from Text File
@@ -1422,9 +1422,9 @@ const DOCS_SECTIONS = [
Download Settings
Download Source Mode — Soulseek, YouTube, Tidal, Qobuz, HiFi, Deezer, or Hybrid. Hybrid tries your primary source first, then falls back to alternates with configurable priority via drag-and-drop. Each streaming source has its own quality dropdown and an Allow quality fallback toggle. See Download Sources and Quality Profiles in the Music Downloads section for details.
-
Download Path — The folder where files are initially downloaded. This must match the folder your download source (slskd) writes to. In Docker, this is the container-side mount point (e.g., /app/downloads), not the host path. SoulSync monitors this folder for completed downloads to begin post-processing.
-
Transfer Path — The final destination for processed music files. After tagging, renaming, and organizing, files are moved here. This must point to your media server's monitored music folder (the folder Plex/Jellyfin/Navidrome watches for new content). In Docker, use the container-side path (e.g., /app/Transfer).
-
Staging Path — Folder for the Import feature (files placed here appear on the Import page). Separate from the download/transfer pipeline.
+
Input Path — The folder where files are initially downloaded. This must match the folder your download source (slskd) writes to. In Docker, this is the container-side mount point (e.g., /app/downloads), not the host path. SoulSync monitors this folder for completed downloads to begin post-processing.
+
Output Path — The final destination for processed music files. After tagging, renaming, and organizing, files are moved here. This must point to your media server's monitored music folder (the folder Plex/Jellyfin/Navidrome watches for new content). In Docker, use the container-side path (e.g., /app/Transfer).
+
Import Path — Folder for the Import feature (files placed here appear on the Import page). Separate from the input/output pipeline.
iTunes Country — Storefront region for iTunes/Apple Music lookups (US, GB, FR, JP, etc.). Changes apply immediately to all searches without restarting. ID-based lookups automatically try up to 10 regional storefronts as fallback when the primary country returns no results.
Lossy Copy — When enabled, creates a lower-bitrate MP3 copy of every downloaded file. Configure the output bitrate (default 320kbps) and output folder. Optionally delete the original lossless file after creating the lossy copy. Useful for syncing to mobile devices or streaming servers with bandwidth constraints.
Content Filtering — Toggle explicit content filtering to control whether explicit tracks appear in search results and downloads.
@@ -1439,7 +1439,7 @@ const DOCS_SECTIONS = [
AcoustID Verification — Toggle on/off. When enabled, every download is fingerprinted and compared against the expected track. Failed matches are quarantined.
Metadata Enhancement — Master toggle for all enrichment workers. When disabled, no background metadata fetching occurs.
Embed Album Art — Automatically embed cover art into audio file tags during post-processing.
-
File Organization — Toggle automatic file renaming and folder placement. When disabled, files stay in the download folder as-is.
+
File Organization — Toggle automatic file renaming and folder placement. When disabled, files stay in the input folder as-is.
Path Template — Customize the folder structure using variables: {artist}, {album}, {title}, {track_number}, {year}, {genre}. Default: {artist}/{album}/{track_number} - {title}
Disc Label — Customize the multi-disc subfolder prefix (default: "Disc"). Multi-disc albums create Disc 1/, Disc 2/, etc.
Soulseek Search Timeout — How long to wait for Soulseek search results before giving up (seconds).
@@ -1594,7 +1594,7 @@ const DOCS_SECTIONS = [
Common Issues
Downloads complete but tracks don't appear in library
-
Check that your Transfer path is correct and writable (see Paths in debug info)
+
Check that your Output Path is correct and writable (see Paths in debug info)
If using a media server, trigger a library scan after downloads complete
Check post_processing.log for file move errors
@@ -2502,9 +2502,9 @@ function initializeDocsPage() {
text += '── Paths ──\n';
const pathStatus = (exists, writable) => exists ? (writable ? ck + ' ok' : ck + ' exists ' + ex + ' not writable') : ex + ' missing';
- text += `Download: ${data.paths?.download_path || '(not set)'} [${pathStatus(data.paths?.download_path_exists, data.paths?.download_path_writable)}]\n`;
- text += `Transfer: ${data.paths?.transfer_folder || '(not set)'} [${pathStatus(data.paths?.transfer_folder_exists, data.paths?.transfer_folder_writable)}]\n`;
- text += `Staging: ${data.paths?.staging_folder ? data.paths.staging_folder + ' [' + (data.paths.staging_folder_exists ? ck + ' ok' : ex + ' missing') + ']' : '(not configured — optional)'}\n`;
+ text += `Input: ${data.paths?.download_path || '(not set)'} [${pathStatus(data.paths?.download_path_exists, data.paths?.download_path_writable)}]\n`;
+ text += `Output: ${data.paths?.transfer_folder || '(not set)'} [${pathStatus(data.paths?.transfer_folder_exists, data.paths?.transfer_folder_writable)}]\n`;
+ text += `Import: ${data.paths?.staging_folder ? data.paths.staging_folder + ' [' + (data.paths.staging_folder_exists ? ck + ' ok' : ex + ' missing') + ']' : '(not configured — optional)'}\n`;
if (data.paths?.music_videos_path) {
text += `Videos: ${data.paths.music_videos_path} [${data.paths.music_videos_path_exists ? ck + ' ok' : ex + ' missing'}]\n`;
}
diff --git a/webui/static/helper.js b/webui/static/helper.js
index 29979218..3fb3f3a9 100644
--- a/webui/static/helper.js
+++ b/webui/static/helper.js
@@ -125,7 +125,7 @@ const HELPER_CONTENT = {
},
'.nav-button[data-page="import"]': {
title: 'Music Import',
- description: 'Import music files from your staging folder. SoulSync identifies tracks using AcoustID fingerprinting, matches them to metadata, and organizes them into your library with proper tagging.',
+ description: 'Import music files from your import folder. SoulSync identifies tracks using AcoustID fingerprinting, matches them to metadata, and organizes them into your library with proper tagging.',
docsId: 'import'
},
'.nav-button[data-page="settings"]': {
@@ -230,7 +230,7 @@ const HELPER_CONTENT = {
},
'#import-button': {
title: 'Quick Import',
- description: 'Shortcut to the Import page. Drop music files in your staging folder and import them into your library with metadata matching and tagging.',
+ description: 'Shortcut to the Import page. Drop music files in your import folder and import them into your library with metadata matching and tagging.',
docsId: 'import'
},
@@ -1856,16 +1856,16 @@ const HELPER_CONTENT = {
'.import-page-container': {
title: 'Import Music',
- description: 'Import audio files from your staging folder into your library. Match files to album metadata, tag them, and organize into your collection.',
+ description: 'Import audio files from your import folder into your library. Match files to album metadata, tag them, and organize into your collection.',
docsId: 'import'
},
'.import-page-refresh-btn': {
title: 'Refresh',
- description: 'Re-scan your staging folder for new audio files. Use after dropping new files into the staging path.',
+ description: 'Re-scan your import folder for new audio files. Use after dropping new files in.',
},
'#import-staging-bar': {
- title: 'Staging Folder',
- description: 'Shows your configured staging folder path and the number of audio files found. Set the staging path in Settings → Download Settings.',
+ title: 'Import Folder',
+ description: 'Shows your configured import folder path and the number of audio files found. Set the import path in Settings → Download Settings.',
docsId: 'imp-setup'
},
'#import-page-queue': {
@@ -1874,7 +1874,7 @@ const HELPER_CONTENT = {
},
'#import-page-tab-album': {
title: 'Albums Tab',
- description: 'Import complete albums. Search for an album, match staging files to tracks, then process. Suggestions appear automatically from your staging folder.',
+ description: 'Import complete albums. Search for an album, match import files to tracks, then process. Suggestions appear automatically from your import folder.',
docsId: 'imp-workflow'
},
'#import-page-tab-singles': {
@@ -1884,15 +1884,15 @@ const HELPER_CONTENT = {
},
'#import-page-suggestions-grid': {
title: 'Suggestions',
- description: 'Albums automatically detected from your staging folder based on folder names and file metadata. Click a suggestion to start the matching process.',
+ description: 'Albums automatically detected from your import folder based on folder names and file metadata. Click a suggestion to start the matching process.',
},
'#import-page-album-search-input': {
title: 'Album Search',
- description: 'Search your metadata source for an album to match against staging files. Enter the album name or artist + album.',
+ description: 'Search your metadata source for an album to match against import files. Enter the album name or artist + album.',
},
'#import-page-album-match-section': {
title: 'Track Matching',
- description: 'Match your staging files to album tracks. Drag files from the unmatched pool onto tracks, or let auto-matching do it. Green = matched, red = unmatched.',
+ description: 'Match your import files to album tracks. Drag files from the unmatched pool onto tracks, or let auto-matching do it. Green = matched, red = unmatched.',
tips: [
'Drag and drop files from the unmatched pool to track slots',
'"Re-match Automatically" re-runs the matching algorithm',
@@ -1902,7 +1902,7 @@ const HELPER_CONTENT = {
},
'#import-page-unmatched-pool': {
title: 'Unmatched Files',
- description: 'Audio files in your staging folder that haven\'t been matched to an album track yet. Drag them onto the correct track slot above.',
+ description: 'Audio files in your import folder that haven\'t been matched to an album track yet. Drag them onto the correct track slot above.',
docsId: 'imp-matching'
},
'#import-page-album-process-btn': {
@@ -1911,7 +1911,7 @@ const HELPER_CONTENT = {
},
'#import-page-singles-list': {
title: 'Singles List',
- description: 'Individual audio files in your staging folder. Select files and click "Process Selected" to identify and import them as single tracks.',
+ description: 'Individual audio files in your import folder. Select files and click "Process Selected" to identify and import them as single tracks.',
docsId: 'imp-singles'
},
'#import-page-singles-process-btn': {
@@ -2696,9 +2696,9 @@ const HELPER_TOURS = {
icon: '📥',
steps: [
// Header
- { page: 'import', selector: '.import-page-header', title: 'Import Music', description: 'Import audio files from your staging folder into your organized library. Files are matched to album metadata, tagged, and moved to the correct location.' },
- { page: 'import', selector: '.import-page-staging-bar', title: 'Staging Folder', description: 'Shows your configured staging folder path and stats (file count, total size). This is where you drop audio files before importing. Configure the path in Settings → Downloads.' },
- { page: 'import', selector: '.import-page-refresh-btn', title: 'Refresh', description: 'Re-scans your staging folder for new audio files. Hit this after dropping new files in.' },
+ { page: 'import', selector: '.import-page-header', title: 'Import Music', description: 'Import audio files from your import folder into your organized library. Files are matched to album metadata, tagged, and moved to the correct location.' },
+ { page: 'import', selector: '.import-page-staging-bar', title: 'Import Folder', description: 'Shows your configured import folder path and stats (file count, total size). This is where you drop audio files before importing. Configure the path in Settings → Downloads.' },
+ { page: 'import', selector: '.import-page-refresh-btn', title: 'Refresh', description: 'Re-scans your import folder for new audio files. Hit this after dropping new files in.' },
// Queue
{ page: 'import', selector: '#import-page-queue', title: 'Processing Queue', description: 'When you process albums or singles, jobs appear here with progress indicators. "Clear finished" removes completed jobs from the list.' },
@@ -2707,7 +2707,7 @@ const HELPER_TOURS = {
{ page: 'import', selector: '.import-page-tab-bar', title: 'Albums vs Singles', description: 'Two modes: Albums tab matches full albums to metadata (cover art, track numbers, disc info). Singles tab processes individual files one at a time.' },
// Album workflow
- { page: 'import', selector: '#import-page-suggestions', title: 'Album Suggestions', description: 'The importer analyzes your staging files and suggests album matches based on embedded tags. Click a suggestion to start the matching process.' },
+ { page: 'import', selector: '#import-page-suggestions', title: 'Album Suggestions', description: 'The importer analyzes your import files and suggests album matches based on embedded tags. Click a suggestion to start the matching process.' },
{ page: 'import', selector: '#import-page-album-search-input', title: 'Album Search', description: 'If suggestions don\'t match, search manually. Type an album name, click Search, and select the correct result.' },
{ page: 'import', selector: '#import-page-album-search-input', title: 'Track Matching', description: 'After selecting an album, you\'ll see a track matching table. Files are auto-matched to tracks by name/number. Drag unmatched files from the pool to the correct track slot, then click "Process Album".' },
@@ -3612,7 +3612,7 @@ const WHATS_NEW = {
// --- April 17, 2026 ---
{ date: 'April 17, 2026' },
{ title: 'SoulSync Standalone Library', desc: 'New "Standalone" server option — manage your library without Plex, Jellyfin, or Navidrome. Downloads and imports write directly to the library database with pre-populated enrichment IDs. Deep scan finds untracked files and cleans stale records. Select in Settings → Connections', page: 'settings' },
- { title: 'Auto-Import', desc: 'Background staging folder watcher that automatically identifies and imports music. Three strategies: audio tags, folder name parsing, and AcoustID fingerprinting. Confidence-gated: 90%+ auto-imports, 70-90% queued for review, below 70% left for manual. Enable on the Import page Auto tab', page: 'import' },
+ { title: 'Auto-Import', desc: 'Background import folder watcher that automatically identifies and imports music. Three strategies: audio tags, folder name parsing, and AcoustID fingerprinting. Confidence-gated: 90%+ auto-imports, 70-90% queued for review, below 70% left for manual. Enable on the Import page Auto tab', page: 'import' },
{ title: 'Wishlist Nebula', desc: 'Wishlist redesigned as an interactive artist orb visualization. Each artist is a glowing orb with their photo — album fans and single moons orbit around them. Click orbs to expand, download albums/singles directly. Processing state shows live progress', page: 'wishlist' },
{ title: 'Automation Group Management', desc: 'Rename, delete, and bulk-toggle automation groups. Drag-and-drop automations between groups. Right-click group headers for context menu', page: 'automations' },
{ title: 'Bidirectional Artist Sync', desc: 'Artist Sync button now pulls new content from your media server AND removes stale library entries no longer on the server. Deep scan mode fetches full metadata for new tracks', page: 'library' },
@@ -3629,7 +3629,7 @@ const WHATS_NEW = {
{ title: 'Downloads Batch Panel', desc: 'Downloads page now shows a batch context panel on the right side. Each active batch (wishlist, sync, album download) gets a color-coded card with progress, cancel button, and expandable track list. Color indicators on download rows link them to their batch. Completed batch history shows the last 7 days', page: 'active-downloads' },
{ title: 'Fix Unknown Artist on Wishlist Downloads', desc: 'Adding tracks to wishlist from a playlist download modal was storing "Unknown Artist" as the artist context. Now resolves the artist per-track from the track\'s own metadata instead of the playlist-level artist which is only set for album downloads' },
{ title: 'Fix Download Modal Freezing Mid-Download', desc: 'Download modals (wishlist, sync, album) would freeze and stop updating after the first track completed. Caused by M3U auto-save firing every 2 seconds during downloads, exhausting Flask server threads. Now saves M3U once on completion only' },
- { title: 'Auto-Import Improvements', desc: 'Recursive staging folder scan (any folder depth), single file support, expandable track match details, stats bar with filters, Scan Now button, Approve All / Clear History batch actions. Tag-based identification preferred over weak metadata matches. AcoustID fallback for untagged files. Race condition fix prevents duplicate processing', page: 'import' },
+ { title: 'Auto-Import Improvements', desc: 'Recursive import folder scan (any folder depth), single file support, expandable track match details, stats bar with filters, Scan Now button, Approve All / Clear History batch actions. Tag-based identification preferred over weak metadata matches. AcoustID fallback for untagged files. Race condition fix prevents duplicate processing', page: 'import' },
{ title: 'Album Delete with File Removal', desc: 'Enhanced library album delete now offers "Delete Files Too" option alongside "Remove from Library" — deletes audio files from disk and cleans up empty album folders', page: 'library' },
// --- April 15, 2026 ---
@@ -3650,7 +3650,7 @@ const WHATS_NEW = {
// --- April 14, 2026 ---
{ date: 'April 14, 2026' },
- { title: 'Fix Staging Files Ignoring Path Template', desc: 'Files matched from the Staging folder were copied to the transfer root with their original filename instead of applying the configured path template. Post-processing now receives full artist/album context for staging matches' },
+ { title: 'Fix Import Files Ignoring Path Template', desc: 'Files matched from the import folder were copied to the output root with their original filename instead of applying the configured path template. Post-processing now receives full artist/album context for import matches' },
// --- April 4, 2026 ---
{ date: 'April 4, 2026' },
diff --git a/webui/static/script.js b/webui/static/script.js
index 96733ff3..6b456e29 100644
--- a/webui/static/script.js
+++ b/webui/static/script.js
@@ -23288,7 +23288,7 @@ const TOOL_HELP_CONTENT = {
title: 'Duplicate Cleaner',
content: `
What does this tool do?
-
The Duplicate Cleaner scans your Transfer folder for duplicate audio files and automatically removes lower-quality versions, keeping only the best copy.
+
The Duplicate Cleaner scans your output folder for duplicate audio files and automatically removes lower-quality versions, keeping only the best copy.
Scans your transfer folder for duplicate audio files (same filename, different format) and removes the lower-quality version. For example, if you have both Song.flac and Song.mp3, the MP3 is removed.
+
Scans your output folder for duplicate audio files (same filename, different format) and removes the lower-quality version. For example, if you have both Song.flac and Song.mp3, the MP3 is removed.
Safety
Removed files are moved to a deleted/ subfolder, not permanently deleted. You can recover them if needed.
- Two-folder system: Music downloads to the Download Folder first as raw files. After post-processing (metadata tagging, file organization), finished tracks are moved to the Transfer Folder organized into Artist/Album subfolders. Point your media server at the Transfer folder.
+ Two-folder system: Music downloads to the Input Folder first as raw files. After post-processing (metadata tagging, file organization), finished tracks are moved to the Output Folder organized into Artist/Album subfolders. Point your media server at the output folder.
-
+
-
+
Your First Download
Try searching for a track to see the full pipeline in action.
- How it works: Type a song name below. SoulSync searches your metadata source for the track, then finds the best matching audio file from your download source. The track is tagged with full metadata (artist, album, track number, artwork) and organized into your Transfer folder.
+ How it works: Type a song name below. SoulSync searches your metadata source for the track, then finds the best matching audio file from your download source. The track is tagged with full metadata (artist, album, track number, artwork) and organized into your output folder.