1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Copyright (c) 2010 Google Inc. All rights reserved.
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Redistribution and use in source and binary forms, with or without
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# modification, are permitted provided that the following conditions are
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# met:
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Redistributions of source code must retain the above copyright
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# notice, this list of conditions and the following disclaimer.
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Redistributions in binary form must reproduce the above
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# copyright notice, this list of conditions and the following disclaimer
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# in the documentation and/or other materials provided with the
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# distribution.
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Neither the name of Google Inc. nor the names of its
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# contributors may be used to endorse or promote products derived from
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# this software without specific prior written permission.
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
292fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockfrom webkitpy.common.config import irc as config_irc
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.common.thread.messagepump import MessagePump, MessagePumpDelegate
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.thirdparty.autoinstalled.irc import ircbot
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfrom webkitpy.thirdparty.autoinstalled.irc import irclib
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass IRCBotDelegate(object):
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def irc_message_received(self, nick, message):
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def irc_nickname(self):
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def irc_password(self):
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass IRCBot(ircbot.SingleServerIRCBot, MessagePumpDelegate):
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # FIXME: We should get this information from a config file.
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def __init__(self,
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                 message_queue,
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                 delegate):
52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._message_queue = message_queue
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._delegate = delegate
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ircbot.SingleServerIRCBot.__init__(
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            self,
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            [(
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                config_irc.server,
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                config_irc.port,
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                self._delegate.irc_password()
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            )],
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            self._delegate.irc_nickname(),
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            self._delegate.irc_nickname())
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._channel = config_irc.channel
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # ircbot.SingleServerIRCBot methods
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def on_nicknameinuse(self, connection, event):
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        connection.nick(connection.get_nickname() + "_")
69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def on_welcome(self, connection, event):
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        connection.join(self._channel)
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._message_pump = MessagePump(self, self._message_queue)
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def on_pubmsg(self, connection, event):
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        nick = irclib.nm_to_n(event.source())
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        request = event.arguments()[0].split(":", 1)
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if len(request) > 1 and irclib.irc_lower(request[0]) == irclib.irc_lower(self.connection.get_nickname()):
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            response = self._delegate.irc_message_received(nick, request[1])
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if response:
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                connection.privmsg(self._channel, response)
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # MessagePumpDelegate methods
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def schedule(self, interval, callback):
85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.connection.execute_delayed(interval, callback)
86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def message_available(self, message):
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.connection.privmsg(self._channel, message)
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def final_message_delivered(self):
91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self.die()
92