Browse Source

Absolute import some circular dependencies to appease Python 3.4.

pull/447/head
Rapptz 8 years ago
parent
commit
79a49f9145
  1. 5
      discord/abc.py
  2. 5
      discord/calls.py
  3. 24
      discord/channel.py
  4. 21
      discord/client.py
  5. 5
      discord/embeds.py
  6. 4
      discord/emoji.py
  7. 13
      discord/gateway.py
  8. 28
      discord/guild.py
  9. 8
      discord/http.py
  10. 8
      discord/member.py
  11. 31
      discord/message.py
  12. 4
      discord/object.py
  13. 38
      discord/state.py
  14. 2
      discord/voice_client.py

5
discord/abc.py

@ -34,6 +34,11 @@ from .iterators import LogsFromIterator
from .context_managers import Typing from .context_managers import Typing
from .errors import ClientException, NoMoreMessages from .errors import ClientException, NoMoreMessages
import discord.message
import discord.iterators
import discord.context_managers
import discord.errors
class Snowflake(metaclass=abc.ABCMeta): class Snowflake(metaclass=abc.ABCMeta):
__slots__ = () __slots__ = ()

5
discord/calls.py

@ -24,8 +24,9 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from . import utils
import datetime import datetime
import discord.utils
from .enums import GuildRegion, try_enum from .enums import GuildRegion, try_enum
from .member import VoiceState from .member import VoiceState
@ -47,7 +48,7 @@ class CallMessage:
def __init__(self, message, **kwargs): def __init__(self, message, **kwargs):
self.message = message self.message = message
self.ended_timestamp = utils.parse_time(kwargs.get('ended_timestamp')) self.ended_timestamp = discord.utils.parse_time(kwargs.get('ended_timestamp'))
self.participants = kwargs.get('participants') self.participants = kwargs.get('participants')
@property @property

24
discord/channel.py

@ -23,7 +23,6 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from . import utils, abc
from .permissions import Permissions, PermissionOverwrite from .permissions import Permissions, PermissionOverwrite
from .enums import ChannelType, try_enum from .enums import ChannelType, try_enum
from collections import namedtuple from collections import namedtuple
@ -32,6 +31,9 @@ from .role import Role
from .user import User from .user import User
from .member import Member from .member import Member
import discord.utils
import discord.abc
import copy import copy
import asyncio import asyncio
@ -103,7 +105,7 @@ class CommonGuildChannel(Hashable):
their default values in the :attr:`Guild.roles` attribute.""" their default values in the :attr:`Guild.roles` attribute."""
ret = [] ret = []
for overwrite in filter(lambda o: o.type == 'role', self._overwrites): for overwrite in filter(lambda o: o.type == 'role', self._overwrites):
role = utils.get(self.guild.roles, id=overwrite.id) role = discord.utils.get(self.guild.roles, id=overwrite.id)
if role is None: if role is None:
continue continue
@ -125,7 +127,7 @@ class CommonGuildChannel(Hashable):
@property @property
def created_at(self): def created_at(self):
"""Returns the channel's creation time in UTC.""" """Returns the channel's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
def overwrites_for(self, obj): def overwrites_for(self, obj):
"""Returns the channel-specific overwrites for a member or a role. """Returns the channel-specific overwrites for a member or a role.
@ -178,7 +180,7 @@ class CommonGuildChannel(Hashable):
if ow.type == 'role': if ow.type == 'role':
# accidentally quadratic # accidentally quadratic
target = utils.find(lambda r: r.id == ow.id, self.server.roles) target = discord.utils.find(lambda r: r.id == ow.id, self.server.roles)
elif ow.type == 'member': elif ow.type == 'member':
target = self.server.get_member(ow.id) target = self.server.get_member(ow.id)
@ -299,7 +301,7 @@ class CommonGuildChannel(Hashable):
""" """
yield from self._state.http.delete_channel(self.id) yield from self._state.http.delete_channel(self.id)
class TextChannel(abc.MessageChannel, CommonGuildChannel): class TextChannel(discord.abc.MessageChannel, CommonGuildChannel):
"""Represents a Discord guild text channel. """Represents a Discord guild text channel.
Supported Operations: Supported Operations:
@ -479,7 +481,7 @@ class VoiceChannel(CommonGuildChannel):
data = yield from self._state.http.edit_channel(self.id, **options) data = yield from self._state.http.edit_channel(self.id, **options)
self._update(self.guild, data) self._update(self.guild, data)
class DMChannel(abc.MessageChannel, Hashable): class DMChannel(discord.abc.MessageChannel, Hashable):
"""Represents a Discord direct message channel. """Represents a Discord direct message channel.
Supported Operations: Supported Operations:
@ -523,7 +525,7 @@ class DMChannel(abc.MessageChannel, Hashable):
@property @property
def created_at(self): def created_at(self):
"""Returns the direct message channel's creation time in UTC.""" """Returns the direct message channel's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
def permissions_for(self, user=None): def permissions_for(self, user=None):
"""Handles permission resolution for a :class:`User`. """Handles permission resolution for a :class:`User`.
@ -554,7 +556,7 @@ class DMChannel(abc.MessageChannel, Hashable):
base.manage_messages = False base.manage_messages = False
return base return base
class GroupChannel(abc.MessageChannel, Hashable): class GroupChannel(discord.abc.MessageChannel, Hashable):
"""Represents a Discord group channel. """Represents a Discord group channel.
Supported Operations: Supported Operations:
@ -597,14 +599,14 @@ class GroupChannel(abc.MessageChannel, Hashable):
self._update_group(data) self._update_group(data)
def _update_group(self, data): def _update_group(self, data):
owner_id = utils._get_as_snowflake(data, 'owner_id') owner_id = discord.utils._get_as_snowflake(data, 'owner_id')
self.icon = data.get('icon') self.icon = data.get('icon')
self.name = data.get('name') self.name = data.get('name')
if owner_id == self.me.id: if owner_id == self.me.id:
self.owner = self.me self.owner = self.me
else: else:
self.owner = utils.find(lambda u: u.id == owner_id, self.recipients) self.owner = discord.utils.find(lambda u: u.id == owner_id, self.recipients)
def _get_destination(self): def _get_destination(self):
return self.id, None return self.id, None
@ -629,7 +631,7 @@ class GroupChannel(abc.MessageChannel, Hashable):
@property @property
def created_at(self): def created_at(self):
"""Returns the channel's creation time in UTC.""" """Returns the channel's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
def permissions_for(self, user): def permissions_for(self, user):
"""Handles permission resolution for a :class:`User`. """Handles permission resolution for a :class:`User`.

21
discord/client.py

@ -24,20 +24,21 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from . import __version__ as library_version
from .user import User from .user import User
from .invite import Invite from .invite import Invite
from .object import Object from .object import Object
from .errors import * from .errors import *
from .state import ConnectionState
from .permissions import Permissions, PermissionOverwrite from .permissions import Permissions, PermissionOverwrite
from . import utils, compat
from .enums import ChannelType, Status from .enums import ChannelType, Status
from .voice_client import VoiceClient from .voice_client import VoiceClient
from .gateway import * from .gateway import *
from .emoji import Emoji from .emoji import Emoji
from .http import HTTPClient from .http import HTTPClient
import discord.utils
import discord.compat
import discord.state
import asyncio import asyncio
import aiohttp import aiohttp
import websockets import websockets
@ -141,11 +142,11 @@ class Client:
connector = options.pop('connector', None) connector = options.pop('connector', None)
self.http = HTTPClient(connector, loop=self.loop) self.http = HTTPClient(connector, loop=self.loop)
self.connection = ConnectionState(dispatch=self.dispatch, self.connection = discord.state.ConnectionState(dispatch=self.dispatch,
chunker=self.request_offline_members, chunker=self.request_offline_members,
syncer=self._syncer, syncer=self._syncer,
http=self.http, loop=self.loop, http=self.http, loop=self.loop,
**options) **options)
self._closed = asyncio.Event(loop=self.loop) self._closed = asyncio.Event(loop=self.loop)
self._is_logged_in = asyncio.Event(loop=self.loop) self._is_logged_in = asyncio.Event(loop=self.loop)
@ -287,7 +288,7 @@ class Client:
getattr(self, handler)(*args, **kwargs) getattr(self, handler)(*args, **kwargs)
if hasattr(self, method): if hasattr(self, method):
compat.create_task(self._run_event(method, *args, **kwargs), loop=self.loop) discord.compat.create_task(self._run_event(method, *args, **kwargs), loop=self.loop)
@asyncio.coroutine @asyncio.coroutine
def on_error(self, event_method, *args, **kwargs): def on_error(self, event_method, *args, **kwargs):
@ -937,7 +938,7 @@ class Client:
avatar = self.user.avatar avatar = self.user.avatar
else: else:
if avatar_bytes is not None: if avatar_bytes is not None:
avatar = utils._bytes_to_base64_data(avatar_bytes) avatar = discord.utils._bytes_to_base64_data(avatar_bytes)
else: else:
avatar = None avatar = None

5
discord/embeds.py

@ -26,8 +26,9 @@ DEALINGS IN THE SOFTWARE.
import datetime import datetime
import discord.utils
from .colour import Colour from .colour import Colour
from . import utils
class _EmptyEmbed: class _EmptyEmbed:
def __bool__(self): def __bool__(self):
@ -128,7 +129,7 @@ class Embed:
pass pass
try: try:
self._timestamp = utils.parse_time(data['timestamp']) self._timestamp = discord.utils.parse_time(data['timestamp'])
except KeyError: except KeyError:
pass pass

4
discord/emoji.py

@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE.
import asyncio import asyncio
from collections import namedtuple from collections import namedtuple
from . import utils import discord.utils
from .mixins import Hashable from .mixins import Hashable
PartialEmoji = namedtuple('PartialEmoji', 'id name') PartialEmoji = namedtuple('PartialEmoji', 'id name')
@ -106,7 +106,7 @@ class Emoji(Hashable):
@property @property
def created_at(self): def created_at(self):
"""Returns the emoji's creation time in UTC.""" """Returns the emoji's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
@property @property
def url(self): def url(self):

13
discord/gateway.py

@ -28,7 +28,10 @@ import sys
import websockets import websockets
import asyncio import asyncio
import aiohttp import aiohttp
from . import utils, compat
import discord.utils
import discord.compat
from .enums import Status, try_enum from .enums import Status, try_enum
from .game import Game from .game import Game
from .errors import GatewayNotFound, ConnectionClosed, InvalidArgument from .errors import GatewayNotFound, ConnectionClosed, InvalidArgument
@ -70,7 +73,7 @@ class KeepAliveHandler(threading.Thread):
data = self.get_payload() data = self.get_payload()
log.debug(self.msg.format(data)) log.debug(self.msg.format(data))
coro = self.ws.send_as_json(data) coro = self.ws.send_as_json(data)
f = compat.run_coroutine_threadsafe(coro, loop=self.ws.loop) f = discord.compat.run_coroutine_threadsafe(coro, loop=self.ws.loop)
try: try:
# block until sending is complete # block until sending is complete
f.result() f.result()
@ -400,7 +403,7 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
@asyncio.coroutine @asyncio.coroutine
def send_as_json(self, data): def send_as_json(self, data):
try: try:
yield from super().send(utils.to_json(data)) yield from super().send(discord.utils.to_json(data))
except websockets.exceptions.ConnectionClosed as e: except websockets.exceptions.ConnectionClosed as e:
if not self._can_handle_close(e.code): if not self._can_handle_close(e.code):
raise ConnectionClosed(e) from e raise ConnectionClosed(e) from e
@ -428,7 +431,7 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
} }
} }
sent = utils.to_json(payload) sent = discord.utils.to_json(payload)
log.debug('Sending "{}" to change status'.format(sent)) log.debug('Sending "{}" to change status'.format(sent))
yield from self.send(sent) yield from self.send(sent)
@ -510,7 +513,7 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol):
@asyncio.coroutine @asyncio.coroutine
def send_as_json(self, data): def send_as_json(self, data):
yield from self.send(utils.to_json(data)) yield from self.send(discord.utils.to_json(data))
@classmethod @classmethod
@asyncio.coroutine @asyncio.coroutine

28
discord/guild.py

@ -27,7 +27,9 @@ DEALINGS IN THE SOFTWARE.
import copy import copy
import asyncio import asyncio
from . import utils
import discord.utils
from .role import Role from .role import Role
from .member import Member, VoiceState from .member import Member, VoiceState
from .emoji import Emoji from .emoji import Emoji
@ -224,7 +226,7 @@ class Guild(Hashable):
for mdata in guild.get('members', []): for mdata in guild.get('members', []):
roles = [self.default_role] roles = [self.default_role]
for role_id in mdata['roles']: for role_id in mdata['roles']:
role = utils.find(lambda r: r.id == role_id, self.roles) role = discord.utils.find(lambda r: r.id == role_id, self.roles)
if role is not None: if role is not None:
roles.append(role) roles.append(role)
@ -235,8 +237,8 @@ class Guild(Hashable):
self._sync(guild) self._sync(guild)
self.large = None if member_count is None else self._member_count >= 250 self.large = None if member_count is None else self._member_count >= 250
self.owner_id = utils._get_as_snowflake(guild, 'owner_id') self.owner_id = discord.utils._get_as_snowflake(guild, 'owner_id')
self.afk_channel = self.get_channel(utils._get_as_snowflake(guild, 'afk_channel_id')) self.afk_channel = self.get_channel(discord.utils._get_as_snowflake(guild, 'afk_channel_id'))
for obj in guild.get('voice_states', []): for obj in guild.get('voice_states', []):
self._update_voice_state(obj, int(obj['channel_id'])) self._update_voice_state(obj, int(obj['channel_id']))
@ -293,15 +295,15 @@ class Guild(Hashable):
"""Returns a :class:`Member` with the given ID. If not found, returns None.""" """Returns a :class:`Member` with the given ID. If not found, returns None."""
return self._members.get(user_id) return self._members.get(user_id)
@utils.cached_slot_property('_default_role') @discord.utils.cached_slot_property('_default_role')
def default_role(self): def default_role(self):
"""Gets the @everyone role that all members have by default.""" """Gets the @everyone role that all members have by default."""
return utils.find(lambda r: r.is_everyone, self.roles) return discord.utils.find(lambda r: r.is_everyone, self.roles)
@utils.cached_slot_property('_default_channel') @discord.utils.cached_slot_property('_default_channel')
def default_channel(self): def default_channel(self):
"""Gets the default :class:`Channel` for the guild.""" """Gets the default :class:`Channel` for the guild."""
return utils.find(lambda c: c.is_default, self.channels) return discord.utils.find(lambda c: c.is_default, self.channels)
@property @property
def owner(self): def owner(self):
@ -330,7 +332,7 @@ class Guild(Hashable):
@property @property
def created_at(self): def created_at(self):
"""Returns the guild's creation time in UTC.""" """Returns the guild's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
@property @property
def role_hierarchy(self): def role_hierarchy(self):
@ -378,14 +380,14 @@ class Guild(Hashable):
# do the actual lookup and return if found # do the actual lookup and return if found
# if it isn't found then we'll do a full name lookup below. # if it isn't found then we'll do a full name lookup below.
result = utils.get(members, name=name[:-5], discriminator=potential_discriminator) result = discord.utils.get(members, name=name[:-5], discriminator=potential_discriminator)
if result is not None: if result is not None:
return result return result
def pred(m): def pred(m):
return m.nick == name or m.name == name return m.nick == name or m.name == name
return utils.find(pred, members) return discord.utils.find(pred, members)
@asyncio.coroutine @asyncio.coroutine
@ -469,7 +471,7 @@ class Guild(Hashable):
icon = self.icon icon = self.icon
else: else:
if icon_bytes is not None: if icon_bytes is not None:
icon = utils._bytes_to_base64_data(icon_bytes) icon = discord.utils._bytes_to_base64_data(icon_bytes)
else: else:
icon = None icon = None
@ -659,7 +661,7 @@ class Guild(Hashable):
An error occurred creating an emoji. An error occurred creating an emoji.
""" """
img = utils._bytes_to_base64_data(image) img = discord.utils._bytes_to_base64_data(image)
data = yield from self._state.http.create_custom_emoji(self.id, name, img) data = yield from self._state.http.create_custom_emoji(self.id, name, img)
return self._state.store_emoji(self, data) return self._state.store_emoji(self, data)

8
discord/http.py

@ -36,7 +36,9 @@ from random import randint as random_integer
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from .errors import HTTPException, Forbidden, NotFound, LoginFailure, GatewayNotFound from .errors import HTTPException, Forbidden, NotFound, LoginFailure, GatewayNotFound
from . import utils, __version__ from . import __version__
import discord.utils
@asyncio.coroutine @asyncio.coroutine
def json_or_text(response): def json_or_text(response):
@ -97,7 +99,7 @@ class HTTPClient:
# some checking if it's a JSON request # some checking if it's a JSON request
if 'json' in kwargs: if 'json' in kwargs:
headers['Content-Type'] = 'application/json' headers['Content-Type'] = 'application/json'
kwargs['data'] = utils.to_json(kwargs.pop('json')) kwargs['data'] = discord.utils.to_json(kwargs.pop('json'))
kwargs['headers'] = headers kwargs['headers'] = headers
with (yield from lock): with (yield from lock):
@ -244,7 +246,7 @@ class HTTPClient:
if embed: if embed:
payload['embed'] = embed payload['embed'] = embed
form.add_field('payload_json', utils.to_json(payload)) form.add_field('payload_json', discord.utils.to_json(payload))
form.add_field('file', buffer, filename=filename, content_type='application/octet-stream') form.add_field('file', buffer, filename=filename, content_type='application/octet-stream')
return self.post(url, data=form, bucket='messages:' + str(guild_id)) return self.post(url, data=form, bucket='messages:' + str(guild_id))

8
discord/member.py

@ -26,10 +26,10 @@ DEALINGS IN THE SOFTWARE.
import asyncio import asyncio
import discord.utils
from .user import User from .user import User
from .game import Game from .game import Game
from .permissions import Permissions from .permissions import Permissions
from . import utils
from .enums import Status, ChannelType, try_enum from .enums import Status, ChannelType, try_enum
from .colour import Colour from .colour import Colour
@ -143,7 +143,7 @@ class Member:
def __init__(self, *, data, guild, state): def __init__(self, *, data, guild, state):
self._state = state self._state = state
self._user = state.store_user(data['user']) self._user = state.store_user(data['user'])
self.joined_at = utils.parse_time(data.get('joined_at')) self.joined_at = discord.utils.parse_time(data.get('joined_at'))
self.roles = data.get('roles', []) self.roles = data.get('roles', [])
self.status = Status.offline self.status = Status.offline
game = data.get('game', {}) game = data.get('game', {})
@ -239,7 +239,7 @@ class Member:
return True return True
for role in message.role_mentions: for role in message.role_mentions:
has_role = utils.get(self.roles, id=role.id) is not None has_role = discord.utils.get(self.roles, id=role.id) is not None
if has_role: if has_role:
return True return True
@ -439,7 +439,7 @@ class Member:
Adding roles failed. Adding roles failed.
""" """
new_roles = utils._unique(r for s in (self.roles[1:], roles) for r in s) new_roles = discord.utils._unique(r for s in (self.roles[1:], roles) for r in s)
yield from self.edit(roles=new_roles) yield from self.edit(roles=new_roles)
@asyncio.coroutine @asyncio.coroutine

31
discord/message.py

@ -27,10 +27,11 @@ DEALINGS IN THE SOFTWARE.
import asyncio import asyncio
import re import re
import discord.utils
import discord.abc
from .user import User from .user import User
from .reaction import Reaction from .reaction import Reaction
from .emoji import Emoji from .emoji import Emoji
from . import utils, abc
from .object import Object from .object import Object
from .calls import CallMessage from .calls import CallMessage
from .enums import MessageType, try_enum from .enums import MessageType, try_enum
@ -132,7 +133,7 @@ class Message:
def _add_reaction(self, data): def _add_reaction(self, data):
emoji = self._state.reaction_emoji(data['emoji']) emoji = self._state.reaction_emoji(data['emoji'])
reaction = utils.find(lambda r: r.emoji == emoji, self.reactions) reaction = discord.utils.find(lambda r: r.emoji == emoji, self.reactions)
is_me = data['me'] = int(data['user_id']) == self._state.self_id is_me = data['me'] = int(data['user_id']) == self._state.self_id
if reaction is None: if reaction is None:
@ -147,7 +148,7 @@ class Message:
def _remove_reaction(self, data): def _remove_reaction(self, data):
emoji = self._state.reaction_emoji(data['emoji']) emoji = self._state.reaction_emoji(data['emoji'])
reaction = utils.find(lambda r: r.emoji == emoji, self.reactions) reaction = discord.utils.find(lambda r: r.emoji == emoji, self.reactions)
if reaction is None: if reaction is None:
# already removed? # already removed?
@ -173,7 +174,7 @@ class Message:
except KeyError: except KeyError:
continue continue
self._try_patch(data, 'edited_timestamp', utils.parse_time) self._try_patch(data, 'edited_timestamp', discord.utils.parse_time)
self._try_patch(data, 'author', self._state.store_user) self._try_patch(data, 'author', self._state.store_user)
self._try_patch(data, 'pinned', bool) self._try_patch(data, 'pinned', bool)
self._try_patch(data, 'mention_everyone', bool) self._try_patch(data, 'mention_everyone', bool)
@ -207,7 +208,7 @@ class Message:
self.role_mentions = [] self.role_mentions = []
if self.guild is not None: if self.guild is not None:
for role_id in role_mentions: for role_id in role_mentions:
role = utils.get(self.guild.roles, id=role_id) role = discord.utils.get(self.guild.roles, id=role_id)
if role is not None: if role is not None:
self.role_mentions.append(role) self.role_mentions.append(role)
@ -224,7 +225,7 @@ class Message:
if uid == self.author.id: if uid == self.author.id:
participants.append(self.author) participants.append(self.author)
else: else:
user = utils.find(lambda u: u.id == uid, self.mentions) user = discord.utils.find(lambda u: u.id == uid, self.mentions)
if user is not None: if user is not None:
participants.append(user) participants.append(user)
@ -236,7 +237,7 @@ class Message:
"""Optional[:class:`Guild`]: The guild that the message belongs to, if applicable.""" """Optional[:class:`Guild`]: The guild that the message belongs to, if applicable."""
return getattr(self.channel, 'guild', None) return getattr(self.channel, 'guild', None)
@utils.cached_slot_property('_cs_raw_mentions') @discord.utils.cached_slot_property('_cs_raw_mentions')
def raw_mentions(self): def raw_mentions(self):
"""A property that returns an array of user IDs matched with """A property that returns an array of user IDs matched with
the syntax of <@user_id> in the message content. the syntax of <@user_id> in the message content.
@ -246,28 +247,28 @@ class Message:
""" """
return [int(x) for x in re.findall(r'<@!?([0-9]+)>', self.content)] return [int(x) for x in re.findall(r'<@!?([0-9]+)>', self.content)]
@utils.cached_slot_property('_cs_raw_channel_mentions') @discord.utils.cached_slot_property('_cs_raw_channel_mentions')
def raw_channel_mentions(self): def raw_channel_mentions(self):
"""A property that returns an array of channel IDs matched with """A property that returns an array of channel IDs matched with
the syntax of <#channel_id> in the message content. the syntax of <#channel_id> in the message content.
""" """
return [int(x) for x in re.findall(r'<#([0-9]+)>', self.content)] return [int(x) for x in re.findall(r'<#([0-9]+)>', self.content)]
@utils.cached_slot_property('_cs_raw_role_mentions') @discord.utils.cached_slot_property('_cs_raw_role_mentions')
def raw_role_mentions(self): def raw_role_mentions(self):
"""A property that returns an array of role IDs matched with """A property that returns an array of role IDs matched with
the syntax of <@&role_id> in the message content. the syntax of <@&role_id> in the message content.
""" """
return [int(x) for x in re.findall(r'<@&([0-9]+)>', self.content)] return [int(x) for x in re.findall(r'<@&([0-9]+)>', self.content)]
@utils.cached_slot_property('_cs_channel_mentions') @discord.utils.cached_slot_property('_cs_channel_mentions')
def channel_mentions(self): def channel_mentions(self):
if self.guild is None: if self.guild is None:
return [] return []
it = filter(None, map(lambda m: self.guild.get_channel(m), self.raw_channel_mentions)) it = filter(None, map(lambda m: self.guild.get_channel(m), self.raw_channel_mentions))
return utils._unique(it) return discord.utils._unique(it)
@utils.cached_slot_property('_cs_clean_content') @discord.utils.cached_slot_property('_cs_clean_content')
def clean_content(self): def clean_content(self):
"""A property that returns the content in a "cleaned up" """A property that returns the content in a "cleaned up"
manner. This basically means that mentions are transformed manner. This basically means that mentions are transformed
@ -332,7 +333,7 @@ class Message:
self.channel.is_private = True self.channel.is_private = True
return return
if isinstance(self.channel, abc.GuildChannel): if isinstance(self.channel, discord.abc.GuildChannel):
self.guild = self.channel.guild self.guild = self.channel.guild
found = self.guild.get_member(self.author.id) found = self.guild.get_member(self.author.id)
if found is not None: if found is not None:
@ -341,9 +342,9 @@ class Message:
@property @property
def created_at(self): def created_at(self):
"""Returns the message's creation time in UTC.""" """Returns the message's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)
@utils.cached_slot_property('_cs_system_content') @discord.utils.cached_slot_property('_cs_system_content')
def system_content(self): def system_content(self):
"""A property that returns the content that is rendered """A property that returns the content that is rendered
regardless of the :attr:`Message.type`. regardless of the :attr:`Message.type`.

4
discord/object.py

@ -23,7 +23,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from . import utils import discord.utils
class Object: class Object:
"""Represents a generic Discord object. """Represents a generic Discord object.
@ -51,4 +51,4 @@ class Object:
@property @property
def created_at(self): def created_at(self):
"""Returns the snowflake's creation time in UTC.""" """Returns the snowflake's creation time in UTC."""
return utils.snowflake_time(self.id) return discord.utils.snowflake_time(self.id)

38
discord/state.py

@ -33,10 +33,12 @@ from .message import Message
from .channel import * from .channel import *
from .member import Member from .member import Member
from .role import Role from .role import Role
from . import utils, compat
from .enums import Status, ChannelType, try_enum from .enums import Status, ChannelType, try_enum
from .calls import GroupCall from .calls import GroupCall
import discord.utils
import discord.compat
from collections import deque, namedtuple from collections import deque, namedtuple
import copy, enum, math import copy, enum, math
import datetime import datetime
@ -180,7 +182,7 @@ class ConnectionState:
self._private_channels_by_user.pop(channel.recipient.id, None) self._private_channels_by_user.pop(channel.recipient.id, None)
def _get_message(self, msg_id): def _get_message(self, msg_id):
return utils.find(lambda m: m.id == msg_id, self.messages) return discord.utils.find(lambda m: m.id == msg_id, self.messages)
def _add_guild_from_data(self, guild): def _add_guild_from_data(self, guild):
guild = Guild(data=guild, state=self.ctx) guild = Guild(data=guild, state=self.ctx)
@ -251,7 +253,7 @@ class ConnectionState:
factory, _ = _channel_factory(pm['type']) factory, _ = _channel_factory(pm['type'])
self._add_private_channel(factory(me=self.user, data=pm, state=self.ctx)) self._add_private_channel(factory(me=self.user, data=pm, state=self.ctx))
compat.create_task(self._delay_ready(), loop=self.loop) discord.compat.create_task(self._delay_ready(), loop=self.loop)
def parse_resumed(self, data): def parse_resumed(self, data):
self.dispatch('resumed') self.dispatch('resumed')
@ -317,7 +319,7 @@ class ConnectionState:
self.dispatch('reaction_remove', reaction, user) self.dispatch('reaction_remove', reaction, user)
def parse_presence_update(self, data): def parse_presence_update(self, data):
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id')) guild = self._get_guild(discord.utils._get_as_snowflake(data, 'guild_id'))
if guild is None: if guild is None:
return return
@ -342,7 +344,7 @@ class ConnectionState:
self.user = User(state=self.ctx, data=data) self.user = User(state=self.ctx, data=data)
def parse_channel_delete(self, data): def parse_channel_delete(self, data):
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id')) guild = self._get_guild(discord.utils._get_as_snowflake(data, 'guild_id'))
channel_id = int(data['id']) channel_id = int(data['id'])
if guild is not None: if guild is not None:
channel = guild.get_channel(channel_id) channel = guild.get_channel(channel_id)
@ -365,7 +367,7 @@ class ConnectionState:
self.dispatch('channel_update', old_channel, channel) self.dispatch('channel_update', old_channel, channel)
return return
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id')) guild = self._get_guild(discord.utils._get_as_snowflake(data, 'guild_id'))
if guild is not None: if guild is not None:
channel = guild.get_channel(channel_id) channel = guild.get_channel(channel_id)
if channel is not None: if channel is not None:
@ -380,7 +382,7 @@ class ConnectionState:
channel = factory(me=self.user, data=data, state=self.ctx) channel = factory(me=self.user, data=data, state=self.ctx)
self._add_private_channel(channel) self._add_private_channel(channel)
else: else:
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id')) guild = self._get_guild(discord.utils._get_as_snowflake(data, 'guild_id'))
if guild is not None: if guild is not None:
channel = factory(guild=guild, state=self.ctx, data=data) channel = factory(guild=guild, state=self.ctx, data=data)
guild._add_channel(channel) guild._add_channel(channel)
@ -406,7 +408,7 @@ class ConnectionState:
def _make_member(self, guild, data): def _make_member(self, guild, data):
roles = [guild.default_role] roles = [guild.default_role]
for roleid in data.get('roles', []): for roleid in data.get('roles', []):
role = utils.get(guild.roles, id=roleid) role = discord.utils.get(guild.roles, id=roleid)
if role is not None: if role is not None:
roles.append(role) roles.append(role)
@ -514,7 +516,7 @@ class ConnectionState:
# since we're not waiting for 'useful' READY we'll just # since we're not waiting for 'useful' READY we'll just
# do the chunk request here # do the chunk request here
compat.create_task(self._chunk_and_dispatch(guild, unavailable), loop=self.loop) discord.compat.create_task(self._chunk_and_dispatch(guild, unavailable), loop=self.loop)
return return
# Dispatch available if newly available # Dispatch available if newly available
@ -561,7 +563,7 @@ class ConnectionState:
guild = self._get_guild(int(data['guild_id'])) guild = self._get_guild(int(data['guild_id']))
if guild is not None: if guild is not None:
user_id = data.get('user', {}).get('id') user_id = data.get('user', {}).get('id')
member = utils.get(guild.members, id=user_id) member = discord.utils.get(guild.members, id=user_id)
if member is not None: if member is not None:
self.dispatch('member_ban', member) self.dispatch('member_ban', member)
@ -583,7 +585,7 @@ class ConnectionState:
guild = self._get_guild(int(data['guild_id'])) guild = self._get_guild(int(data['guild_id']))
if guild is not None: if guild is not None:
role_id = int(data['role_id']) role_id = int(data['role_id'])
role = utils.find(lambda r: r.id == role_id, guild.roles) role = discord.utils.find(lambda r: r.id == role_id, guild.roles)
try: try:
guild._remove_role(role) guild._remove_role(role)
except ValueError: except ValueError:
@ -596,7 +598,7 @@ class ConnectionState:
if guild is not None: if guild is not None:
role_data = data['role'] role_data = data['role']
role_id = int(role_data['id']) role_id = int(role_data['id'])
role = utils.find(lambda r: r.id == role_id, guild.roles) role = discord.utils.find(lambda r: r.id == role_id, guild.roles)
if role is not None: if role is not None:
old_role = copy.copy(role) old_role = copy.copy(role)
role._update(role_data) role._update(role_data)
@ -615,8 +617,8 @@ class ConnectionState:
self.process_listeners(ListenerType.chunk, guild, len(members)) self.process_listeners(ListenerType.chunk, guild, len(members))
def parse_voice_state_update(self, data): def parse_voice_state_update(self, data):
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id')) guild = self._get_guild(discord.utils._get_as_snowflake(data, 'guild_id'))
channel_id = utils._get_as_snowflake(data, 'channel_id') channel_id = discord.utils._get_as_snowflake(data, 'channel_id')
if guild is not None: if guild is not None:
if int(data['user_id']) == self.user.id: if int(data['user_id']) == self.user.id:
voice = self._get_voice_client(guild.id) voice = self._get_voice_client(guild.id)
@ -636,13 +638,13 @@ class ConnectionState:
channel = self.get_channel(int(data['channel_id'])) channel = self.get_channel(int(data['channel_id']))
if channel is not None: if channel is not None:
member = None member = None
user_id = utils._get_as_snowflake(data, 'user_id') user_id = discord.utils._get_as_snowflake(data, 'user_id')
if isinstance(channel, DMChannel): if isinstance(channel, DMChannel):
member = channel.recipient member = channel.recipient
elif isinstance(channel, TextChannel): elif isinstance(channel, TextChannel):
member = channel.guild.get_member(user_id) member = channel.guild.get_member(user_id)
elif isinstance(channel, GroupChannel): elif isinstance(channel, GroupChannel):
member = utils.find(lambda x: x.id == user_id, channel.recipients) member = discord.utils.find(lambda x: x.id == user_id, channel.recipients)
if member is not None: if member is not None:
timestamp = datetime.datetime.utcfromtimestamp(data.get('timestamp')) timestamp = datetime.datetime.utcfromtimestamp(data.get('timestamp'))
@ -673,12 +675,12 @@ class ConnectionState:
elif isinstance(channel, TextChannel): elif isinstance(channel, TextChannel):
return channel.guild.get_member(user_id) return channel.guild.get_member(user_id)
elif isinstance(channel, GroupChannel): elif isinstance(channel, GroupChannel):
return utils.find(lambda m: m.id == user_id, channel.recipients) return discord.utils.find(lambda m: m.id == user_id, channel.recipients)
else: else:
return None return None
def _get_reaction_emoji(self, data): def _get_reaction_emoji(self, data):
emoji_id = utils._get_as_snowflake(data, 'id') emoji_id = discord.utils._get_as_snowflake(data, 'id')
if not emoji_id: if not emoji_id:
return data['name'] return data['name']

2
discord/voice_client.py

@ -61,7 +61,7 @@ try:
except ImportError: except ImportError:
has_nacl = False has_nacl = False
from . import utils, opus from . import opus
from .gateway import * from .gateway import *
from .errors import ClientException, InvalidArgument, ConnectionClosed from .errors import ClientException, InvalidArgument, ConnectionClosed

Loading…
Cancel
Save