No description
  • Python 97%
  • Shell 3%
Find a file
2026-07-23 15:49:20 +02:00
docs/images Replace English overview graphic with transparent version 2026-07-23 00:12:30 +02:00
legacy/server Import current production scripts as migration reference 2026-07-22 17:07:28 +02:00
src/music_maintenance Preserve rich formats through Apprise API 2026-07-23 15:42:13 +02:00
tests Add run logs and revert support 2026-07-22 20:23:11 +02:00
.gitignore Remove development artifacts 2026-07-22 22:07:01 +02:00
CHANGELOG.md Preserve rich formats through Apprise API 2026-07-23 15:42:13 +02:00
install.sh Fix installer source checkout and cleanup 2026-07-23 15:47:57 +02:00
LICENSE Initial project structure 2026-07-22 16:57:46 +02:00
pyproject.toml Preserve rich formats through Apprise API 2026-07-23 15:42:13 +02:00
README.md Restore overview image in README 2026-07-23 15:49:20 +02:00

musicfix

musicfix is a safety-focused command-line toolkit for maintaining large, folder-based music libraries on Linux. It can validate and repair FLAC files, clean metadata and titles, normalize filenames, manage album and artist artwork, quarantine unwanted files, and keep detailed logs, reports, backups, and reversible run manifests.

The application is designed for both careful dry runs and explicit write operations. An incremental SQLite index avoids repeatedly processing unchanged music, while a configurable cleanup allow-list protects audio, image, lyrics, video, and custom file formats. Optional Apprise notifications provide service-neutral success and failure summaries for email, Telegram, Discord, Slack, ntfy, Gotify, and many other destinations.

musicfix overview

Installation

Installer

Install the latest release from Forgejo:

curl -fsSL \
  https://git.justdoit.network/Jan/musicfix/raw/branch/main/install.sh \
  | bash

Install a specific tag:

curl -fsSL \
  https://git.justdoit.network/Jan/musicfix/raw/branch/main/install.sh \
  | bash -s -- v1.2.3

The installer:

  • detects common Linux package managers
  • installs Git, Python, pipx, FLAC and FFmpeg when required
  • installs musicfix with pipx
  • installs the Python dependencies, including Apprise
  • prints the Fish command needed when the pipx binary directory is not in PATH

After installation:

musicfix --version
musicfix doctor
musicfix index rebuild

Manual installation

Clone the repository and install it with pipx:

git clone https://git.justdoit.network/Jan/musicfix.git
cd musicfix
pipx install .

To reinstall after updating the repository:

git pull
pipx install --force .

Apprise is included as a normal musicfix dependency and does not require a separate installation.

Configuration

Show the current configuration:

musicfix config

Set the music-library path:

musicfix config /path/to/music

Set the interface language:

musicfix config --language de
musicfix config --language en

Enable or disable rainbow progress bars:

musicfix config --rainbow on
musicfix config --rainbow off

Set custom quarantine and log directories:

musicfix config --quarantine-dir /path/to/quarantine
musicfix config --logs-dir /path/to/logs

Reset custom paths to their defaults:

musicfix config --reset-quarantine-dir
musicfix config --reset-logs-dir

Validate the configuration and required directories:

musicfix config --check

Open the active configuration file directly in Nano:

musicfix config --edit

Configuration inspection and validation are read-only:

musicfix config
musicfix config --check

The configuration file is rewritten only when an actual setting is changed.

Cleanup allow-list

The cleanup step preserves only file extensions listed in cleanup.keep_extensions. Matching is case-insensitive.

The default configuration preserves common audio, lyrics, image and video formats. To stop preserving a format, comment out or remove its entry. To keep another format, add its extension to the list.

Files whose extension is not present may be moved to quarantine during:

musicfix cleanup --write
musicfix all --write

A dry run shows what would be quarantined without changing the library:

musicfix cleanup

Example:

[cleanup]
# Extensions that cleanup must preserve. Matching is case-insensitive.
# Comment out an entry to stop preserving that format.
# Add another extension to preserve additional file types.
# Files not listed here may be moved to quarantine by cleanup --write.
keep_extensions = [
  # Audio
  ".flac",
  ".mp3",
  ".m4a",
  ".mp4",

  # Lyrics
  ".lrc",
  ".lyrics",

  # Images
  ".jpg",
  ".jpeg",
  ".png",
  ".webp",

  # Video
  ".avi",
  ".m2ts",
  ".m4v",
  ".mkv",
  ".mov",
  ".mpeg",
  ".mpg",
  ".mts",
  ".ts",
  ".vob",
  ".webm",
  ".wmv",

  # Custom examples
  # ".cue",
  # ".nfo",
]

The configuration is stored at:

~/.config/musicfix/config.toml

The default state directory is:

~/.local/share/musicfix

Example configuration:

# musicfix configuration
# Generated and updated by `musicfix config`.
# TOML comments begin with # and may be edited freely.

[paths]
# Root directory of the music library. The directory must exist.
music_root = "/path/to/music"

# Directory for logs, reports, backups, run manifests and quarantine.
state_dir = "/home/user/.local/share/musicfix"

# Optional custom quarantine directory.
# Remove this line or run `musicfix config --reset-quarantine-dir`
# to use <state_dir>/quarantine.
quarantine_dir = "/path/to/quarantine"

# Optional custom log directory.
# Remove this line or run `musicfix config --reset-logs-dir`
# to use <state_dir>/logs.
logs_dir = "/path/to/logs"

[ui]
# Terminal language. Allowed values: "de" or "en".
language = "de"

# Rainbow progress bars. Allowed values: true or false.
# Set the NO_COLOR environment variable to disable all ANSI colors.
rainbow = true

[retention]
# Number of days to retain generated state.
# Use 0 to disable pruning for a category.
logs_days = 30
runs_days = 90
backups_days = 30
reports_days = 90

[library]
# Top-level library categories recognized by musicfix.
# Add, remove or rename entries to match the directory layout.
categories = [
  "Anime",
  "Filme und Serien",
  "Gaming",
  "Künstler",
  "Youtube",
]

Configuration options

  • paths.music_root: existing root directory of the music library
  • paths.state_dir: base directory for reports, backups, runs, logs and quarantine
  • paths.quarantine_dir: optional override for the quarantine directory
  • paths.logs_dir: optional override for the log directory
  • ui.language: de or en
  • ui.rainbow: true or false
  • retention.*_days: retention period in days; 0 disables pruning
  • library.categories: top-level folders used to describe the library layout
  • notifications.enabled: enable or disable Apprise notifications
  • notifications.notify_on_success: notify after successful complete runs
  • notifications.notify_on_failure: notify after failed complete runs
  • notifications.urls: one or more Apprise service URLs

Commands

Inspection and diagnostics

musicfix doctor
musicfix status
musicfix config
musicfix config --check
musicfix scan
musicfix scan --no-tags
musicfix logs
musicfix logs --last

Library maintenance

musicfix flac-repair
musicfix title
musicfix update
musicfix files
musicfix covers
musicfix cover-online
musicfix placeholder-covers
musicfix artist-images
musicfix cleanup

Complete workflow

Preview every maintenance step:

musicfix all

Apply the proposed changes:

musicfix all --write

Revert and retention

Preview reverting the latest write run:

musicfix revert

Apply the revert:

musicfix revert --write

Preview expired logs, runs, backups, and reports:

musicfix prune

Delete expired state:

musicfix prune --write

Notification templates and compatibility

Notifications use a service-neutral structure that remains readable in email, Telegram, Discord, Slack, ntfy, Gotify, and plain-text destinations.

The default format is Markdown:

[notifications]
format = "markdown"

When an apprise:// or apprises:// gateway URL is configured, musicfix sends directly to the Apprise API /notify/{key} endpoint. This preserves the selected format value across the gateway instead of allowing an intermediate client plugin to downgrade HTML or Markdown to plain text.

For HTML notifications, musicfix uses an email-client-safe layout with inline styles and presentation tables. This avoids collapsed labels and values in mail clients that strip modern CSS or semantic definition-list formatting.

Supported values are:

  • text for maximum compatibility
  • markdown as the recommended default for mixed services
  • html mainly for email and other rich-content destinations

Templates avoid tables and complex nesting. Run notifications include mode, run ID, runtime, library statistics, incremental change counts, log and manifest paths, the installed version, and failure details when applicable. Apprise notification types are set to success, failure, or info so compatible services may apply their own icons, colors, or priorities.

Preview the exact configured template with realistic example data:

musicfix apprise test

Incremental maintenance

musicfix all uses a SQLite index to process only new, modified, deleted, or otherwise affected library items.

Create the initial baseline after installation:

musicfix index rebuild

Inspect the current index and pending changes:

musicfix index status

Normal runs are incremental:

musicfix all
musicfix all --write

Force a complete pass when needed:

musicfix all --full
musicfix all --full --write

Delete the index and return to an uninitialized state:

musicfix index clear

The index is stored below the configured state directory as index.sqlite3. Detection uses path, file size, and nanosecond modification time. Audio and artwork changes select the affected album files. Directory-level artist-image validation and cleanup still run globally because they validate library structure rather than individual audio files.

The index is updated only after a successful write run. Dry runs never consume pending changes.

Optional Apprise notifications

musicfix all can send a compact summary through Apprise after a successful or failed run.

Apprise is installed automatically as a musicfix dependency.

Test all configured notification targets without running library maintenance:

musicfix apprise test

The test uses every URL from [notifications].urls. It can also be used while notifications.enabled is false, which makes it useful while preparing a configuration before enabling automatic run notifications.

The generated configuration contains a commented example. Uncomment it and replace the service URL:

[notifications]
enabled = true
notify_on_success = true
notify_on_failure = true
format = "markdown"
urls = [
  "tgram://BOT_TOKEN/CHAT_ID",
]

Multiple Apprise URLs may be configured:

urls = [
  "tgram://BOT_TOKEN/CHAT_ID",
  "discord://WEBHOOK_ID/WEBHOOK_TOKEN",
]

The notification includes:

  • success or failure status
  • dry-run or write mode
  • run ID
  • runtime
  • audio-file and folder counts
  • total library size
  • log-file path

Notification failures are reported as warnings and never change the result of the music-maintenance run.

Apprise supports Telegram, Discord, Matrix, Gotify, ntfy, email and many other services. Service URL formats are documented in the Apprise wiki.

Safety model

All commands that can change the library use dry-run mode by default.

Changes require the explicit --write option. Write operations are protected by a process lock, and suspiciously broad library roots are rejected. Each complete write run records logs, reports, backups, and a JSON manifest for recovery.

Features

  • detailed library scans with JSON reports
  • FLAC metadata inspection and repair
  • title and tag normalization
  • filename normalization with collision checks
  • embedded cover extraction
  • online cover lookup with confidence scoring
  • fallback cover generation
  • artist image generation
  • quarantine-based cleanup
  • dry-run and explicit write modes
  • write locking and path-safety checks
  • timestamped logs and run manifests
  • previewable revert operations
  • configurable retention and pruning
  • German and English terminal output
  • live progress bars with optional rainbow rendering

Requirements

  • Python 3.11 or newer
  • pipx
  • flac
  • metaflac
  • ffmpeg
  • ffprobe

Arch Linux, CachyOS, EndeavourOS, and Manjaro

sudo pacman -Syu --needed git python python-pipx flac ffmpeg

Debian, Ubuntu, Linux Mint, and Pop!_OS

sudo apt update
sudo apt install -y git python3 python3-venv pipx flac ffmpeg

Fedora

sudo dnf install -y git python3 pipx flac ffmpeg-free

License

MIT