vjeranc / cmus-status-scrobbler

Standalone scrobbler program, not a continuously running process, written in Python 3 that works together with cmus. Allows offline mode, scrobbling multiple servers simultaneously, sending a now playing request and handles pause status well.
GNU General Public License v3.0
16 stars 1 forks source link

Tracks being scrobbled twice to Listenbrainz #2

Closed alscaldas closed 1 year ago

alscaldas commented 2 years ago

Edit: @vjeranc Set now_playing = no to avoid double scrobble. You won't have "Scrobbling now" but the track will scrobble once.

Sorry to bother again.

Thing is I really liked the combination of cmus and cmus-status-scrobbler and I'd like to keep using them as my main audio player/scrobbler. After the fixes you kindly did yesterday I noticed that although it's working with the three servers it's been scrobbling each track twice to Listenbrainz.

If it's not much time consuming could you please take a look at this?

vjeranc commented 2 years ago

A nice way to test:

  1. set now_playing = no for listenbrainz and see if it scrobbles twice,
  2. check if Scrobbling previous tracks for listenbrainz shows twice in the logs with the same track,
  3. make sure there's no two [listenbrainz] blocks in your .ini file.

If cmus-status-scrobbler code does not do it twice (highly probable given that it does not do it twice for lastfm/librefm), then listenbrainz has another bug again and you can ask them at metabrainz issue tracker why they decided to scrobble the tracks twice.

alscaldas commented 2 years ago

Just to let you know:

  1. If I set now_playing = no it just doesn't scrobble for listenbrainz at all.
  2. Scrobbling previous tracks for listenbrainz only shows once in the logs, although the scrobble happens twice. I noticed that it seems to happen as soon as the track starts and when the next one begins. That's the corresponding log, which shows that each block of code repeats twice (one I believe when the track really plays and the next one after the next track begins). Notice the pattern with the song "La Terrasse", for example:
    INFO:root:Status(status='playing', file='/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Tout Est Calme/08 La Terrasse.flac', artist='Yann Tiersen', albumartist='Yann Tiersen', album='Tout est calme', discnumber='1', tracknumber='8', title='La Terrasse', date='1999-03-29', duration='175', musicbrainz_trackid='ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', cur_time=datetime.datetime(2021, 11, 9, 10, 57, 2, 848696))
    INFO:root:Sending now playing for lastfm
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Terrasse', 'album': 'Tout est calme', 'trackNumber': '8', 'duration': '175', 'mbid': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'f309b696978a73caadf3b9677a8022c2', 'format': 'json'}
    INFO:root:{"nowplaying":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"track":{"corrected":"0","#text":"La Terrasse"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"album":{"corrected":"0","#text":"Tout est calme"}}}
    INFO:root:Sending now playing for librefm
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Terrasse', 'album': 'Tout est calme', 'trackNumber': '8', 'duration': '175', 'mbid': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'a49d2fcf490a7cf3b4152aec8431ba37', 'format': 'json'}
    INFO:root:{"nowplaying":{"track":{"#text":"La Terrasse","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"ignoredMessage":{"#text":"","code":"0"}}}
    INFO:root:Sending now playing for listenbrainz
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Terrasse', 'album': 'Tout est calme', 'trackNumber': '8', 'duration': '175', 'mbid': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '5ccdf817c4829308609745db48be1503'}
    INFO:root:<?xml version="1.0" encoding="utf-8"?>
    <lfm status="ok">
    <nowplaying>
    <track corrected="0">La Terrasse</track>
    <artist corrected="0">Yann Tiersen</artist>
    <album corrected="0">Tout est calme</album>
    <albumArtist corrected="0">Yann Tiersen</albumArtist>
    <timestamp>1636455425</timestamp>
    <ignoredMessage code="0"></ignoredMessage>
    </nowplaying>
    </lfm>
    INFO:root:Status(status='playing', file="/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Tout Est Calme/09 L'Étal.flac", artist='Yann Tiersen', albumartist='Yann Tiersen', album='Tout est calme', discnumber='1', tracknumber='9', title="L'Étal", date='1999-03-29', duration='114', musicbrainz_trackid='6e937503-9d01-428c-84b5-1200bab9d1c6', cur_time=datetime.datetime(2021, 11, 9, 10, 59, 58, 29274))
    INFO:root:Sending now playing for lastfm
    INFO:root:{'artist': 'Yann Tiersen', 'track': "L'Étal", 'album': 'Tout est calme', 'trackNumber': '9', 'duration': '114', 'mbid': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '881d6da1711d647c1f2549d4b9e119d1', 'format': 'json'}
    INFO:root:{"nowplaying":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"track":{"corrected":"0","#text":"L'Étal"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"album":{"corrected":"0","#text":"Tout est calme"}}}
    INFO:root:Scrobbling previous tracks for lastfm
    INFO:root:{'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'artist[0]': 'Yann Tiersen', 'track[0]': 'La Terrasse', 'timestamp[0]': '1636455422', 'album[0]': 'Tout est calme', 'trackNumber[0]': '8', 'mbid[0]': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'duration[0]': '175', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': 'addb943e5a5f2ebd13d40e84ef17a79b', 'format': 'json'}
    INFO:root:{"scrobbles":{"scrobble":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"album":{"corrected":"0","#text":"Tout est calme"},"track":{"corrected":"0","#text":"La Terrasse"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"timestamp":"1636455422"},"@attr":{"ignored":0,"accepted":1}}}
    INFO:root:Sending now playing for librefm
    INFO:root:{'artist': 'Yann Tiersen', 'track': "L'Étal", 'album': 'Tout est calme', 'trackNumber': '9', 'duration': '114', 'mbid': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '799a434390079aa514cd6aaefe8840c8', 'format': 'json'}
    INFO:root:{"nowplaying":{"track":{"#text":"L'\u00c9tal","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"ignoredMessage":{"#text":"","code":"0"}}}
    INFO:root:Scrobbling previous tracks for librefm
    INFO:root:{'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'artist[0]': 'Yann Tiersen', 'track[0]': 'La Terrasse', 'timestamp[0]': '1636455422', 'album[0]': 'Tout est calme', 'trackNumber[0]': '8', 'mbid[0]': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'duration[0]': '175', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '824f56957f31bf6c69b8dd7cace65b9f', 'format': 'json'}
    INFO:root:{"scrobbles":{"scrobble":{"track":{"#text":"La Terrasse","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"timestamp":"1636455422","ignoredMessage":{"#text":"","code":"0"}},"@attr":{"accepted":"1","ignored":"0"}}}
    INFO:root:Sending now playing for listenbrainz
    INFO:root:{'artist': 'Yann Tiersen', 'track': "L'Étal", 'album': 'Tout est calme', 'trackNumber': '9', 'duration': '114', 'mbid': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '21eb805c1d928d25d44d8c8dfe7f9f3d'}
    INFO:root:<?xml version="1.0" encoding="utf-8"?>
    <lfm status="ok">
    <nowplaying>
    <track corrected="0">L'Étal</track>
    <artist corrected="0">Yann Tiersen</artist>
    <album corrected="0">Tout est calme</album>
    <albumArtist corrected="0">Yann Tiersen</albumArtist>
    <timestamp>1636455606</timestamp>
    <ignoredMessage code="0"></ignoredMessage>
    </nowplaying>
    </lfm>
    INFO:root:Scrobbling previous tracks for listenbrainz
    INFO:root:{'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'artist[0]': 'Yann Tiersen', 'track[0]': 'La Terrasse', 'timestamp[0]': '1636455422', 'album[0]': 'Tout est calme', 'trackNumber[0]': '8', 'mbid[0]': 'ae7f8502-778d-4f5e-9dba-6fc5d553ad0e', 'duration[0]': '175', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '99acd7eaae4e5f7a47dbad424b1fe59f'}
    INFO:root:<?xml version="1.0" encoding="utf-8"?>
    <lfm status="ok">
    <scrobbles accepted="1" ignored="0">
    <scrobble>
      <track corrected="0">La Terrasse</track>
      <artist corrected="0">Yann Tiersen</artist>
      <album corrected="0">Tout est calme</album>
      <albumArtist corrected="0">Yann Tiersen</albumArtist>
      <timestamp>1636455422</timestamp>
      <ignoredMessage code="0"></ignoredMessage>
    </scrobble>
    </scrobbles>
    </lfm>
    INFO:root:Status(status='playing', file='/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Tout Est Calme/10 La Découverte.flac', artist='Yann Tiersen', albumartist='Yann Tiersen', album='Tout est calme', discnumber='1', tracknumber='10', title='La Découverte', date='1999-03-29', duration='133', musicbrainz_trackid='2c4c845c-907a-4d96-940a-bbe8b2d0f126', cur_time=datetime.datetime(2021, 11, 9, 11, 1, 52, 283429))
    INFO:root:Sending now playing for lastfm
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Découverte', 'album': 'Tout est calme', 'trackNumber': '10', 'duration': '133', 'mbid': '2c4c845c-907a-4d96-940a-bbe8b2d0f126', 'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'c3b222e00d408ce892e44631ee0e5454', 'format': 'json'}
    INFO:root:{"nowplaying":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"track":{"corrected":"0","#text":"La Découverte"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"album":{"corrected":"0","#text":"Tout est calme"}}}
    INFO:root:Scrobbling previous tracks for lastfm
    INFO:root:{'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'artist[0]': 'Yann Tiersen', 'track[0]': "L'Étal", 'timestamp[0]': '1636455598', 'album[0]': 'Tout est calme', 'trackNumber[0]': '9', 'mbid[0]': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'duration[0]': '114', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '4b37a3d483c7381a32b5ab05978377f5', 'format': 'json'}
    INFO:root:{"scrobbles":{"scrobble":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"album":{"corrected":"0","#text":"Tout est calme"},"track":{"corrected":"0","#text":"L'Étal"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"timestamp":"1636455598"},"@attr":{"ignored":0,"accepted":1}}}
    INFO:root:Sending now playing for librefm
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Découverte', 'album': 'Tout est calme', 'trackNumber': '10', 'duration': '133', 'mbid': '2c4c845c-907a-4d96-940a-bbe8b2d0f126', 'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '83ea5a09649cabd04abe17a75abeb559', 'format': 'json'}
    INFO:root:{"nowplaying":{"track":{"#text":"La D\u00e9couverte","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"ignoredMessage":{"#text":"","code":"0"}}}
    INFO:root:Scrobbling previous tracks for librefm
    INFO:root:{'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'artist[0]': 'Yann Tiersen', 'track[0]': "L'Étal", 'timestamp[0]': '1636455598', 'album[0]': 'Tout est calme', 'trackNumber[0]': '9', 'mbid[0]': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'duration[0]': '114', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '9990da60fa580f55c58d722aa482e3f3', 'format': 'json'}
    INFO:root:{"scrobbles":{"scrobble":{"track":{"#text":"L'\u00c9tal","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"timestamp":"1636455598","ignoredMessage":{"#text":"","code":"0"}},"@attr":{"accepted":"1","ignored":"0"}}}
    INFO:root:Sending now playing for listenbrainz
    INFO:root:{'artist': 'Yann Tiersen', 'track': 'La Découverte', 'album': 'Tout est calme', 'trackNumber': '10', 'duration': '133', 'mbid': '2c4c845c-907a-4d96-940a-bbe8b2d0f126', 'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '94d9dbcd794415b3cc5f3ea1b43d8c03'}
    INFO:root:<?xml version="1.0" encoding="utf-8"?>
    <lfm status="ok">
    <nowplaying>
    <track corrected="0">La Découverte</track>
    <artist corrected="0">Yann Tiersen</artist>
    <album corrected="0">Tout est calme</album>
    <albumArtist corrected="0">Yann Tiersen</albumArtist>
    <timestamp>1636455717</timestamp>
    <ignoredMessage code="0"></ignoredMessage>
    </nowplaying>
    </lfm>
    INFO:root:Scrobbling previous tracks for listenbrainz
    INFO:root:{'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'artist[0]': 'Yann Tiersen', 'track[0]': "L'Étal", 'timestamp[0]': '1636455598', 'album[0]': 'Tout est calme', 'trackNumber[0]': '9', 'mbid[0]': '6e937503-9d01-428c-84b5-1200bab9d1c6', 'duration[0]': '114', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': 'dbca3253fdb750e2e5d2e698f285ec1f'}
    INFO:root:<?xml version="1.0" encoding="utf-8"?>
    <lfm status="ok">
    <scrobbles accepted="1" ignored="0">
    <scrobble>
      <track corrected="0">L'Étal</track>
      <artist corrected="0">Yann Tiersen</artist>
      <album corrected="0">Tout est calme</album>
      <albumArtist corrected="0">Yann Tiersen</albumArtist>
      <timestamp>1636455598</timestamp>
      <ignoredMessage code="0"></ignoredMessage>
    </scrobble>
    </scrobbles>
    </lfm>
    INFO:root:Status(status='playing', file='/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Black Session/01 Yann Tiersen - Sur le fil.flac', artist='Yann Tiersen', albumartist='Yann Tiersen', album='Black Session', discnumber='1', tracknumber='1', title='Sur le fil', date='1999-10', duration='187', musicbrainz_trackid='e9ab1801-a2ea-452c-82ee-dc18d8cca858', cur_time=datetime.datetime(2021, 11, 9, 11, 4, 5, 792868))
    INFO:root:Sending now playing for lastfm
  3. No. There's one block code for each service I use on my inifile.

I noticed though that if I comment out the parameter format_xml = yes the logs show errors, but intringuily it scrobbles correctly (just once, as expected). Here is the log of that second situation:

INFO:root:Status(status='playing', file='/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Tout Est Calme/01 Plus au sud.flac', artist='Yann Tiersen', albumartist='Yann Tiersen', album='Tout est calme', discnumber='1', tracknumber='1', title='Plus au sud', date='1999-03-29', duration='182', musicbrainz_trackid='9f342af1-982d-4c26-9f61-3ac258957a83', cur_time=datetime.datetime(2021, 11, 9, 10, 38, 4, 718094))
INFO:root:Sending now playing for lastfm
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Plus au sud', 'album': 'Tout est calme', 'trackNumber': '1', 'duration': '182', 'mbid': '9f342af1-982d-4c26-9f61-3ac258957a83', 'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'aad45cfd56f4864dc07a139d80d99b1f', 'format': 'json'}
INFO:root:{"nowplaying":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"track":{"corrected":"0","#text":"Plus au sud"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"album":{"corrected":"0","#text":"Tout est calme"}}}
INFO:root:Sending now playing for librefm
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Plus au sud', 'album': 'Tout est calme', 'trackNumber': '1', 'duration': '182', 'mbid': '9f342af1-982d-4c26-9f61-3ac258957a83', 'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'e44ec8e29a263447b2c3229fe3011f31', 'format': 'json'}
INFO:root:{"nowplaying":{"track":{"#text":"Plus au sud","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"ignoredMessage":{"#text":"","code":"0"}}}
INFO:root:Sending now playing for listenbrainz
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Plus au sud', 'album': 'Tout est calme', 'trackNumber': '1', 'duration': '182', 'mbid': '9f342af1-982d-4c26-9f61-3ac258957a83', 'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '60a3c4eced9b743b523f88a8abf2978f', 'format': 'json'}
ERROR:root:Ignoring error.
Traceback (most recent call last):
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 115, in send_req
    with ur.urlopen(api_req, up.urlencode(params, encoding='utf-8').encode()) as f:
  File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/usr/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 500: INTERNAL SERVER ERROR
INFO:root:Status(status='playing', file='/run/media/myuser/Home/myuser/Áudio/Músicas/Lossless/U-Z/Yann Tiersen/Yann Tiersen - 1999 - Tout Est Calme/02 Les Grandes Marées.flac', artist='Yann Tiersen', albumartist='Yann Tiersen', album='Tout est calme', discnumber='1', tracknumber='2', title='Les Grandes Marées', date='1999-03-29', duration='218', musicbrainz_trackid='eba1a9a9-1810-41f1-8cc9-2a00dda0a68c', cur_time=datetime.datetime(2021, 11, 9, 10, 41, 6, 941305))
INFO:root:Sending now playing for lastfm
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Les Grandes Marées', 'album': 'Tout est calme', 'trackNumber': '2', 'duration': '218', 'mbid': 'eba1a9a9-1810-41f1-8cc9-2a00dda0a68c', 'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '07b197c49bb729f15535914676076c00', 'format': 'json'}
INFO:root:{"nowplaying":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"track":{"corrected":"0","#text":"Les Grandes Marées"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"album":{"corrected":"0","#text":"Tout est calme"}}}
INFO:root:Scrobbling previous tracks for lastfm
INFO:root:{'sk': '-sJaBh8zQEszFk8sScIDkm8UgJPGKQUn', 'artist[0]': 'Yann Tiersen', 'track[0]': 'Plus au sud', 'timestamp[0]': '1636454284', 'album[0]': 'Tout est calme', 'trackNumber[0]': '1', 'mbid[0]': '9f342af1-982d-4c26-9f61-3ac258957a83', 'duration[0]': '182', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': 'f135a7d82a08cf3f64591f470aca207e', 'format': 'json'}
INFO:root:{"scrobbles":{"scrobble":{"artist":{"corrected":"0","#text":"Yann Tiersen"},"album":{"corrected":"0","#text":"Tout est calme"},"track":{"corrected":"0","#text":"Plus au sud"},"ignoredMessage":{"code":"0","#text":""},"albumArtist":{"corrected":"0","#text":""},"timestamp":"1636454284"},"@attr":{"ignored":0,"accepted":1}}}
INFO:root:Sending now playing for librefm
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Les Grandes Marées', 'album': 'Tout est calme', 'trackNumber': '2', 'duration': '218', 'mbid': 'eba1a9a9-1810-41f1-8cc9-2a00dda0a68c', 'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': 'fb63a26cbb9f761cb5f5e5c1668667fe', 'format': 'json'}
INFO:root:{"nowplaying":{"track":{"#text":"Les Grandes Mar\u00e9es","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"ignoredMessage":{"#text":"","code":"0"}}}
INFO:root:Scrobbling previous tracks for librefm
INFO:root:{'sk': '7fb10139d7f9e17f9691d2555f2001ef', 'artist[0]': 'Yann Tiersen', 'track[0]': 'Plus au sud', 'timestamp[0]': '1636454284', 'album[0]': 'Tout est calme', 'trackNumber[0]': '1', 'mbid[0]': '9f342af1-982d-4c26-9f61-3ac258957a83', 'duration[0]': '182', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '5097c7cfefd2574fa181167ac145ccce', 'format': 'json'}
INFO:root:{"scrobbles":{"scrobble":{"track":{"#text":"Plus au sud","corrected":"0"},"artist":{"#text":"Yann Tiersen","corrected":"0"},"album":{"#text":"Tout est calme","corrected":"0"},"albumArtist":{"#text":"","corrected":"0"},"timestamp":"1636454284","ignoredMessage":{"#text":"","code":"0"}},"@attr":{"accepted":"1","ignored":"0"}}}
INFO:root:Sending now playing for listenbrainz
INFO:root:{'artist': 'Yann Tiersen', 'track': 'Les Grandes Marées', 'album': 'Tout est calme', 'trackNumber': '2', 'duration': '218', 'mbid': 'eba1a9a9-1810-41f1-8cc9-2a00dda0a68c', 'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.updateNowPlaying', 'api_sig': '8de7ea0d526960e989728863953a729a', 'format': 'json'}
ERROR:root:Ignoring error.
Traceback (most recent call last):
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 115, in send_req
    with ur.urlopen(api_req, up.urlencode(params, encoding='utf-8').encode()) as f:
  File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/usr/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 500: INTERNAL SERVER ERROR
INFO:root:Scrobbling previous tracks for listenbrainz
INFO:root:{'sk': '\\x39343231666136633762303061396338396164373536623534333432396135386664383065626563', 'artist[0]': 'Yann Tiersen', 'track[0]': 'Plus au sud', 'timestamp[0]': '1636454284', 'album[0]': 'Tout est calme', 'trackNumber[0]': '1', 'mbid[0]': '9f342af1-982d-4c26-9f61-3ac258957a83', 'duration[0]': '182', 'api_key': '3f427fc05464646ddf068ca2b02fbb6c', 'method': 'track.scrobble', 'api_sig': '8f5d87ca33c7cb659b0f21365a10db41', 'format': 'json'}
ERROR:root:Scrobbling failed
Traceback (most recent call last):
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 344, in update_scrobble_state
    scrobbler.scrobble(scrobbles[i:i + SCROBBLE_BATCH_SIZE])
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 203, in scrobble
    send_req(self.api_url,
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 125, in send_req
    raise e
  File "/home/myuser/.local/bin/cmus_status_scrobbler.py", line 115, in send_req
    with ur.urlopen(api_req, up.urlencode(params, encoding='utf-8').encode()) as f:
  File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/usr/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: BAD REQUEST

By the way, to avoid any possibility of errors I'm always removing the sqlite3 file before doing any new tests, so that a new one is created each time and I know for sure that there's no old tracks being scrobbled by mistake.

I also delete the logs before doing any tests, just to be sure.

And, well... I noticed that it's becoming a bit too complicated. No trouble at all if you can't (or won't) go ahead with all this debbuging thing, ok?

vjeranc commented 2 years ago

It's most definitely bugs on listenbrainz. Scrobbling script is extremely simple.

It's just:

  1. send now playing request
  2. given a sequence of (play-pause-stopped) events figure out what needs to be scrobbled
  3. send a scrobble request (there's stuff inbetween, like storing the event sequence, synchronizing between multiple processes, mapping data from status line input params to request params, batching scrobble requests if more than 50 tracks, all very straightforward).

It's weird that with now_playing = no you lose both scrobbles.

I tried it out on my machine and I noticed that now_playing = yes creates a scrobble immediately on the now_playing request. This seems to be listenbrainz side. I guess we should report that as a bug, because the track just started playing.

With now_playing = no, I get only one scrobble.

You have to leave format_xml because then track.scrobble method will not work on listenbrainz server (server crashes).

The only way to fix all of these bugs is to go on tickets.metabrainz.org and report the bad behavior.

alscaldas commented 2 years ago

Ok, thank you very much!

I'll copy these logs and paste and open a new ticker using them on metabrainz.

vjeranc commented 2 years ago

@alscaldas Looks like there are some fixes incoming https://github.com/metabrainz/listenbrainz-server/pull/1799

I'll go through the code again and see if some changes I made previously are necessary.

Although I'm not sure if scrobbling twice is fixed here.

hrueschwein commented 1 year ago

I'm facing the same behavior. Unfortunately, it can scrobble tracks even more than two times! For example, on this page there are tracks that were listened only one time.

I think this depends on pauses.

vjeranc commented 1 year ago

@dikey0ficial , it depends on the now_playing request sent to listenbrainz.

If you're scrobbling to librefm or lastfm, you will notice that they do not have duplicate scrobbles (even though same cmus-status-scrobbler code is used for all).

Listenbrainz code is open:

https://github.com/metabrainz/listenbrainz-server/blob/218d5139a417e1e43e75c06668258e6b6a0cefec/listenbrainz/webserver/views/api_compat.py#L92-L95

Look here, obviously, their compat server does a record_listens on track.updatenowplaying and track.scrobble.

Why and how do they do it? I have no idea.

But you are correct, when you pause, I only store that pause event in local sqlite.

When you unpause (press play), track.updatenowplaying is sent to listenbrainz, and they decide to do a scrobble, instead of just showing it as "Now playing" on their website.

vjeranc commented 1 year ago

https://github.com/metabrainz/listenbrainz-server/pull/2424

I've created a PR here after skimming through the listenbrainz-server code.

It looks like there's a type mismatch (due to Python being untyped) and somehow the code still runs through this mismatch (a str is passed, instead of an int).

hrueschwein commented 1 year ago

If you're scrobbling to librefm or lastfm, you will notice that they do not have duplicate scrobbles (even though same cmus-status-scrobbler code is used for all).

Just looked to lastfm — yes, there aren't any duplicates, so problem is on Listenbrainz' part.

Thank you very much for your quick reaction! =)

dertuxmalwieder commented 1 year ago

This issue is annoying, just when I wanted to slowly migrate over to ListenBrainz. CC'ing myself...

hrueschwein commented 1 year ago

Good news: eight hours ago PR with bugfix was merged, so issue would disappear soon.

dertuxmalwieder commented 1 year ago

Soon. I hope they'll hurry!

dertuxmalwieder commented 1 year ago

Still happening, it seems.

vjeranc commented 1 year ago

putting now_playing = no will prevent it, because the server interprets now_playing as a scrobble (or at least the old version before that PR).

dertuxmalwieder commented 1 year ago

Ah, I misunderstood it then. So "now_playing = no" equals Last.fm's "Scrobbling now", but it will still publish the track after it's finished?

Thank you, I'll try that!

vjeranc commented 1 year ago

@dertuxmalwieder @dikey0ficial

I've just scrobbled with now_playing = yes and it just happens once.

I guess my server fix was deployed.