id = "musicbrainz-picard" name = "MusicBrainz Picard" homepage = "https://picard.musicbrainz.org" description = "a cross-platform music tagger powered by the MusicBrainz database." icon = "SimpleIcons:musicbrainz" executables = ["picard"] [dotfiles] # picard/config.py builds the configuration as # `QtCore.QSettings.__init__(..., QSettings.Format.IniFormat, # QSettings.Scope.UserScope, PICARD_ORG_NAME, PICARD_APP_NAME)` — organisation # "MusicBrainz", application "Picard". Qt's IniFormat/UserScope location is # $XDG_CONFIG_HOME (else ~/.config) on Unix *and on macOS*, and %APPDATA% on # Windows, with the file named .ini — the one place [configHome] # stands for. The Homebrew cask `musicbrainz-picard` corroborates the macOS # half: its `zap trash:` list names ~/.config/MusicBrainz, not a path under # ~/Library/Preferences (https://formulae.brew.sh/api/cask/musicbrainz-picard.json). paths = ["[configHome]/MusicBrainz/Picard.ini"] exclude = [] # Picard.ini is not a credential end to end — it is the tagging and file-naming # options, the scripts and the plugin list. Only the token and password keys # are lifted out below. secret = [] # Picard's account credentials, which live in the same INI. The names are the # option definitions in picard/options.py: # # TextOption('persist', 'oauth_access_token', '') # TextOption('persist', 'oauth_refresh_token', '') # TextOption('setting', 'proxy_password', '', title="Proxy password") # # plus the pre-1.4 shape: config_upgrade_hooks.py's remove_username_password() # says "Options "username" and "password" are removed and replaced with OAuth # tokens", so a file written before that upgrade ran still has a bare # `password`, and a rule that named only the OAuth keys would let it sync in # the clear. # # QSettings writes an INI as `key=value`, so each prefix carries the `=`: it # keeps `oauth_access_token` from also matching `oauth_access_token_expires` # and `oauth_refresh_token` from matching `oauth_refresh_token_scopes`, neither # of which is a secret. [[dotfiles.secret_paths]] file = "[configHome]/MusicBrainz/Picard.ini" match = { prefix = [ "oauth_access_token=", "oauth_refresh_token=", "proxy_password=", "password=", ] } # The destination directory Picard moves tagged files into: # `TextOption('setting', 'move_files_to', DEFAULT_MUSIC_DIR, title="Destination # directory")` — an absolute path into this machine's disk. The proxy host is # the other machine-local line: a proxy that exists on the office network and # not at home. # Both are the user's own answers — where their library lives, which proxy this # location needs — so both are kept for rebuilding this machine and neither is # pushed to another. [[dotfiles.machine_lines]] file = "[configHome]/MusicBrainz/Picard.ini" match = { prefix = ["move_files_to=", "proxy_server_host="] } scope = "backup"