From 25d72680cb608fb8827b54f2eb0d404d52cde754 Mon Sep 17 00:00:00 2001 From: Pratyush Desai Date: Wed, 19 Nov 2025 19:19:21 +0530 Subject: [PATCH 1/2] Added more commands added 2 commands that show the top tracks and albums played by a user. There are some formatting decisions that will need to be taken. Also the client library for the API seems exhausted. Missing some key things. Yet to use a constructor the initialize an instance of the client when plugin is called rather than under each function. Signed-off-by: Pratyush Desai --- plugin.py | 113 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 16 deletions(-) diff --git a/plugin.py b/plugin.py index 2c4d543..3b4a589 100644 --- a/plugin.py +++ b/plugin.py @@ -35,14 +35,15 @@ from supybot.commands import * from supybot.i18n import PluginInternationalization -_ = PluginInternationalization('ListenBrainz') +_ = PluginInternationalization("ListenBrainz") class ListenBrainz(callbacks.Plugin): """Fetches scrobbled metadata for users.""" + threaded = True - @wrap(["something"]) + @wrap(["text"]) def np(self, irc, msg, args, user): """ @@ -50,31 +51,111 @@ class ListenBrainz(callbacks.Plugin): """ client = liblistenbrainz.ListenBrainz() listen = client.get_playing_now(user) - if listen is not None: - response = ( - f"{user} is currently playing: \x02{listen.track_name}\x0F " - f"from \x02{listen.release_name}\x0F by \x02{listen.artist_name}\x0F " - f"at \x02{listen.listened_at}\x0F") - irc.reply(response) - else: + if listen is None: response = f"{user} doen't seem to be listening to anything" - irc.reply(response) + else: + response = ( + f"{user} is currently playing: \x02{listen.track_name}\x0f " + f"from \x02{listen.release_name}\x0f by \x02{listen.artist_name}\x0f " + f"at \x02{listen.listened_at}\x0f" + ) + irc.reply(response) - @wrap(["something"]) - def listencount(self,irc,msg, args, user): + @wrap(["text"]) + def listencount(self, irc, msg, args, user): """ Announces total number of tracks scrobbled by """ client = liblistenbrainz.ListenBrainz() count = client.get_user_listen_count(user) - if count is not None: - response = f"{user} has recorded listening to {count} tracks" - else: + if count is None: response = "Nothing recorded" + else: + response = (f"{user} has recorded listening to {count} tracks") irc.reply(response) - + @wrap(["text"]) + def tracks(self, irc, msg, args, user): + """ + + 's top listened to album releases. + """ + client = liblistenbrainz.ListenBrainz() + try: + data = client.get_user_recordings(user) + payload = data.get("payload", {}) + + except Exception as e: + irc.error(f"An unexpected error occurred: {e}", Raise=True) + return + + total_tracks = payload.get("total_recording_count", "N/A") + recordings = payload.get("recordings", []) + + if not recordings: + irc.reply(f"{user} has no recorded tracks.") + return + + top_tracks = recordings[:3] + + header = f"{user}'s Top {len(top_tracks)} Tracks (Total unique tracks: {total_tracks:,}):" + irc.reply(header) + + for i, track in enumerate(top_tracks): + rank = i + 1 + artist = track.get("artist_name", "Unknown Artist") + track_name = track.get("track_name", "Unknown Track") + release_name = track.get("release_name") + count = track.get("listen_count", 0) + + release_info = f" from \x02{release_name}\x0f" if release_name else "" + + response = ( + f"({count:,} listens): " + f"\x02{track_name}\x0f{release_info} by " + f"\x02{artist}\x0f" + ) + irc.reply(response) + + @wrap(["text"]) + def albums(self, irc, msg, args, user): + """ + + Announces the top albums/releases listened to by . + """ + client = liblistenbrainz.ListenBrainz() + try: + data = client.get_user_releases(user) + payload = data.get("payload", {}) + except Exception as e: + irc.error(f"An unexpected error occurred: {e}", Raise=True) + return + + total_albums = payload.get("total_release_count", "N/A") + releases = payload.get("releases", []) + + if not releases: + irc.reply(f"{user} has no recorded releases.") + return + + top_releases = releases[:3] + + header = f"{user}'s Top {len(top_releases)} Releases (Total unique releases: {total_albums:,}):" + irc.reply(header) + + for i, release in enumerate(top_releases): + rank = i + 1 + artist = release.get("artist_name", "Unknown Artist") + release_name = release.get("release_name", "Unknown Album") + count = release.get("listen_count", 0) + + response = ( + f"({count:,} listens): " + f"\x02{release_name}\x0f by " + f"\x02{artist}\x0f" + ) + irc.reply(response) Class = ListenBrainz From a675fc8c18b8b1c3042afc80cc039d751fce6b93 Mon Sep 17 00:00:00 2001 From: Pratyush Desai Date: Fri, 21 Nov 2025 00:56:59 +0530 Subject: [PATCH 2/2] Fix Instance Creation fix client instance initialization. Signed-off-by: Pratyush Desai --- plugin.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/plugin.py b/plugin.py index 3b4a589..c985e83 100644 --- a/plugin.py +++ b/plugin.py @@ -40,17 +40,21 @@ _ = PluginInternationalization("ListenBrainz") class ListenBrainz(callbacks.Plugin): """Fetches scrobbled metadata for users.""" - threaded = True + def __init__(self, irc): + self.__parent = super(ListenBrainz, self) + self.__parent.__init__(irc) + self.client = liblistenbrainz.ListenBrainz() + self.DISPLAY_LIMIT = 3 + @wrap(["text"]) def np(self, irc, msg, args, user): """ Announces the track currently being played by . """ - client = liblistenbrainz.ListenBrainz() - listen = client.get_playing_now(user) + listen = self.client.get_playing_now(user) if listen is None: response = f"{user} doen't seem to be listening to anything" else: @@ -61,47 +65,44 @@ class ListenBrainz(callbacks.Plugin): ) irc.reply(response) + @wrap(["text"]) def listencount(self, irc, msg, args, user): """ Announces total number of tracks scrobbled by """ - client = liblistenbrainz.ListenBrainz() - count = client.get_user_listen_count(user) + count = self.client.get_user_listen_count(user) if count is None: response = "Nothing recorded" else: response = (f"{user} has recorded listening to {count} tracks") irc.reply(response) + @wrap(["text"]) def tracks(self, irc, msg, args, user): """ 's top listened to album releases. """ - client = liblistenbrainz.ListenBrainz() try: - data = client.get_user_recordings(user) + data = self.client.get_user_recordings(user) payload = data.get("payload", {}) except Exception as e: irc.error(f"An unexpected error occurred: {e}", Raise=True) return - + total_tracks = payload.get("total_recording_count", "N/A") recordings = payload.get("recordings", []) - if not recordings: irc.reply(f"{user} has no recorded tracks.") return - top_tracks = recordings[:3] - + top_tracks = recordings[:DISPLAY_LIMIT] header = f"{user}'s Top {len(top_tracks)} Tracks (Total unique tracks: {total_tracks:,}):" irc.reply(header) - for i, track in enumerate(top_tracks): rank = i + 1 artist = track.get("artist_name", "Unknown Artist") @@ -118,15 +119,15 @@ class ListenBrainz(callbacks.Plugin): ) irc.reply(response) + @wrap(["text"]) def albums(self, irc, msg, args, user): """ Announces the top albums/releases listened to by . """ - client = liblistenbrainz.ListenBrainz() try: - data = client.get_user_releases(user) + data = self.client.get_user_releases(user) payload = data.get("payload", {}) except Exception as e: irc.error(f"An unexpected error occurred: {e}", Raise=True) @@ -139,7 +140,7 @@ class ListenBrainz(callbacks.Plugin): irc.reply(f"{user} has no recorded releases.") return - top_releases = releases[:3] + top_releases = releases[:DISPLAY_LIMIT] header = f"{user}'s Top {len(top_releases)} Releases (Total unique releases: {total_albums:,}):" irc.reply(header)