Skip to content

Commit 7e9f7fc

Browse files
authored
Improve ListenBrainz error handling and simplify playlist handling (#5480)
Fixes #5459
2 parents 9345103 + b9c6ee2 commit 7e9f7fc

File tree

2 files changed

+50
-39
lines changed

2 files changed

+50
-39
lines changed

beetsplug/listenbrainz.py

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,6 @@ def get_playlists_createdfor(self, username):
148148
return self._make_request(url)
149149

150150
def get_listenbrainz_playlists(self):
151-
"""Returns a list of playlists created by ListenBrainz."""
152-
import re
153-
154151
resp = self.get_playlists_createdfor(self.username)
155152
playlists = resp.get("playlists")
156153
listenbrainz_playlists = []
@@ -159,35 +156,32 @@ def get_listenbrainz_playlists(self):
159156
playlist_info = playlist.get("playlist")
160157
if playlist_info.get("creator") == "listenbrainz":
161158
title = playlist_info.get("title")
162-
match = re.search(
163-
r"(Missed Recordings of \d{4}|Discoveries of \d{4})", title
159+
self._log.debug(f"Playlist title: {title}")
160+
playlist_type = (
161+
"Exploration" if "Exploration" in title else "Jams"
164162
)
165-
if "Exploration" in title:
166-
playlist_type = "Exploration"
167-
elif "Jams" in title:
168-
playlist_type = "Jams"
169-
elif match:
170-
playlist_type = match.group(1)
171-
else:
172-
playlist_type = None
173-
if "week of " in title:
163+
if "week of" in title:
174164
date_str = title.split("week of ")[1].split(" ")[0]
175165
date = datetime.datetime.strptime(
176166
date_str, "%Y-%m-%d"
177167
).date()
178168
else:
179-
date = None
169+
continue
180170
identifier = playlist_info.get("identifier")
181171
id = identifier.split("/")[-1]
182-
if playlist_type in ["Jams", "Exploration"]:
183-
listenbrainz_playlists.append(
184-
{
185-
"type": playlist_type,
186-
"date": date,
187-
"identifier": id,
188-
"title": title,
189-
}
190-
)
172+
listenbrainz_playlists.append(
173+
{"type": playlist_type, "date": date, "identifier": id}
174+
)
175+
listenbrainz_playlists = sorted(
176+
listenbrainz_playlists, key=lambda x: x["type"]
177+
)
178+
listenbrainz_playlists = sorted(
179+
listenbrainz_playlists, key=lambda x: x["date"], reverse=True
180+
)
181+
for playlist in listenbrainz_playlists:
182+
self._log.debug(
183+
f'Playlist: {playlist["type"]} - {playlist["date"]}'
184+
)
191185
return listenbrainz_playlists
192186

193187
def get_playlist(self, identifier):
@@ -199,17 +193,20 @@ def get_tracks_from_playlist(self, playlist):
199193
"""This function returns a list of tracks in the playlist."""
200194
tracks = []
201195
for track in playlist.get("playlist").get("track"):
196+
identifier = track.get("identifier")
197+
if isinstance(identifier, list):
198+
identifier = identifier[0]
199+
202200
tracks.append(
203201
{
204-
"artist": track.get("creator"),
205-
"identifier": track.get("identifier").split("/")[-1],
202+
"artist": track.get("creator", "Unknown artist"),
203+
"identifier": identifier.split("/")[-1],
206204
"title": track.get("title"),
207205
}
208206
)
209207
return self.get_track_info(tracks)
210208

211209
def get_track_info(self, tracks):
212-
"""Returns a list of track info."""
213210
track_info = []
214211
for track in tracks:
215212
identifier = track.get("identifier")
@@ -242,25 +239,37 @@ def get_track_info(self, tracks):
242239
)
243240
return track_info
244241

245-
def get_weekly_playlist(self, index):
246-
"""Returns a list of weekly playlists based on the index."""
242+
def get_weekly_playlist(self, playlist_type, most_recent=True):
243+
# Fetch all playlists
247244
playlists = self.get_listenbrainz_playlists()
248-
playlist = self.get_playlist(playlists[index].get("identifier"))
249-
self._log.info(f"Getting {playlist.get('playlist').get('title')}")
245+
# Filter playlists by type
246+
filtered_playlists = [
247+
p for p in playlists if p["type"] == playlist_type
248+
]
249+
# Sort playlists by date in descending order
250+
sorted_playlists = sorted(
251+
filtered_playlists, key=lambda x: x["date"], reverse=True
252+
)
253+
# Select the most recent or older playlist based on the most_recent flag
254+
selected_playlist = (
255+
sorted_playlists[0] if most_recent else sorted_playlists[1]
256+
)
257+
self._log.debug(
258+
f"Selected playlist: {selected_playlist['type']} "
259+
f"- {selected_playlist['date']}"
260+
)
261+
# Fetch and return tracks from the selected playlist
262+
playlist = self.get_playlist(selected_playlist.get("identifier"))
250263
return self.get_tracks_from_playlist(playlist)
251264

252265
def get_weekly_exploration(self):
253-
"""Returns a list of weekly exploration."""
254-
return self.get_weekly_playlist(0)
266+
return self.get_weekly_playlist("Exploration", most_recent=True)
255267

256268
def get_weekly_jams(self):
257-
"""Returns a list of weekly jams."""
258-
return self.get_weekly_playlist(1)
269+
return self.get_weekly_playlist("Jams", most_recent=True)
259270

260271
def get_last_weekly_exploration(self):
261-
"""Returns a list of weekly exploration."""
262-
return self.get_weekly_playlist(3)
272+
return self.get_weekly_playlist("Exploration", most_recent=False)
263273

264274
def get_last_weekly_jams(self):
265-
"""Returns a list of weekly jams."""
266-
return self.get_weekly_playlist(3)
275+
return self.get_weekly_playlist("Jams", most_recent=False)

docs/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ New features:
258258

259259
Bug fixes:
260260

261+
* Improve ListenBrainz error handling.
262+
:bug:`5459`
261263
* :doc:`/plugins/deezer`: Improve requests error handling.
262264
* :doc:`/plugins/lastimport`: Improve error handling in the `process_tracks` function and enable it to be used with other plugins.
263265
* :doc:`/plugins/spotify`: Improve handling of ConnectionError.

0 commit comments

Comments
 (0)