From cb90f56523f9543d72d81330c811b636321dee4b Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:31:20 +0000 Subject: [PATCH 1/6] Fix extras (userData) for Playlist Currently is trying to add to track object rather than Track.extras --- wavelink/tracks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 8751dcf2..384f3a27 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -582,7 +582,7 @@ def track_extras(self, **attrs: object) -> None: """ for track in self.tracks: for name, value in attrs.items(): - setattr(track, name, value) + setattr(track.extras, name, value) class PlaylistInfo: From 0f7c768a4fb95ee70a251925d6b438e12cde239d Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:15:24 +0000 Subject: [PATCH 2/6] Add bool to avoid breaking change Add bool to avoid breaking change --- wavelink/tracks.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 384f3a27..2e0eadc9 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -555,7 +555,7 @@ def __contains__(self, item: Playable) -> bool: def pop(self, index: int = -1) -> Playable: return self.tracks.pop(index) - def track_extras(self, **attrs: object) -> None: + def track_extras(self, *, extras: bool = False, **attrs: object) -> None: """Method which sets attributes to all :class:`Playable` in this playlist, with the provided keyword arguments. This is useful when you need to attach state to your :class:`Playable`, E.g. create a requester attribute. @@ -567,6 +567,8 @@ def track_extras(self, **attrs: object) -> None: Parameters ---------- + extras: bool + True sets data in track.extras and False to track. Default is False. **attrs The keyword arguments to set as attribute name=value on each :class:`Playable`. @@ -581,8 +583,9 @@ def track_extras(self, **attrs: object) -> None: print(track.requester) """ for track in self.tracks: + target = track.extras if extras else track for name, value in attrs.items(): - setattr(track.extras, name, value) + setattr(target, name, value) class PlaylistInfo: From f41a57171f1ce8c9e850acb8d2169afa5a4e5ea3 Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Fri, 19 Jan 2024 21:02:59 +0000 Subject: [PATCH 3/6] Change to Playlist.extras property Keep track_extras method as is and implement Playlist.extras to mirror Track.extras. Applies to all tracks in Playlist. --- wavelink/tracks.py | 52 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 2e0eadc9..17e6ea67 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -555,7 +555,7 @@ def __contains__(self, item: Playable) -> bool: def pop(self, index: int = -1) -> Playable: return self.tracks.pop(index) - def track_extras(self, *, extras: bool = False, **attrs: object) -> None: + def track_extras(self, **attrs: object) -> None: """Method which sets attributes to all :class:`Playable` in this playlist, with the provided keyword arguments. This is useful when you need to attach state to your :class:`Playable`, E.g. create a requester attribute. @@ -583,10 +583,56 @@ def track_extras(self, *, extras: bool = False, **attrs: object) -> None: print(track.requester) """ for track in self.tracks: - target = track.extras if extras else track for name, value in attrs.items(): - setattr(target, name, value) + setattr(track, name, value) + @property + def extras(self) -> ExtrasNamespace: + """Property returning a :class:`~wavelink.ExtrasNamespace` of extras for this :class:`Playlist`. + + You can set this property with a :class:`dict` of valid :class:`str` keys to any valid ``JSON`` value, + or a :class:`~wavelink.ExtrasNamespace`. + + If a dict is passed, it will be converted into an :class:`~wavelink.ExtrasNamespace`, + which can be converted back to a dict with dict(...). Additionally, you can also use list or tuple on + :class:`~wavelink.ExtrasNamespace`. + + The extras dict will be sent to Lavalink as the ``userData`` field for each track in the playlist. + + + .. warning:: + + This is only available when using Lavalink 4+ (**Non BETA**) versions. + + + Examples + -------- + + .. code:: python + + playlist: wavelink.Playable = wavelink.Playable.search("QUERY") + playlist.extras = {"requester_id": 1234567890} + + # later... + print(playlist.extras.requester_id) + # or + print(dict(playlist.extras)["requester_id"]) + + + .. versionadded:: 3.2.0 + """ + return self._extras + + @extras.setter + def extras(self, __value: ExtrasNamespace | dict[str, Any]) -> None: + if isinstance(__value, ExtrasNamespace): + self._extras = __value + else: + self._extras = ExtrasNamespace(__value) + + for track in self.tracks: + for name, value in dict(self._extras).items(): + setattr(track, name, value) class PlaylistInfo: """The wavelink PlaylistInfo container class. From d35eb6c1ab532662931d3b0f53d49350be583d10 Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Fri, 19 Jan 2024 21:04:42 +0000 Subject: [PATCH 4/6] Update docs --- wavelink/tracks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 17e6ea67..7d585754 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -610,7 +610,7 @@ def extras(self) -> ExtrasNamespace: .. code:: python - playlist: wavelink.Playable = wavelink.Playable.search("QUERY") + playlist: wavelink.Search = wavelink.Playable.search("QUERY") playlist.extras = {"requester_id": 1234567890} # later... From 99a3c5e5ee0f0979ec5441274f0dfe921c46228f Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Fri, 19 Jan 2024 21:05:33 +0000 Subject: [PATCH 5/6] black format --- wavelink/tracks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 7d585754..3fba22f0 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -629,11 +629,12 @@ def extras(self, __value: ExtrasNamespace | dict[str, Any]) -> None: self._extras = __value else: self._extras = ExtrasNamespace(__value) - + for track in self.tracks: for name, value in dict(self._extras).items(): setattr(track, name, value) + class PlaylistInfo: """The wavelink PlaylistInfo container class. From 110fbfad7d6ccf80d5f7e8bc9e5a6e6f741d5988 Mon Sep 17 00:00:00 2001 From: chillymosh <86857777+chillymosh@users.noreply.github.com> Date: Sat, 3 Feb 2024 14:14:34 +0000 Subject: [PATCH 6/6] Cleanup docs Cleanup docs --- wavelink/tracks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/wavelink/tracks.py b/wavelink/tracks.py index 3fba22f0..78a5b6d8 100644 --- a/wavelink/tracks.py +++ b/wavelink/tracks.py @@ -567,8 +567,6 @@ def track_extras(self, **attrs: object) -> None: Parameters ---------- - extras: bool - True sets data in track.extras and False to track. Default is False. **attrs The keyword arguments to set as attribute name=value on each :class:`Playable`.