aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2016-12-23 23:00:09 -0500
committerRapptz <[email protected]>2017-01-03 09:52:00 -0500
commit30394d03f2348d707f7e795ee3a40a5676ef7b34 (patch)
treef5c777a06371256c5caf39369dca9a3d66ed27e4
parentAdd Message.clear_reactions (diff)
downloaddiscord.py-30394d03f2348d707f7e795ee3a40a5676ef7b34.tar.xz
discord.py-30394d03f2348d707f7e795ee3a40a5676ef7b34.zip
Remove no longer used functions in Client.
-rw-r--r--discord/client.py1851
1 files changed, 1 insertions, 1850 deletions
diff --git a/discord/client.py b/discord/client.py
index b760ee83..74bb941c 100644
--- a/discord/client.py
+++ b/discord/client.py
@@ -26,20 +26,14 @@ DEALINGS IN THE SOFTWARE.
from . import __version__ as library_version
from .user import User
-from .member import Member
-from .channel import *
-from .guild import Guild
-from .message import Message
from .invite import Invite
from .object import Object
-from .role import Role
from .errors import *
from .state import ConnectionState
from .permissions import Permissions, PermissionOverwrite
from . import utils, compat
-from .enums import ChannelType, GuildRegion, VerificationLevel, Status
+from .enums import ChannelType, Status
from .voice_client import VoiceClient
-from .iterators import LogsFromIterator
from .gateway import *
from .emoji import Emoji
from .http import HTTPClient
@@ -259,33 +253,6 @@ class Client:
return m.group(1)
return invite
- @asyncio.coroutine
- def _resolve_destination(self, destination):
- if isinstance(destination, TextChannel):
- return destination.id, destination.guild.id
- elif isinstance(destination, DMChannel):
- return destination.id, None
- elif isinstance(destination, Guild):
- return destination.id, destination.id
- elif isinstance(destination, User):
- found = self.connection._get_private_channel_by_user(destination.id)
- if found is None:
- # Couldn't find the user, so start a PM with them first.
- channel = yield from self.start_private_message(destination)
- return channel.id, None
- else:
- return found.id, None
- elif isinstance(destination, Object):
- found = self.get_channel(destination.id)
- if found is not None:
- return (yield from self._resolve_destination(found))
-
- # couldn't find it in cache so YOLO
- return destination.id, destination.id
- else:
- fmt = 'Destination must be TextChannel, DMChannel, User, or Object. Received {0.__class__.__name__}'
- raise InvalidArgument(fmt.format(destination))
-
def __getattr__(self, name):
if name in ('user', 'guilds', 'private_channels', 'messages', 'voice_clients'):
return getattr(self.connection, name)
@@ -881,764 +848,6 @@ class Client:
return self.event(coro)
- # Message sending/management
-
- @asyncio.coroutine
- def start_private_message(self, user):
- """|coro|
-
- Starts a private message with the user. This allows you to
- :meth:`send_message` to the user.
-
- Note
- -----
- This method should rarely be called as :meth:`send_message`
- does it automatically for you.
-
- Parameters
- -----------
- user : :class:`User`
- The user to start the private message with.
-
- Raises
- ------
- HTTPException
- The request failed.
- InvalidArgument
- The user argument was not of :class:`User`.
- """
-
- if not isinstance(user, User):
- raise InvalidArgument('user argument must be a User')
-
- data = yield from self.http.start_private_message(user.id)
- channel = PrivateChannel(me=self.user, data=data, state=self.connection.ctx)
- self.connection._add_private_channel(channel)
- return channel
-
- @asyncio.coroutine
- def add_reaction(self, message, emoji):
- """|coro|
-
- Add a reaction to the given message.
-
- The message must be a :class:`Message` that exists. emoji may be a unicode emoji,
- or a custom server :class:`Emoji`.
-
- Parameters
- ------------
- message : :class:`Message`
- The message to react to.
- emoji : :class:`Emoji` or str
- The emoji to react with.
-
- Raises
- --------
- HTTPException
- Adding the reaction failed.
- Forbidden
- You do not have the proper permissions to react to the message.
- NotFound
- The message or emoji you specified was not found.
- InvalidArgument
- The message or emoji parameter is invalid.
- """
- if not isinstance(message, Message):
- raise InvalidArgument('message argument must be a Message')
- if not isinstance(emoji, (str, Emoji)):
- raise InvalidArgument('emoji argument must be a string or Emoji')
-
- if isinstance(emoji, Emoji):
- emoji = '{}:{}'.format(emoji.name, emoji.id)
-
- yield from self.http.add_reaction(message.id, message.channel.id, emoji)
-
- @asyncio.coroutine
- def remove_reaction(self, message, emoji, member):
- """|coro|
-
- Remove a reaction by the member from the given message.
-
- If member != server.me, you need Manage Messages to remove the reaction.
-
- The message must be a :class:`Message` that exists. emoji may be a unicode emoji,
- or a custom server :class:`Emoji`.
-
- Parameters
- ------------
- message : :class:`Message`
- The message.
- emoji : :class:`Emoji` or str
- The emoji to remove.
- member : :class:`Member`
- The member for which to delete the reaction.
-
- Raises
- --------
- HTTPException
- Removing the reaction failed.
- Forbidden
- You do not have the proper permissions to remove the reaction.
- NotFound
- The message or emoji you specified was not found.
- InvalidArgument
- The message or emoji parameter is invalid.
- """
- if not isinstance(message, Message):
- raise InvalidArgument('message argument must be a Message')
- if not isinstance(emoji, (str, Emoji)):
- raise InvalidArgument('emoji must be a string or Emoji')
-
- if isinstance(emoji, Emoji):
- emoji = '{}:{}'.format(emoji.name, emoji.id)
-
- if member == self.user:
- member_id = '@me'
- else:
- member_id = member.id
-
- yield from self.http.remove_reaction(message.id, message.channel.id, emoji, member_id)
-
- @asyncio.coroutine
- def get_reaction_users(self, reaction, limit=100, after=None):
- """|coro|
-
- Get the users that added a reaction to a message.
-
- Parameters
- ------------
- reaction : :class:`Reaction`
- The reaction to retrieve users for.
- limit : int
- The maximum number of results to return.
- after : :class:`Member` or :class:`Object`
- For pagination, reactions are sorted by member.
-
- Raises
- --------
- HTTPException
- Getting the users for the reaction failed.
- NotFound
- The message or emoji you specified was not found.
- InvalidArgument
- The reaction parameter is invalid.
- """
- if not isinstance(reaction, Reaction):
- raise InvalidArgument('reaction must be a Reaction')
-
- emoji = reaction.emoji
-
- if isinstance(emoji, Emoji):
- emoji = '{}:{}'.format(emoji.name, emoji.id)
-
- if after:
- after = after.id
-
- data = yield from self.http.get_reaction_users(
- reaction.message.id, reaction.message.channel.id,
- emoji, limit, after=after)
-
- return [User(**user) for user in data]
-
- @asyncio.coroutine
- def clear_reactions(self, message):
- """|coro|
-
- Removes all the reactions from a given message.
-
- You need Manage Messages permission to use this.
-
- Parameters
- -----------
- message: :class:`Message`
- The message to remove all reactions from.
-
- Raises
- --------
- HTTPException
- Removing the reactions failed.
- Forbidden
- You do not have the proper permissions to remove all the reactions.
- """
- yield from self.http.clear_reactions(message.id, message.channel.id)
-
- @asyncio.coroutine
- def send_message(self, destination, content=None, *, tts=False, embed=None):
- """|coro|
-
- Sends a message to the destination given with the content given.
-
- The destination could be a :class:`Channel`, :class:`PrivateChannel` or :class:`Guild`.
- For convenience it could also be a :class:`User`. If it's a :class:`User` or :class:`PrivateChannel`
- then it sends the message via private message, otherwise it sends the message to the channel.
- If the destination is a :class:`Guild` then it's equivalent to calling
- :attr:`Guild.default_channel` and sending it there.
-
- If it is a :class:`Object` instance then it is assumed to be the
- destination ID. The destination ID is a *channel* so passing in a user
- ID will not be a valid destination.
-
- .. versionchanged:: 0.9.0
- ``str`` being allowed was removed and replaced with :class:`Object`.
-
- 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
- be provided.
-
- If the ``embed`` parameter is provided, it must be of type :class:`Embed` and
- it must be a rich embed type.
-
- Parameters
- ------------
- destination
- The location to send the message.
- content
- The content of the message to send. If this is missing,
- then the ``embed`` parameter must be present.
- tts : bool
- Indicates if the message should be sent using text-to-speech.
- embed: :class:`Embed`
- The rich embed for the content.
-
- Raises
- --------
- HTTPException
- Sending the message failed.
- Forbidden
- You do not have the proper permissions to send the message.
- NotFound
- The destination was not found and hence is invalid.
- InvalidArgument
- The destination parameter is invalid.
-
- Examples
- ----------
-
- Sending a regular message:
-
- .. code-block:: python
-
- await client.send_message(message.channel, 'Hello')
-
- Sending a TTS message:
-
- .. code-block:: python
-
- await client.send_message(message.channel, 'Goodbye.', tts=True)
-
- Sending an embed message:
-
- .. code-block:: python
-
- em = discord.Embed(title='My Embed Title', description='My Embed Content.', colour=0xDEADBF)
- em.set_author(name='Someone', icon_url=client.user.default_avatar_url)
- await client.send_message(message.channel, embed=em)
-
- Returns
- ---------
- :class:`Message`
- The message that was sent.
- """
-
- channel_id, guild_id = yield from self._resolve_destination(destination)
-
- content = str(content) if content else None
-
- if embed is not None:
- embed = embed.to_dict()
-
- data = yield from self.http.send_message(channel_id, content, guild_id=guild_id, tts=tts, embed=embed)
- channel = self.get_channel(data.get('channel_id'))
- message = Message(channel=channel, state=self.connection.ctx, data=data)
- return message
-
- @asyncio.coroutine
- def send_typing(self, destination):
- """|coro|
-
- Send a *typing* status to the destination.
-
- *Typing* status will go away after 10 seconds, or after a message is sent.
-
- The destination parameter follows the same rules as :meth:`send_message`.
-
- Parameters
- ----------
- destination
- The location to send the typing update.
- """
-
- channel_id, guild_id = yield from self._resolve_destination(destination)
- yield from self.http.send_typing(channel_id)
-
- @asyncio.coroutine
- def send_file(self, destination, fp, *, filename=None, content=None, tts=False):
- """|coro|
-
- Sends a message to the destination given with the file given.
-
- The destination parameter follows the same rules as :meth:`send_message`.
-
- The ``fp`` parameter should be either a string denoting the location for a
- file or a *file-like object*. The *file-like object* passed is **not closed**
- at the end of execution. You are responsible for closing it yourself.
-
- .. note::
-
- If the file-like object passed is opened via ``open`` then the modes
- 'rb' should be used.
-
- The ``filename`` parameter is the filename of the file.
- If this is not given then it defaults to ``fp.name`` or if ``fp`` is a string
- then the ``filename`` will default to the string given. You can overwrite
- this value by passing this in.
-
- Parameters
- ------------
- destination
- The location to send the message.
- fp
- The *file-like object* or file path to send.
- filename : str
- The filename of the file. Defaults to ``fp.name`` if it's available.
- content
- The content of the message to send along with the file. This is
- forced into a string by a ``str(content)`` call.
- tts : bool
- If the content of the message should be sent with TTS enabled.
-
- Raises
- -------
- HTTPException
- Sending the file failed.
-
- Returns
- --------
- :class:`Message`
- The message sent.
- """
-
- channel_id, guild_id = yield from self._resolve_destination(destination)
-
- try:
- with open(fp, 'rb') as f:
- buffer = io.BytesIO(f.read())
- if filename is None:
- _, filename = path_split(fp)
- except TypeError:
- buffer = fp
-
- data = yield from self.http.send_file(channel_id, buffer, guild_id=guild_id,
- filename=filename, content=content, tts=tts)
- channel = self.get_channel(data.get('channel_id'))
- message = Message(channel=channel, state=self.connection.ctx, data=data)
- return message
-
- @asyncio.coroutine
- def delete_message(self, message):
- """|coro|
-
- Deletes a :class:`Message`.
-
- Your own messages could be deleted without any proper permissions. However to
- delete other people's messages, you need the proper permissions to do so.
-
- Parameters
- -----------
- message : :class:`Message`
- The message to delete.
-
- Raises
- ------
- Forbidden
- You do not have proper permissions to delete the message.
- HTTPException
- Deleting the message failed.
- """
- channel = message.channel
- guild_id = channel.guild.id if not getattr(channel, 'is_private', True) else None
- yield from self.http.delete_message(channel.id, message.id, guild_id)
-
- @asyncio.coroutine
- def delete_messages(self, messages):
- """|coro|
-
- Deletes a list of messages. This is similar to :func:`delete_message`
- except it bulk deletes multiple messages.
-
- The channel to check where the message is deleted from is handled via
- the first element of the iterable's ``.channel.id`` attributes. If the
- channel is not consistent throughout the entire sequence, then an
- :exc:`HTTPException` will be raised.
-
- Usable only by bot accounts.
-
- Parameters
- -----------
- messages : iterable of :class:`Message`
- An iterable of messages denoting which ones to bulk delete.
-
- Raises
- ------
- ClientException
- The number of messages to delete is less than 2 or more than 100.
- Forbidden
- You do not have proper permissions to delete the messages or
- you're not using a bot account.
- HTTPException
- Deleting the messages failed.
- """
-
- messages = list(messages)
- if len(messages) > 100 or len(messages) < 2:
- raise ClientException('Can only delete messages in the range of [2, 100]')
-
- channel = messages[0].channel
- message_ids = [m.id for m in messages]
- guild_id = channel.guild.id if not getattr(channel, 'is_private', True) else None
- yield from self.http.delete_messages(channel.id, message_ids, guild_id)
-
- @asyncio.coroutine
- def purge_from(self, channel, *, limit=100, check=None, before=None, after=None, around=None):
- """|coro|
-
- Purges a list of messages that meet the criteria given by the predicate
- ``check``. If a ``check`` is not provided then all messages are deleted
- without discrimination.
-
- You must have Manage Messages permission to delete messages even if they
- are your own. The Read Message History permission is also needed to
- retrieve message history.
-
- Usable only by bot accounts.
-
- Parameters
- -----------
- channel : :class:`Channel`
- The channel to purge from.
- limit : int
- The number of messages to search through. This is not the number
- of messages that will be deleted, though it can be.
- check : predicate
- The function used to check if a message should be deleted.
- It must take a :class:`Message` as its sole parameter.
- before : :class:`Message` or `datetime`
- The message or date before which all deleted messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
- after : :class:`Message` or `datetime`
- The message or date after which all deleted messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
- around : :class:`Message` or `datetime`
- The message or date around which all deleted messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
-
- Raises
- -------
- Forbidden
- You do not have proper permissions to do the actions required or
- you're not using a bot account.
- HTTPException
- Purging the messages failed.
-
- Examples
- ---------
-
- Deleting bot's messages ::
-
- def is_me(m):
- return m.author == client.user
-
- deleted = await client.purge_from(channel, limit=100, check=is_me)
- await client.send_message(channel, 'Deleted {} message(s)'.format(len(deleted)))
-
- Returns
- --------
- list
- The list of messages that were deleted.
- """
-
- if check is None:
- check = lambda m: True
-
- if isinstance(before, datetime.datetime):
- before = Object(utils.time_snowflake(before, high=False))
- if isinstance(after, datetime.datetime):
- after = Object(utils.time_snowflake(after, high=True))
- if isinstance(around, datetime.datetime):
- around = Object(utils.time_snowflake(around, high=True))
-
- iterator = LogsFromIterator(self, channel, limit, before=before, after=after, around=around)
- ret = []
- count = 0
-
- while True:
- try:
- msg = yield from iterator.iterate()
- except asyncio.QueueEmpty:
- # no more messages to poll
- if count >= 2:
- # more than 2 messages -> bulk delete
- to_delete = ret[-count:]
- yield from self.delete_messages(to_delete)
- elif count == 1:
- # delete a single message
- yield from self.delete_message(ret[-1])
-
- return ret
- else:
- if count == 100:
- # we've reached a full 'queue'
- to_delete = ret[-100:]
- yield from self.delete_messages(to_delete)
- count = 0
- yield from asyncio.sleep(1, loop=self.loop)
-
- if check(msg):
- count += 1
- ret.append(msg)
-
- @asyncio.coroutine
- def edit_message(self, message, new_content=None, *, embed=None):
- """|coro|
-
- Edits a :class:`Message` with the new message content.
-
- The new_content must be able to be transformed into a string via ``str(new_content)``.
-
- If the ``new_content`` is not provided, then ``embed`` must be provided, which must
- be of type :class:`Embed`.
-
- The :class:`Message` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- -----------
- message : :class:`Message`
- The message to edit.
- new_content
- The new content to replace the message with.
- embed: :class:`Embed`
- The new embed to replace the original embed with.
-
- Raises
- -------
- HTTPException
- Editing the message failed.
-
- Returns
- --------
- :class:`Message`
- The new edited message.
- """
-
- channel = message.channel
- content = str(new_content) if new_content else None
- embed = embed.to_dict() if embed else None
- guild_id = channel.guild.id if not getattr(channel, 'is_private', True) else None
- data = yield from self.http.edit_message(message.id, channel.id, content, guild_id=guild_id, embed=embed)
- return Message(channel=channel, state=self.connection.ctx, data=data)
-
- @asyncio.coroutine
- def get_message(self, channel, id):
- """|coro|
-
- Retrieves a single :class:`Message` from a :class:`Channel`.
-
- This can only be used by bot accounts.
-
- Parameters
- ------------
- channel: :class:`Channel` or :class:`PrivateChannel`
- The text channel to retrieve the message from.
- id: str
- The message ID to look for.
-
- Returns
- --------
- :class:`Message`
- The message asked for.
-
- Raises
- --------
- NotFound
- The specified channel or message was not found.
- Forbidden
- You do not have the permissions required to get a message.
- HTTPException
- Retrieving the message failed.
- """
-
- data = yield from self.http.get_message(channel.id, id)
- return Message(channel=channel, state=self.connection.ctx, data=data)
-
- @asyncio.coroutine
- def pin_message(self, message):
- """|coro|
-
- Pins a message. You must have Manage Messages permissions
- to do this in a non-private channel context.
-
- Parameters
- -----------
- message: :class:`Message`
- The message to pin.
-
- Raises
- -------
- Forbidden
- You do not have permissions to pin the message.
- NotFound
- The message or channel was not found.
- HTTPException
- Pinning the message failed, probably due to the channel
- having more than 50 pinned messages.
- """
- yield from self.http.pin_message(message.channel.id, message.id)
-
- @asyncio.coroutine
- def unpin_message(self, message):
- """|coro|
-
- Unpins a message. You must have Manage Messages permissions
- to do this in a non-private channel context.
-
- Parameters
- -----------
- message: :class:`Message`
- The message to unpin.
-
- Raises
- -------
- Forbidden
- You do not have permissions to unpin the message.
- NotFound
- The message or channel was not found.
- HTTPException
- Unpinning the message failed.
- """
- yield from self.http.unpin_message(message.channel.id, message.id)
-
- @asyncio.coroutine
- def pins_from(self, channel):
- """|coro|
-
- Returns a list of :class:`Message` that are currently pinned for
- the specified :class:`Channel` or :class:`PrivateChannel`.
-
- Parameters
- -----------
- channel: :class:`Channel` or :class:`PrivateChannel`
- The channel to look through pins for.
-
- Raises
- -------
- NotFound
- The channel was not found.
- HTTPException
- Retrieving the pinned messages failed.
- """
-
- data = yield from self.http.pins_from(channel.id)
- return [Message(channel=channel, state=self.connection.ctx, data=m) for m in data]
-
- def _logs_from(self, channel, limit=100, before=None, after=None, around=None):
- """|coro|
-
- This coroutine returns a generator that obtains logs from a specified channel.
-
- Parameters
- -----------
- channel : :class:`Channel` or :class:`PrivateChannel`
- The channel to obtain the logs from.
- limit : int
- The number of messages to retrieve.
- before : :class:`Message` or `datetime`
- The message or date before which all returned messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
- after : :class:`Message` or `datetime`
- The message or date after which all returned messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
- around : :class:`Message` or `datetime`
- The message or date around which all returned messages must be.
- If a date is provided it must be a timezone-naive datetime representing UTC time.
-
- Raises
- ------
- Forbidden
- You do not have permissions to get channel logs.
- NotFound
- The channel you are requesting for doesn't exist.
- HTTPException
- The request to get logs failed.
-
- Yields
- -------
- :class:`Message`
- The message with the message data parsed.
-
- Examples
- ---------
-
- Basic logging: ::
-
- logs = yield from client.logs_from(channel)
- for message in logs:
- if message.content.startswith('!hello'):
- if message.author == client.user:
- yield from client.edit_message(message, 'goodbye')
-
- Python 3.5 Usage ::
-
- counter = 0
- async for message in client.logs_from(channel, limit=500):
- if message.author == client.user:
- counter += 1
- """
- before = getattr(before, 'id', None)
- after = getattr(after, 'id', None)
- around = getattr(around, 'id', None)
-
- return self.http.logs_from(channel.id, limit, before=before, after=after, around=around)
-
- if PY35:
- def logs_from(self, channel, limit=100, *, before=None, after=None, around=None, reverse=False):
- if isinstance(before, datetime.datetime):
- before = Object(utils.time_snowflake(before, high=False))
- if isinstance(after, datetime.datetime):
- after = Object(utils.time_snowflake(after, high=True))
- if isinstance(around, datetime.datetime):
- around = Object(utils.time_snowflake(around))
-
- return LogsFromIterator(self, channel, limit, before=before, after=after, around=around, reverse=reverse)
- else:
- @asyncio.coroutine
- def logs_from(self, channel, limit=100, *, before=None, after=None):
- if isinstance(before, datetime.datetime):
- before = Object(utils.time_snowflake(before, high=False))
- if isinstance(after, datetime.datetime):
- after = Object(utils.time_snowflake(after, high=True))
-
- def generator(data):
- for message in data:
- yield Message(channel=channel, state=self.connection.ctx, data=message)
-
- result = []
- while limit > 0:
- retrieve = limit if limit <= 100 else 100
- data = yield from self._logs_from(channel, retrieve, before, after)
- if len(data):
- limit -= retrieve
- result.extend(data)
- before = Object(id=data[-1]['id'])
- else:
- break
-
- return generator(result)
-
- logs_from.__doc__ = _logs_from.__doc__
-
- # Member management
-
@asyncio.coroutine
def request_offline_members(self, guild):
"""|coro|
@@ -1677,113 +886,6 @@ class Client:
yield from self.ws.send_as_json(payload)
@asyncio.coroutine
- def kick(self, member):
- """|coro|
-
- Kicks a :class:`Member` from the guild they belong to.
-
- Warning
- --------
- This function kicks the :class:`Member` based on the guild it
- belongs to, which is accessed via :attr:`Member.guild`. So you
- must have the proper permissions in that guild.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to kick from their guild.
-
- Raises
- -------
- Forbidden
- You do not have the proper permissions to kick.
- HTTPException
- Kicking failed.
- """
- yield from self.http.kick(member.id, member.guild.id)
-
- @asyncio.coroutine
- def ban(self, member, delete_message_days=1):
- """|coro|
-
- Bans a :class:`Member` from the guild they belong to.
-
- Warning
- --------
- This function bans the :class:`Member` based on the guild it
- belongs to, which is accessed via :attr:`Member.guild`. So you
- must have the proper permissions in that guild.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to ban from their guild.
- delete_message_days : int
- The number of days worth of messages to delete from the user
- in the guild. The minimum is 0 and the maximum is 7.
-
- Raises
- -------
- Forbidden
- You do not have the proper permissions to ban.
- HTTPException
- Banning failed.
- """
- yield from self.http.ban(member.id, member.guild.id, delete_message_days)
-
- @asyncio.coroutine
- def unban(self, guild, user):
- """|coro|
-
- Unbans a :class:`User` from the guild they are banned from.
-
- Parameters
- -----------
- guild : :class:`Guild`
- The guild to unban the user from.
- user : :class:`User`
- The user to unban.
-
- Raises
- -------
- Forbidden
- You do not have the proper permissions to unban.
- HTTPException
- Unbanning failed.
- """
- yield from self.http.unban(user.id, guild.id)
-
- @asyncio.coroutine
- def guild_voice_state(self, member, *, mute=None, deafen=None):
- """|coro|
-
- Guild mutes or deafens a specific :class:`Member`.
-
- Warning
- --------
- This function mutes or un-deafens the :class:`Member` based on the
- guild it belongs to, which is accessed via :attr:`Member.guild`.
- So you must have the proper permissions in that guild.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to unban from their guild.
- mute: Optional[bool]
- Indicates if the member should be guild muted or un-muted.
- deafen: Optional[bool]
- Indicates if the member should be guild deafened or un-deafened.
-
- Raises
- -------
- Forbidden
- You do not have the proper permissions to deafen or mute.
- HTTPException
- The operation failed.
- """
- yield from self.http.guild_voice_state(member.id, member.guild.id, mute=mute, deafen=deafen)
-
- @asyncio.coroutine
def edit_profile(self, password=None, **fields):
"""|coro|
@@ -1865,36 +967,6 @@ class Client:
self._update_cache(self.email, password)
@asyncio.coroutine
- @utils.deprecated('change_presence')
- def change_status(self, game=None, idle=False):
- """|coro|
-
- Changes the client's status.
-
- The game parameter is a Game object (not a string) that represents
- a game being played currently.
-
- The idle parameter is a boolean parameter that indicates whether the
- client should go idle or not.
-
- .. deprecated:: v0.13.0
- Use :meth:`change_presence` instead.
-
- Parameters
- ----------
- game : Optional[:class:`Game`]
- The game being played. None if no game is being played.
- idle : bool
- Indicates if the client should go idle.
-
- Raises
- ------
- InvalidArgument
- If the ``game`` parameter is not :class:`Game` or None.
- """
- yield from self.ws.change_presence(game=game, idle=idle)
-
- @asyncio.coroutine
def change_presence(self, *, game=None, status=None, afk=False):
"""|coro|
@@ -1930,637 +1002,6 @@ class Client:
yield from self.ws.change_presence(game=game, status=status, afk=afk)
- @asyncio.coroutine
- def change_nickname(self, member, nickname):
- """|coro|
-
- Changes a member's nickname.
-
- You must have the proper permissions to change someone's
- (or your own) nickname.
-
- Parameters
- ----------
- member : :class:`Member`
- The member to change the nickname for.
- nickname : Optional[str]
- The nickname to change it to. ``None`` to remove
- the nickname.
-
- Raises
- ------
- Forbidden
- You do not have permissions to change the nickname.
- HTTPException
- Changing the nickname failed.
- """
-
- nickname = nickname if nickname else ''
-
- if member == self.user:
- yield from self.http.change_my_nickname(member.guild.id, nickname)
- else:
- yield from self.http.change_nickname(member.guild.id, member.id, nickname)
-
- # Channel management
-
- @asyncio.coroutine
- def edit_channel(self, channel, **options):
- """|coro|
-
- Edits a :class:`Channel`.
-
- You must have the proper permissions to edit the channel.
-
- To move the channel's position use :meth:`move_channel` instead.
-
- The :class:`Channel` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- ----------
- channel : :class:`Channel`
- The channel to update.
- name : str
- The new channel name.
- topic : str
- The new channel's topic.
- bitrate : int
- The new channel's bitrate. Voice only.
- user_limit : int
- The new channel's user limit. Voice only.
-
- Raises
- ------
- Forbidden
- You do not have permissions to edit the channel.
- HTTPException
- Editing the channel failed.
- """
-
- keys = ('name', 'topic', 'position')
- for key in keys:
- if key not in options:
- options[key] = getattr(channel, key)
-
- yield from self.http.edit_channel(channel.id, **options)
-
- @asyncio.coroutine
- def move_channel(self, channel, position):
- """|coro|
-
- Moves the specified :class:`Channel` to the given position in the GUI.
- Note that voice channels and text channels have different position values.
-
- The :class:`Channel` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- .. warning::
-
- :class:`Object` instances do not work with this function.
-
- Parameters
- -----------
- channel : :class:`Channel`
- The channel to change positions of.
- position : int
- The position to insert the channel to.
-
- Raises
- -------
- InvalidArgument
- If position is less than 0 or greater than the number of channels.
- Forbidden
- You do not have permissions to change channel order.
- HTTPException
- If moving the channel failed, or you are of too low rank to move the channel.
- """
-
- if position < 0:
- raise InvalidArgument('Channel position cannot be less than 0.')
-
- url = '{0}/{1.guild.id}/channels'.format(self.http.GUILDS, channel)
- channels = [c for c in channel.guild.channels if c.type is channel.type]
-
- if position >= len(channels):
- raise InvalidArgument('Channel position cannot be greater than {}'.format(len(channels) - 1))
-
- channels.sort(key=lambda c: c.position)
-
- try:
- # remove ourselves from the channel list
- channels.remove(channel)
- except ValueError:
- # not there somehow lol
- return
- else:
- # add ourselves at our designated position
- channels.insert(position, channel)
-
- payload = [{'id': c.id, 'position': index } for index, c in enumerate(channels)]
- yield from self.http.patch(url, json=payload, bucket='move_channel')
-
- @asyncio.coroutine
- def create_channel(self, guild, name, *overwrites, type=None):
- """|coro|
-
- Creates a :class:`Channel` in the specified :class:`Guild`.
-
- Note that you need the proper permissions to create the channel.
-
- The ``overwrites`` argument list can be used to create a 'secret'
- channel upon creation. A namedtuple of :class:`ChannelPermissions`
- is exposed to create a channel-specific permission overwrite in a more
- self-documenting matter. You can also use a regular tuple of ``(target, overwrite)``
- where the ``overwrite`` expected has to be of type :class:`PermissionOverwrite`.
-
- Examples
- ----------
-
- Creating a voice channel:
-
- .. code-block:: python
-
- await client.create_channel(guild, 'Voice', type=discord.ChannelType.voice)
-
- Creating a 'secret' text channel:
-
- .. code-block:: python
-
- everyone_perms = discord.PermissionOverwrite(read_messages=False)
- my_perms = discord.PermissionOverwrite(read_messages=True)
-
- everyone = discord.ChannelPermissions(target=guild.default_role, overwrite=everyone_perms)
- mine = discord.ChannelPermissions(target=guild.me, overwrite=my_perms)
- await client.create_channel(guild, 'secret', everyone, mine)
-
- Or in a more 'compact' way:
-
- .. code-block:: python
-
- everyone = discord.PermissionOverwrite(read_messages=False)
- mine = discord.PermissionOverwrite(read_messages=True)
- await client.create_channel(guild, 'secret', (guild.default_role, everyone), (guild.me, mine))
-
- Parameters
- -----------
- guild : :class:`Guild`
- The guild to create the channel in.
- name : str
- The channel's name.
- type : :class:`ChannelType`
- The type of channel to create. Defaults to :attr:`ChannelType.text`.
- overwrites:
- An argument list of channel specific overwrites to apply on the channel on
- creation. Useful for creating 'secret' channels.
-
- Raises
- -------
- Forbidden
- You do not have the proper permissions to create the channel.
- NotFound
- The guild specified was not found.
- HTTPException
- Creating the channel failed.
- InvalidArgument
- The permission overwrite array is not in proper form.
-
- Returns
- -------
- :class:`Channel`
- The channel that was just created. This channel is
- different than the one that will be added in cache.
- """
-
- if type is None:
- type = ChannelType.text
-
- perms = []
- for overwrite in overwrites:
- target = overwrite[0]
- perm = overwrite[1]
- if not isinstance(perm, PermissionOverwrite):
- raise InvalidArgument('Expected PermissionOverwrite received {0.__name__}'.format(type(perm)))
-
- allow, deny = perm.pair()
- payload = {
- 'allow': allow.value,
- 'deny': deny.value,
- 'id': target.id
- }
-
- if isinstance(target, User):
- payload['type'] = 'member'
- elif isinstance(target, Role):
- payload['type'] = 'role'
- else:
- raise InvalidArgument('Expected Role, User, or Member target, received {0.__name__}'.format(type(target)))
-
- perms.append(payload)
-
- data = yield from self.http.create_channel(guild.id, name, str(type), permission_overwrites=perms)
- channel = Channel(guild=guild, state=self.connection.ctx, data=data)
- return channel
-
- @asyncio.coroutine
- def delete_channel(self, channel):
- """|coro|
-
- Deletes a :class:`Channel`.
-
- In order to delete the channel, the client must have the proper permissions
- in the guild the channel belongs to.
-
- Parameters
- ------------
- channel : :class:`Channel`
- The channel to delete.
-
- Raises
- -------
- Forbidden
- You do not have proper permissions to delete the channel.
- NotFound
- The specified channel was not found.
- HTTPException
- Deleting the channel failed.
- """
- yield from self.http.delete_channel(channel.id)
-
- # Guild management
-
- @asyncio.coroutine
- def leave_guild(self, guild):
- """|coro|
-
- Leaves a :class:`Guild`.
-
- Note
- --------
- You cannot leave the guild that you own, you must delete it instead
- via :meth:`delete_guild`.
-
- Parameters
- ----------
- guild : :class:`Guild`
- The guild to leave.
-
- Raises
- --------
- HTTPException
- If leaving the guild failed.
- """
- yield from self.http.leave_guild(guild.id)
-
- @asyncio.coroutine
- def delete_guild(self, guild):
- """|coro|
-
- Deletes a :class:`Guild`. You must be the guild owner to delete the
- guild.
-
- Parameters
- ----------
- guild : :class:`Guild`
- The guild to delete.
-
- Raises
- --------
- HTTPException
- If deleting the guild failed.
- Forbidden
- You do not have permissions to delete the guild.
- """
-
- yield from self.http.delete_guild(guild.id)
-
- @asyncio.coroutine
- def create_guild(self, name, region=None, icon=None):
- """|coro|
-
- Creates a :class:`Guild`.
-
- Parameters
- ----------
- name : str
- The name of the guild.
- region : :class:`GuildRegion`
- The region for the voice communication guild.
- Defaults to :attr:`GuildRegion.us_west`.
- icon : bytes
- The *bytes-like* object representing the icon. See :meth:`edit_profile`
- for more details on what is expected.
-
- Raises
- ------
- HTTPException
- Guild creation failed.
- InvalidArgument
- Invalid icon image format given. Must be PNG or JPG.
-
- Returns
- -------
- :class:`Guild`
- The guild created. This is not the same guild that is
- added to cache.
- """
- if icon is not None:
- icon = utils._bytes_to_base64_data(icon)
-
- if region is None:
- region = GuildRegion.us_west.name
- else:
- region = region.name
-
- data = yield from self.http.create_guild(name, region, icon)
- return Guild(data=data, state=self.connection.ctx)
-
- @asyncio.coroutine
- def edit_guild(self, guild, **fields):
- """|coro|
-
- Edits a :class:`Guild`.
-
- You must have the proper permissions to edit the guild.
-
- The :class:`Guild` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- ----------
- guild: :class:`Guild`
- The guild to edit.
- name: str
- The new name of the guild.
- icon: bytes
- A *bytes-like* object representing the icon. See :meth:`edit_profile`
- for more details. Could be ``None`` to denote no icon.
- splash: bytes
- A *bytes-like* object representing the invite splash. See
- :meth:`edit_profile` for more details. Could be ``None`` to denote
- no invite splash. Only available for partnered servers with
- ``INVITE_SPLASH`` feature.
- region: :class:`GuildRegion`
- The new region for the guild's voice communication.
- afk_channel: :class:`Channel`
- The new channel that is the AFK channel. Could be ``None`` for no AFK channel.
- afk_timeout: int
- The number of seconds until someone is moved to the AFK channel.
- owner: :class:`Member`
- The new owner of the guild to transfer ownership to. Note that you must
- be owner of the guild to do this.
- verification_level: :class:`VerificationLevel`
- The new verification level for the guild.
-
- Raises
- -------
- Forbidden
- You do not have permissions to edit the guild.
- NotFound
- The guild you are trying to edit does not exist.
- HTTPException
- Editing the guild failed.
- InvalidArgument
- The image format passed in to ``icon`` is invalid. It must be
- PNG or JPG. This is also raised if you are not the owner of the
- guild and request an ownership transfer.
- """
-
- try:
- icon_bytes = fields['icon']
- except KeyError:
- icon = guild.icon
- else:
- if icon_bytes is not None:
- icon = utils._bytes_to_base64_data(icon_bytes)
- else:
- icon = None
-
- try:
- splash_bytes = fields['splash']
- except KeyError:
- splash = server.splash
- else:
- if splash_bytes is not None:
- splash = utils._bytes_to_base64_data(splash_bytes)
- else:
- splash = None
-
- fields['icon'] = icon
- fields['splash'] = splash
- if 'afk_channel' in fields:
- fields['afk_channel_id'] = fields['afk_channel'].id
-
- if 'owner' in fields:
- if guild.owner != guild.me:
- raise InvalidArgument('To transfer ownership you must be the owner of the guild.')
-
- fields['owner_id'] = fields['owner'].id
-
- if 'region' in fields:
- fields['region'] = str(fields['region'])
-
- level = fields.get('verification_level', guild.verification_level)
- if not isinstance(level, VerificationLevel):
- raise InvalidArgument('verification_level field must of type VerificationLevel')
-
- fields['verification_level'] = level.value
- yield from self.http.edit_guild(guild.id, **fields)
-
- @asyncio.coroutine
- def get_bans(self, guild):
- """|coro|
-
- Retrieves all the :class:`User` s that are banned from the specified
- guild.
-
- You must have proper permissions to get this information.
-
- Parameters
- ----------
- guild : :class:`Guild`
- The guild to get ban information from.
-
- Raises
- -------
- Forbidden
- You do not have proper permissions to get the information.
- HTTPException
- An error occurred while fetching the information.
-
- Returns
- --------
- list
- A list of :class:`User` that have been banned.
- """
-
- data = yield from self.http.get_bans(guild.id)
- return [self.connection.store_user(user) for user in data]
-
- @asyncio.coroutine
- def prune_members(self, guild, *, days):
- """|coro|
-
- Prunes a :class:`Guild` from its inactive members.
-
- The inactive members are denoted if they have not logged on in
- ``days`` number of days and they have no roles.
-
- You must have the "Kick Members" permission to use this.
-
- To check how many members you would prune without actually pruning,
- see the :meth:`estimate_pruned_members` function.
-
- Parameters
- -----------
- guild: :class:`Guild`
- The guild to prune from.
- days: int
- The number of days before counting as inactive.
-
- Raises
- -------
- Forbidden
- You do not have permissions to prune members.
- HTTPException
- An error occurred while pruning members.
- InvalidArgument
- An integer was not passed for ``days``.
-
- Returns
- ---------
- int
- The number of members pruned.
- """
-
- if not isinstance(days, int):
- raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days))
-
- data = yield from self.http.prune_members(guild.id, days)
- return data['pruned']
-
- @asyncio.coroutine
- def estimate_pruned_members(self, guild, *, days):
- """|coro|
-
- Similar to :meth:`prune_members` except instead of actually
- pruning members, it returns how many members it would prune
- from the guild had it been called.
-
- Parameters
- -----------
- guild: :class:`Guild`
- The guild to estimate a prune from.
- days: int
- The number of days before counting as inactive.
-
- Raises
- -------
- Forbidden
- You do not have permissions to prune members.
- HTTPException
- An error occurred while fetching the prune members estimate.
- InvalidArgument
- An integer was not passed for ``days``.
-
- Returns
- ---------
- int
- The number of members estimated to be pruned.
- """
-
- if not isinstance(days, int):
- raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days))
-
- data = yield from self.http.estimate_pruned_members(guild.id, days)
- return data['pruned']
-
- @asyncio.coroutine
- def create_custom_emoji(self, guild, *, name, image):
- """|coro|
-
- Creates a custom :class:`Emoji` for a :class:`Guild`.
-
- This endpoint is only allowed for user bots or white listed
- bots. If this is done by a user bot then this is a local
- emoji that can only be used inside that guild.
-
- There is currently a limit of 50 local emotes per guild.
-
- Parameters
- -----------
- guild: :class:`Guild`
- The guild to add the emoji to.
- name: str
- The emoji name. Must be at least 2 characters.
- image: bytes
- The *bytes-like* object representing the image data to use.
- Only JPG and PNG images are supported.
-
- Returns
- --------
- :class:`Emoji`
- The created emoji.
-
- Raises
- -------
- Forbidden
- You are not allowed to create emojis.
- HTTPException
- An error occurred creating an emoji.
- """
-
- img = utils._bytes_to_base64_data(image)
- data = yield from self.http.create_custom_emoji(guild.id, name, img)
- return Emoji(guild=guild, data=data, state=self.connection.ctx)
-
- @asyncio.coroutine
- def delete_custom_emoji(self, emoji):
- """|coro|
-
- Deletes a custom :class:`Emoji` from a :class:`Guild`.
-
- This follows the same rules as :meth:`create_custom_emoji`.
-
- Parameters
- -----------
- emoji: :class:`Emoji`
- The emoji to delete.
-
- Raises
- -------
- Forbidden
- You are not allowed to delete emojis.
- HTTPException
- An error occurred deleting the emoji.
- """
-
- yield from self.http.delete_custom_emoji(emoji.guild.id, emoji.id)
-
- @asyncio.coroutine
- def edit_custom_emoji(self, emoji, *, name):
- """|coro|
-
- Edits a :class:`Emoji`.
-
- Parameters
- -----------
- emoji: :class:`Emoji`
- The emoji to edit.
- name: str
- The new emoji name.
-
- Raises
- -------
- Forbidden
- You are not allowed to edit emojis.
- HTTPException
- An error occurred editing the emoji.
- """
-
- yield from self.http.edit_custom_emoji(emoji.guild.id, emoji.id, name=name)
-
-
# Invite management
def _fill_invite_data(self, data):
@@ -2739,261 +1180,6 @@ class Client:
invite_id = self._resolve_invite(invite)
yield from self.http.delete_invite(invite_id)
- # Role management
-
- @asyncio.coroutine
- def move_role(self, guild, role, position):
- """|coro|
-
- Moves the specified :class:`Role` to the given position in the :class:`Guild`.
-
- The :class:`Role` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- -----------
- guild : :class:`Guild`
- The guild the role belongs to.
- role : :class:`Role`
- The role to edit.
- position : int
- The position to insert the role to.
-
- Raises
- -------
- InvalidArgument
- If position is 0, or role is guild.default_role
- Forbidden
- You do not have permissions to change role order.
- HTTPException
- If moving the role failed, or you are of too low rank to move the role.
- """
-
- if position == 0:
- raise InvalidArgument("Cannot move role to position 0")
-
- if role == guild.default_role:
- raise InvalidArgument("Cannot move default role")
-
- if role.position == position:
- return # Save discord the extra request.
-
- url = '{0}/{1.id}/roles'.format(self.http.GUILDS, guild)
-
- change_range = range(min(role.position, position), max(role.position, position) + 1)
-
- roles = [r.id for r in sorted(filter(lambda x: (x.position in change_range) and x != role, guild.roles), key=lambda x: x.position)]
-
- if role.position > position:
- roles.insert(0, role.id)
- else:
- roles.append(role.id)
-
- payload = [{"id": z[0], "position": z[1]} for z in zip(roles, change_range)]
- yield from self.http.patch(url, json=payload, bucket='move_role')
-
- @asyncio.coroutine
- def edit_role(self, guild, role, **fields):
- """|coro|
-
- Edits the specified :class:`Role` for the entire :class:`Guild`.
-
- The :class:`Role` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- All fields except ``guild`` and ``role`` are optional. To change
- the position of a role, use :func:`move_role` instead.
-
- .. versionchanged:: 0.8.0
- Editing now uses keyword arguments instead of editing the :class:`Role` object directly.
-
- Parameters
- -----------
- guild : :class:`Guild`
- The guild the role belongs to.
- role : :class:`Role`
- The role to edit.
- name : str
- The new role name to change to.
- permissions : :class:`Permissions`
- The new permissions to change to.
- colour : :class:`Colour`
- The new colour to change to. (aliased to color as well)
- hoist : bool
- Indicates if the role should be shown separately in the online list.
- mentionable : bool
- Indicates if the role should be mentionable by others.
-
- Raises
- -------
- Forbidden
- You do not have permissions to change the role.
- HTTPException
- Editing the role failed.
- """
-
- colour = fields.get('colour')
- if colour is None:
- colour = fields.get('color', role.colour)
-
- payload = {
- 'name': fields.get('name', role.name),
- 'permissions': fields.get('permissions', role.permissions).value,
- 'color': colour.value,
- 'hoist': fields.get('hoist', role.hoist),
- 'mentionable': fields.get('mentionable', role.mentionable)
- }
-
- yield from self.http.edit_role(guild.id, role.id, **payload)
-
- @asyncio.coroutine
- def delete_role(self, guild, role):
- """|coro|
-
- Deletes the specified :class:`Role` for the entire :class:`Guild`.
-
- Parameters
- -----------
- guild : :class:`Guild`
- The guild the role belongs to.
- role : :class:`Role`
- The role to delete.
-
- Raises
- --------
- Forbidden
- You do not have permissions to delete the role.
- HTTPException
- Deleting the role failed.
- """
-
- yield from self.http.delete_role(guild.id, role.id)
-
- @asyncio.coroutine
- def _replace_roles(self, member, roles):
- yield from self.http.replace_roles(member.id, member.guild.id, roles)
-
- @asyncio.coroutine
- def add_roles(self, member, *roles):
- """|coro|
-
- Gives the specified :class:`Member` a number of :class:`Role` s.
-
- You must have the proper permissions to use this function.
-
- The :class:`Member` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to give roles to.
- \*roles
- An argument list of :class:`Role` s to give the member.
-
- Raises
- -------
- Forbidden
- You do not have permissions to add roles.
- HTTPException
- Adding roles failed.
- """
-
- new_roles = utils._unique(role.id for role in itertools.chain(member.roles, roles))
- yield from self._replace_roles(member, new_roles)
-
- @asyncio.coroutine
- def remove_roles(self, member, *roles):
- """|coro|
-
- Removes the :class:`Role` s from the :class:`Member`.
-
- You must have the proper permissions to use this function.
-
- The :class:`Member` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to revoke roles from.
- \*roles
- An argument list of :class:`Role` s to revoke the member.
-
- Raises
- -------
- Forbidden
- You do not have permissions to revoke roles.
- HTTPException
- Removing roles failed.
- """
- new_roles = [x.id for x in member.roles]
- for role in roles:
- try:
- new_roles.remove(role.id)
- except ValueError:
- pass
-
- yield from self._replace_roles(member, new_roles)
-
- @asyncio.coroutine
- def replace_roles(self, member, *roles):
- """|coro|
-
- Replaces the :class:`Member`'s roles.
-
- You must have the proper permissions to use this function.
-
- This function **replaces** all roles that the member has.
- For example if the member has roles ``[a, b, c]`` and the
- call is ``client.replace_roles(member, d, e, c)`` then
- the member has the roles ``[d, e, c]``.
-
- The :class:`Member` object is not directly modified afterwards until the
- corresponding WebSocket event is received.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to replace roles from.
- \*roles
- An argument list of :class:`Role` s to replace the roles with.
-
- Raises
- -------
- Forbidden
- You do not have permissions to revoke roles.
- HTTPException
- Removing roles failed.
- """
-
- new_roles = utils._unique(role.id for role in roles)
- yield from self._replace_roles(member, new_roles)
-
- @asyncio.coroutine
- def create_role(self, guild, **fields):
- """|coro|
-
- Creates a :class:`Role`.
-
- This function is similar to :class:`edit_role` in both
- the fields taken and exceptions thrown.
-
- Returns
- --------
- :class:`Role`
- The newly created role. This not the same role that
- is stored in cache.
- """
-
- data = yield from self.http.create_role(guild.id)
- role = Role(guild=guild, data=data, state=self.connection.ctx)
-
- # we have to call edit because you can't pass a payload to the
- # http request currently.
- yield from self.edit_role(guild, role, **fields)
- return role
-
@asyncio.coroutine
def edit_channel_permissions(self, channel, target, overwrite=None):
"""|coro|
@@ -3087,41 +1273,6 @@ class Client:
# Voice management
@asyncio.coroutine
- def move_member(self, member, channel):
- """|coro|
-
- Moves a :class:`Member` to a different voice channel.
-
- You must have proper permissions to do this.
-
- Note
- -----
- You cannot pass in a :class:`Object` instead of a :class:`Channel`
- object in this function.
-
- Parameters
- -----------
- member : :class:`Member`
- The member to move to another voice channel.
- channel : :class:`Channel`
- The voice channel to move the member to.
-
- Raises
- -------
- InvalidArgument
- The channel provided is not a voice channel.
- HTTPException
- Moving the member failed.
- Forbidden
- You do not have permissions to move the member.
- """
-
- if getattr(channel, 'type', ChannelType.text) != ChannelType.voice:
- raise InvalidArgument('The channel provided must be a voice channel.')
-
- yield from self.http.move_member(member.id, member.guild.id, channel.id)
-
- @asyncio.coroutine
def join_voice_channel(self, channel):
"""|coro|