Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#166] Add LIST Support #172

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion pydle/features/rfc1459/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import datetime
import ipaddress
import itertools

import asyncio
from pydle.client import BasicClient, NotInChannel, AlreadyInChannel
from . import parsing, protocol

Expand Down Expand Up @@ -59,6 +59,24 @@ def _reset_attributes(self):
self.channels = parsing.NormalizingDict(self.channels, case_mapping=self._case_mapping)
self.users = parsing.NormalizingDict(self.users, case_mapping=self._case_mapping)

# List.
self.all_channels = []
self._list_client = []
self._list_channel = []
self._list_count = []
self._list_topic = []
Comment on lines +63 to +67
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should get some type annotations.

self._list_query = asyncio.Queue()

async def channel_list(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing return type annotation.

await self.rawmsg("LIST")
future = asyncio.get_running_loop().create_future()
await self._list_query.put(future)
Comment on lines +71 to +73
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This future should be enqueued prior to emitting the LIST command, to prevent a race.

try:
await future
return self.all_channels
except asyncio.CancelledError:
pass
Comment on lines +77 to +78
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should likely propagate up the cancellation error, right now it unexpectedly returns None from a function that should return a list[Channel] (where Channel = str, probably)


def _reset_connection_attributes(self):
super()._reset_connection_attributes()
self.password = None
Expand Down Expand Up @@ -869,6 +887,41 @@ async def on_raw_319(self, message):
if nickname in self._pending['whois']:
self._whois_info[nickname].update(info)

async def on_raw_321(self, message):
"""RPL_LISTSTART, an OPTIONAL indication a LIST is starting."""
...

async def on_raw_322(self, message):
"""RPL_LIST, the list of channels from the server"""
# The * channel doesn't exist but some IRCds return * as the server itself.
if message.params[1] != "*":
self._list_client.append(message.params[0])
self._list_channel.append(message.params[1])
self._list_count.append(message.params[2])
self._list_topic.append(message.params[3])

async def on_raw_323(self, message):
"""RPL_LISTEND, end of the channel list"""
self.all_channels = []

for counter, channel in enumerate(self._list_channel):
channel_dict = {
"client": self._list_client[counter],
"channel": self._list_channel[counter],
"client_count": self._list_count[counter],
"topic": self._list_topic[counter],
}
self.all_channels.append(channel_dict)

# Clear the supporting lists
self._list_client.clear()
self._list_channel.clear()
self._list_count.clear()
self._list_topic.clear()
if not self._list_query.empty():
future = await self._list_query.get()
future.set_result(self.all_channels)

async def on_raw_324(self, message):
""" Channel mode. """
target, channel = message.params[:2]
Expand Down