aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--discord/client.py328
1 files changed, 328 insertions, 0 deletions
diff --git a/discord/client.py b/discord/client.py
index 3a6eea33..80d8dd13 100644
--- a/discord/client.py
+++ b/discord/client.py
@@ -1495,3 +1495,331 @@ class Client:
response = yield from self.session.delete(url, headers=self.headers)
log.debug(request_logging_format.format(method='DELETE', response=response))
yield from utils._verify_successful_response(response)
+
+
+ # Role management
+
+ @asyncio.coroutine
+ def edit_role(self, server, role, **fields):
+ """|coro|
+
+ Edits the specified :class:`Role` for the entire :class:`Server`.
+
+ This does **not** edit the role in place.
+
+ All fields except ``server`` and ``role`` are optional.
+
+ .. versionchanged:: 0.8.0
+ Editing now uses keyword arguments instead of editing the :class:`Role` object directly.
+
+ Note
+ -----
+ At the moment, the Discord API allows you to set the colour to any
+ RGB value. This might change in the future so it is recommended that
+ you use the constants in the :class:`Colour` instead such as
+ :meth:`Colour.green`.
+
+ Parameters
+ -----------
+ server : :class:`Server`
+ The server 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.
+
+ Raises
+ -------
+ Forbidden
+ You do not have permissions to change the role.
+ HTTPException
+ Editing the role failed.
+ """
+
+ url = '{0}/{1.id}/roles/{2.id}'.format(endpoints.SERVERS, server, role)
+ color = fields.get('color')
+ if color is None:
+ color = fields.get('colour', role.colour)
+
+ payload = {
+ 'name': fields.get('name', role.name),
+ 'permissions': fields.get('permissions', role.permissions).value,
+ 'color': color.value,
+ 'hoist': fields.get('hoist', role.hoist)
+ }
+
+ r = yield from self.session.patch(url, data=to_json(payload), headers=self.headers)
+ log.debug(request_logging_format.format(method='PATCH', response=r))
+ yield from utils._verify_successful_response(r)
+
+ data = yield from r.json()
+ log.debug(request_success_log.format(json=payload, response=r, data=data))
+
+ @asyncio.coroutine
+ def delete_role(self, server, role):
+ """|coro|
+
+ Deletes the specified :class:`Role` for the entire :class:`Server`.
+
+ Works in a similar matter to :func:`edit_role`.
+
+ Parameters
+ -----------
+ server : :class:`Server`
+ The server 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.
+ """
+
+ url = '{0}/{1.id}/roles/{2.id}'.format(endpoints.SERVERS, server, role)
+ response = yield from self.session.delete(url, headers=self.headers)
+ log.debug(request_logging_format.format(method='DELETE', response=response))
+ yield from utils._verify_successful_response(response)
+
+ @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.
+
+ This method **appends** a role to a member but does **not** do it
+ in-place.
+
+ 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 = [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.
+
+ This method does **not** do edit the member in-place.
+
+ 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 = {role.id for role in member.roles}
+ new_roles = new_roles.difference(roles)
+ 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]``.
+
+ This method does **not** do edit the member in-place.
+
+ 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.
+ """
+
+ url = '{0}/{1.server.id}/members/{1.id}'.format(endpoints.SERVERS, member)
+
+ payload = {
+ 'roles': [role.id for role in roles]
+ }
+
+ r = yield from self.session.patch(url, headers=self.headers, data=to_json(payload))
+ log.debug(request_logging_format.format(method='PATCH', response=r))
+ yield from utils._verify_successful_response(r)
+
+ @asyncio.coroutine
+ def create_role(self, server, **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.
+ """
+
+ url = '{0}/{1.id}/roles'.format(endpoints.SERVERS, server)
+ r = yield from self.session.post(url, headers=self.headers)
+ log.debug(request_logging_format.format(method='POST', response=r))
+ yield from utils._verify_successful_response(r)
+
+ data = yield from r.json()
+ everyone = server.id == data.get('id')
+ role = Role(everyone=everyone, **data)
+
+ # we have to call edit because you can't pass a payload to the
+ # http request currently.
+ yield from self.edit_role(server, role, **fields)
+ return role
+
+ @asyncio.coroutine
+ def edit_channel_permissions(self, channel, target, allow=None, deny=None):
+ """|coro|
+
+ Sets the channel specific permission overwrites for a target in the
+ specified :class:`Channel`.
+
+ The ``target`` parameter should either be a :class:`Member` or a
+ :class:`Role` that belongs to the channel's server.
+
+ You must have the proper permissions to do this.
+
+ Examples
+ ----------
+
+ Setting allow and deny: ::
+
+ allow = discord.Permissions.none()
+ deny = discord.Permissions.none()
+ allow.can_mention_everyone = True
+ deny.can_manage_messages = True
+ client.set_channel_permissions(message.channel, message.author, allow, deny)
+
+ Parameters
+ -----------
+ channel : :class:`Channel`
+ The channel to give the specific permissions for.
+ target
+ The :class:`Member` or :class:`Role` to overwrite permissions for.
+ allow : :class:`Permissions`
+ The permissions to explicitly allow. (optional)
+ deny : :class:`Permissions`
+ The permissions to explicitly deny. (optional)
+
+ Raises
+ -------
+ Forbidden
+ You do not have permissions to edit channel specific permissions.
+ NotFound
+ The channel specified was not found.
+ HTTPException
+ Editing channel specific permissions failed.
+ InvalidArgument
+ The allow or deny arguments were not of type :class:`Permissions`
+ or the target type was not :class:`Role` or :class:`Member`.
+ """
+
+ url = '{0}/{1.id}/permissions/{2.id}'.format(endpoints.CHANNELS, channel, target)
+
+ allow = Permissions.none() if allow is None else allow
+ deny = Permissions.none() if deny is None else deny
+
+ if not (isinstance(allow, Permissions) and isinstance(deny, Permissions)):
+ raise InvalidArgument('allow and deny parameters must be discord.Permissions')
+
+ deny = deny.value
+ allow = allow.value
+
+ payload = {
+ 'id': target.id,
+ 'allow': allow,
+ 'deny': deny
+ }
+
+ if isinstance(target, Member):
+ payload['type'] = 'member'
+ elif isinstance(target, Role):
+ payload['type'] = 'role'
+ else:
+ raise InvalidArgument('target parameter must be either discord.Member or discord.Role')
+
+ r = yield from self.session.put(url, data=to_json(payload), headers=self.headers)
+ log.debug(request_logging_format.format(method='PUT', response=r))
+ yield from utils._verify_successful_response(r)
+
+ @asyncio.coroutine
+ def delete_channel_permissions(self, channel, target):
+ """|coro|
+
+ Removes a channel specific permission overwrites for a target
+ in the specified :class:`Channel`.
+
+ The target parameter follows the same rules as :meth:`set_channel_permissions`.
+
+ You must have the proper permissions to do this.
+
+ Parameters
+ ----------
+ channel : :class:`Channel`
+ The channel to give the specific permissions for.
+ target
+ The :class:`Member` or :class:`Role` to overwrite permissions for.
+
+ Raises
+ ------
+ Forbidden
+ You do not have permissions to delete channel specific permissions.
+ NotFound
+ The channel specified was not found.
+ HTTPException
+ Deleting channel specific permissions failed.
+ """
+
+ url = '{0}/{1.id}/permissions/{2.id}'.format(endpoints.CHANNELS, channel, target)
+ response = yield from self.session.delete(url, headers=self.headers)
+ log.debug(request_logging_format.format(method='DELETE', response=response))
+ yield from utils._verify_successful_response(response)