From 777e240ef41c736189c26aead5ffc902ea9503df Mon Sep 17 00:00:00 2001 From: GermainZ Date: Tue, 17 Feb 2015 17:57:38 +0200 Subject: [PATCH 1/8] Automatically join channel if new message is received --- pickups/irc.py | 6 +++++- pickups/server.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pickups/irc.py b/pickups/irc.py index 040a73d..aa62dab 100644 --- a/pickups/irc.py +++ b/pickups/irc.py @@ -28,6 +28,7 @@ def __init__(self, reader, writer): self.nickname = None self.sent_messages = [] + self.joined_channels = set() def readline(self): return self.reader.readline() @@ -64,7 +65,8 @@ def list_channels(self, info): def join(self, channel): """Tells the client to join a channel.""" - self.write(self.nickname, 'JOIN', ':{}'.format(channel)) + self.joined_channels.add(channel) + self.write(self.nickname, 'JOIN', channel) def list_nicks(self, channel, nicks): """Tells the client what nicks are in channel.""" @@ -87,6 +89,8 @@ def topic(self, channel, topic): def privmsg(self, hostmask, target, message): """Sends the client a message from someone.""" + if target not in self.joined_channels: + self.join(target) for line in message.splitlines(): if line: self.write(hostmask, 'PRIVMSG', target, ':{}'.format(line)) diff --git a/pickups/server.py b/pickups/server.py index 19dfb20..6f0894f 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -122,6 +122,10 @@ def _handle_client(self, client): client.topic(channel, util.get_topic(conv)) client.list_nicks(channel, (util.get_nick(user) for user in conv.users)) + client.joined_channels.add(channel) + elif line.startswith('PART'): + channel = line.split(' ')[1] + client.joined_channels.remove(channel) elif line.startswith('WHO'): query = line.split(' ')[1] if query.startswith('#'): From 6ceb7b2ba9c883620d3fb01dac900000894b629e Mon Sep 17 00:00:00 2001 From: GermainZ Date: Tue, 17 Feb 2015 18:52:33 +0200 Subject: [PATCH 2/8] Set topic/nicklist when channel is joined automatically --- pickups/irc.py | 8 +++++++- pickups/server.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pickups/irc.py b/pickups/irc.py index aa62dab..cd7d216 100644 --- a/pickups/irc.py +++ b/pickups/irc.py @@ -1,4 +1,5 @@ import logging +from . import util RPL_WELCOME = 1 RPL_WHOISUSER = 311 @@ -22,7 +23,8 @@ class Client(object): - def __init__(self, reader, writer): + def __init__(self, server, reader, writer): + self.server = server self.reader = reader self.writer = writer @@ -67,6 +69,10 @@ def join(self, channel): """Tells the client to join a channel.""" self.joined_channels.add(channel) self.write(self.nickname, 'JOIN', channel) + conv = util.channel_to_conversation(channel, self.server._conv_list) + self.topic(channel, util.get_topic(conv)) + self.list_nicks(channel, (util.get_nick(user) for user in conv.users)) + def list_nicks(self, channel, nicks): """Tells the client what nicks are in channel.""" diff --git a/pickups/server.py b/pickups/server.py index 6f0894f..3d54e6a 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -61,7 +61,7 @@ def _on_hangups_event(self, conv_event): def _on_client_connect(self, client_reader, client_writer): """Called when an IRC client connects.""" - client = irc.Client(client_reader, client_writer) + client = irc.Client(self, client_reader, client_writer) task = asyncio.Task(self._handle_client(client)) self.clients[task] = client logger.info("New Connection") From 1ca8b096e6201d4fbac29ec0b3846a9cd56790e9 Mon Sep 17 00:00:00 2001 From: GermainZ Date: Tue, 17 Feb 2015 18:56:27 +0200 Subject: [PATCH 3/8] Fix: 'channel' referenced before assignment --- pickups/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pickups/server.py b/pickups/server.py index 3d54e6a..64c6015 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -129,6 +129,7 @@ def _handle_client(self, client): elif line.startswith('WHO'): query = line.split(' ')[1] if query.startswith('#'): + channel = line.split(' ')[1] conv = util.channel_to_conversation(channel, self._conv_list) if not conv: From df4a1c38e6346be1594b58120fb16390bec28c34 Mon Sep 17 00:00:00 2001 From: Jeff Corcoran Date: Thu, 25 Jun 2015 11:42:52 -0400 Subject: [PATCH 4/8] Add custom cookies param --- pickups/__main__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pickups/__main__.py b/pickups/__main__.py index a6a6b8d..5918f3c 100644 --- a/pickups/__main__.py +++ b/pickups/__main__.py @@ -12,14 +12,16 @@ logging.basicConfig(level=logging.INFO, stream=sys.stdout) logging.getLogger('hangups').setLevel(logging.WARNING) dirs = appdirs.AppDirs('hangups', 'hangups') - default_cookies_path = os.path.join(dirs.user_cache_dir, 'cookies.json') - cookies = hangups.auth.get_auth_stdin(default_cookies_path) parser = argparse.ArgumentParser(description='IRC Gateway for Hangouts') + parser.add_argument('--cookies', help='cookies filename', default='cookies.json') parser.add_argument('--address', help='bind address', default='127.0.0.1') parser.add_argument('--port', help='bind port', default=6667) parser.add_argument('--ascii-smileys', action='store_true', help='display smileys in ascii') args = parser.parse_args() + default_cookies_path = os.path.join(dirs.user_cache_dir, args.cookies) + cookies = hangups.auth.get_auth_stdin(default_cookies_path) + Server(cookies, args.ascii_smileys).run(args.address, args.port) From a15d4ca09c010e7c7fae156c9d802c8290a17954 Mon Sep 17 00:00:00 2001 From: Jeff Corcoran Date: Thu, 25 Jun 2015 12:04:35 -0400 Subject: [PATCH 5/8] Fix double part issue with ZNC --- pickups/server.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pickups/server.py b/pickups/server.py index 64c6015..f76cfeb 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -125,7 +125,10 @@ def _handle_client(self, client): client.joined_channels.add(channel) elif line.startswith('PART'): channel = line.split(' ')[1] - client.joined_channels.remove(channel) + if channel in client.joined_channels: + client.joined_channels.remove(channel) + client.write(util.get_nick(self._user_list._self_user), + 'PART', channel) elif line.startswith('WHO'): query = line.split(' ')[1] if query.startswith('#'): From 9cd2ad4f614c27d87d5a31a8298a86e209517070 Mon Sep 17 00:00:00 2001 From: Jeff Corcoran Date: Thu, 25 Jun 2015 12:38:33 -0400 Subject: [PATCH 6/8] Bump hangups requirement --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0fc3957..4710292 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -hangups==0.2 +hangups>=0.2 From 28af83a1fdd2d49e4b6989f7504acb89db0d7787 Mon Sep 17 00:00:00 2001 From: Jeff Corcoran Date: Thu, 25 Jun 2015 12:55:09 -0400 Subject: [PATCH 7/8] Handle multiple comma separated join/parts --- pickups/server.py | 48 +++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/pickups/server.py b/pickups/server.py index f76cfeb..af4e0c3 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -106,29 +106,33 @@ def _handle_client(self, client): segments = hangups.ChatMessageSegment.from_str(message[1:]) asyncio.async(conv.send_message(segments)) elif line.startswith('JOIN'): - channel = line.split(' ')[1] - conv = util.channel_to_conversation(channel, self._conv_list) - if not conv: - client.swrite(irc.ERR_NOSUCHCHANNEL, - ':{}: Channel not found'.format(channel)) - else: - # If a JOIN is successful, the user receives a JOIN message - # as confirmation and is then sent the channel's topic - # (using RPL_TOPIC) and the list of users who are on the - # channel (using RPL_NAMREPLY), which MUST include the user - # joining. - client.write(util.get_nick(self._user_list._self_user), - 'JOIN', channel) - client.topic(channel, util.get_topic(conv)) - client.list_nicks(channel, (util.get_nick(user) - for user in conv.users)) - client.joined_channels.add(channel) + channel_line = line.split(' ')[1] + channels = channel_line.split(',') + for channel in channels: + conv = util.channel_to_conversation(channel, self._conv_list) + if not conv: + client.swrite(irc.ERR_NOSUCHCHANNEL, + ':{}: Channel not found'.format(channel)) + else: + # If a JOIN is successful, the user receives a JOIN message + # as confirmation and is then sent the channel's topic + # (using RPL_TOPIC) and the list of users who are on the + # channel (using RPL_NAMREPLY), which MUST include the user + # joining. + client.write(util.get_nick(self._user_list._self_user), + 'JOIN', channel) + client.topic(channel, util.get_topic(conv)) + client.list_nicks(channel, (util.get_nick(user) + for user in conv.users)) + client.joined_channels.add(channel) elif line.startswith('PART'): - channel = line.split(' ')[1] - if channel in client.joined_channels: - client.joined_channels.remove(channel) - client.write(util.get_nick(self._user_list._self_user), - 'PART', channel) + channel_line = line.split(' ')[1] + channels = channel_line.split(',') + for channel in channels: + if channel in client.joined_channels: + client.joined_channels.remove(channel) + client.write(util.get_nick(self._user_list._self_user), + 'PART', channel) elif line.startswith('WHO'): query = line.split(' ')[1] if query.startswith('#'): From 1eac14767370f91bb99923357a97dd37a377c683 Mon Sep 17 00:00:00 2001 From: Jeff Corcoran Date: Thu, 25 Jun 2015 13:39:45 -0400 Subject: [PATCH 8/8] Only add to dict when actually joined --- pickups/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pickups/server.py b/pickups/server.py index af4e0c3..83254c0 100644 --- a/pickups/server.py +++ b/pickups/server.py @@ -124,7 +124,7 @@ def _handle_client(self, client): client.topic(channel, util.get_topic(conv)) client.list_nicks(channel, (util.get_nick(user) for user in conv.users)) - client.joined_channels.add(channel) + client.joined_channels.add(channel) elif line.startswith('PART'): channel_line = line.split(' ')[1] channels = channel_line.split(',')