Browse Source

Add permission overwrites to GuildChannel.

pull/447/head
Rapptz 8 years ago
parent
commit
633eacc982
  1. 110
      discord/abc.py
  2. 90
      discord/client.py

110
discord/abc.py

@ -34,7 +34,17 @@ from collections import namedtuple
from .message import Message
from .iterators import LogsFromIterator
from .context_managers import Typing
from .errors import ClientException, NoMoreMessages
from .errors import ClientException, NoMoreMessages, InvalidArgument
from .permissions import PermissionOverwrite, Permissions
from .role import Role
import discord.utils
class _Undefined:
def __repr__(self):
return 'see-below'
_undefined = _Undefined()
class Snowflake(metaclass=abc.ABCMeta):
__slots__ = ()
@ -236,16 +246,16 @@ class GuildChannel:
The channel's permission overwrites.
"""
ret = []
for ow in self._permission_overwrites:
for ow in self._overwrites:
allow = Permissions(ow.allow)
deny = Permissions(ow.deny)
overwrite = PermissionOverwrite.from_pair(allow, deny)
if ow.type == 'role':
# accidentally quadratic
target = discord.utils.find(lambda r: r.id == ow.id, self.server.roles)
target = discord.utils.find(lambda r: r.id == ow.id, self.guild.roles)
elif ow.type == 'member':
target = self.server.get_member(ow.id)
target = self.guild.get_member(ow.id)
ret.append((target, overwrite))
return ret
@ -364,6 +374,98 @@ class GuildChannel:
"""
yield from self._state.http.delete_channel(self.id)
@asyncio.coroutine
def set_permissions(self, target, *, overwrite=_undefined, **permissions):
"""|coro|
Sets the channel specific permission overwrites for a target in the
channel.
The ``target`` parameter should either be a :class:`Member` or a
:class:`Role` that belongs to guild.
The ``overwrite`` parameter, if given, must either be ``None`` or
:class:`PermissionOverwrite`. For convenience, you can pass in
keyword arguments denoting :class:`Permissions` attributes. If this is
done, then you cannot mix the keyword arguments with the ``overwrite``
parameter.
If the ``overwrite`` parameter is ``None``, then the permission
overwrites are deleted.
You must have :attr:`Permissions.manage_roles` permission to use this.
Examples
----------
Setting allow and deny: ::
await message.channel.set_permissions(message.author, read_messages=True,
send_messages=False)
Deleting overwrites ::
await channel.set_permissions(member, overwrite=None)
Using :class:`PermissionOverwrite` ::
overwrite = discord.PermissionOverwrite()
overwrite.send_messages = False
overwrite.read_messages = True
await channel.set_permissions(member, overwrite=overwrite)
Parameters
-----------
target
The :class:`Member` or :class:`Role` to overwrite permissions for.
overwrite: :class:`PermissionOverwrite`
The permissions to allow and deny to the target.
\*\*permissions
A keyword argument list of permissions to set for ease of use.
Cannot be mixed with ``overwrite``.
Raises
-------
Forbidden
You do not have permissions to edit channel specific permissions.
HTTPException
Editing channel specific permissions failed.
InvalidArgument
The overwrite parameter invalid or the target type was not
:class:`Role` or :class:`Member`.
"""
http = self._state.http
if isinstance(target, User):
perm_type = 'member'
elif isinstance(target, Role):
perm_type = 'role'
else:
raise InvalidArgument('target parameter must be either Member or Role')
if isinstance(overwrite, _Undefined):
if len(permissions) == 0:
raise InvalidArgument('No overwrite provided.')
try:
overwrite = PermissionOverwrite(**permissions)
except:
raise InvalidArgument('Invalid permissions given to keyword arguments.')
else:
if len(permissions) > 0:
raise InvalidArgument('Cannot mix overwrite and keyword arguments.')
# TODO: wait for event
if overwrite is None:
yield from http.delete_channel_permissions(self.id, target.id)
elif isinstance(overwrite, PermissionOverwrite):
(allow, deny) = overwrite.pair()
yield from http.edit_channel_permissions(self.id, target.id, allow.value, deny.value, perm_type)
else:
raise InvalidArgument('Invalid overwrite type provided.')
class MessageChannel(metaclass=abc.ABCMeta):
__slots__ = ()

90
discord/client.py

@ -1180,96 +1180,6 @@ class Client:
invite_id = self._resolve_invite(invite)
yield from self.http.delete_invite(invite_id)
@asyncio.coroutine
def edit_channel_permissions(self, channel, target, overwrite=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 guild.
You must have the proper permissions to do this.
Examples
----------
Setting allow and deny: ::
overwrite = discord.PermissionOverwrite()
overwrite.read_messages = True
overwrite.ban_members = False
yield from client.edit_channel_permissions(message.channel, message.author, overwrite)
Parameters
-----------
channel : :class:`Channel`
The channel to give the specific permissions for.
target
The :class:`Member` or :class:`Role` to overwrite permissions for.
overwrite: :class:`PermissionOverwrite`
The permissions to allow and deny to the target.
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 overwrite parameter was not of type :class:`PermissionOverwrite`
or the target type was not :class:`Role` or :class:`Member`.
"""
overwrite = PermissionOverwrite() if overwrite is None else overwrite
if not isinstance(overwrite, PermissionOverwrite):
raise InvalidArgument('allow and deny parameters must be PermissionOverwrite')
allow, deny = overwrite.pair()
if isinstance(target, Member):
perm_type = 'member'
elif isinstance(target, Role):
perm_type = 'role'
else:
raise InvalidArgument('target parameter must be either Member or Role')
yield from self.http.edit_channel_permissions(channel.id, target.id, allow.value, deny.value, perm_type)
@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:`edit_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.
"""
yield from self.http.delete_channel_permissions(channel.id, target.id)
# Miscellaneous stuff
@asyncio.coroutine

Loading…
Cancel
Save