Add Activity.buttons
This commit is contained in:
		| @@ -22,7 +22,10 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
| DEALINGS IN THE SOFTWARE. | ||||
| """ | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| import datetime | ||||
| from typing import List, TYPE_CHECKING | ||||
|  | ||||
| from .asset import Asset | ||||
| from .enums import ActivityType, try_enum | ||||
| @@ -71,6 +74,9 @@ type: int | ||||
| sync_id: str | ||||
| session_id: str | ||||
| flags: int | ||||
| buttons: list[dict] | ||||
|     label: str (max: 32) | ||||
|     url: str (max: 512) | ||||
|  | ||||
| There are also activity flags which are mostly uninteresting for the library atm. | ||||
|  | ||||
| @@ -84,6 +90,15 @@ t.ActivityFlags = { | ||||
| } | ||||
| """ | ||||
|  | ||||
| if TYPE_CHECKING: | ||||
|     from .types.activity import ( | ||||
|         ActivityTimestamps, | ||||
|         ActivityParty, | ||||
|         ActivityAssets, | ||||
|         ActivityButton, | ||||
|     ) | ||||
|  | ||||
|  | ||||
| class BaseActivity: | ||||
|     """The base activity that all user-settable activities inherit from. | ||||
|     A user-settable activity is one that can be used in :meth:`Client.change_presence`. | ||||
| @@ -102,6 +117,7 @@ class BaseActivity: | ||||
|  | ||||
|     .. versionadded:: 1.3 | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ('_created_at',) | ||||
|  | ||||
|     def __init__(self, **kwargs): | ||||
| @@ -116,6 +132,7 @@ class BaseActivity: | ||||
|         if self._created_at is not None: | ||||
|             return datetime.datetime.utcfromtimestamp(self._created_at / 1000) | ||||
|  | ||||
|  | ||||
| class Activity(BaseActivity): | ||||
|     """Represents an activity in Discord. | ||||
|  | ||||
| @@ -164,27 +181,51 @@ class Activity(BaseActivity): | ||||
|  | ||||
|         - ``id``: A string representing the party ID. | ||||
|         - ``size``: A list of up to two integer elements denoting (current_size, maximum_size). | ||||
|     buttons: List[:class:`dict`] | ||||
|         An list of dictionaries representing custom buttons shown in a rich presence. | ||||
|         Each dictionary contains the following keys: | ||||
|  | ||||
|         - ``label``: A string representing the text shown on the button. | ||||
|         - ``url``: A string representing the URL opened upon clicking the button. | ||||
|  | ||||
|         .. versionadded:: 2.0 | ||||
|  | ||||
|     emoji: Optional[:class:`PartialEmoji`] | ||||
|         The emoji that belongs to this activity. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ('state', 'details', '_created_at', 'timestamps', 'assets', 'party', | ||||
|                  'flags', 'sync_id', 'session_id', 'type', 'name', 'url', | ||||
|                  'application_id', 'emoji') | ||||
|     __slots__ = ( | ||||
|         'state', | ||||
|         'details', | ||||
|         '_created_at', | ||||
|         'timestamps', | ||||
|         'assets', | ||||
|         'party', | ||||
|         'flags', | ||||
|         'sync_id', | ||||
|         'session_id', | ||||
|         'type', | ||||
|         'name', | ||||
|         'url', | ||||
|         'application_id', | ||||
|         'emoji', | ||||
|         'buttons', | ||||
|     ) | ||||
|  | ||||
|     def __init__(self, **kwargs): | ||||
|         super().__init__(**kwargs) | ||||
|         self.state = kwargs.pop('state', None) | ||||
|         self.details = kwargs.pop('details', None) | ||||
|         self.timestamps = kwargs.pop('timestamps', {}) | ||||
|         self.assets = kwargs.pop('assets', {}) | ||||
|         self.party = kwargs.pop('party', {}) | ||||
|         self.timestamps: ActivityTimestamps = kwargs.pop('timestamps', {}) | ||||
|         self.assets: ActivityAssets = kwargs.pop('assets', {}) | ||||
|         self.party: ActivityParty = kwargs.pop('party', {}) | ||||
|         self.application_id = _get_as_snowflake(kwargs, 'application_id') | ||||
|         self.name = kwargs.pop('name', None) | ||||
|         self.url = kwargs.pop('url', None) | ||||
|         self.flags = kwargs.pop('flags', 0) | ||||
|         self.sync_id = kwargs.pop('sync_id', None) | ||||
|         self.session_id = kwargs.pop('session_id', None) | ||||
|         self.buttons: List[ActivityButton] = kwargs.pop('buttons', []) | ||||
|  | ||||
|         activity_type = kwargs.pop('type', -1) | ||||
|         self.type = activity_type if isinstance(activity_type, ActivityType) else try_enum(ActivityType, activity_type) | ||||
| @@ -269,6 +310,7 @@ class Activity(BaseActivity): | ||||
|             return None | ||||
|         else: | ||||
|             return Asset.BASE + f'/app-assets/{self.application_id}/{small_image}.png' | ||||
|  | ||||
|     @property | ||||
|     def large_image_text(self): | ||||
|         """Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable.""" | ||||
| @@ -321,7 +363,7 @@ class Game(BaseActivity): | ||||
|         self.name = name | ||||
|  | ||||
|         try: | ||||
|             timestamps = extra['timestamps'] | ||||
|             timestamps: ActivityTimestamps = extra['timestamps'] | ||||
|         except KeyError: | ||||
|             self._start = 0 | ||||
|             self._end = 0 | ||||
| @@ -365,11 +407,13 @@ class Game(BaseActivity): | ||||
|         if self._end: | ||||
|             timestamps['end'] = self._end | ||||
|  | ||||
|         # fmt: off | ||||
|         return { | ||||
|             'type': ActivityType.playing.value, | ||||
|             'name': str(self.name), | ||||
|             'timestamps': timestamps | ||||
|         } | ||||
|         # fmt: on | ||||
|  | ||||
|     def __eq__(self, other): | ||||
|         return isinstance(other, Game) and other.name == self.name | ||||
| @@ -380,6 +424,7 @@ class Game(BaseActivity): | ||||
|     def __hash__(self): | ||||
|         return hash(self.name) | ||||
|  | ||||
|  | ||||
| class Streaming(BaseActivity): | ||||
|     """A slimmed down version of :class:`Activity` that represents a Discord streaming status. | ||||
|  | ||||
| @@ -433,8 +478,8 @@ class Streaming(BaseActivity): | ||||
|         self.name = extra.pop('details', name) | ||||
|         self.game = extra.pop('state', None) | ||||
|         self.url = url | ||||
|         self.details = extra.pop('details', self.name) # compatibility | ||||
|         self.assets = extra.pop('assets', {}) | ||||
|         self.details = extra.pop('details', self.name)  # compatibility | ||||
|         self.assets: ActivityAssets = extra.pop('assets', {}) | ||||
|  | ||||
|     @property | ||||
|     def type(self): | ||||
| @@ -466,12 +511,14 @@ class Streaming(BaseActivity): | ||||
|             return name[7:] if name[:7] == 'twitch:' else None | ||||
|  | ||||
|     def to_dict(self): | ||||
|         # fmt: off | ||||
|         ret = { | ||||
|             'type': ActivityType.streaming.value, | ||||
|             'name': str(self.name), | ||||
|             'url': str(self.url), | ||||
|             'assets': self.assets | ||||
|         } | ||||
|         # fmt: on | ||||
|         if self.details: | ||||
|             ret['details'] = self.details | ||||
|         return ret | ||||
| @@ -485,6 +532,7 @@ class Streaming(BaseActivity): | ||||
|     def __hash__(self): | ||||
|         return hash(self.name) | ||||
|  | ||||
|  | ||||
| class Spotify: | ||||
|     """Represents a Spotify listening activity from Discord. This is a special case of | ||||
|     :class:`Activity` that makes it easier to work with the Spotify integration. | ||||
| @@ -508,8 +556,7 @@ class Spotify: | ||||
|             Returns the string 'Spotify'. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id', | ||||
|                  '_created_at') | ||||
|     __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id', '_created_at') | ||||
|  | ||||
|     def __init__(self, **data): | ||||
|         self._state = data.pop('state', None) | ||||
| @@ -543,7 +590,7 @@ class Spotify: | ||||
|         """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`. | ||||
|  | ||||
|         There is an alias for this named :attr:`color`""" | ||||
|         return Colour(0x1db954) | ||||
|         return Colour(0x1DB954) | ||||
|  | ||||
|     @property | ||||
|     def color(self): | ||||
| @@ -554,7 +601,7 @@ class Spotify: | ||||
|  | ||||
|     def to_dict(self): | ||||
|         return { | ||||
|             'flags': 48, # SYNC | PLAY | ||||
|             'flags': 48,  # SYNC | PLAY | ||||
|             'name': 'Spotify', | ||||
|             'assets': self._assets, | ||||
|             'party': self._party, | ||||
| @@ -562,7 +609,7 @@ class Spotify: | ||||
|             'session_id': self._session_id, | ||||
|             'timestamps': self._timestamps, | ||||
|             'details': self._details, | ||||
|             'state': self._state | ||||
|             'state': self._state, | ||||
|         } | ||||
|  | ||||
|     @property | ||||
| @@ -571,8 +618,12 @@ class Spotify: | ||||
|         return 'Spotify' | ||||
|  | ||||
|     def __eq__(self, other): | ||||
|         return (isinstance(other, Spotify) and other._session_id == self._session_id | ||||
|                 and other._sync_id == self._sync_id and other.start == self.start) | ||||
|         return ( | ||||
|             isinstance(other, Spotify) | ||||
|             and other._session_id == self._session_id | ||||
|             and other._sync_id == self._sync_id | ||||
|             and other.start == self.start | ||||
|         ) | ||||
|  | ||||
|     def __ne__(self, other): | ||||
|         return not self.__eq__(other) | ||||
| @@ -644,6 +695,7 @@ class Spotify: | ||||
|         """:class:`str`: The party ID of the listening party.""" | ||||
|         return self._party.get('id', '') | ||||
|  | ||||
|  | ||||
| class CustomActivity(BaseActivity): | ||||
|     """Represents a Custom activity from Discord. | ||||
|  | ||||
| @@ -721,7 +773,7 @@ class CustomActivity(BaseActivity): | ||||
|         return o | ||||
|  | ||||
|     def __eq__(self, other): | ||||
|         return (isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji) | ||||
|         return isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji | ||||
|  | ||||
|     def __ne__(self, other): | ||||
|         return not self.__eq__(other) | ||||
|   | ||||
| @@ -78,6 +78,11 @@ class ActivityEmoji(_ActivityEmojiOptional): | ||||
|     name: str | ||||
|  | ||||
|  | ||||
| class ActivityButton(TypedDict): | ||||
|     label: str | ||||
|     url: str | ||||
|  | ||||
|  | ||||
| class _SendableActivityOptional(TypedDict, total=False): | ||||
|     url: Optional[str] | ||||
|  | ||||
| @@ -106,3 +111,4 @@ class Activity(_BaseActivity, total=False): | ||||
|     secrets: ActivitySecrets | ||||
|     session_id: Optional[str] | ||||
|     instance: bool | ||||
|     buttons: List[ActivityButton] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user