Browse Source

Fix support for instant invites.

pull/452/merge
Rapptz 8 years ago
parent
commit
274e6af0dd
  1. 68
      discord/abc.py
  2. 92
      discord/client.py
  3. 38
      discord/guild.py
  4. 63
      discord/invite.py

68
discord/abc.py

@ -36,6 +36,7 @@ from .context_managers import Typing
from .errors import ClientException, NoMoreItems, InvalidArgument from .errors import ClientException, NoMoreItems, InvalidArgument
from .permissions import PermissionOverwrite, Permissions from .permissions import PermissionOverwrite, Permissions
from .role import Role from .role import Role
from .invite import Invite
from . import utils, compat from . import utils, compat
class _Undefined: class _Undefined:
@ -457,6 +458,73 @@ class GuildChannel:
else: else:
raise InvalidArgument('Invalid overwrite type provided.') raise InvalidArgument('Invalid overwrite type provided.')
@asyncio.coroutine
def create_invite(self, **fields):
"""|coro|
Creates an instant invite.
Parameters
------------
max_age : int
How long the invite should last. If it's 0 then the invite
doesn't expire. Defaults to 0.
max_uses : int
How many uses the invite could be used for. If it's 0 then there
are unlimited uses. Defaults to 0.
temporary : bool
Denotes that the invite grants temporary membership
(i.e. they get kicked after they disconnect). Defaults to False.
unique: bool
Indicates if a unique invite URL should be created. Defaults to True.
If this is set to False then it will return a previously created
invite.
Raises
-------
HTTPException
Invite creation failed.
Returns
--------
:class:`Invite`
The invite that was created.
"""
data = yield from self._state.http.create_invite(self.id, **fields)
return Invite.from_incomplete(data=data, state=self._state)
@asyncio.coroutine
def invites(self):
"""|coro|
Returns a list of all active instant invites from this channel.
You must have proper permissions to get this information.
Raises
-------
Forbidden
You do not have proper permissions to get the information.
HTTPException
An error occurred while fetching the information.
Returns
-------
List[:class:`Invite`]
The list of invites that are currently active.
"""
state = self._state
data = yield from state.http.invites_from_channel(self.id)
result = []
for invite in data:
invite['channel'] = self
invite['guild'] = self.guild
result.append(Invite(state=state, data=invite))
return result
class Messageable(metaclass=abc.ABCMeta): class Messageable(metaclass=abc.ABCMeta):
__slots__ = () __slots__ = ()

92
discord/client.py

@ -696,59 +696,6 @@ class Client:
# Invite management # Invite management
def _fill_invite_data(self, data):
guild = self.connection._get_guild(data['guild']['id'])
if guild is not None:
ch_id = data['channel']['id']
channel = guild.get_channel(ch_id)
else:
guild = Object(id=data['guild']['id'])
guild.name = data['guild']['name']
channel = Object(id=data['channel']['id'])
channel.name = data['channel']['name']
data['guild'] = guild
data['channel'] = channel
@asyncio.coroutine
def create_invite(self, destination, **options):
"""|coro|
Creates an invite for the destination which could be either a
:class:`Guild` or :class:`Channel`.
Parameters
------------
destination
The :class:`Guild` or :class:`Channel` to create the invite to.
max_age : int
How long the invite should last. If it's 0 then the invite
doesn't expire. Defaults to 0.
max_uses : int
How many uses the invite could be used for. If it's 0 then there
are unlimited uses. Defaults to 0.
temporary : bool
Denotes that the invite grants temporary membership
(i.e. they get kicked after they disconnect). Defaults to False.
unique: bool
Indicates if a unique invite URL should be created. Defaults to True.
If this is set to False then it will return a previously created
invite.
Raises
-------
HTTPException
Invite creation failed.
Returns
--------
:class:`Invite`
The invite that was created.
"""
data = yield from self.http.create_invite(destination.id, **options)
self._fill_invite_data(data)
return Invite(**data)
@asyncio.coroutine @asyncio.coroutine
def get_invite(self, url): def get_invite(self, url):
"""|coro| """|coro|
@ -781,44 +728,7 @@ class Client:
invite_id = self._resolve_invite(url) invite_id = self._resolve_invite(url)
data = yield from self.http.get_invite(invite_id) data = yield from self.http.get_invite(invite_id)
self._fill_invite_data(data) return Invite.from_incomplete(state=self._connection, data=data)
return Invite(**data)
@asyncio.coroutine
def invites_from(self, guild):
"""|coro|
Returns a list of all active instant invites from a :class:`Guild`.
You must have proper permissions to get this information.
Parameters
----------
guild : :class:`Guild`
The guild to get invites from.
Raises
-------
Forbidden
You do not have proper permissions to get the information.
HTTPException
An error occurred while fetching the information.
Returns
-------
list of :class:`Invite`
The list of invites that are currently active.
"""
data = yield from self.http.invites_from(guild.id)
result = []
for invite in data:
channel = guild.get_channel(invite['channel']['id'])
invite['channel'] = channel
invite['guild'] = guild
result.append(Invite(**invite))
return result
@asyncio.coroutine @asyncio.coroutine
def accept_invite(self, invite): def accept_invite(self, invite):

38
discord/guild.py

@ -729,7 +729,7 @@ class Guild(Hashable):
Returns Returns
------- -------
list of :class:`Invite` List[:class:`Invite`]
The list of invites that are currently active. The list of invites that are currently active.
""" """
@ -743,6 +743,42 @@ class Guild(Hashable):
return result return result
@asyncio.coroutine
def create_invite(self, **fields):
"""|coro|
Creates an instant invite.
Parameters
------------
max_age : int
How long the invite should last. If it's 0 then the invite
doesn't expire. Defaults to 0.
max_uses : int
How many uses the invite could be used for. If it's 0 then there
are unlimited uses. Defaults to 0.
temporary : bool
Denotes that the invite grants temporary membership
(i.e. they get kicked after they disconnect). Defaults to False.
unique: bool
Indicates if a unique invite URL should be created. Defaults to True.
If this is set to False then it will return a previously created
invite.
Raises
-------
HTTPException
Invite creation failed.
Returns
--------
:class:`Invite`
The invite that was created.
"""
data = yield from self._state.http.create_invite(self.id, **fields)
return Invite.from_incomplete(data=data, state=self._state)
@asyncio.coroutine @asyncio.coroutine
def create_custom_emoji(self, *, name, image): def create_custom_emoji(self, *, name, image):
"""|coro| """|coro|

63
discord/invite.py

@ -24,9 +24,11 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from .user import User import asyncio
from .utils import parse_time from .utils import parse_time
from .mixins import Hashable from .mixins import Hashable
from .object import Object
class Invite(Hashable): class Invite(Hashable):
"""Represents a Discord :class:`Guild` or :class:`Channel` invite. """Represents a Discord :class:`Guild` or :class:`Channel` invite.
@ -89,9 +91,26 @@ class Invite(Hashable):
self.max_uses = data.get('max_uses') self.max_uses = data.get('max_uses')
inviter_data = data.get('inviter') inviter_data = data.get('inviter')
self.inviter = None if inviter_data is None else User(state=state, data=inviter_data) self.inviter = None if inviter_data is None else self._state.store_user(inviter_data)
self.channel = data.get('channel') self.channel = data.get('channel')
@classmethod
def from_incomplete(cls, *, state, data):
guild_id = int(data['guild']['id'])
channel_id = int(data['channel']['id'])
guild = state._get_guild(guild_id)
if guild is not None:
channel = guild.get_channel(channel_id)
else:
guild = Object(id=guild_id)
channel = Object(id=channel_id)
guild.name = data['guild']['name']
channel.name = data['channel']['name']
data['guild'] = guild
data['channel'] = channel
return cls(state=state, data=data)
def __str__(self): def __str__(self):
return self.url return self.url
@ -106,5 +125,41 @@ class Invite(Hashable):
@property @property
def url(self): def url(self):
"""A property that retrieves the invite URL.""" """A property that retrieves the invite URL."""
return 'http://discord.gg/{}'.format(self.id) return 'http://discord.gg/' + self.code
@asyncio.coroutine
def accept(self):
"""|coro|
Accepts the instant invite and adds you to the guild
the invite is in.
Raises
-------
HTTPException
Accepting the invite failed.
NotFound
The invite is invalid or expired.
Forbidden
You are a bot user and cannot use this endpoint.
"""
yield from self._state.http.accept_invite(self.code)
@asyncio.coroutine
def delete(self):
"""|coro|
Revokes the instant invite.
Raises
-------
Forbidden
You do not have permissions to revoke invites.
NotFound
The invite is invalid or expired.
HTTPException
Revoking the invite failed.
"""
yield from self._state.http.delete_invite(self.code)

Loading…
Cancel
Save