aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2016-07-13 00:10:16 -0400
committerRapptz <[email protected]>2016-07-13 00:10:16 -0400
commitddd3fd0a3dcce2d48b2df26377e136f2310809b3 (patch)
tree1db729a099756f89c1e36e448bb05449593d0736
parentAdd stderr arg to create_ffmpeg_player (diff)
downloaddiscord.py-ddd3fd0a3dcce2d48b2df26377e136f2310809b3.tar.xz
discord.py-ddd3fd0a3dcce2d48b2df26377e136f2310809b3.zip
Begin working on gateway v6 changes.
The first batch of changes are related to channel types and group direct messages. Support these first so READY begins parsing.
-rw-r--r--discord/channel.py71
-rw-r--r--discord/enums.py8
-rw-r--r--discord/gateway.py2
-rw-r--r--discord/http.py4
-rw-r--r--discord/state.py7
-rw-r--r--docs/api.rst6
6 files changed, 77 insertions, 21 deletions
diff --git a/discord/channel.py b/discord/channel.py
index 1dc82025..c53a96cf 100644
--- a/discord/channel.py
+++ b/discord/channel.py
@@ -30,6 +30,7 @@ from .enums import ChannelType
from collections import namedtuple
from .mixins import Hashable
from .role import Role
+from .user import User
from .member import Member
Overwrites = namedtuple('Overwrites', 'id allow deny type')
@@ -298,25 +299,69 @@ class PrivateChannel(Hashable):
Attributes
----------
- user : :class:`User`
- The user you are participating with in the private channel.
- id : str
+ recipients: list of :class:`User`
+ The users you are participating with in the private channel.
+ id: str
The private channel ID.
- is_private : bool
+ is_private: bool
``True`` if the channel is a private channel (i.e. PM). ``True`` in this case.
+ type: :class:`ChannelType`
+ The type of private channel.
+ owner: Optional[:class:`User`]
+ The user that owns the private channel. If the channel type is not
+ :attr:`ChannelType.group` then this is always ``None``.
+ icon: Optional[str]
+ The private channel's icon hash. If the channel type is not
+ :attr:`ChannelType.group` then this is always ``None``.
+ name: Optional[str]
+ The private channel's name. If the channel type is not
+ :attr:`ChannelType.group` then this is always ``None``.
"""
- __slots__ = ['user', 'id', 'is_private']
+ __slots__ = ['id', 'is_private', 'recipients', 'type', 'owner', 'icon', 'name']
- def __init__(self, user, id, **kwargs):
- self.user = user
- self.id = id
+ def __init__(self, me, **kwargs):
+ self.recipients = [User(**u) for u in kwargs['recipients']]
+ self.id = kwargs['id']
self.is_private = True
+ self.type = ChannelType(kwargs['type'])
+
+ owner_id = kwargs.get('owner_id')
+ self.owner = None
+ self.icon = kwargs.get('icon')
+ self.name = kwargs.get('name')
+
+ self.recipients = []
+ for data in kwargs['recipients']:
+ to_add = User(**data)
+ if to_add.id == owner_id:
+ self.owner = to_add
+ self.recipients.append(to_add)
+
+ if owner_id == me.id:
+ self.owner = me
def __str__(self):
return 'Direct Message with {0.name}'.format(self.user)
@property
+ def user(self):
+ """A property that returns the first recipient of the private channel.
+
+ This is mainly for compatibility and ease of use with old style private
+ channels that had a single recipient.
+ """
+ return self.recipients[0]
+
+ @property
+ def icon_url(self):
+ """Returns the channel's icon URL if available or an empty string otherwise."""
+ if self.icon is None:
+ return ''
+
+ return 'https://cdn.discordapp.com/channel-icons/{0.id}/{0.icon}.jpg'.format(self)
+
+ @property
def created_at(self):
"""Returns the private channel's creation time in UTC."""
return utils.snowflake_time(self.id)
@@ -332,7 +377,9 @@ class PrivateChannel(Hashable):
- send_tts_messages: You cannot send TTS messages in a PM.
- manage_messages: You cannot delete others messages in a PM.
- - mention_everyone: There is no one to mention in a PM.
+
+ This also handles permissions for :attr:`ChannelType.group` channels
+ such as kicking or mentioning everyone.
Parameters
-----------
@@ -348,7 +395,11 @@ class PrivateChannel(Hashable):
base = Permissions.text()
base.send_tts_messages = False
base.manage_messages = False
- base.mention_everyone = False
+ base.mention_everyone = self.type is ChannelType.group
+
+ if user == self.owner:
+ base.kick_members = True
+
return base
diff --git a/discord/enums.py b/discord/enums.py
index 4666c52f..10a7f60b 100644
--- a/discord/enums.py
+++ b/discord/enums.py
@@ -27,11 +27,13 @@ DEALINGS IN THE SOFTWARE.
from enum import Enum
class ChannelType(Enum):
- text = 'text'
- voice = 'voice'
+ text = 0
+ private = 1
+ voice = 2
+ group = 3
def __str__(self):
- return self.value
+ return self.name
class ServerRegion(Enum):
us_west = 'us-west'
diff --git a/discord/gateway.py b/discord/gateway.py
index 7ba78b07..56e4ba6f 100644
--- a/discord/gateway.py
+++ b/discord/gateway.py
@@ -98,7 +98,7 @@ class VoiceKeepAliveHandler(KeepAliveHandler):
}
class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
- """Implements a WebSocket for Discord's gateway v4.
+ """Implements a WebSocket for Discord's gateway v6.
This is created through :func:`create_main_websocket`. Library
users should never create this manually.
diff --git a/discord/http.py b/discord/http.py
index 192337fe..fabcafd6 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -53,7 +53,7 @@ class HTTPClient:
"""Represents an HTTP client sending HTTP requests to the Discord API."""
BASE = 'https://discordapp.com'
- API_BASE = BASE + '/api'
+ API_BASE = BASE + '/api/v6'
GATEWAY = API_BASE + '/gateway'
USERS = API_BASE + '/users'
ME = USERS + '/@me'
@@ -500,4 +500,4 @@ class HTTPClient:
data = yield from self.get(self.GATEWAY, bucket=_func_())
except HTTPException as e:
raise GatewayNotFound() from e
- return data.get('url') + '?encoding=json&v=5'
+ return data.get('url') + '?encoding=json&v=6'
diff --git a/discord/state.py b/discord/state.py
index 7fc8debc..25988a62 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -205,8 +205,7 @@ class ConnectionState:
servers.append(server)
for pm in data.get('private_channels'):
- self._add_private_channel(PrivateChannel(id=pm['id'],
- user=User(**pm['recipient'])))
+ self._add_private_channel(PrivateChannel(self.user, **pm))
compat.create_task(self._delay_ready(), loop=self.loop)
@@ -303,9 +302,7 @@ class ConnectionState:
is_private = data.get('is_private', False)
channel = None
if is_private:
- recipient = User(**data.get('recipient'))
- pm_id = data.get('id')
- channel = PrivateChannel(id=pm_id, user=recipient)
+ channel = PrivateChannel(self.user, **data)
self._add_private_channel(channel)
else:
server = self._get_server(data.get('guild_id'))
diff --git a/docs/api.rst b/docs/api.rst
index 7d015b63..32014d6b 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -391,6 +391,12 @@ All enumerations are subclasses of `enum`_.
.. attribute:: voice
A voice channel.
+ .. attribute:: private
+
+ A private text channel. Also called a direct message.
+ .. attribute:: group
+
+ A private group text channel.
.. class:: ServerRegion