Skip to content
6 changes: 4 additions & 2 deletions pickups/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
14 changes: 12 additions & 2 deletions pickups/irc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from . import util

RPL_WELCOME = 1
RPL_WHOISUSER = 311
Expand All @@ -22,12 +23,14 @@

class Client(object):

def __init__(self, reader, writer):
def __init__(self, server, reader, writer):
self.server = server
self.reader = reader
self.writer = writer

self.nickname = None
self.sent_messages = []
self.joined_channels = set()

def readline(self):
return self.reader.readline()
Expand Down Expand Up @@ -64,7 +67,12 @@ 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)
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."""
Expand All @@ -87,6 +95,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))
Expand Down
44 changes: 28 additions & 16 deletions pickups/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,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")
Expand Down Expand Up @@ -102,25 +102,37 @@ 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.
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 = 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),
'JOIN', channel)
client.topic(channel, util.get_topic(conv))
client.list_nicks(channel, (util.get_nick(user)
for user in conv.users))
'PART', channel)
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:
Expand Down