From 5efddaf35def4559e8f2124bc4fc6bf8acb8b158 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Sat, 24 Oct 2015 05:10:58 -0400 Subject: [PATCH] Support unavailable servers. --- discord/client.py | 25 +++++++++++++++++++++++++ discord/server.py | 8 ++++++++ docs/api.rst | 8 ++++++++ 3 files changed, 41 insertions(+) diff --git a/discord/client.py b/discord/client.py index ddf8385f0..25c7137d1 100644 --- a/discord/client.py +++ b/discord/client.py @@ -202,6 +202,8 @@ class ConnectionState(object): guilds = data.get('guilds') for guild in guilds: + if guild.get('unavailable', False): + continue self._add_server(guild) for pm in data.get('private_channels'): @@ -327,10 +329,33 @@ class ConnectionState(object): self.dispatch('member_update', member) def handle_guild_create(self, data): + if data.get('unavailable') is not None: + # GUILD_CREATE with unavailable in the response + # usually means that the server has become available + # and is therefore in the cache + server = self._get_server(data.get('id')) + if server is not None: + server.unavailable = False + self.dispatch('server_available', server) + return + + # if we're at this point then it was probably + # unavailable during the READY event and is now + # available, so it isn't in the cache... + self._add_server(data) self.dispatch('server_create', self.servers[-1]) def handle_guild_delete(self, data): + if data.get('unavailable', False): + # GUILD_DELETE with unavailable being True means that the + # server that was available is now currently unavailable + server = self._get_server(data.get('id')) + if server is not None: + server.unavailable = True + self.dispatch('server_unavailable', server) + return + server = self._get_server(data.get('id')) self.servers.remove(server) self.dispatch('server_delete', server) diff --git a/discord/server.py b/discord/server.py index 4004967a3..d5809032a 100644 --- a/discord/server.py +++ b/discord/server.py @@ -136,6 +136,13 @@ class Server(object): .. attribute:: owner The :class:`Member` who owns the server. + .. attribute:: unavailable + + A boolean indicating if the server is unavailable. If this is ``True`` then the + reliability of other attributes outside of :meth:`Server.id` is slim and they might + all be None. It is best to not do anything with the server if it is unavailable. + + Check the :func:`on_server_unavailable` and :func:`on_server_available` events. """ def __init__(self, **kwargs): @@ -148,6 +155,7 @@ class Server(object): self.icon = kwargs.get('icon') self.id = kwargs.get('id') self.owner = kwargs.get('owner') + self.unavailable = kwargs.get('unavailable', False) def get_default_role(self): """Gets the @everyone role that all members have by default.""" diff --git a/docs/api.rst b/docs/api.rst index eb59ca273..8c288120e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -212,6 +212,14 @@ to handle it, which defaults to print a traceback and ignore the exception. :param role: The :class:`Role` that was updated. +.. function:: on_server_available(server) + on_server_unavailable(server) + + Called when a server becomes available or unavailable. The server must have + existed in the :attr:`Client.servers` cache. + + :param server: The :class:`Server` that has changed availability. + .. function:: on_voice_state_update(member) Called when a :class:`Member` changes their voice state.