Repository metrics
- Stars
- (12,133 stars)
- PR merge metrics
- (Avg merge 26d 4h) (51 merged PRs in 30d)
Description
Problem
I think there's a typo in the documentation for the titlecase plugin's %titlecase template function.
For every other template function it is documented as %func{arg,arg}.1
Titlecase also is not mentioned in the list of plugins providing templates.2
The documentation for the titlecase plugin specifies it with parentheses. https://github.com/beetbox/beets/blob/26ab6b26361e8c9d77cdf04ba9cf5ca64bbbc722/docs/plugins/titlecase.rst#L34-L40
I didn't catch this initially when I added the titlecase plugin to my config leading to results like %titlecase(Smiths, The) as part of the directory and file names.
Running this command in verbose (-vv) mode:
$ beet -vv import -q -L artist:"The Smiths"
Led to this problem:
user configuration: /home/tom/.config/beets/config.yaml
data directory: /home/tom/.config/beets
plugin paths: []
Loading plugins: chroma, convert, discogs, duplicates, edit, fuzzy, info, mbsync, musicbrainz, permissions, replace, spotify, the, titlecase, unimported, web
Sending event: pluginload
library database: /home/tom/.config/beets/musiclibrary.db
library directory: /home/tom/Music
Sending event: library_opened
Sending event: import_begin
Parsed query: AndQuery([SubstringQuery('artist', 'The Smiths', fast=True)])
Parsed sort: NullSort()
yielding album 1436: The Smiths - Hatful of Hollow
Sending event: import_task_created
Sending event: import_task_start
# [...] output of unrelated plugins cut
/home/tom/Music/Smiths, The/Hatful of Hollow (1 items)
Sending event: import_task_before_choice
Importing as-is.
Sending event: import_task_choice
Replacing item 6502: /home/tom/Music/Smiths, The/Hatful of Hollow/How Soon Is Now_.mp4
Sending event: database_change
Sending event: database_change
Sending event: album_removed
Sending event: item_removed
1 of 1 items replaced
Sending event: database_change
Sending event: database_change
Sending event: database_change
Sending event: database_change
Reimported album 1453. Preserving attribute ['added']. Path: /home/tom/Music/Smiths, The/Hatful of Hollow
Reimported album 1453. Preserving flexible attributes ['data_source', 'media']. Path: /home/tom/Music/Smiths, The/Hatful of Hollow
Reimported item 6538. Preserving attribute ['added']. Path: /home/tom/Music/Smiths, The/Hatful of Hollow/How Soon Is Now_.mp4
Reimported item 6538. Preserving flexible attributes ['data_source', 'spotify_time_signature', 'spotify_valence', 'spotify_danceability', 'spotify_artist_id', 'spotify_track_id', 'spotify_key', 'spotify_acousticness', 'spotify_liveness', 'spotify_energy', 'spotify_updated', 'spotify_speechiness', 'spotify_track_popularity', 'spotify_tempo', 'spotify_instrumentalness', 'track_alt', 'spotify_loudness', 'spotify_mode']. Path: /home/tom/Music/Smiths, The/Hatful of Hollow/How Soon Is Now_.mp4
Sending event: database_change
Parsed query: AndQuery([NoneQuery('album_id', True)])
Parsed sort: NullSort()
Parsed query: AndQuery([BooleanQuery('comp', 1, fast=True)])
Parsed sort: NullSort()
the: "The Smiths" -> "Smiths, The"
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
Sending event: database_change
Sending event: import_task_files
Sending event: album_imported
permissions: setting file permissions on /home/tom/Music/%titlecase(Smiths, The)/%titlecase(Hatful of Hollow)/%titlecase(How Soon Is Now_).mp4
permissions: setting directory permissions on /home/tom/Music/%titlecase(Smiths, The)/%titlecase(Hatful of Hollow)
permissions: setting directory permissions on /home/tom/Music/%titlecase(Smiths, The)
Sending event: import
Sending event: cli_exit
I was able to fix this and reimport my library automatically with beet import -q -m -L,
which resolved the filename issues.
Setup
- OS: Arch Linux
- Python version: 3.14.5
- beets version: 2.11.0
- Turning off plugins made problem go away (yes/no): Not applicable
My configuration (output of beet config) is:
Related sections only
# --------------- Main ---------------
library: ~/.config/beets/musiclibrary.db
directory: ~/Music/
include: [secrets.yaml]
paths:
default: '%titlecase{%the{$albumartist}}/%titlecase{$album}/%titlecase{$title}'
singleton: '%titlecase{%the{$albumartist}}/%titlecase{$album}/%titlecase{$title}'
import:
copy: yes
quiet_fallback: asis
incremental: yes
incremental_skip_later: yes
resume: ask
languages: en
log: ~/.config/beets/import.log
# [...]
# --------------- Plugins ---------------
plugins:
- chroma
- convert
- discogs
- duplicates
- edit
- fuzzy
- info
- mbsync
- musicbrainz
- permissions
- replace
- spotify
- the
- titlecase
- unimported
- web
# [...]
titlecase:
auto: no
preserve: []
replace:
"\u2013": '-'
"\u2014": '-'
"\u2026": '...'
"\u2018": '''' # This is "'" in the file
"\u2019": '''' # Not sure why `beet config`
"\u201B": '''' # prints them as ''''
"\u2039": ''''
"\u203A": ''''
"\u201A": ''''
"\u275B": ''''
"\u275C": ''''
"\u275F": ''''
"\u276E": ''''
"\u276F": ''''
"\uFF07": ''''
"\xAB": '"'
"\xBB": '"'
"\u201C": '"'
"\u201D": '"'
"\u201E": '"'
"\u201F": '"'
"\u275D": '"'
"\u275E": '"'
"\u301E": '"'
"\u301F": '"'
"\u2E42": '"'
"\uFF02": '"'
fields: []
separators: []
force_lowercase: no
small_first_last: yes
the_artist: yes
all_caps: no
all_lowercase: no
after_choice: no