beetbox / beets

music library manager and MusicBrainz tagger
http://beets.io/
MIT License
12.78k stars 1.82k forks source link

Crash KeyError: 'title' #5218

Open eric-sofisoftwarellc opened 5 months ago

eric-sofisoftwarellc commented 5 months ago

Import fails with KeyError: 'title'

The problem seems to be the file name doesn't have a space. If a track is named "01LadyOfAutumn.mp3", it crashes. If I change all the tracks to have a space after the number, eg "01 LadyOfAutumn.mp3", it succeeds.

Turning off plugins works, it does not crash. Update: I narrowed down the plugin to fromfilename. If I remove that, it works.

I have latest version from git (pipx install https://github.com/beetbox/beets/tarball/master).

(beets) ➜  ~ beet import test
Traceback (most recent call last):
  File "/Users/user/.local/pipx/venvs/beets/bin/beet", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/ui/__init__.py", line 1865, in main
    _raw_main(args)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/ui/__init__.py", line 1852, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/ui/commands.py", line 1395, in import_func
    import_files(lib, paths, query)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/ui/commands.py", line 1326, in import_files
    session.run()
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/importer.py", line 360, in run
    pl.run_parallel(QUEUE_SIZE)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/util/pipeline.py", line 447, in run_parallel
    raise exc_info[1].with_traceback(exc_info[2])
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/util/pipeline.py", line 312, in run
    out = self.coro.send(msg)
          ^^^^^^^^^^^^^^^^^^^
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/util/pipeline.py", line 195, in coro
    func(*(args + (task,)))
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/importer.py", line 1490, in lookup_candidates
    plugins.send("import_task_start", session=session, task=task)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/plugins.py", line 507, in send
    result = handler(**arguments)
             ^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beets/plugins.py", line 143, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beetsplug/fromfilename.py", line 165, in filename_task
    apply_matches(d, self._log)
  File "/Users/user/.local/pipx/venvs/beets/lib/python3.12/site-packages/beetsplug/fromfilename.py", line 124, in apply_matches
    item.title = str(d[item][title_field])
                     ~~~~~~~^^^^^^^^^^^^^
KeyError: 'title'

Setup

(beets) ➜  ~ beet version
beets version 1.6.1
Python version 3.12.3
plugins: badfiles, chroma, embedart, fetchart, fromfilename, mbsync, unimported, web
beet --plugins=  import test

Finding tags for album "foo".
  Candidates:
[etc]

My configuration (output of beet config) is:

(beets) ➜  ~ beet config
directory: /Volumes/Bigly/music/beets/music
# --------------- Main ---------------

library: /Volumes/Bigly/music/beets/data/musiclibrary.db

# --------------- Plugins ---------------

plugins: web chroma badfiles fromfilename embedart fetchart unimported mbsync
unimported:
    ignore_extensions: jpg png DS_Store
    ignore_subdirectories: NonMusic data temp
chroma:
    auto: yes
web:
    host: 127.0.0.1
    port: 8337
    cors: ''
    cors_supports_credentials: no
    reverse_proxy: no
    include_paths: no
    readonly: yes
fetchart:
    auto: yes
    minwidth: 0
    maxwidth: 0
    quality: 0
    max_filesize: 0
    enforce_ratio: no
    cautious: no
    cover_names:
    - cover
    - front
    - art
    - album
    - folder
    sources:
    - filesystem
    - coverart
    - itunes
    - amazon
    - albumart
    - cover_art_url
    store_source: no
    high_resolution: no
    deinterlace: no
    cover_format:
    google_key: REDACTED
    google_engine: 001442825323518660753:hrh5ch1gjzm
    fanarttv_key: REDACTED
    lastfm_key: REDACTED
embedart:
    maxwidth: 0
    auto: yes
    compare_threshold: 0
    ifempty: no
    remove_art_file: no
    quality: 0
tumbleboy commented 3 months ago

Hey! I am looking to make my first contribution to an open source program

I was able to handle the filename by adding a new regex pattern in PATTERNS. r"^(?P<track>\d+)(?P<title>.+)$"

what does everyone think?

Vrihub commented 3 months ago

Hey! I am looking to make my first contribution to an open source program

I was able to handle the filename by adding a new regex pattern in PATTERNS. r"^(?P<track>\d+)(?P<title>.+)$"

what does everyone think?

It still crashes with filenames like 01.mp3 02.mp3 etc

Files of this kind were working fine before the changes introduced in 2839302 and 5461ddf. Indeed I've been using a very old version of beets without problems, and I've just noticed this bug today after updating to 2.0.0

The fromfilename plugin should be fixed to allow a wider range of filenames, either relaxing/refactoring some of the regexps in PATTERNS or by not requiring existence of the title dictionary key in the checks done in apply_matches()

tumbleboy commented 3 months ago

I think not requiring the existence of the title key could be the way to go. I don't think this is a very common issue among users but happy to discuss another way.

Vrihub commented 3 months ago

FYI, I'm having a closer look at the fromfilename plugin and I'll try to come up with a PR to fix the bug

tumbleboy commented 3 months ago

Hey @Vrihub, I've been working on this issue and I can create a draft PR soon for you to review?