beetbox / beets

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

Deezer: `contributors` field is not always present, can crash the importer #4339

Open ghost opened 2 years ago

ghost commented 2 years ago

Problem

Running this command in verbose (-vv) mode:

$ beet -vv import /Volumes/Pink/Downloads/Music/Artists

Led to this problem:

Candidate: Various Artists - Total - Volume One (3beb9d31-2b59-4cf8-95c3-0a5e2faea75f)
Computing track assignment...
...done.
Success. Distance: 0.59
discogs: Searching for release 3beb9d31-2b59-4cf8-95c3-0a5e2faea75f
deezer: Searching Deezer for album '3beb9d31-2b59-4cf8-95c3-0a5e2faea75f'
chroma: chroma: fingerprinted b'/Volumes/Pink/Downloads/Music/Artists/Coil/Extras/\xd0\xa1ompilation Appearances/1996 - Treat The Gods As If They Exist/14. Asmus Tietchens - Nur Ton.flac'
chroma: matched recordings ['8bcd4988-84cb-4fda-87d1-390b29e45f57'] on releases ['61273ee1-0d18-4a2c-9394-83d22bc3b536']
Looking up: /Volumes/Pink/Downloads/Music/Artists/Coil/Extras/Сompilation Appearances/1996 - Treat The Gods As If They Exist
Tagging Various - Treat The Gods As If They Exist
Searching for discovered album ID: 61273ee1-0d18-4a2c-9394-83d22bc3b536
Requesting MusicBrainz release 61273ee1-0d18-4a2c-9394-83d22bc3b536
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_album_extract
Sending event: albuminfo_received
Candidate: Various Artists - Treat the Gods as If They Exist (61273ee1-0d18-4a2c-9394-83d22bc3b536)
Computing track assignment...
...done.
Success. Distance: 0.00
Album ID match recommendation is Recommendation.strong
ID match.
Traceback (most recent call last):
  File "/Users/username/Documents/Code/beets/venv/bin/beet", line 8, in <module>
    sys.exit(main())
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/__init__.py", line 1285, in main
    _raw_main(args)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/__init__.py", line 1272, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/commands.py", line 973, in import_func
    import_files(lib, paths, query)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/commands.py", line 943, in import_files
    session.run()
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/importer.py", line 340, in run
    pl.run_parallel(QUEUE_SIZE)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/util/pipeline.py", line 446, in run_parallel
    raise exc_info[1].with_traceback(exc_info[2])
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/util/pipeline.py", line 311, in run
    out = self.coro.send(msg)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/util/pipeline.py", line 170, in coro
    task = func(*(args + (task,)))
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/importer.py", line 1400, in user_query
    task.choose_match(session)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/importer.py", line 859, in choose_match
    choice = session.choose_match(self)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/commands.py", line 743, in choose_match
    post_choice = choice.callback(self, task)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/ui/commands.py", line 673, in manual_id
    _, _, prop = autotag.tag_album(
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/autotag/match.py", line 422, in tag_album
    for id_candidate in hooks.albums_for_id(search_id):
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/autotag/hooks.py", line 584, in albums_for_id
    for a in plugins.album_for_id(album_id):
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beets/plugins.py", line 399, in album_for_id
    album = plugin.album_for_id(album_id)
  File "/Users/username/Documents/Code/beets/venv/lib/python3.9/site-packages/beetsplug/deezer.py", line 59, in album_for_id
    artist, artist_id = self.get_artist(album_data['contributors'])
KeyError: 'contributors'

(venv) FAIL: 1

Here's a link to the music files that trigger the bug (if relevant):

Setup

My configuration (output of beet config) is:

library: /Users/username/.config/beets/musiclibrary.db
directory: /Volumes/Pink/Downloads/Music-Clean/Artists

import:
    move: no
    copy: yes
    write: yes
art_filename: Cover

plugins: chroma discogs deezer fromfilename lastgenre fetchart
pluginpath: /Users/username/.config/beets/plugins
fetchart:
    auto: yes
    cautious: yes
    cover_names: cover front art album folder
    sources: filesystem coverart itunes lastfm amazon albumart *
    lastfm_key: REDACTED
    minwidth: 0
    maxwidth: 0
    quality: 0
    max_filesize: 0
    enforce_ratio: no
    google_key: REDACTED
    google_engine: 001442825323518660753:hrh5ch1gjzm
    fanarttv_key: REDACTED
    store_source: no
    high_resolution: no
    deinterlace: no
    cover_format:

replace:
    '[\\/]': _
    ^\.: _
    '[\x00-\x1f]': _
    '[<>:"\?\*\|]': _
    \.$: _
    \s+$: ''
    ^\s+: ''
    ^-: _
threaded: yes

match:
    strong_rec_thresh: 0.15
    ignored: missing_tracks unmatched_tracks

paths:
    default: $albumartist/$year - $album%aunique{}/$track $artist - $title
    comp: Compilations/$year - $album%aunique{}/$track $artist - $title
chroma:
    auto: yes
discogs:
    apikey: REDACTED
    apisecret: REDACTED
    tokenfile: discogs_token.json
    source_weight: 0.5
    user_token: REDACTED
    separator: ', '
    index_tracks: no
deezer:
    source_weight: 0.5
lastgenre:
    whitelist: yes
    min_weight: 10
    count: 1
    fallback:
    canonical: no
    source: album
    force: yes
    auto: yes
    separator: ', '
    prefer_specific: no
    title_case: yes
wisp3rwind commented 2 years ago

Looks like a bug, we seem to be making invalid assumptions about the data that deezer returns. Unfortunately, I can't really tell what exact result from the deezer API this happens for.

Related: https://github.com/beetbox/beets/issues/4116, https://github.com/beetbox/beets/pull/4196

sampsyo commented 2 years ago

Indeed; while knowing the details of the release that crashes would help, it looks like the plugin needs to avoid relying on the existence of that contributors key.