wrtag

package module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2025 License: GPL-3.0 Imports: 28 Imported by: 0

README

wrtag

Fast automated music tagging and organisation based on MusicBrainz


wrtag is similar to music tagging and organisation tools such as Beets and MusicBrainz Picard but aims to be simpler, more composable, and faster.

To describe the general workflow:

  1. Input files are provided (existing or new).
  2. They are matched with releases in the MusicBrainz database. This may be done using existing tags or filenames.
  3. The files are moved or copied to a user-defined filesystem layout. For example, My music/Artist name/(Release year) Release name/1. Track title.ext.
  4. The file's tags are updated to match the tags in the MusicBrainz database.
  5. Enjoy a clean, consistent, and accurate browsing experience in your music player/server of choice.

Table of Contents

  1. Features
  2. Included tools
  3. Installation
  4. Global configuration
  5. Path format
  6. Addons
  7. Notifications
  8. Goals and non-goals

Features

  • Unix-style suite of tools for different use cases, using the same core wrtag functionality.
  • Fast tagging thanks to Go.
  • Filesystem organisation of music files, covers, and configurable extra files.
  • Cover fetching or upgrades from the Cover Art Archive.
  • Care taken to ensure no orphan folders are left in the library when moves or copies occur.
  • Validation to ensure your library is always consistent with no duplicates or unrecognised paths.
  • Safe concurrent processing with tree-style filesystem locking.
  • Addons for fetching lyrics, calculating ReplayGain, or any user-defined subprocess.
  • Rescanning the library and processing it for new changes in MusicBrainz (wrtag sync).
  • An optional web interface for importing new releases over the network. Allows the user to be notified and confirm details if there is no 100% match found.
  • Support for gazelle-origin files to improve matching from certain sources.
  • Support for Linux, macOS, and Windows with static/portable binaries available for each.

Included tools

Tool wrtag

The wrtag tool is the main command line tool for music organisation. It has two subcommands for working on individual folders (copy, move), and one for bulk processing (sync).

Importing new music
Moving from source

wrtag is the main command line tool that works on a single folder and requires an operation such as move or copy.

For example:

$ wrtag move "Example"                 # tags and moves `Example` into the library defined by the path-format config option
$ wrtag move -dry-run "Example"        # shows move and tag operations without applying them
$ wrtag move -yes "Example"            # use anyway even if low match
$ wrtag move -mbid "abc" -yes "Example" # overwrite matched MusicBrainz release UUID
Copying from source

If the source files should be left alone, wrtag also provides a copy operation:

$ wrtag copy -yes "Example"      # copies and tags `Example` into the library, use anyway even if low match
$ wrtag copy -mbid "abc" -yes    # overwrite matched MusicBrainz release UUID even if low match
Re-tagging already imported music

Re-tagging your music can be useful for a few reasons. For example, if your path-format configuration has changed, or the metadata in the MusicBrainz database has changed.

Re-tagging a single release

Since a move operation always cleans up the source directory - and is smart about the music already being in place - a re-tag is just a move pointed at some music that is already in place:

# path-format is /my/music/XXX
$ wrtag move "/my/music/Tame Impala/(2010) Innerspeaker"
# now has updated tags, and moved again if needed
Available operations

The full list of core wrtag operations. They can be used in other tools like wrtagweb too.

Name Description
move Moves files from the source to the destination directory.
copy Copies files from the source to the destination directory.
reflink On supported filesystems, creates a reflink (copy-on-write) clone of a file from the source to the destination.
Re-tagging in bulk

Bulk operations are done with the sync subcommand. Unlike the copy and move commands which operate on single releases, the sync command works on your already imported and tagged library.

[!WARNING] As the sync command is non-interactive, when used incorrectly it can be destructive. Only use sync on a library whose contents have been populated by copy or move.

By default, sync recurses through all directories rooted in path-format and finds leaf directories. A leaf directory is one that has no sub-folders, and therefore looks like a release. The tracks are read, and if they have a MUSICBRAINZ_ALBUMID (e.g., from copy or move), the release info is fetched from MusicBrainz and the release is re-tagged.

If no MUSICBRAINZ_ALBUMID is present, the release is matched as it usually would, and only re-tagged if a high match score is calculated.

$ wrtag sync                          # recurse all releases and re-tag
$ wrtag sync -dry-run                 # show what above would do
$ wrtag sync "/my/music/Tame Impala"  # find all releases in "Tame Impala/" and re-tag those
$ wrtag sync -age-older 24h           # find all releases older than 1 day and re-tag
$ wrtag sync -num-workers 16          # process a maximum of 16 releases at a time

Tool wrtagweb

wrtagweb is based on the same core functionality as wrtag, except it's web-based instead of command line. Instead of importing releases from the command line arguments, new releases are imported over HTTP.

For example, an HTTP client (a custom script, a BitTorrent client "on complete" script, or Soulseek) sends an HTTP request to wrtagweb, giving it a new path to import. wrtagweb imports it. If there isn't a 100% match, the user is notified. Then, the user can correct the match, reject, or accept anyway.

%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '26px' }}}%%
flowchart LR
    a["BitTorrent / Soulseek script"] -->
    b["Release added to queue"] -->
    c["User notified if input needed"] -->
    d["Release imported"]
API

Jobs are added to the queue with an HTTP request like POST <wrtag.host>/op/<copy|move> with form value path=<absolute path to directory>. The form value can be an application/x-www-form-urlencoded form body, or URL query parameter.

Authentication is done via a HTTP Basic authentication password without a username. The password is configured with the web-api-key config option.

[!WARNING] HTTP Basic Authentication is only as secure as the transport layer it runs on. Make sure wrtagweb is secured using TLS behind your reverse proxy.

Example with cURL
curl \
    --request POST \
    --data-urlencode "path=/path/to/the/release" \
    "https://:my-api-key@wrtag.hostname/op/copy"
Example with Transmission

Create a script named done.sh or anything you like, and make it executable: chmod +x done.sh

Update your Transmission settings.json to reference the new script:

...
"script-torrent-done-enabled": true,
"script-torrent-done-filename": "/scripts/done.sh",
...

Edit the script to send a copy job with the newly finished torrent. Transmission will set TR_TORRENT_NAME to the name/path of the torrent. See all variables

#!/bin/sh

curl \
    --request POST \
    --data-urlencode "path=<path to downloads>/$TR_TORRENT_NAME" \
    "http://:<wrtag api key>@<wrtag host>/op/copy"
Example with qBittorrent

TODO

Example with Deluge

TODO

Example with sldkd

TODO

Configuration

Configuration for wrtagweb works the same as Global configuration. For example, wrtagweb -web-arg, WRTAG_WEB_ARG, and the global config file is also read.

Options
CLI argument Environment variable Config file key Description
-web-api-key WRTAG_WEB_API_KEY web-api-key API key for web interface
-web-db-path WRTAG_WEB_DB_PATH web-db-path Path to database path for web interface (default "wrtag.db")
-web-listen-addr WRTAG_WEB_LISTEN_ADDR web-listen-addr Listen address for web interface
-web-public-url WRTAG_WEB_PUBLIC_URL web-public-url Public URL for web interface (optional)

Tool metadata

The metadata tool is a standalone helper program for reading and writing track metadata. It can write multiple tags (each with multiple values) to multiple files in a single invocation.

Since it uses the same tag normalisation as wrtag itself, it works well with the subproc addon. This allows for custom metadata read and write after the main release process has completed.

Usage
  $ metadata [<options>] read  <tag>... -- <path>...
  $ metadata [<options>] write ( <tag> <value>... , )... -- <path>...
  $ metadata [<options>] clear <tag>... -- <path>...

  # <tag> is an audio metadata tag key
  # <value> is an audio metadata tag value
  # <path> is path(s) to audio files, dir(s) to find audio files in, or "-" for list audio file paths from stdin
Examples
  $ metadata read -- a.flac b.flac c.flac
  $ metadata read artist title -- a.flac
  $ metadata read -properties -- a.flac
  $ metadata read -properties title length -- a.flac
  $ metadata write album "album name" -- x.flac
  $ metadata write artist "Sensient" , genres "psy" "minimal" "techno" -- dir/*.flac
  $ metadata write artist "Sensient" , genres "psy" "minimal" "techno" -- dir/
  $ metadata clear -- a.flac
  $ metadata clear lyrics artist_credit -- *.flac
  $ find x/ -type f | metadata write artist "Sensient" b -
  $ find y/ -type f | metadata read artist title -
  $ find y/ -type f -name "*extended*" | metadata read -properties length -

For more, see metadata -h and metadata read -h

Installation

Download a release

You can find static/portable binaries (wrtag, wrtagweb, metadata) on the releases page for Windows, macOS, and Linux.

Build from source

To install from source, install a recent Go toolchain, clone the repo, and run go install ./cmd/... from inside.

For packagers, CGO is not required, so you can build with CGO_ENABLED=0 to produce a static binary.

Using Docker

Docker images for many architectures are available on Docker Hub and GitHub. The Docker image by default starts wrtagweb, but has the wrtag tools included too.

If you're using Docker Compose and wrtagweb, you can use this compose.yml to get started:

services:
  wrtag:
    image: sentriz/wrtag
    environment:
      - WRTAG_WEB_API_KEY= # change this
      - WRTAG_WEB_LISTEN_ADDR=:80
      - WRTAG_WEB_PUBLIC_URL=https://wrtag.example.com
      - WRTAG_WEB_DB_PATH=/data/wrtag.db
      - WRTAG_LOG_LEVEL=debug
      # add more config options, like mentioned in the docs above
      # - WRTAG_PATH_FORMAT=...
      # - WRTAG_ADDON=...,...
      # - WRTAG_RESEARCH_LINK=...,...
      # or, use the config file if you use wrtag outside the container. make sure to add it to `volumes:` too
      # - WRTAG_CONFIG_PATH=/config
    expose:
      - 80
    volumes:
      - ./data:/data # for the wrtagweb job queue DB
      - /path/to/music:/path/to/music

Global configuration

Global configuration is used by all tools. Any option can be provided with a CLI argument, environment variable, or config file key. See Format for more technical details.

Options
CLI argument Environment variable Config file key Description
-addon WRTAG_ADDON addon Define an addon for extra metadata writing (see Addons) (stackable)
-caa-base-url WRTAG_CAA_BASE_URL caa-base-url CoverArtArchive base URL (default "https://coverartarchive.org/")
-caa-rate-limit WRTAG_CAA_RATE_LIMIT caa-rate-limit CoverArtArchive rate limit duration
-config WRTAG_CONFIG config Print the parsed config and exit
-config-path WRTAG_CONFIG_PATH config-path Path to config file (default "$XDG_CONFIG_HOME/wrtag/config")
-cover-upgrade WRTAG_COVER_UPGRADE cover-upgrade Fetch new cover art even if it exists locally
-keep-file WRTAG_KEEP_FILE keep-file Define an extra file path to keep when moving/copying to root dir (stackable)
-log-level WRTAG_LOG_LEVEL log-level Set the logging level (default INFO)
-mb-base-url WRTAG_MB_BASE_URL mb-base-url MusicBrainz base URL (default "https://musicbrainz.org/ws/2/")
-mb-rate-limit WRTAG_MB_RATE_LIMIT mb-rate-limit MusicBrainz rate limit duration (default 1s)
-notification-uri WRTAG_NOTIFICATION_URI notification-uri Add a shoutrrr notification URI for an event (see Notifications) (stackable)
-path-format WRTAG_PATH_FORMAT path-format Path to root music directory including path format rules (see Path format)
-research-link WRTAG_RESEARCH_LINK research-link Define a helper URL to help find information about an unmatched release (stackable)
-tag-weight WRTAG_TAG_WEIGHT tag-weight Adjust distance weighting for a tag (0 to ignore) (stackable)
-version WRTAG_VERSION version Print the version and exit
Format
CLI arguments

Just call the command with the CLI argument. For example, wrtag -some-key "some value". For stackable (repeatable) arguments, pass them multiple times. For example, wrtag -some-key "value 1" -some-key "value 2".

[!NOTE] Be aware of the position of global vs command arguments. For example, wrtag <global options> cmd <cmd options>. Check -h when in doubt.

Environment variables

Environment variables are prefixed with WRTAG_ usually. For example, WRTAG_LOG_LEVEL=info wrtag. For stackable (repeatable) arguments, join them with a comma (,). For example, WRTAG_ADDON="replaygain,lyrics genius musixmatch". If the value of the variable should have a comma, it can be escaped with a backslash. For example, \,.

Config file

The config file can be used instead of CLI arguments or environment variables, but can be overwritten with the -config-path CLI argument or WRTAG_CONFIG_PATH environment variable.

Note the default config file locations:

OS Path
Linux $XDG_CONFIG_HOME/wrtag/config
Windows %AppData%\wrtag\config
macOS $HOME/Library/Application Support/wrtag/config

The format follows (flagconf), which looks something like:

some-key argument
other-key argument

For stackable (repeatable) arguments, provide the same key multiple times. For example:

addon replaygain
addon lyrics genius musixmatch

See the example config for more.

Path format

The path-format configuration option defines both the root music directory and the template for organising your music files. This template uses Go's text/template syntax and is populated with MusicBrainz release data.

Basic structure

In order to minimise potential release conflict, the path format should include at least three path segments:

  1. The root music directory (where all your music will be stored).
  2. Artist/release organisation (typically artist name and album details).
  3. Track naming format (including track numbers and titles).

For example:

path-format /music/library/{{ <some artist format> }}/({{ <some release format> }}/{{ <track format> }}

This could format a release like:

/music/library/Tame Impala/(2010) Innerspeaker/01. It Is Not Meant to Be.flac
/music/library/Tame Impala/(2010) Innerspeaker/02. Desire Be Desire Go.flac
/music/library/Tame Impala/(2010) Innerspeaker/03. Alter Ego.flac
...

On Windows, you can use drive letters and backslashes:

path-format C:\User\John\Music\{{ <some artist format> }}\({{ <some release format> }}\{{ <track format> }}

Available template data

The template has access to the following data:

  • .Release - The full MusicBrainz release object (see type Release struct {)
  • .Track - The current track being processed (see type Track struct {)
  • .TrackNum - The track number (integer, starting at 1)
  • .Tracks - The list of tracks in the release
  • .ReleaseDisambiguation - A string for release and release group disambiguation
  • .IsCompilation - Boolean indicating if this is a compilation album
  • .Ext - The file extension for the current track, including the dot (e.g., ".flac")

Helper functions

In addition to what's provided by Go text/template, several helper functions are available to format your paths:

Function Description Example
join Joins strings with a delimiter {{ artists .Release.Artists | join "; " }}
pad0 Zero-pads a number to specified width {{ pad0 2 .TrackNum }} → "01"
sort Sorts a string array {{ artists .Release.Artists | sort }}
safepath Makes a string safe for filesystem use {{ .Track.Title | safepath }}
artists Gets artist names from artist credits {{ artists .Release.Artists }}
artistsString Formats artists as a string {{ artistsString .Track.Artists }}
artistsEn Gets artist names in English locale from artist credits {{ artistsEn .Release.Artists }}
artistsEnString Formats artists names in English locale as a string {{ artistsEnString .Track.Artists }}
artistsCredit Gets credit names from artist credits {{ artistsCredit .Release.Artists }}
artistsCreditString Formats artist credits as a string {{ artistsCreditString .Release.Artists }}

Example formats

[!NOTE] If you need help with creating custom path formats, please see the provided playground here

Including multi-album artist support, release group year, release group and release disambiguations, track numbers, total track numbers, artist names if the release is a compilation album:

/music/{{ artists .Release.Artists | sort | join "; " | safepath }}/({{ .Release.ReleaseGroup.FirstReleaseDate.Year }}) {{ .Release.Title | safepath }}{{ if not (eq .ReleaseDisambiguation "") }} ({{ .ReleaseDisambiguation | safepath }}){{ end }}/{{ pad0 2 .TrackNum }}.{{ len .Tracks | pad0 2 }} {{ if .IsCompilation }}{{ artistsString .Track.Artists | safepath }} - {{ end }}{{ .Track.Title | safepath }}{{ .Ext }}
A basic format
/music/{{ artists .Release.Artists | join "; " | safepath }}/{{ .Release.Title | safepath }}/{{ pad0 2 .TrackNum }} {{ .Track.Title | safepath }}{{ .Ext }}
With year and disambiguation
/music/{{ artists .Release.Artists | sort | join "; " | safepath }}/({{ .Release.ReleaseGroup.FirstReleaseDate.Year }}) {{ .Release.Title | safepath }}{{ if not (eq .ReleaseDisambiguation "") }} ({{ .ReleaseDisambiguation | safepath }}){{ end }}/{{ pad0 2 .TrackNum }} {{ .Track.Title | safepath }}{{ .Ext }}
With compilation handling
/music/{{ artists .Release.Artists | sort | join "; " | safepath }}/({{ .Release.ReleaseGroup.FirstReleaseDate.Year }}) {{ .Release.Title | safepath }}/{{ pad0 2 .TrackNum }} {{ if .IsCompilation }}{{ artistsString .Track.Artists | safepath }} - {{ end }}{{ .Track.Title | safepath }}{{ .Ext }}
With disc and track numbers
/music/{{ artists .Release.Artists | sort | join "; " | safepath }}/({{ .Release.ReleaseGroup.FirstReleaseDate.Year }}) {{ .Release.Title | safepath }}/{{ pad0 2 .TrackNum }}.{{ len .Tracks | pad0 2 }} {{ .Track.Title | safepath }}{{ .Ext }}

Addons

Addons can be used to fetch/compute additional metadata after the MusicBrainz match has been applied and the files have been tagged.

They are configured as part of the global configuration using a config format.

For example:

  • $ wrtag -addon "lyrics a b c" -addon "replaygain x y z"
  • $ WRTAG_ADDON="lyrics a b c,replaygain" wrtag
  • or repeating the addon clause in the config file.

Addon Lyrics

The lyrics addon can fetch and embed lyric information from Genius and Musixmatch in your tracks.

The format of the addon config is lyrics <source>... where the source is one of genius or musixmatch. For example, "lyrics genius musixmatch". Note that sources will be tried in the order they are specified.

Addon ReplayGain

The replaygain addon computes and adds ReplayGain 2.0 information to your files. It is great for normalising the perceived loudness of audio in your tracks.

The format of the addon config is replaygain <opts>... where opts can be true-peak and force. If the force option is passed, ReplayGain information is recomputed even if it’s already present in the files.

Addon Subprocess

The subprocess addon is for running a user-provided program.

The format of the addon config is subproc <path> <args>..., where path is the path to the program, or the program name itself if it’s in your $PATH. args are extra command line arguments to pass to the program. One of the args should be a special placeholder named <files>. This will be expanded to the paths to the files that were just processed by wrtag.

For example, the addon "subproc my-program a --b 'c d' <files>" might call my-program with arguments ["a", "--b", "c d", "track 1.flac", "track 2.flac", "track 3.flac"] after importing a release with 3 tracks.

Notifications

Notifications can be used to notify you or another system of events such as importing or syncing. For example, sending an email when user input is needed to import a release. Or notifying your music server after a sync has completed.

The possible events are:

Tool Name Description
wrtagweb complete Executed when a release is imported
wrtagweb needs-input Executed when a release requires input
wrtag sync-complete Executed when a sync has completed
wrtag sync-error Executed when a sync has completed with errors

wrtag uses shoutrrr to provide upstream notifications over SMTP, HTTP, etc.

For example:

  • smtp://username:password@host:port/?from=from@example.com&to=recipient@example.com
  • generic+https://my.subsonic.com/rest/startScan.view?c=wrtag&v=1.16&u=user&p=password

See the shoutrrr documentation for the list of providers.

Notifications are configured as part of the global configuration. The format is <eventspec> <shoutrrr uri>. eventspec is a comma-separated list of event names.

For example, "complete,sync-complete smtp://example.com". Multiple eventspec and URIs can be configured by stacking the config option according to the config format.

Goals and non-goals

TODO

Documentation

Overview

Package wrtag provides functionality for music file tagging and organisation. It allows for automatic lookup of music metadata from MusicBrainz, tagging files with proper metadata, and organising files in a directory structure based on a configurable path format.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrScoreTooLow is returned when the match confidence between local tracks and
	// MusicBrainz data is below the required threshold.
	ErrScoreTooLow = errors.New("score too low")

	// ErrTrackCountMismatch is returned when the number of tracks in the local directory
	// doesn't match the number of tracks in the MusicBrainz release.
	ErrTrackCountMismatch = errors.New("track count mismatch")

	// ErrNoTracks is returned when no audio tracks are found in the source directory.
	ErrNoTracks = errors.New("no tracks in dir")

	// ErrNotSortable is returned when the tracks in a directory cannot be reliably sorted
	// due to missing track numbers or numerical identifiers in filenames.
	ErrNotSortable = errors.New("tracks in dir can't be sorted")

	// ErrSelfCopy is returned when attempting to copy a file to itself.
	ErrSelfCopy = errors.New("can't copy self to self")
)
View Source
var Name = "wrtag"
View Source
var Version = strings.TrimSpace(version)

Functions

func DestDir

func DestDir(pathFormat *pathformat.Format, release *musicbrainz.Release) (string, error)

DestDir generates the destination directory path for a release based on the given path format.

func IsNonFatalError added in v0.6.0

func IsNonFatalError(err error) bool

IsNonFatalError determines whether an error is non-fatal during processing. Non-fatal errors include low match scores and track count mismatches.

Types

type Config

type Config struct {
	// MusicBrainzClient is used to search and retrieve release data from MusicBrainz
	MusicBrainzClient musicbrainz.MBClient

	// CoverArtArchiveClient is used to retrieve cover art
	CoverArtArchiveClient musicbrainz.CAAClient

	// PathFormat defines the directory structure for organising music files
	PathFormat pathformat.Format

	// TagWeights defines the relative importance of different tags when calculating match scores
	TagWeights tagmap.TagWeights

	// KeepFiles specifies files that should be preserved during processing
	KeepFiles map[string]struct{}

	// Addons are plugins that can perform additional processing after the main import
	Addons []addon.Addon

	// UpgradeCover specifies whether to attempt to replace existing covers with better versions
	UpgradeCover bool
}

Config contains configuration options for processing music directories.

type Copy

type Copy struct {
	// contains filtered or unexported fields
}

Copy implements FileSystemOperation to copy files from source to destination.

func NewCopy added in v0.10.0

func NewCopy(dryRun bool) Copy

NewCopy creates a new Copy operation with the specified dry-run mode. If dryRun is true, no files will actually be copied.

func (Copy) CanModifyDest added in v0.10.0

func (c Copy) CanModifyDest() bool

CanModifyDest returns whether this operation can modify destination files. For Copy operations, this is determined by the dryRun setting.

func (Copy) PostSource added in v0.10.0

func (Copy) PostSource(dc DirContext, limit string, src string) error

PostSource performs any necessary cleanup of the source directory. For Copy operations, this is a no-op since the source files remain in place.

func (Copy) ProcessPath added in v0.10.0

func (c Copy) ProcessPath(dc DirContext, src, dest string) error

ProcessPath copies a file from src to dest, ensuring the destination directory exists. If the operation is in dry-run mode, it will only log the intended action. If src and dest are the same, it returns ErrSelfCopy.

type DirContext

type DirContext struct {
	// contains filtered or unexported fields
}

DirContext tracks known files in the destination directory. After a release is put in place, unknown files not in the DirContext will be deleted.

func NewDirContext

func NewDirContext() DirContext

NewDirContext creates a new DirContext to track destination paths.

type FileSystemOperation

type FileSystemOperation interface {
	// CanModifyDest returns whether this operation can modify existing destination files.
	// Note: If down the line some sort of "in place" tagging operation is needed, then a `CanModifySource` may be appropriate too.
	CanModifyDest() bool

	// ProcessPath handles transferring a file from src to dest path.
	// It ensures the destination directory exists and records the path in the DirContext.
	// The exact behaviour (move/copy/reflink) depends on the specific implementation.
	// Returns an error if the operation fails.
	ProcessPath(dc DirContext, src, dest string) error

	// PostSource performs any cleanup or post-processing on the source directory
	// after all files have been processed. For example, removing empty directories
	// after a move operation.
	// The limit parameter specifies a boundary directory that should not be removed.
	// Returns an error if the cleanup operation fails.
	PostSource(dc DirContext, limit string, src string) error
}

FileSystemOperation defines operations that can be performed on files during the import/tagging process. Implementations handle different ways to transfer files (move, copy, reflink) while maintaining consistent behaviours.

type ImportCondition

type ImportCondition uint8

ImportCondition defines the conditions under which a release will be imported.

const (
	// HighScore requires the match to have a high confidence score
	HighScore ImportCondition = iota

	// HighScoreOrMBID accepts either a high score or a matching MusicBrainz ID
	HighScoreOrMBID

	// Confirm always imports regardless of score
	Confirm
)

type Move

type Move struct {
	// contains filtered or unexported fields
}

Move implements FileSystemOperation to move files from source to destination.

func NewMove added in v0.10.0

func NewMove(dryRun bool) Move

NewMove creates a new Move operation with the specified dry-run mode. If dryRun is true, no files will actually be moved.

func (Move) CanModifyDest added in v0.10.0

func (m Move) CanModifyDest() bool

CanModifyDest returns whether this operation can modify destination files. For Move operations, this is determined by the dryRun setting.

func (Move) PostSource added in v0.10.0

func (m Move) PostSource(dc DirContext, limit string, src string) error

PostSource cleans up the source directory after all files have been moved. It removes empty directories up to the specified limit directory.

func (Move) ProcessPath added in v0.10.0

func (m Move) ProcessPath(dc DirContext, src, dest string) error

ProcessPath moves a file from src to dest, ensuring the destination directory exists. If the operation is in dry-run mode, it will only log the intended action. If src and dest are the same, no action is taken.

type PathTags added in v0.6.1

type PathTags struct {
	// Path is the file path
	Path string

	// Tags contains the audio file's metadata tags
	tags.Tags
}

PathTags associates a file path with its tags.

func ReadReleaseDir

func ReadReleaseDir(dirPath string) (string, []PathTags, error)

ReadReleaseDir reads a directory containing music files and extracts tags from each file. It returns the path to the cover image (if found) and a slice of PathTags for each audio file. Files are sorted by disc number, directory, track number, and finally path.

type Reflink struct {
	// contains filtered or unexported fields
}

Reflink implements FileSystemOperation to copy files using reflink (copy-on-write) when supported.

func NewReflink(dryRun bool) Reflink

NewReflink creates a new Reflink operation with the specified dry-run mode. If dryRun is true, no files will actually be reflinked.

func (Reflink) CanModifyDest added in v0.10.0

func (c Reflink) CanModifyDest() bool

CanModifyDest returns whether this operation can modify destination files. For Reflink operations, this is determined by the dryRun setting.

func (Reflink) PostSource added in v0.10.0

func (Reflink) PostSource(dc DirContext, limit string, src string) error

PostSource performs any necessary cleanup of the source directory. For Reflink operations, this is a no-op since the source files remain in place.

func (Reflink) ProcessPath added in v0.10.0

func (c Reflink) ProcessPath(dc DirContext, src, dest string) error

ProcessPath creates a reflink (copy-on-write) clone of a file from src to dest. If the operation is in dry-run mode, it will only log the intended action. If src and dest are the same, it returns ErrSelfCopy.

type SearchResult

type SearchResult struct {
	// Release contains the matched MusicBrainz release data
	Release *musicbrainz.Release

	// Query contains the search parameters used for the MusicBrainz lookup
	Query musicbrainz.ReleaseQuery

	// Score indicates the confidence of the match (0-100)
	Score float64

	// DestDir is the destination directory path where files were or would be placed
	DestDir string

	// Diff contains the differences between local tags and MusicBrainz tags
	Diff []tagmap.Diff

	// OriginFile contains information from any gazelle-origin file found in the source directory
	OriginFile *originfile.OriginFile
}

SearchResult contains the results of a MusicBrainz lookup and potential import operation.

func ProcessDir

func ProcessDir(
	ctx context.Context, cfg *Config,
	op FileSystemOperation, srcDir string, cond ImportCondition, useMBID string,
) (*SearchResult, error)

ProcessDir processes a music directory by looking up metadata on MusicBrainz and either moving, copying, or reflinking the files to a new location with proper tags. It returns a SearchResult containing information about the match and operation.

The srcDir must be an absolute path. The cond parameter determines the conditions under which the import will proceed. The useMBID parameter can be used to force a specific MusicBrainz release ID.

Directories

Path Synopsis
cmd
Code generated by gen_taglist.
Code generated by gen_taglist.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL