<commit_before>#!/usr/bin/env python
""" 
James.py - main bot
"""

from utils.irc import IRCHandler
import utils
import traceback
import re
import os
import sys
import yaml
import json
import plugins
from collections import deque
from utils import logging
from utils.commandhandler import CommandHandler
from utils.events import Event
from utils.decorators import startinfo, sethook

CONFIG = {}
VERSION = "3.5-a1"

class James(IRCHandler):
    """ James main bot executable thingy class """
    @startinfo(VERSION)
    def __init__(self, config: dict, verbose: bool=False):
        super(James, self).__init__(config, verbose=verbose)
        globals()['CONFIG'] = config

        self.version = VERSION

        # Bot state and logger.
        self.state = utils.ServerState()
        self.log = logging.Logger()

        # state.
        self.state.events = self.initialize_events()
        self.state.apikeys = yaml.safe_load(open('apikeys.conf'))
        self.state.data = {'autojoin_channels': ['#programming']}
        self.state.data['autojoin_channels'].extend(CONFIG['autojoin'])
        self.state.admins.extend(CONFIG['admins'])
        self.state.nick = CONFIG['nick']

        # Various things
        self.lastmsgof = {}
        self.cmdhandler = CommandHandler(self, plugins.get_plugins())

    def initialize_events(self):
        return {item:Event() for item in utils.events.StandardEvents}

    def welcome(self, msg: dict):
        """ welcome(msg) - handles on-login actions """
        if CONFIG['ident_pass']:
            self.msg(CONFIG['identify_service'], 'identify %s' % (CONFIG['ident_pass']))
        self._send("MODE %s +B" % (self.state.nick))
        self.state.events['WelcomeEvent'].fire(self)

    def notice(self, msg):
        actualargs = msg['arg'].split(' ',1)[1][1:]
        sender = msg['host'].split('!')[0]
        self.state.notices.append({'sender': sender, 'message': actualargs})
        self.log.log(u"-%s- %s" % (sender, actualargs))
        

    def names(self, msg):
        """ Executed on NAMES reply """
        chantype = re.match(r'(=|@|\*).*', msg['arg'].split(' ', 1)[1])
        chantype = chantype.groups()[0]
        args = msg['arg'].split(chantype)[1]
        channel = args.split(':')[0][:-1].strip().lower()
        users = args.split(':')[1].split()
        modes = ['+', '%', '@', '&', '~']

        
        users = [u for u in users if not u[:1] in modes] + [u[1:] for u in users if u[:1] in modes]
        
        if not channel in self.state.get_channels():
            print(self.state.add_channel(channel, users))
        else:
            self.state.set_channel_users(channel, users)

    def topic(self, msg):
        """ Executed when someone changes the topic """
        channel = msg['arg'].split()[0].lower()
        user = msg['host'].split('!')[0]
        topic = msg['arg'].split(' ', 1)[1][1:]
        self.state.set_channel_topic(channel, topic)
        self.log.log("%s set topic of %s to %s" % (user, channel, topic))

    def newtopic(self, msg):
        """ Executed when you join a new channel """
        args = msg['arg']
        topic = args.split(' ', 2)[2][1:]
        channel = args.split()[1].strip().lower()
        if len(self.state.get_channel(channel)) > 0:
            self.state.get_channel(channel)[0].set_topic(topic)
        else:
            self.state.add_channel(channel, [''], topic=topic)

    def privmsg(self, msg_):
        """ Handles messages """
        nick = onick = msg_['host'].split('!')[0]
        chan = msg_['arg'].split()[0]
        if chan == self.state.nick:
            chan = nick
        chan = chan.lower()
        msg = omsg = msg_['arg'].split(':', 1)[1]
        try:
            if ':' in msg: # need this clause for directional substitution, until there's a better one
                target = msg.split(':')[0]
                if target in self.lastmsgof[chan].keys():
                    msg = msg.split(':', 1)[1].lstrip()
                    nick = target

            if utils.parse.check_for_sed(self, nick, msg):
                parsed_msg = utils.parse.parse_sed(self, msg.replace("\/", "\13"), self.lastmsgof[chan][nick])
                if parsed_msg is -1:
                    self._msg(chan, "%s: No matches found" % (onick))
                else:
                    new_msg = re.sub(parsed_msg['to_replace'], parsed_msg['replacement'], parsed_msg['oldmsg'], 0 if parsed_msg['glob'] else 1, parsed_msg['flags'])
                    self._msg(chan, "<%s> %s" % (nick, new_msg.replace("\13", "/")))

            self.oldprivmsg(msg_)
        except KeyError:
            if chan in self.lastmsgof.keys():
                self.lastmsgof[chan][onick] = deque([omsg], 16)
            else:
                self.lastmsgof[chan] = {onick: deque([omsg], 16)}

    def oldprivmsg(self, msg):
        """ Handles Messages """
        nick = onick = msg['host'].split('!')[0]
        chan = msg['arg'].split()[0]
        if chan == self.state.nick:
            chan = nick
        chan = chan.lower()
        msg = omsg = msg['arg'].split(' ', 1)[1][1:]
        if ':' in msg:<commit_msg>Sorry! Should not have committed that change.<commit_after>#!/usr/bin/env python
""" 
James.py - main bot
"""

from utils.irc import IRCHandler
import utils
import traceback
import re
import os
import sys
import yaml
import json
import plugins
from collections import deque
from utils import logging
from utils.commandhandler import CommandHandler
from utils.events import Event
from utils.decorators import startinfo, sethook

CONFIG = {}
VERSION = "3.5-a1"

class James(IRCHandler):
    """ James main bot executable thingy class """
    @startinfo(VERSION)
    def __init__(self, config: dict, verbose: bool=False):
        super(James, self).__init__(config, verbose=verbose)
        globals()['CONFIG'] = config

        self.version = VERSION

        # Bot state and logger.
        self.state = utils.ServerState()
        self.log = logging.Logger()

        # state.
        self.state.events = self.initialize_events()
        self.state.apikeys = yaml.safe_load(open('apikeys.conf'))
        self.state.data = {'autojoin_channels': ['#programming']}
        self.state.data['autojoin_channels'].extend(CONFIG['autojoin'])
        self.state.admins.extend(CONFIG['admins'])
        self.state.nick = CONFIG['nick']

        # Various things
        self.lastmsgof = {}
        self.cmdhandler = CommandHandler(self, plugins.get_plugins())

    def initialize_events(self):
        return {item:Event() for item in utils.events.StandardEvents}

    def welcome(self, msg: dict):
        """ welcome(msg) - handles on-login actions """
        if CONFIG['ident_pass']:
            self.msg(CONFIG['identify_service'], 'identify %s' % (CONFIG['ident_pass']))
        self._send("MODE %s +B" % (self.state.nick))
        self.state.events['WelcomeEvent'].fire(self)

    def notice(self, msg):
        actualargs = msg['arg'].split(' ',1)[1][1:]
        sender = msg['host'].split('!')[0]
        self.state.notices.append({'sender': sender, 'message': actualargs})
        self.log.log(u"-%s- %s" % (sender, actualargs))
        

    def names(self, msg):
        """ Executed on NAMES reply """
        chantype = re.match(r'(=|@|\*).*', msg['arg'].split(' ', 1)[1])
        chantype = chantype.groups()[0]
        args = msg['arg'].split(chantype)[1]
        channel = args.split(':')[0][:-1].strip().lower()
        users = args.split(':')[1].split()
        modes = ['+', '%', '@', '&', '~']

        
        users = [u for u in users if not u[:1] in modes] + [u[1:] for u in users if u[:1] in modes]
        
        if not channel in self.state.get_channels():
            print(self.state.add_channel(channel, users))
        else:
            self.state.set_channel_users(channel, users)

    def topic(self, msg):
        """ Executed when someone changes the topic """
        channel = msg['arg'].split()[0].lower()
        user = msg['host'].split('!')[0]
        topic = msg['arg'].split(' ', 1)[1][1:]
        self.state.set_channel_topic(channel, topic)
        self.log.log("%s set topic of %s to %s" % (user, channel, topic))

    def newtopic(self, msg):
        """ Executed when you join a new channel """
        args = msg['arg']
        topic = args.split(' ', 2)[2][1:]
        channel = args.split()[1].strip().lower()
        if len(self.state.get_channel(channel)) > 0:
            self.state.get_channel(channel)[0].set_topic(topic)
        else:
            self.state.add_channel(channel, [''], topic=topic)

    def privmsg(self, msg_):
        """ Handles messages """
        nick = onick = msg_['host'].split('!')[0]
        chan = msg_['arg'].split()[0]
        if chan == self.state.nick:
            chan = nick
        chan = chan.lower()
        msg = omsg = msg_['arg'].split(':', 1)[1]
        try:
            if ':' in msg: # need this clause for directional substitution, until there's a better one
                target = msg.split(':')[0]
                if target in self.lastmsgof[chan].keys():
                    msg = msg.split(':', 1)[1].lstrip()
                    nick = target

            if utils.parse.check_for_sed(self, nick, msg):
                parsed_msg = utils.parse.parse_sed(self, msg.replace("\/", "\13"), self.lastmsgof[chan][nick])
                if parsed_msg is -1:
                    self._msg(chan, "%s: No matches found" % (onick))
                else:
                    new_msg = re.sub(parsed_msg['to_replace'], parsed_msg['replacement'], parsed_msg['oldmsg'], 0 if parsed_msg['glob'] else 1, parsed_msg['flags'])
                    self._msg(chan, "<%s> %s" % (nick, new_msg.replace("\13", "/")))

            self.oldprivmsg(msg_)
        except KeyError:
            if chan in self.lastmsgof.keys():
                self.lastmsgof[chan][onick] = deque([omsg], 16)
            else:
                self.lastmsgof[chan] = {onick: deque([omsg], 16)}

    def oldprivmsg(self, msg):
        """ Handles Messages """
        nick = onick = msg['host'].split('!')[0]
        chan = msg['arg'].split()[0]
        if chan == self.state.nick:
            chan = nick
        chan = chan.lower()
        msg = omsg = msg['arg'].split(' ', 1)[1]
        if ':' in msg:
{'fraction_non_alphanumeric': 0.16572706065318818, 'fraction_numerical': 0.009817262830482116, 'mean_word_length': 2.3471047495120363, 'pattern_counts': {'":': 0, '<': 5, '<?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': '147504', 'n_tokens_mistral': 3253, 'n_tokens_neox': 3129, 'n_words': 731}