<commit_before>import sys
import random

from twisted.words.protocols import irc
from twisted.internet import reactor, protocol, task, ssl
from twisted.python import log

import thing
import command

VERSION = "0.2"


class Context(object):

    def __init__(self, user, where, bot):
        self.user = user
        self.where = where
        self.bot = bot
        self.replied = False

    @property
    def nick(self):
        return self.user.split("!", 1)[0]

    @property
    def who(self):
        return self.nick

    def reply(self, msg, where=None, replied=True):
        if not where:
            where = self.where

        self.bot.msg(where, msg)
        self.replied = replied


class KarmaBot(irc.IRCClient):
    affirmative_prefixes = [u"Affirmative", u"Alright", u"Done",
                            u"K", u"OK", u"Okay", u"Sure", u"Yes"]
    huh_msgs = [u"Huh?", u"What?"]

    def connectionMade(self):
        self.nickname = self.factory.nick
        self.password = <PASSWORD>
        irc.IRCClient.connectionMade(self)
        self.init()
        
    def init(self):
        self.things = thing.ThingStore(self.factory.filename)
        self.things.load()
        self.command_parser = command.thing.compile()
        self.listen_parser = command.listen.compile()
        
        self.save_timer = task.LoopingCall(self.save)
        self.save_timer.start(60.0*5, now=False)

    def connectionLost(self, reason):
        log.msg("Disconnected")
        self.things.save()
        irc.IRCClient.connectionLost(self, reason)

    def signedOn(self):
        log.msg("Connected")
        for channel in self.factory.channels:
            self.join_with_key(channel)

    def join_with_key(self, channel):
        if ":" in channel:
            channel, key = channel.split(":")
        else:
            key = None
        log.msg("Joining {0}".format(channel))
        self.join(channel, key)

    def save(self):
        log.msg("Saving data")
        self.things.save()

    def topicUpdated(self, user, channel, newTopic):
        thing = self.things.get_thing(channel, Context(user, channel, self))
        thing.facets["ircchannel"].topic = newTopic

    def msg(self, user, message, length=None):
        # Force conversion from unicode to utf-8
        if type(message) is unicode:
            message = message.encode("utf-8")

        for line in message.split("\n"):
            irc.IRCClient.msg(self, user, line, length)

    def privmsg(self, user, channel, msg):
        log.msg("[{channel}] {user}: {msg}".format(channel=channel,
                                                   user=user, msg=msg))
        msg = msg.decode("utf-8")
        where = self.nickname if channel == self.nickname else channel
        context = Context(user, where, self)

        listen_handled, msg = self.listen_parser.handle_command(msg, context)

        # Addressed (either in channel or by private message)
        command = None
        if msg.startswith(self.nickname):
            command = msg[len(self.factory.nick):].lstrip(" ,:").rstrip()
            if not self.command_parser.handle_command(command, context)[0]:
                self.msg(where, random.choice(self.huh_msgs))
            else:
                if not context.replied:
                    self.tell_yes(where, context.nick)

    def tell_yes(self, who, nick):
        self.msg(who, u"{yesmsg}, {nick}.".format(
                yesmsg=random.choice(self.affirmative_prefixes), nick=nick))


class KarmaBotFactory(protocol.ClientFactory):
    protocol = KarmaBot

    def __init__(self, filename, nick, channels, trusted, password=None):
        self.nick = nick
        self.channels = channels
        self.filename = filename
        self.trusted = trusted
        self.password = password

    def clientConnectionLost(self, connector, reason):
        # FIXME: Infinite reconnects are bad
        #connector.connect()
        pass

    def clientConnectionFailed(self, connector, reason):
        reactor.stop()


def main():
    from optparse import OptionParser
    parser = OptionParser(usage="usage: %prog [options] channels")

    # IRC connection options
    parser.add_option("-s", "--server",
                      action="store", dest="server",
                      default="irc.freenode.net",<commit_msg>Use ReconnectingClientFactory to get cheap and sane reconnection facilities.<commit_after>import sys
import random

from twisted.words.protocols import irc
from twisted.internet import reactor, protocol, task, ssl
from twisted.python import log

import thing
import command

VERSION = "0.2"


class Context(object):

    def __init__(self, user, where, bot):
        self.user = user
        self.where = where
        self.bot = bot
        self.replied = False

    @property
    def nick(self):
        return self.user.split("!", 1)[0]

    @property
    def who(self):
        return self.nick

    def reply(self, msg, where=None, replied=True):
        if not where:
            where = self.where

        self.bot.msg(where, msg)
        self.replied = replied


class KarmaBot(irc.IRCClient):
    affirmative_prefixes = [u"Affirmative", u"Alright", u"Done",
                            u"K", u"OK", u"Okay", u"Sure", u"Yes"]
    huh_msgs = [u"Huh?", u"What?"]

    def connectionMade(self):
        self.nickname = self.factory.nick
        self.password = self.<PASSWORD>
        irc.IRCClient.connectionMade(self)
        self.init()
        
    def init(self):
        self.things = thing.ThingStore(self.factory.filename)
        self.things.load()
        self.command_parser = command.thing.compile()
        self.listen_parser = command.listen.compile()
        
        self.save_timer = task.LoopingCall(self.save)
        self.save_timer.start(60.0*5, now=False)

    def connectionLost(self, reason):
        log.msg("Disconnected")
        self.things.save()
        irc.IRCClient.connectionLost(self, reason)

    def signedOn(self):
        log.msg("Connected")
        for channel in self.factory.channels:
            self.join_with_key(channel)

    def join_with_key(self, channel):
        if ":" in channel:
            channel, key = channel.split(":")
        else:
            key = None
        log.msg("Joining {0}".format(channel))
        self.join(channel, key)

    def save(self):
        log.msg("Saving data")
        self.things.save()

    def topicUpdated(self, user, channel, newTopic):
        thing = self.things.get_thing(channel, Context(user, channel, self))
        thing.facets["ircchannel"].topic = newTopic

    def msg(self, user, message, length=None):
        # Force conversion from unicode to utf-8
        if type(message) is unicode:
            message = message.encode("utf-8")

        for line in message.split("\n"):
            irc.IRCClient.msg(self, user, line, length)

    def privmsg(self, user, channel, msg):
        log.msg("[{channel}] {user}: {msg}".format(channel=channel,
                                                   user=user, msg=msg))
        msg = msg.decode("utf-8")
        where = self.nickname if channel == self.nickname else channel
        context = Context(user, where, self)

        listen_handled, msg = self.listen_parser.handle_command(msg, context)

        # Addressed (either in channel or by private message)
        command = None
        if msg.startswith(self.nickname):
            command = msg[len(self.factory.nick):].lstrip(" ,:").rstrip()
            if not self.command_parser.handle_command(command, context)[0]:
                self.msg(where, random.choice(self.huh_msgs))
            else:
                if not context.replied:
                    self.tell_yes(where, context.nick)

    def tell_yes(self, who, nick):
        self.msg(who, u"{yesmsg}, {nick}.".format(
                yesmsg=random.choice(self.affirmative_prefixes), nick=nick))


class KarmaBotFactory(protocol.ReconnectingClientFactory):
    protocol = KarmaBot

    def __init__(self, filename, nick, channels, trusted, password=<PASSWORD>):
        self.nick = nick
        self.channels = channels
        self.filename = filename
        self.trusted = trusted
        self.password = password

    def buildProtocol(self, addr):
        # Reset the ReconnectingClientFactory reconnect delay because we have
        # reconnected then build our protocol.
        self.resetDelay()
        return protocol.ReconnectingClientFactory.buildProtocol(self, addr)

    def clientConnectionLost(self, connector, reason):
        protocol.ReconnectingClientFactory.clientConnectionLost(self, connector, reason)

    def clientConnectionFailed(self, connector, reason):
        reactor.stop()


def main():
    from optparse import OptionParser
    parser = OptionParser(usage="usage: %prog [options] channels")

    # IRC connection options
    parser.add_option("-s", "--server",
                      action="store", dest="server",
                      default="irc.freenode.net",
{'fraction_non_alphanumeric': 0.11553430445902368, 'fraction_numerical': 0.0028911375514288893, 'mean_word_length': 2.345982142857143, 'pattern_counts': {'":': 4, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1496260', 'n_tokens_mistral': 2666, 'n_tokens_neox': 2548, 'n_words': 607}