|
|
@ -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) |
|
|
|