Browse Source

Rename MessageChannel abc to Messageable.

pull/447/head
Rapptz 8 years ago
parent
commit
d5b616fa11
  1. 57
      discord/abc.py
  2. 27
      discord/channel.py
  3. 19
      discord/ext/commands/context.py
  4. 2
      discord/reaction.py

57
discord/abc.py

@ -466,18 +466,22 @@ class GuildChannel:
raise InvalidArgument('Invalid overwrite type provided.') raise InvalidArgument('Invalid overwrite type provided.')
class MessageChannel(metaclass=abc.ABCMeta): class Messageable(metaclass=abc.ABCMeta):
__slots__ = () __slots__ = ()
@abc.abstractmethod @abc.abstractmethod
def _get_destination(self): def _get_channel(self):
raise NotImplementedError
@abc.abstractmethod
def _get_guild_id(self):
raise NotImplementedError raise NotImplementedError
@asyncio.coroutine @asyncio.coroutine
def send(self, content=None, *, tts=False, embed=None, file=None, filename=None, delete_after=None): def send(self, content=None, *, tts=False, embed=None, file=None, filename=None, delete_after=None):
"""|coro| """|coro|
Sends a message to the channel with the content given. Sends a message to the destination with the content given.
The content must be a type that can convert to a string through ``str(content)``. The content must be a type that can convert to a string through ``str(content)``.
If the content is set to ``None`` (the default), then the ``embed`` parameter must If the content is set to ``None`` (the default), then the ``embed`` parameter must
@ -532,7 +536,8 @@ class MessageChannel(metaclass=abc.ABCMeta):
The message that was sent. The message that was sent.
""" """
channel_id, guild_id = self._get_destination() channel = self._get_channel()
guild_id = self._get_guild_id()
state = self._state state = self._state
content = str(content) if content else None content = str(content) if content else None
if embed is not None: if embed is not None:
@ -547,12 +552,12 @@ class MessageChannel(metaclass=abc.ABCMeta):
except TypeError: except TypeError:
buffer = file buffer = file
data = yield from state.http.send_file(channel_id, buffer, guild_id=guild_id, filename=filename, data = yield from state.http.send_file(channel.id, buffer, guild_id=guild_id, filename=filename,
content=content, tts=tts, embed=embed) content=content, tts=tts, embed=embed)
else: else:
data = yield from state.http.send_message(channel_id, content, guild_id=guild_id, tts=tts, embed=embed) data = yield from state.http.send_message(channel.id, content, guild_id=guild_id, tts=tts, embed=embed)
ret = Message(channel=self, state=state, data=data) ret = Message(channel=channel, state=state, data=data)
if delete_after is not None: if delete_after is not None:
@asyncio.coroutine @asyncio.coroutine
def delete(): def delete():
@ -565,22 +570,27 @@ class MessageChannel(metaclass=abc.ABCMeta):
return ret return ret
@asyncio.coroutine @asyncio.coroutine
def send_typing(self): def trigger_typing(self):
"""|coro| """|coro|
Send a *typing* status to the channel. Triggers a *typing* indicator to the destination.
*Typing* status will go away after 10 seconds, or after a message is sent. *Typing* indicator will go away after 10 seconds, or after a message is sent.
""" """
channel_id, _ = self._get_destination() channel = self._get_channel()
yield from self._state.http.send_typing(channel_id) yield from self._state.http.send_typing(channel.id)
def typing(self): def typing(self):
"""Returns a context manager that allows you to type for an indefinite period of time. """Returns a context manager that allows you to type for an indefinite period of time.
This is useful for denoting long computations in your bot. This is useful for denoting long computations in your bot.
.. note::
This is both a regular context manager and an async context manager.
This means that both ``with`` and ``async with`` work with this.
Example Usage: :: Example Usage: ::
with channel.typing(): with channel.typing():
@ -588,13 +598,13 @@ class MessageChannel(metaclass=abc.ABCMeta):
await channel.send_message('done!') await channel.send_message('done!')
""" """
return Typing(self) return Typing(self._get_channel())
@asyncio.coroutine @asyncio.coroutine
def get_message(self, id): def get_message(self, id):
"""|coro| """|coro|
Retrieves a single :class:`Message` from a channel. Retrieves a single :class:`Message` from the destination.
This can only be used by bot accounts. This can only be used by bot accounts.
@ -618,8 +628,9 @@ class MessageChannel(metaclass=abc.ABCMeta):
Retrieving the message failed. Retrieving the message failed.
""" """
data = yield from self._state.http.get_message(self.id, id) channel = self._get_channel()
return Message(channel=self, state=self._state, data=data) data = yield from self._state.http.get_message(channel.id, id)
return Message(channel=channel, state=self._state, data=data)
@asyncio.coroutine @asyncio.coroutine
def delete_messages(self, messages): def delete_messages(self, messages):
@ -651,9 +662,10 @@ class MessageChannel(metaclass=abc.ABCMeta):
raise ClientException('Can only delete messages in the range of [2, 100]') raise ClientException('Can only delete messages in the range of [2, 100]')
message_ids = [m.id for m in messages] message_ids = [m.id for m in messages]
channel_id, guild_id = self._get_destination() channel = self._get_channel()
guild_id = self._get_guild_id()
yield from self._state.http.delete_messages(channel_id, message_ids, guild_id) yield from self._state.http.delete_messages(channel.id, message_ids, guild_id)
@asyncio.coroutine @asyncio.coroutine
def pins(self): def pins(self):
@ -667,12 +679,13 @@ class MessageChannel(metaclass=abc.ABCMeta):
Retrieving the pinned messages failed. Retrieving the pinned messages failed.
""" """
channel = self._get_channel()
state = self._state state = self._state
data = yield from state.http.pins_from(self.id) data = yield from state.http.pins_from(channel.id)
return [Message(channel=self, state=state, data=m) for m in data] return [Message(channel=channel, state=state, data=m) for m in data]
def history(self, *, limit=100, before=None, after=None, around=None, reverse=None): def history(self, *, limit=100, before=None, after=None, around=None, reverse=None):
"""Return an async iterator that enables receiving the channel's message history. """Return an async iterator that enables receiving the destination's message history.
You must have Read Message History permissions to use this. You must have Read Message History permissions to use this.
@ -734,7 +747,7 @@ class MessageChannel(metaclass=abc.ABCMeta):
if message.author == client.user: if message.author == client.user:
counter += 1 counter += 1
""" """
return LogsFromIterator(self, limit=limit, before=before, after=after, around=around, reverse=reverse) return LogsFromIterator(self._get_channel(), limit=limit, before=before, after=after, around=around, reverse=reverse)
@asyncio.coroutine @asyncio.coroutine
def purge(self, *, limit=100, check=None, before=None, after=None, around=None): def purge(self, *, limit=100, check=None, before=None, after=None, around=None):

27
discord/channel.py

@ -38,7 +38,7 @@ import asyncio
__all__ = ('TextChannel', 'VoiceChannel', 'DMChannel', 'GroupChannel', '_channel_factory') __all__ = ('TextChannel', 'VoiceChannel', 'DMChannel', 'GroupChannel', '_channel_factory')
class TextChannel(discord.abc.MessageChannel, discord.abc.GuildChannel, Hashable): class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
"""Represents a Discord guild text channel. """Represents a Discord guild text channel.
Supported Operations: Supported Operations:
@ -88,8 +88,11 @@ class TextChannel(discord.abc.MessageChannel, discord.abc.GuildChannel, Hashable
self.position = data['position'] self.position = data['position']
self._fill_overwrites(data) self._fill_overwrites(data)
def _get_destination(self): def _get_channel(self):
return self.id, self.guild.id return self
def _get_guild_id(self):
return self.guild.id
@asyncio.coroutine @asyncio.coroutine
def edit(self, **options): def edit(self, **options):
@ -224,7 +227,7 @@ class VoiceChannel(discord.abc.GuildChannel, Hashable):
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(discord.abc.MessageChannel, Hashable): class DMChannel(discord.abc.Messageable, Hashable):
"""Represents a Discord direct message channel. """Represents a Discord direct message channel.
Supported Operations: Supported Operations:
@ -259,8 +262,11 @@ class DMChannel(discord.abc.MessageChannel, Hashable):
self.me = me self.me = me
self.id = int(data['id']) self.id = int(data['id'])
def _get_destination(self): def _get_channel(self):
return self.id, None return self
def _get_guild_id(self):
return None
def __str__(self): def __str__(self):
return 'Direct Message with %s' % self.recipient return 'Direct Message with %s' % self.recipient
@ -302,7 +308,7 @@ class DMChannel(discord.abc.MessageChannel, Hashable):
base.manage_messages = False base.manage_messages = False
return base return base
class GroupChannel(discord.abc.MessageChannel, Hashable): class GroupChannel(discord.abc.Messageable, Hashable):
"""Represents a Discord group channel. """Represents a Discord group channel.
Supported Operations: Supported Operations:
@ -354,8 +360,11 @@ class GroupChannel(discord.abc.MessageChannel, Hashable):
else: else:
self.owner = discord.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_channel(self):
return self.id, None return self
def _get_guild_id(self):
return None
def __str__(self): def __str__(self):
if self.name: if self.name:

19
discord/ext/commands/context.py

@ -27,14 +27,14 @@ import asyncio
import discord.abc import discord.abc
import discord.utils import discord.utils
class Context(discord.abc.MessageChannel): class Context(discord.abc.Messageable):
"""Represents the context in which a command is being invoked under. """Represents the context in which a command is being invoked under.
This class contains a lot of meta data to help you understand more about This class contains a lot of meta data to help you understand more about
the invocation context. This class is not created manually and is instead the invocation context. This class is not created manually and is instead
passed around to commands by passing in :attr:`Command.pass_context`. passed around to commands by passing in :attr:`Command.pass_context`.
This class implements the :class:`abc.MessageChannel` ABC. This class implements the :class:`abc.Messageable` ABC.
Attributes Attributes
----------- -----------
@ -117,8 +117,12 @@ class Context(discord.abc.MessageChannel):
ret = yield from command.callback(*arguments, **kwargs) ret = yield from command.callback(*arguments, **kwargs)
return ret return ret
def _get_destination(self): def _get_channel(self):
return self.channel.id, getattr(self.guild, 'id', None) return self.channel
def _get_guild_id(self):
g = self.guild
return g.id if g is not None else None
@property @property
def cog(self): def cog(self):
@ -128,13 +132,6 @@ class Context(discord.abc.MessageChannel):
return None return None
return self.command.instance return self.command.instance
@discord.utils.cached_property
def id(self):
# we need this to meet MessageChannel abc
# it is purposefully undocumented because it makes no logistic sense
# outside of providing the sugar of the main class.
return self.channel.id
@discord.utils.cached_property @discord.utils.cached_property
def guild(self): def guild(self):
"""Returns the guild associated with this context's command. None if not available.""" """Returns the guild associated with this context's command. None if not available."""

2
discord/reaction.py

@ -113,7 +113,7 @@ class Reaction:
A list of users who reacted to the message. A list of users who reacted to the message.
""" """
# TODO: Return an iterator a la `MessageChannel.history`? # TODO: Return an iterator a la `Messageable.history`?
if self.custom_emoji: if self.custom_emoji:
emoji = '{0.name}:{0.id}'.format(self.emoji) emoji = '{0.name}:{0.id}'.format(self.emoji)

Loading…
Cancel
Save