Browse Source

Add role management functions.

pull/57/head
Rapptz 9 years ago
parent
commit
161e2ebfb0
  1. 328
      discord/client.py

328
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)

Loading…
Cancel
Save