<commit_before>from collections import deque, namedtuple
import logging
import re
import traceback
from fnmatch import fnmatch

from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
from twisted.plugin import getPlugins
from zope.interface import implementedBy
from zope.interface.verify import verifyObject
from zope.interface.exceptions import DoesNotImplement

import sqlalchemy
from sqlalchemy import orm

import hamper.config
import hamper.log
from hamper import plugins
from hamper.interfaces import (BaseInterface, IPresencePlugin, IChatPlugin,
                               IPopulationPlugin)


log = logging.getLogger('hamper')


def main():
    config = hamper.config.load()
    hamper.log.setup_logging()

    reactor.connectTCP(config['server'], config['port'],
                       CommanderFactory(config))
    reactor.run()


class CommanderProtocol(irc.IRCClient):
    """Interacts with a single server, and delegates to the plugins."""

    ##### Properties #####
    @property
    def nickname(self):
        return self.factory.nickname

    @property
    def db(self):
        return self.factory.loader.db

    ##### Twisted events #####

    def signedOn(self):
        """Called after successfully signing on to the server."""
        log.info("Signed on as %s.", self.nickname)
        self.dispatch('presence', 'signedOn')
        for c in self.factory.channels:
            self.join(c)

    def joined(self, channel):
        """Called after successfully joining a channel."""
        print "Joined {0}.".format(channel)
        # ask for the current list of users in the channel
        self.dispatch('presence', 'joined', channel)

    def left(self, channel):
        """Called after leaving a channel."""
        print "Left {0}.".format(channel)
        self.dispatch('presence', 'left', channel)

    def privmsg(self, raw_user, channel, raw_message):
        """Called when a message is received from a channel or user."""
        print channel, raw_user, raw_message

        if not raw_user:
            # ignore server messages
            return

        # This monster of a regex extracts msg and target from a message, where
        # the target may not be there, and the target is a valid irc name.
        # Valid ways to target someone are "<nick>: ..." and "<nick>, ..."
        target, message = re.match(
            r'^(?:([a-z_\-\[\]\\^{}|`]'  # First letter can't be a number
            '[a-z0-9_\-\[\]\\^{}|`]*)'   # The rest can be many things
            '[:,] )? *(.*)$',            # The actual message
            raw_message, re.I).groups()

        pm = channel == self.nickname
        if target:
            directed = target.lower() == self.nickname.lower()
        else:
            directed = False
        if message.startswith('!'):
            message = message[1:]
            directed = True

        try:
            user, mask = raw_user.split('!', 1)
        except ValueError:
            user = raw_user
            mask = ''

        comm = {
            'raw_message': raw_message,
            'message': message,
            'raw_user': raw_user,
            'user': user,
            'mask': mask,
            'target': target,
            'channel': channel,
            'directed': directed,
            'pm': pm,
        }

        self.dispatch('chat', 'message', comm)<commit_msg>Core: message contains target if target is not hamper.<commit_after>from collections import deque, namedtuple
import logging
import re
import traceback
from fnmatch import fnmatch

from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
from twisted.plugin import getPlugins
from zope.interface import implementedBy
from zope.interface.verify import verifyObject
from zope.interface.exceptions import DoesNotImplement

import sqlalchemy
from sqlalchemy import orm

import hamper.config
import hamper.log
from hamper import plugins
from hamper.interfaces import (BaseInterface, IPresencePlugin, IChatPlugin,
                               IPopulationPlugin)


log = logging.getLogger('hamper')


def main():
    config = hamper.config.load()
    hamper.log.setup_logging()

    reactor.connectTCP(config['server'], config['port'],
                       CommanderFactory(config))
    reactor.run()


class CommanderProtocol(irc.IRCClient):
    """Interacts with a single server, and delegates to the plugins."""

    ##### Properties #####
    @property
    def nickname(self):
        return self.factory.nickname

    @property
    def db(self):
        return self.factory.loader.db

    ##### Twisted events #####

    def signedOn(self):
        """Called after successfully signing on to the server."""
        log.info("Signed on as %s.", self.nickname)
        self.dispatch('presence', 'signedOn')
        for c in self.factory.channels:
            self.join(c)

    def joined(self, channel):
        """Called after successfully joining a channel."""
        print "Joined {0}.".format(channel)
        # ask for the current list of users in the channel
        self.dispatch('presence', 'joined', channel)

    def left(self, channel):
        """Called after leaving a channel."""
        print "Left {0}.".format(channel)
        self.dispatch('presence', 'left', channel)

    def privmsg(self, raw_user, channel, raw_message):
        """Called when a message is received from a channel or user."""
        print channel, raw_user, raw_message

        if not raw_user:
            # ignore server messages
            return

        # This monster of a regex extracts msg and target from a message, where
        # the target may not be there, and the target is a valid irc name.
        # Valid ways to target someone are "<nick>: ..." and "<nick>, ..."
        target, message = re.match(
            r'^(?:([a-z_\-\[\]\\^{}|`]'  # First letter can't be a number
            '[a-z0-9_\-\[\]\\^{}|`]*)'   # The rest can be many things
            '[:,] )? *(.*)$',            # The actual message
            raw_message, re.I).groups()

        pm = channel == self.nickname
        if target:
            if target.lower() == self.nickname.lower():
                directed = True
            else:
                directed = False
                message = '{0}: {1}'.format(target, msg)
        else:
            directed = False
        if message.startswith('!'):
            message = message[1:]
            directed = True

        try:
            user, mask = raw_user.split('!', 1)
        except ValueError:
            user = raw_user
            mask = ''

        comm = {
            'raw_message': raw_message,
            'message': message,
            'raw_user': raw_user,
            'user': user,
            'mask': mask,
            'target': target,
            'channel': channel,
            'directed': directed,
            'pm': pm,
        }

        self.dispatch('chat', 'message', comm)
{'fraction_non_alphanumeric': 0.11635581061692969, 'fraction_numerical': 0.0020086083213773313, 'mean_word_length': 2.1657584014532243, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1414226', 'n_tokens_mistral': 1890, 'n_tokens_neox': 1843, 'n_words': 600}