Browse Source

Improve thread event parsing and add DM closing

pull/10109/head
dolfies 4 years ago
parent
commit
8ed7091d9d
  1. 22
      discord/channel.py
  2. 21
      discord/gateway.py
  3. 40
      discord/state.py

22
discord/channel.py

@ -448,7 +448,6 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
List[:class:`.Message`] List[:class:`.Message`]
The list of messages that were deleted. The list of messages that were deleted.
""" """
if check is MISSING: if check is MISSING:
check = lambda m: True check = lambda m: True
@ -461,7 +460,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
async for message in iterator: async for message in iterator:
if count == 50: if count == 50:
to_delete = ret[-50:] to_delete = ret[-50:]
await _delete_messages(state, channel_id, to_delete) await state._delete_messages(channel_id, to_delete)
count = 0 count = 0
if not check(message): if not check(message):
@ -472,7 +471,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
# Some messages remaining to poll # Some messages remaining to poll
to_delete = ret[-count:] to_delete = ret[-count:]
await _delete_messages(state, channel_id, to_delete) await state._delete_messages(channel_id, to_delete)
return ret return ret
@ -1805,6 +1804,21 @@ class DMChannel(discord.abc.Messageable, discord.abc.Connectable, Hashable):
return PartialMessage(channel=self, id=message_id) return PartialMessage(channel=self, id=message_id)
async def close(self):
"""|coro|
"Deletes" the channel.
In reality, if you recreate a DM with the same user,
all your message history will be there.
Raises
-------
HTTPException
Closing the channel failed.
"""
await self._state.http.delete_channel(self.id)
async def connect(self, *, ring=True, **kwargs): async def connect(self, *, ring=True, **kwargs):
await self._get_channel() await self._get_channel()
call = self.call call = self.call
@ -2075,7 +2089,7 @@ class GroupChannel(discord.abc.Messageable, discord.abc.Connectable, Hashable):
Leaving the group failed. Leaving the group failed.
""" """
await self._state.http.leave_group(self.id) await self._state.http.delete_channel(self.id)
class PartialMessageable(discord.abc.Messageable, Hashable): class PartialMessageable(discord.abc.Messageable, Hashable):

21
discord/gateway.py

@ -116,7 +116,7 @@ class KeepAliveHandler: # Inspired by enhanced-discord.py/Gnome
self.not_responding_msg = 'Gateway has stopped responding. Closing and restarting.' self.not_responding_msg = 'Gateway has stopped responding. Closing and restarting.'
self.no_stop_msg = 'An error occurred while stopping the gateway. Ignoring.' self.no_stop_msg = 'An error occurred while stopping the gateway. Ignoring.'
self._stop_ev = asyncio.Event() self._stop = asyncio.Event()
self._last_send = time.perf_counter() self._last_send = time.perf_counter()
self._last_recv = time.perf_counter() self._last_recv = time.perf_counter()
self._last_ack = time.perf_counter() self._last_ack = time.perf_counter()
@ -125,7 +125,7 @@ class KeepAliveHandler: # Inspired by enhanced-discord.py/Gnome
async def run(self): async def run(self):
while True: while True:
try: try:
await asyncio.wait_for(self._stop_ev.wait(), timeout=self.interval) await asyncio.wait_for(self._stop.wait(), timeout=self.interval)
except asyncio.TimeoutError: except asyncio.TimeoutError:
pass pass
else: else:
@ -145,7 +145,6 @@ class KeepAliveHandler: # Inspired by enhanced-discord.py/Gnome
data = self.get_payload() data = self.get_payload()
_log.debug(self.msg) _log.debug(self.msg)
try: try:
# Block until sending is complete
total = 0 total = 0
while True: while True:
try: try:
@ -173,7 +172,7 @@ class KeepAliveHandler: # Inspired by enhanced-discord.py/Gnome
self.ws.loop.create_task(self.run()) self.ws.loop.create_task(self.run())
def stop(self): def stop(self):
self._stop_ev.set() self._stop.set()
def tick(self): def tick(self):
self._last_recv = time.perf_counter() self._last_recv = time.perf_counter()
@ -235,7 +234,7 @@ class DiscordWebSocket:
RECONNECT RECONNECT
Receive only. Tells the client to reconnect to a new gateway. Receive only. Tells the client to reconnect to a new gateway.
REQUEST_MEMBERS REQUEST_MEMBERS
Send only. Asks for the full member list of a guild. Send only. Asks for the guild members.
INVALIDATE_SESSION INVALIDATE_SESSION
Receive only. Tells the client to optionally invalidate the session Receive only. Tells the client to optionally invalidate the session
and IDENTIFY again. and IDENTIFY again.
@ -268,7 +267,7 @@ class DiscordWebSocket:
INVALIDATE_SESSION = 9 INVALIDATE_SESSION = 9
HELLO = 10 HELLO = 10
HEARTBEAT_ACK = 11 HEARTBEAT_ACK = 11
GUILD_SYNC = 12 GUILD_SYNC = 12 # :(
ACCESS_DM = 13 ACCESS_DM = 13
GUILD_SUBSCRIBE = 14 GUILD_SUBSCRIBE = 14
@ -276,15 +275,15 @@ class DiscordWebSocket:
self.socket = socket self.socket = socket
self.loop = loop self.loop = loop
# an empty dispatcher to prevent crashes # An empty dispatcher to prevent crashes
self._dispatch = lambda *args: None self._dispatch = lambda *args: None
# generic event listeners # Generic event listeners
self._dispatch_listeners = [] self._dispatch_listeners = []
# the keep alive # the keep alive
self._keep_alive = None self._keep_alive = None
self.thread_id = threading.get_ident() self.thread_id = threading.get_ident()
# ws related stuff # WS related stuff
self.session_id = None self.session_id = None
self.sequence = None self.sequence = None
self._zlib = zlib.decompressobj() self._zlib = zlib.decompressobj()
@ -315,7 +314,7 @@ class DiscordWebSocket:
socket = await client.http.ws_connect(gateway) socket = await client.http.ws_connect(gateway)
ws = cls(socket, loop=client.loop) ws = cls(socket, loop=client.loop)
# dynamically add attributes needed # Dynamically add attributes needed
ws.token = client.http.token ws.token = client.http.token
ws._connection = client._connection ws._connection = client._connection
ws._discord_parsers = client._connection.parsers ws._discord_parsers = client._connection.parsers
@ -627,7 +626,7 @@ class DiscordWebSocket:
} }
sent = utils._to_json(payload) sent = utils._to_json(payload)
_log.debug('Sending "%s" to change status', sent) _log.debug('Sending "%s" to change presence.', sent)
await self.send(sent) await self.send(sent)
async def request_lazy_guild(self, guild_id, *, typing=None, threads=None, activities=None, members=None, channels=None, thread_member_lists=None): async def request_lazy_guild(self, guild_id, *, typing=None, threads=None, activities=None, members=None, channels=None, thread_member_lists=None):

40
discord/state.py

@ -870,6 +870,11 @@ class ConnectionState:
if channel is not None: if channel is not None:
guild._remove_channel(channel) guild._remove_channel(channel)
self.dispatch('guild_channel_delete', channel) self.dispatch('guild_channel_delete', channel)
else:
channel = self._get_private_channel(channel_id)
if channel is not None:
self._remove_private_channel(channel)
self.dispatch('private_channel_delete', channel)
def parse_channel_update(self, data) -> None: def parse_channel_update(self, data) -> None:
channel_type = try_enum(ChannelType, data.get('type')) channel_type = try_enum(ChannelType, data.get('type'))
@ -956,11 +961,17 @@ class ConnectionState:
_log.debug('THREAD_CREATE referencing an unknown guild ID: %s. Discarding.', guild_id) _log.debug('THREAD_CREATE referencing an unknown guild ID: %s. Discarding.', guild_id)
return return
thread = Thread(guild=guild, state=self, data=data) existing = guild.get_thread(int(data['id']))
has_thread = guild.get_thread(thread.id) if existing is not None: # Shouldn't happen
guild._add_thread(thread) old = existing._update(data)
if not has_thread: if old is not None:
self.dispatch('thread_join', thread) self.dispatch('thread_update', old, existing)
else:
thread = Thread(guild=guild, state=self, data=data)
guild._add_thread(thread)
self.dispatch('thread_create', thread)
if self.self_id in thread.member_ids: # Thread was created by us/we were added to a private thread
self.dispatch('thread_join', thread)
def parse_thread_update(self, data) -> None: def parse_thread_update(self, data) -> None:
guild_id = int(data['guild_id']) guild_id = int(data['guild_id'])
@ -969,16 +980,17 @@ class ConnectionState:
_log.debug('THREAD_UPDATE referencing an unknown guild ID: %s. Discarding', guild_id) _log.debug('THREAD_UPDATE referencing an unknown guild ID: %s. Discarding', guild_id)
return return
thread_id = int(data['id']) existing = guild.get_thread(int(data['id']))
thread = guild.get_thread(thread_id) if existing is not None:
if thread is not None: old = existing._update(data)
old = copy.copy(thread) if old is not None:
thread._update(data) self.dispatch('thread_update', old, existing)
self.dispatch('thread_update', old, thread) else: # Shouldn't happen
else: thread = Thread(guild=guild, state=self, data=data)
thread = Thread(guild=guild, state=guild._state, data=data)
guild._add_thread(thread) guild._add_thread(thread)
self.dispatch('thread_join', thread) self.dispatch('thread_create', thread)
if self.self_id in thread.member_ids: # Thread was created by us/we were added to a private thread
self.dispatch('thread_join', thread)
def parse_thread_delete(self, data) -> None: def parse_thread_delete(self, data) -> None:
guild_id = int(data['guild_id']) guild_id = int(data['guild_id'])

Loading…
Cancel
Save