Fix support for instant invites.
This commit is contained in:
		| @@ -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__ = () | ||||||
|   | |||||||
| @@ -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): | ||||||
|   | |||||||
| @@ -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| | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user