diff --git a/MANIFEST.in b/MANIFEST.in index 5e2e278..bddc36d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,3 +7,4 @@ recursive-include tests * recursive-exclude * __pycache__ recursive-exclude * *.py[co] recursive-include sopel_modules/SpiceBot_GifSearch/gifapi * +recursive-include sopel_modules/SpiceBot_Configs/aiml * diff --git a/sopel_modules/SpiceBot/AI.py b/sopel_modules/SpiceBot/AI.py new file mode 100644 index 0000000..850669e --- /dev/null +++ b/sopel_modules/SpiceBot/AI.py @@ -0,0 +1,243 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot AI system. Based On Chatty cathy +""" + +from sopel.tools import Identifier +from sopel.config.types import StaticSection, ListAttribute, ValidatedAttribute + +import os +import tempfile +import aiml + +from .Database import db as botdb +from .Config import config as botconfig + + +class SpiceBot_AI_MainSection(StaticSection): + extra = ListAttribute('extra') + gender = ValidatedAttribute('gender', default='female') + + +class SpiceBot_AI(): + + def __init__(self): + self.setup_ai() + self.braindirs = [] + self.dict = { + "patterncounts": 0, + "filecounts": 0, + "sessioncache": {}, + "files": {} + } + # Load AIML kernel + self.aiml_kernel = aiml.Kernel() + + # aiml parser + self.aiml_parser = aiml.AimlParser.create_parser() + + # Don't warn for no matches + self.aiml_kernel._verboseMode = False + + # Learn responses + self.load_saved_brain() + self.load_brain() + + # Load bot values + self.load_bot_values() + + def setup_ai(self): + botconfig.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False) + botconfig.config.aibrain = os.path.join(botconfig.homedir, botconfig.config.core.basename + '.aibrain.brn') + + def load_saved_brain(self): + if os.path.isfile(botconfig.config.aibrain): + self.aiml_kernel.bootstrap(brainFile=botconfig.config.aibrain) + self.save_brain() + + def load_brain(self): + import sopel_modules + braindirs = [] + for plugin_dir in set(sopel_modules.__path__): + configsdir = os.path.join(plugin_dir, "SpiceBot_Configs") + aimldir = os.path.join(configsdir, "aiml") + braindirs.append(aimldir) + + if len(botconfig.SpiceBot_AI.extra): + for extrabraindir in botconfig.SpiceBot_AI.extra: + braindirs.append(extrabraindir) + + # learn directories + self.learn(braindirs) + self.save_brain() + + def load_bot_values(self): + + current_bot_db = botdb.get_bot_value('botai') or None + if current_bot_db: + for predicate in current_bot_db.keys(): + predval = current_bot_db[predicate] + self.aiml_kernel.setBotPredicate(predicate, predval) + + # sopel nick + self.aiml_kernel.setBotPredicate("nick", botconfig.nick) + + # gender + self.aiml_kernel.setBotPredicate("gender", botconfig.SpiceBot_AI.gender.lower()) + if botconfig.SpiceBot_AI.gender.lower() not in ["male", "female"]: + self.aiml_kernel.setBotPredicate("gendertype", "item") + else: + self.aiml_kernel.setBotPredicate("gendertype", botconfig.SpiceBot_AI.gender.lower()) + + def learn(self, braindirs): + for braindir in braindirs: + if braindir not in self.braindirs: + self.braindirs.append(braindir) + + # Count matches + for pathname in os.listdir(braindir): + self.dict["filecounts"] += 1 + aimlfile = os.path.join(braindir, pathname) + data = open(aimlfile).read() + count = data.count('pattern') + count = count / 2 + self.dict["patterncounts"] += int(count) + + tempbrain = tempfile.mkstemp()[1] + with open(tempbrain, 'w') as fileo: + fileo.write( + "" + " \n" + " \n" + " LOAD AIML B\n" + " \n" + " \n" + "".format(os.path.join(braindir, "*.aiml")) + ) + self.aiml_kernel.learn(tempbrain) + self.aiml_kernel.respond("LOAD AIML B") + + def on_message(self, bot, trigger, message): + + nick = Identifier(trigger.nick) + nick_id = botdb.get_nick_id(nick, create=True) + self.check_user_import(nick, nick_id) + + message = self.bot_message_precipher(bot, trigger, message) + aiml_response = self.aiml_kernel.respond(message, nick_id) + if aiml_response: + aiml_response = self.bot_message_decipher(bot, trigger, aiml_response) + + self.save_nick_session(nick, nick_id) + self.save_brain() + + return aiml_response + + def bot_message_precipher(self, bot, trigger, message): + + # uppercase input + message = message.upper() + + # punctuation + puct_dict = {"!": "exclamationmark", ".": "period", "?": "questionmark", ",": "comma"} + for puctuation in puct_dict.keys(): + message = message.replace(puctuation, puct_dict[puctuation]) + + # bot items + for botitem in ["nick"]: + message = message.replace(str(eval("bot." + botitem)).upper(), str("bot" + botitem).upper()) + + for triggeritem in ["nick", "sender"]: + message = message.replace(str(eval("trigger." + triggeritem)).upper(), str("trigger" + triggeritem).upper()) + + return message + + def bot_message_decipher(self, bot, trigger, aiml_response): + + # bot items + for botitem in ["nick"]: + aiml_response = aiml_response.replace("bot" + botitem, str(eval("bot." + botitem))) + + # trigger items + for triggeritem in ["nick", "sender"]: + aiml_response = aiml_response.replace("trigger" + triggeritem, str(eval("trigger." + triggeritem))) + + # pronouns + botgendertype = self.aiml_kernel.getBotPredicate("gendertype") + pronounsdict = { + "male": { + "main": "he", + "possess": "his", + "self": "himself", + }, + "female": { + "main": "her", + "possess": "hers", + "self": "herself", + }, + "item": { + "main": "it", + "possess": "its", + "self": "itself", + }, + "point": { + "main": "you", + "possess": "yours", + "self": "yourself", + }, + "group": { + "main": "them", + "possess": "theirs", + "self": "themselves", + }, + } + for pronounitem in pronounsdict[botgendertype].keys(): + aiml_response = aiml_response.replace("BOTPRONOUN" + pronounitem, pronounsdict[botgendertype][pronounitem]) + triggergendertype = self.getPredicate("gender", trigger.nick) + if not triggergendertype or triggergendertype == "": + triggergendertype = "point" + for pronounitem in pronounsdict[triggergendertype].keys(): + aiml_response = aiml_response.replace("TRIGGERPRONOUN" + pronounitem, pronounsdict[triggergendertype][pronounitem]) + + aiml_response = "\x0315" + aiml_response + "\x03" + + return aiml_response + + def getPredicate(self, predicate, nick, nick_id=None): + if not nick_id: + nick = Identifier(nick) + nick_id = botdb.get_nick_id(nick, create=True) + self.aiml_kernel.getPredicate(predicate, nick_id) + + def check_user_import(self, nick, nick_id=None): + if not nick_id: + nick = Identifier(nick) + nick_id = botdb.get_nick_id(nick, create=True) + if nick_id not in self.dict["sessioncache"].keys(): + self.dict["sessioncache"][nick_id] = botdb.get_nick_value(nick, 'botai') or {} + for predicate in self.dict["sessioncache"][nick_id].keys(): + predval = self.dict["sessioncache"][nick_id][predicate] + self.aiml_kernel.setPredicate(predicate, predval, nick_id) + + # defaults + if "nick" not in self.dict["sessioncache"][nick_id].keys(): + self.dict["sessioncache"][nick_id]["nick"] = nick + self.aiml_kernel.setPredicate("nick", nick, nick_id) + + def save_nick_session(self, nick, nick_id=None): + if not nick_id: + nick = Identifier(nick) + nick_id = botdb.get_nick_id(nick, create=True) + sessionData = self.aiml_kernel.getSessionData(nick_id) + botdb.set_nick_value(nick, 'botai', sessionData) + + def save_brain(self): + self.aiml_kernel.saveBrain(botconfig.config.aibrain) + botsessiondata = self.aiml_kernel._botPredicates + botdb.set_bot_value('botai', botsessiondata) + + +botai = SpiceBot_AI() diff --git a/sopel_modules/SpiceBot/Channels.py b/sopel_modules/SpiceBot/Channels.py index c8f8d72..ddf89ce 100644 --- a/sopel_modules/SpiceBot/Channels.py +++ b/sopel_modules/SpiceBot/Channels.py @@ -1,22 +1,38 @@ # coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function """ -This is the SpiceBot Logs system. - -This Class stores logs in an easy to access manner +This is the SpiceBot Channels system. """ import sopel +from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute + import re +import threading + +from .Config import config as botconfig + + +class SpiceBot_Channels_MainSection(StaticSection): + announcenew = ValidatedAttribute('announcenew', default=False) + joinall = ValidatedAttribute('joinall', default=False) + operadmin = ValidatedAttribute('operadmin', default=False) + chanignore = ListAttribute('chanignore') class BotChannels(): """This Logs all channels known to the server""" def __init__(self): + self.setup_channels() + + self.lock = threading.Lock() self.channel_lock = False - self.SpiceBot_Channels = { - "list": {}, - "InitialProcess": False - } + self.dict = { + "list": {}, + "InitialProcess": False + } + + def setup_channels(self): + botconfig.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) def channel_list_request(self, bot): bot.write(['LIST']) @@ -25,16 +41,20 @@ class BotChannels(): self.channel_lock = True def channel_list_recieve_input(self, trigger): + self.lock.acquire() channel, _, topic = trigger.args[1:] - if channel.lower() not in self.SpiceBot_Channels['list'].keys(): - self.SpiceBot_Channels['list'][channel.lower()] = dict() - self.SpiceBot_Channels['list'][channel.lower()]['name'] = channel - self.SpiceBot_Channels['list'][channel.lower()]['topic'] = self.topic_compile(topic) + if channel.lower() not in self.dict['list'].keys(): + self.dict['list'][channel.lower()] = dict() + self.dict['list'][channel.lower()]['name'] = channel + self.dict['list'][channel.lower()]['topic'] = self.topic_compile(topic) self.channel_lock = True + self.lock.release() def channel_list_recieve_finish(self): - if not self.SpiceBot_Channels['InitialProcess']: - self.SpiceBot_Channels['InitialProcess'] = True + self.lock.acquire() + if not self.dict['InitialProcess']: + self.dict['InitialProcess'] = True + self.lock.release() self.channel_lock = False def topic_compile(self, topic): @@ -50,28 +70,30 @@ class BotChannels(): for channel in bot.channels.keys(): if len(bot.channels[channel].privileges.keys()) == 1 and channel not in ignorepartlist and channel.startswith("#"): bot.part(channel, "Leaving Empty Channel") - if channel.lower() in botchannels.SpiceBot_Channels['list']: - del botchannels.SpiceBot_Channels['list'][channel.lower()] + if channel.lower() in self.dict['list']: + self.lock.acquire() + del self.dict['list'][channel.lower()] + self.lock.release() def join_all_channels(self, bot): - if bot.config.SpiceBot_Channels.joinall: - for channel in botchannels.SpiceBot_Channels['list'].keys(): + if botconfig.SpiceBot_Channels.joinall: + for channel in self.dict['list'].keys(): if channel.startswith("#"): - if channel not in bot.channels.keys() and channel not in bot.config.SpiceBot_Channels.chanignore: - bot.write(('JOIN', bot.nick, botchannels.SpiceBot_Channels['list'][channel]['name'])) - if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin: - bot.write(('SAJOIN', bot.nick, botchannels.SpiceBot_Channels['list'][channel]['name'])) + if channel not in bot.channels.keys() and channel not in botconfig.SpiceBot_Channels.chanignore: + bot.write(('JOIN', bot.nick, self.dict['list'][channel]['name'])) + if channel not in bot.channels.keys() and botconfig.SpiceBot_Channels.operadmin: + bot.write(('SAJOIN', bot.nick, self.dict['list'][channel]['name'])) def chanadmin_all_channels(self, bot): # Chan ADMIN +a for channel in bot.channels.keys(): if channel.startswith("#"): - if channel not in bot.config.SpiceBot_Channels.chanignore: - if bot.config.SpiceBot_Channels.operadmin: + if channel not in botconfig.SpiceBot_Channels.chanignore: + if botconfig.SpiceBot_Channels.operadmin: if not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN: bot.write(('SAMODE', channel, "+a", bot.nick)) else: bot.part(channel) -botchannels = BotChannels() +channels = BotChannels() diff --git a/sopel_modules/SpiceBot/Commands.py b/sopel_modules/SpiceBot/Commands.py new file mode 100644 index 0000000..e495b21 --- /dev/null +++ b/sopel_modules/SpiceBot/Commands.py @@ -0,0 +1,259 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Commands system. + +This Class stores commands in an easy to access manner +""" + +import sopel +from sopel.config.types import StaticSection, ValidatedAttribute + +import os +import threading + +import spicemanip + +from .Logs import logs +from .Config import config as botconfig +from .Database import db as botdb + + +class SpiceBot_Commands_MainSection(StaticSection): + query_prefix = ValidatedAttribute('query_prefix', default="?") + + +class BotCommands(): + """This Logs all commands known to the bot""" + def __init__(self): + self.setup_commands() + self.lock = threading.Lock() + self.dict = { + "counts": 0, + 'nickrules': [], + 'nickaiml': [], + "commands": { + 'module': {}, + 'nickname': {}, + 'rule': {} + }, + 'disabled': {} + } + self.module_files_parse() + self.nickrules() + for comtype in ['module', 'nickname', 'rule']: + logs.log('SpiceBot_Commands', "Found " + str(len(self.dict['commands'][comtype].keys())) + " " + comtype + " commands.", True) + + def setup_commands(self): + botconfig.define_section("SpiceBot_Commands", SpiceBot_Commands_MainSection, validate=False) + botconfig.core.query_list = str(botconfig.SpiceBot_Commands.query_prefix).replace("\\", '').split("|") + botconfig.core.prefix_list.extend(botconfig.SpiceBot_Commands.query_prefix) + + def nickrules(self): + for command in self.dict['commands']['rule'].keys(): + if command.startswith("$nickname"): + command = command.split("$nickname")[-1] + if command not in self.dict['nickrules']: + self.dict['nickrules'].append(command) + + def find_command_type(self, command): + for commandstype in self.dict['commands'].keys(): + if commandstype not in ['rule']: + for com in self.dict['commands'][commandstype].keys(): + if com.lower() == command.lower(): + return commandstype + return None + + def get_commands_disabled(self, channel): + if not len(list(self.dict['disabled'])): + self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {} + return self.dict['disabled'] + + def check_commands_disabled(self, command, channel): + if command in self.get_commands_disabled(channel).keys(): + return True + else: + return False + + def get_realcom(self, command, trigger_command_type): + realcom = command + + if trigger_command_type not in self.dict['commands'].keys(): + return realcom + + if command not in self.dict['commands'][trigger_command_type].keys(): + return realcom + + if "aliasfor" in self.dict['commands'][trigger_command_type][command].keys(): + realcom = self.dict['commands'][trigger_command_type][command] + + return realcom + + def set_command_disabled(self, command, channel, timestamp, reason, bywhom): + if not len(list(self.dict['disabled'])): + self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {} + self.dict['disabled'][command] = {"reason": reason, "timestamp": timestamp, "disabledby": bywhom} + botdb.set_channel_value(channel, 'commands_disabled', self.dict['disabled']) + + def unset_command_disabled(self, command, channel): + if not len(list(self.dict['disabled'])): + self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {} + if command in self.dict['disabled'].keys(): + del self.dict['disabled'][command] + botdb.set_channel_value(channel, 'commands_disabled', self.dict['disabled']) + + def register(self, command_dict): + + self.lock.acquire() + + command_type = command_dict["comtype"] + validcoms = command_dict["validcoms"] + + if not isinstance(validcoms, list): + validcoms = [validcoms] + + if command_type not in self.dict['commands'].keys(): + self.dict['commands'][command_type] = dict() + + dict_from_file = dict() + + # default command to filename + if "validcoms" not in dict_from_file.keys(): + dict_from_file["validcoms"] = validcoms + + maincom = dict_from_file["validcoms"][0] + if len(dict_from_file["validcoms"]) > 1: + comaliases = spicemanip.main(dict_from_file["validcoms"], '2+', 'list') + else: + comaliases = [] + + self.dict['commands'][command_type][maincom] = dict_from_file + for comalias in comaliases: + if comalias not in self.dict['commands'][command_type].keys(): + self.dict['commands'][command_type][comalias] = {"aliasfor": maincom} + + self.lock.release() + + def module_directory_list(self): + filepathlisting = [] + + # main Modules directory + main_dir = os.path.dirname(os.path.abspath(sopel.__file__)) + modules_dir = os.path.join(main_dir, 'modules') + filepathlisting.append(modules_dir) + + # Home Directory + home_modules_dir = os.path.join(botconfig.homedir, 'modules') + if os.path.isdir(home_modules_dir): + filepathlisting.append(home_modules_dir) + + # pypi installed + try: + import sopel_modules + for plugin_dir in set(sopel_modules.__path__): + for pathname in os.listdir(plugin_dir): + pypi_modules_dir = os.path.join(plugin_dir, pathname) + filepathlisting.append(pypi_modules_dir) + except Exception as e: + logs.log('SpiceBOT_COMMANDS', "sopel_modules not loaded :" + str(e)) + + # Extra directories + for directory in botconfig.extra: + filepathlisting.append(directory) + + return filepathlisting + + def module_files_list(self): + filepathlisting = self.module_directory_list() + + filepathlist = [] + + for directory in filepathlisting: + for pathname in os.listdir(directory): + path = os.path.join(directory, pathname) + if (os.path.isfile(path) and path.endswith('.py') and not path.startswith('_')): + if pathname not in ["SpiceBot_dummycommand.py"]: + filepathlist.append(str(path)) + + # CoreTasks + main_dir = os.path.dirname(os.path.abspath(sopel.__file__)) + ct_path = os.path.join(main_dir, 'coretasks.py') + filepathlist.append(ct_path) + + return filepathlist + + def module_files_parse(self): + filepathlist = self.module_files_list() + + for modulefile in filepathlist: + + module_file_lines = [] + module_file = open(modulefile, 'r') + lines = module_file.readlines() + for line in lines: + module_file_lines.append(line) + module_file.close() + + detected_lines = [] + for line in module_file_lines: + + if str(line).startswith("@"): + line = str(line)[1:] + + if str(line).startswith(tuple(["commands", "module.commands", "sopel.module.commands"])): + line = str(line).split("commands")[-1] + line = "commands" + line + detected_lines.append(line) + elif str(line).startswith(tuple(["nickname_commands", "module.nickname_commands", "sopel.module.nickname_commands"])): + line = str(line).split("nickname_commands")[-1] + line = "nickname_commands" + line + detected_lines.append(line) + elif str(line).startswith(tuple(["rule", "module.rule", "sopel.module.rule"])): + line = str(line).split("rule")[-1] + line = "rule" + line + else: + line = None + + if line: + detected_lines.append(line) + + if len(detected_lines): + + filelinelist = [] + currentsuccesslines = 0 + for detected_line in detected_lines: + + # Commands + if str(detected_line).startswith("commands"): + comtype = "module" + validcoms = eval(str(detected_line).split("commands")[-1]) + elif str(detected_line).startswith("nickname_commands"): + comtype = "nickname" + validcoms = eval(str(detected_line).split("nickname_commands")[-1]) + elif str(detected_line).startswith("rule"): + comtype = "rule" + validcoms = eval(str(detected_line).split("rule")[-1]) + + if isinstance(validcoms, tuple): + validcoms = list(validcoms) + else: + validcoms = [validcoms] + for regexcom in ["(.*)", '^\?(.*)']: + if regexcom in validcoms: + while regexcom in validcoms: + validcoms.remove(regexcom) + + if len(validcoms): + validcomdict = {"comtype": comtype, "validcoms": validcoms} + filelinelist.append(validcomdict) + currentsuccesslines += 1 + + if currentsuccesslines: + self.dict['counts'] += 1 + + if len(filelinelist): + for atlinefound in filelinelist: + self.register(atlinefound) + + +commands = BotCommands() diff --git a/sopel_modules/SpiceBot/Config.py b/sopel_modules/SpiceBot/Config.py new file mode 100644 index 0000000..b7f9bb5 --- /dev/null +++ b/sopel_modules/SpiceBot/Config.py @@ -0,0 +1,57 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +"""A way to read the bot's config without bot""" + +from sopel.cli.run import build_parser, get_configuration + +import sys +import os +import configparser + + +class BotConfig(): + + def __init__(self): + self.dict = {} + # Load config + parser = build_parser() + if not len(sys.argv[1:]): + argv = ['legacy'] + else: + argv = sys.argv[1:] + opts = parser.parse_args(argv) + self.config = get_configuration(opts) + + self.setup_config() + + # load as dict + config = configparser.ConfigParser() + config.read(self.config.filename) + for each_section in config.sections(): + if each_section.lower() not in self.dict.keys(): + self.dict[each_section.lower()] = dict() + for (each_key, each_val) in config.items(each_section): + if each_key.lower() not in self.dict[each_section.lower()].keys(): + self.dict[each_section.lower()][each_key.lower()] = each_val + + def setup_config(self): + self.config.core.basename = os.path.basename(self.config.filename).rsplit('.', 1)[0] + self.config.core.prefix_list = str(self.config.core.prefix).replace("\\", '').split("|") + + def define_section(self, name, cls_, validate=True): + return self.config.define_section(name, cls_, validate) + + def __getattr__(self, name): + ''' will only get called for undefined attributes ''' + """We will try to find a core value, or return None""" + if hasattr(self.config.core, name): + return eval("self.config.core." + name) + elif name.lower() in self.dict["core"].keys(): + return self.dict["core"][str(name).lower()] + elif hasattr(self.config, name): + return eval("self.config." + name) + else: + return None + + +config = BotConfig() diff --git a/sopel_modules/SpiceBot/Database.py b/sopel_modules/SpiceBot/Database.py new file mode 100644 index 0000000..9c07eda --- /dev/null +++ b/sopel_modules/SpiceBot/Database.py @@ -0,0 +1,595 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Database +""" + +# sopel imports +from sopel.tools import Identifier +import sopel.db +from sopel.db import SopelDB, _deserialize + +from .Config import config as botconfig + +from sqlalchemy import Column, String, ForeignKey, Integer, Text +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.exc import SQLAlchemyError + +import json + + +BASE = declarative_base() + + +class NickIDs(BASE): + """ + NickIDs SQLAlchemy Class + """ + __tablename__ = 'nick_ids' + nick_id = Column(Integer, primary_key=True) + + +class Nicknames(BASE): + """ + Nicknames SQLAlchemy Class + """ + __tablename__ = 'nicknames' + nick_id = Column(Integer, ForeignKey('nick_ids.nick_id'), primary_key=True) + slug = Column(String(255), primary_key=True) + canonical = Column(String(255)) + + +class NickValues(BASE): + """ + NickValues SQLAlchemy Class + """ + __tablename__ = 'spice_nick_values' + nick_id = Column(Integer, ForeignKey('nick_ids.nick_id'), primary_key=True) + namespace = Column(String(255), primary_key=True) + key = Column(String(255), primary_key=True) + value = Column(Text()) + + +class ChannelValues(BASE): + """ + ChannelValues SQLAlchemy Class + """ + __tablename__ = 'spice_channel_values' + channel = Column(String(255), primary_key=True) + namespace = Column(String(255), primary_key=True) + key = Column(String(255), primary_key=True) + value = Column(Text()) + + +class PluginValues(BASE): + """ + PluginValues SQLAlchemy Class + """ + __tablename__ = 'spice_plugin_values' + plugin = Column(String(255), primary_key=True) + namespace = Column(String(255), primary_key=True) + key = Column(String(255), primary_key=True) + value = Column(Text()) + + +class SpiceDB(object): + + # NICK FUNCTIONS + + def set_nick_value(self, nick, key, value, namespace='default'): + """Sets the value for a given key to be associated with the nick.""" + nick = Identifier(nick) + value = json.dumps(value, ensure_ascii=False) + nick_id = self.get_nick_id(nick) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.namespace == namespace)\ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, update + if result: + result.value = value + session.commit() + # DNE - Insert + else: + new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=value) + session.add(new_nickvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def get_nick_value(self, nick, key, namespace='default'): + """Retrieves the value for a given key associated with a nick.""" + nick = Identifier(nick) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(Nicknames.nick_id == NickValues.nick_id) \ + .filter(Nicknames.slug == nick.lower()) \ + .filter(NickValues.namespace == namespace)\ + .filter(NickValues.key == key) \ + .one_or_none() + if result is not None: + result = result.value + return _deserialize(result) + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def delete_nick_value(self, nick, key, namespace='default'): + """Deletes the value for a given key to be associated with the nick.""" + nick = Identifier(nick) + nick_id = self.get_nick_id(nick) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.namespace == namespace)\ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, delete + if result: + session.delete(result) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_nick_value(self, nick, key, value, namespace='default'): + """Sets the value for a given key to be associated with the nick.""" + nick = Identifier(nick) + value = json.dumps(value, ensure_ascii=False) + nick_id = self.get_nick_id(nick) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.namespace == namespace)\ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, update + if result: + result.value = float(result.value) + float(value) + session.commit() + # DNE - Insert + else: + new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=float(value)) + session.add(new_nickvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_nick_list(self, nick, key, entries, adjustmentdirection, namespace='default'): + """Sets the value for a given key to be associated with the nick.""" + nick = Identifier(nick) + if not isinstance(entries, list): + entries = [entries] + entries = json.dumps(entries, ensure_ascii=False) + nick_id = self.get_nick_id(nick) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.namespace == namespace)\ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, update + if result: + if adjustmentdirection == 'add': + for entry in entries: + if entry not in result.value: + result.value.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in result.value: + result.value.remove(entry) + session.commit() + # DNE - Insert + else: + values = [] + if adjustmentdirection == 'add': + for entry in entries: + if entry not in values: + values.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in values: + values.remove(entry) + new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=values) + session.add(new_nickvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + # CHANNEL FUNCTIONS + + def set_channel_value(self, channel, key, value, namespace='default'): + """Sets the value for a given key to be associated with the channel.""" + channel = Identifier(channel).lower() + value = json.dumps(value, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.namespace == namespace)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + result.value = value + session.commit() + # DNE - Insert + else: + new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=value) + session.add(new_channelvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def get_channel_value(self, channel, key, namespace='default'): + """Retrieves the value for a given key associated with a channel.""" + channel = Identifier(channel).lower() + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.namespace == namespace)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + if result is not None: + result = result.value + return _deserialize(result) + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def delete_channel_value(self, channel, key, namespace='default'): + """Sets the value for a given key to be associated with the channel.""" + channel = Identifier(channel).lower() + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.namespace == namespace)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, delete + if result: + session.delete(result) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_channel_value(self, channel, key, value, namespace='default'): + """Sets the value for a given key to be associated with the channel.""" + channel = Identifier(channel).lower() + value = json.dumps(value, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.namespace == namespace)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + result.value = float(result.value) + float(value) + session.commit() + # DNE - Insert + else: + new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=float(value)) + session.add(new_channelvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_channel_list(self, channel, key, entries, adjustmentdirection, namespace='default'): + """Sets the value for a given key to be associated with the channel.""" + channel = Identifier(channel).lower() + if not isinstance(entries, list): + entries = [entries] + entries = json.dumps(entries, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.namespace == namespace)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + if adjustmentdirection == 'add': + for entry in entries: + if entry not in result.value: + result.value.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in result.value: + result.value.remove(entry) + session.commit() + # DNE - Insert + else: + values = [] + if adjustmentdirection == 'add': + for entry in entries: + if entry not in values: + values.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in values: + values.remove(entry) + new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=values) + session.add(new_channelvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + # PLUGIN FUNCTIONS + + def set_plugin_value(self, plugin, key, value, namespace='default'): + """Sets the value for a given key to be associated with the plugin.""" + plugin = Identifier(plugin).lower() + value = json.dumps(value, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(PluginValues) \ + .filter(PluginValues.plugin == plugin)\ + .filter(PluginValues.namespace == namespace)\ + .filter(PluginValues.key == key) \ + .one_or_none() + # PluginValues exists, update + if result: + result.value = value + session.commit() + # DNE - Insert + else: + new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=value) + session.add(new_pluginvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def get_plugin_value(self, plugin, key, namespace='default'): + """Retrieves the value for a given key associated with a plugin.""" + plugin = Identifier(plugin).lower() + session = self.ssession() + try: + result = session.query(PluginValues) \ + .filter(PluginValues.plugin == plugin)\ + .filter(PluginValues.namespace == namespace)\ + .filter(PluginValues.key == key) \ + .one_or_none() + if result is not None: + result = result.value + return _deserialize(result) + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def delete_plugin_value(self, plugin, key, namespace='default'): + """Deletes the value for a given key to be associated with the plugin.""" + plugin = Identifier(plugin).lower() + session = self.ssession() + try: + result = session.query(PluginValues) \ + .filter(PluginValues.plugin == plugin)\ + .filter(PluginValues.namespace == namespace)\ + .filter(PluginValues.key == key) \ + .one_or_none() + # PluginValues exists, delete + if result: + session.delete(result) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_plugin_value(self, plugin, key, value, namespace='default'): + """Sets the value for a given key to be associated with the plugin.""" + plugin = Identifier(plugin).lower() + value = json.dumps(value, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(PluginValues) \ + .filter(PluginValues.plugin == plugin)\ + .filter(PluginValues.namespace == namespace)\ + .filter(PluginValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + result.value = float(result.value) + float(value) + session.commit() + # DNE - Insert + else: + new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=float(value)) + session.add(new_pluginvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + def adjust_plugin_list(self, plugin, key, entries, adjustmentdirection, namespace='default'): + """Sets the value for a given key to be associated with the plugin.""" + plugin = Identifier(plugin).lower() + if not isinstance(entries, list): + entries = [entries] + entries = json.dumps(entries, ensure_ascii=False) + session = self.ssession() + try: + result = session.query(PluginValues) \ + .filter(PluginValues.plugin == plugin)\ + .filter(PluginValues.namespace == namespace)\ + .filter(PluginValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + if adjustmentdirection == 'add': + for entry in entries: + if entry not in result.value: + result.value.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in result.value: + result.value.remove(entry) + session.commit() + # DNE - Insert + else: + values = [] + if adjustmentdirection == 'add': + for entry in entries: + if entry not in values: + values.append(entry) + elif adjustmentdirection == 'del': + for entry in entries: + while entry in values: + values.remove(entry) + new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=values) + session.add(new_pluginvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() + + +class BotDatabase(): + """A thread safe database cache""" + + def __init__(self): + + sopel.db.NickValues = NickValues + SopelDB.get_nick_value = SpiceDB.get_nick_value + SopelDB.set_nick_value = SpiceDB.set_nick_value + SopelDB.delete_nick_value = SpiceDB.delete_nick_value + SopelDB.adjust_nick_value = SpiceDB.adjust_nick_value + SopelDB.adjust_nick_list = SpiceDB.adjust_nick_list + + sopel.db.ChannelValues = ChannelValues + SopelDB.get_channel_value = SpiceDB.get_channel_value + SopelDB.set_channel_value = SpiceDB.set_channel_value + SopelDB.delete_channel_value = SpiceDB.delete_channel_value + SopelDB.adjust_channel_value = SpiceDB.adjust_channel_value + SopelDB.adjust_channel_list = SpiceDB.adjust_channel_list + + sopel.db.PluginValues = PluginValues + SopelDB.get_plugin_value = SpiceDB.get_plugin_value + SopelDB.set_plugin_value = SpiceDB.set_plugin_value + SopelDB.delete_plugin_value = SpiceDB.delete_plugin_value + SopelDB.adjust_plugin_value = SpiceDB.adjust_plugin_value + SopelDB.adjust_plugin_list = SpiceDB.adjust_plugin_list + + self.db = SopelDB(botconfig.config) + BASE.metadata.create_all(self.db.engine) + + """Nick""" + + def get_nick_id(self, nick, create=True): + return self.db.get_nick_id(nick, create) + + def get_nick_value(self, nick, key, namespace='default'): + return self.db.get_nick_value(nick, key, namespace) + + def set_nick_value(self, nick, key, value, namespace='default'): + return self.db.set_nick_value(nick, key, value, namespace) + + def delete_nick_value(self, nick, key, namespace='default'): + return self.db.delete_nick_value(nick, key, namespace) + + def adjust_nick_value(self, nick, key, value, namespace='default'): + return self.db.adjust_nick_value(nick, key, value, namespace) + + def adjust_nick_list(self, nick, key, entries, adjustmentdirection, namespace='default'): + return self.db.adjust_nick_list(nick, key, entries, adjustmentdirection, namespace) + + """Bot""" + + def get_bot_value(self, key, namespace='default'): + return self.db.get_nick_value(botconfig.nick, key, namespace) + + def set_bot_value(self, key, value, namespace='default'): + return self.db.set_nick_value(botconfig.nick, key, value, namespace) + + def delete_bot_value(self, key, namespace='default'): + return self.db.delete_nick_value(botconfig.nick, key, namespace) + + def adjust_bot_value(self, key, value, namespace='default'): + return self.db.adjust_nick_value(botconfig.nick, key, value, namespace) + + def adjust_bot_list(self, key, entries, adjustmentdirection, namespace='default'): + return self.db.adjust_nick_list(botconfig.nick, key, entries, adjustmentdirection, namespace) + + """Channels""" + + def get_channel_value(self, channel, key, namespace='default'): + return self.db.get_channel_value(channel, key, namespace) + + def set_channel_value(self, channel, key, value, namespace='default'): + return self.db.set_channel_value(channel, key, value, namespace) + + def delete_channel_value(self, channel, key, namespace='default'): + return self.db.delete_channel_value(channel, key, namespace) + + def adjust_channel_value(self, channel, key, value, namespace='default'): + return self.db.adjust_channel_value(channel, key, value, namespace) + + def adjust_channel_list(self, nick, key, entries, adjustmentdirection, namespace='default'): + return self.db.adjust_channel_list(nick, key, entries, adjustmentdirection, namespace) + + """Plugins""" + + def get_plugin_value(self, plugin, key, namespace='default'): + return self.db.get_plugin_value(plugin, key, namespace) + + def set_plugin_value(self, plugin, key, value, namespace='default'): + return self.db.set_plugin_value(plugin, key, value, namespace) + + def delete_plugin_value(self, plugin, key, namespace='default'): + return self.db.delete_plugin_value(plugin, key, namespace) + + def adjust_plugin_value(self, plugin, key, value, namespace='default'): + return self.db.adjust_plugin_value(plugin, key, value, namespace) + + def adjust_plugin_list(self, nick, key, entries, adjustmentdirection, namespace='default'): + return self.db.adjust_plugin_list(nick, key, entries, adjustmentdirection, namespace) + + +db = BotDatabase() diff --git a/sopel_modules/SpiceBot/Events.py b/sopel_modules/SpiceBot/Events.py index 34dfc54..a716277 100644 --- a/sopel_modules/SpiceBot/Events.py +++ b/sopel_modules/SpiceBot/Events.py @@ -7,9 +7,16 @@ We utilize the Sopel code for event numbers and self-trigger the bot into performing actions """ - import sopel import functools +import threading +import time + +from .Logs import logs + + +# TODO +# full_message = ':{} PRIVMSG {} :{}'.format(hostmask, sender, msg) class BotEvents(object): @@ -17,7 +24,7 @@ class BotEvents(object): Events will be assigned a 4-digit number above 1000. - This allows you to do, ``@module.event(botevents.BOT_WELCOME)```` + This allows you to do, ``@module.event(events.BOT_WELCOME)```` Triggers handled by this module will be processed immediately. Others will be placed into a queue. @@ -26,26 +33,30 @@ class BotEvents(object): """ def __init__(self): + self.lock = threading.Lock() self.RPL_WELCOME = '001' # This is a defined IRC event + self.BOT_UPTIME = time.time() self.BOT_WELCOME = '1001' self.BOT_READY = '1002' self.BOT_CONNECTED = '1003' self.BOT_LOADED = '1004' self.BOT_RECONNECTED = '1005' self.defaultevents = [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED, self.BOT_LOADED, self.BOT_RECONNECTED] - self.SpiceBot_Events = { - "assigned_IDs": {1000: "Default", 1001: "BOT_WELCOME", 1002: "BOT_READY", 1003: "BOT_CONNECTED", 1004: "BOT_LOADED", 1005: "BOT_RECONNECTED"}, - "triggers_recieved": {}, - "trigger_queue": [], - "startup_required": [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED], - "RPL_WELCOME_Count": 0 - } + self.dict = { + "assigned_IDs": {1000: "BOT_UPTIME", 1001: "BOT_WELCOME", 1002: "BOT_READY", 1003: "BOT_CONNECTED", 1004: "BOT_LOADED", 1005: "BOT_RECONNECTED"}, + "triggers_recieved": {}, + "trigger_queue": [], + "startup_required": [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED], + "RPL_WELCOME_Count": 0 + } def __getattr__(self, name): ''' will only get called for undefined attributes ''' - eventnumber = max(list(self.SpiceBot_Events["assigned_IDs"].keys())) + 1 - self.SpiceBot_Events["assigned_IDs"][eventnumber] = str(name) + self.lock.acquire() + eventnumber = max(list(self.dict["assigned_IDs"].keys())) + 1 + self.dict["assigned_IDs"][eventnumber] = str(name) setattr(self, name, str(eventnumber)) + self.lock.release() return str(eventnumber) def trigger(self, bot, number, message="SpiceBot_Events"): @@ -53,7 +64,7 @@ class BotEvents(object): if number in self.defaultevents: self.dispatch(bot, pretriggerdict) else: - self.SpiceBot_Events["trigger_queue"].append(pretriggerdict) + self.dict["trigger_queue"].append(pretriggerdict) def dispatch(self, bot, pretriggerdict): number = pretriggerdict["number"] @@ -66,43 +77,51 @@ class BotEvents(object): self.recieved({"number": number, "message": message}) def recieved(self, trigger): + self.lock.acquire() + if isinstance(trigger, dict): eventnumber = str(trigger["number"]) message = str(trigger["message"]) else: eventnumber = str(trigger.event) message = trigger.args[1] - if eventnumber not in self.SpiceBot_Events["triggers_recieved"]: - self.SpiceBot_Events["triggers_recieved"][eventnumber] = [] - self.SpiceBot_Events["triggers_recieved"][eventnumber].append(message) + logs.log('SpiceBot_Events', str(eventnumber) + " " + str(message)) + if eventnumber not in self.dict["triggers_recieved"]: + self.dict["triggers_recieved"][eventnumber] = [] + self.dict["triggers_recieved"][eventnumber].append(message) + self.lock.release() def check(self, checklist): if not isinstance(checklist, list): checklist = [str(checklist)] for number in checklist: - if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys(): + if str(number) not in self.dict["triggers_recieved"].keys(): return False return True def startup_add(self, startlist): + self.lock.acquire() if not isinstance(startlist, list): startlist = [str(startlist)] - self.SpiceBot_Events["startup_required"].extend(startlist) + for eventitem in startlist: + if eventitem not in self.dict["startup_required"]: + self.dict["startup_required"].append(eventitem) + self.lock.release() def startup_check(self): - for number in self.SpiceBot_Events["startup_required"]: - if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys(): + for number in self.dict["startup_required"]: + if str(number) not in self.dict["triggers_recieved"].keys(): return False return True def startup_debug(self): not_done = [] - for number in self.SpiceBot_Events["startup_required"]: - if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys(): + for number in self.dict["startup_required"]: + if str(number) not in self.dict["triggers_recieved"].keys(): not_done.append(int(number)) reference_not_done = [] for item in not_done: - reference_not_done.append(str(self.SpiceBot_Events["assigned_IDs"][item])) + reference_not_done.append(str(self.dict["assigned_IDs"][item])) return reference_not_done def check_ready(self, checklist): @@ -126,4 +145,4 @@ class BotEvents(object): return actual_decorator -botevents = BotEvents() +events = BotEvents() diff --git a/sopel_modules/SpiceBot/Kick.py b/sopel_modules/SpiceBot/Kick.py new file mode 100644 index 0000000..0b7d5e7 --- /dev/null +++ b/sopel_modules/SpiceBot/Kick.py @@ -0,0 +1,37 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Update system. +""" + +from sopel.config.types import StaticSection, ValidatedAttribute + + +class SpiceBot_Kick(StaticSection): + kick = ValidatedAttribute('kick', default=1) + + +class SopelKICK: + + def kick(self, nick, channel, text=None): + """Send an IRC KICK command. + Within the context of a triggered callable, ``channel`` will default to the + channel in which the call was triggered. If triggered from a private message, + ``channel`` is required (or the call to ``kick()`` will be ignored). + The bot must be a channel operator in specified channel for this to work. + .. versionadded:: 7.0 + """ + self.write(['KICK', channel, nick], text) + + +class SopelWrapperKICK(object): + + def kick(self, nick, channel=None, message=None): + if channel is None: + if self._trigger.is_privmsg: + raise RuntimeError('Error: KICK requires a channel.') + else: + channel = self._trigger.sender + if nick is None: + raise RuntimeError('Error: KICK requires a nick.') + self._bot.kick(nick, channel, message) diff --git a/sopel_modules/SpiceBot/Logs.py b/sopel_modules/SpiceBot/Logs.py index da458ae..1226d98 100644 --- a/sopel_modules/SpiceBot/Logs.py +++ b/sopel_modules/SpiceBot/Logs.py @@ -6,51 +6,74 @@ This is the SpiceBot Logs system. This Class stores logs in an easy to access manner """ - -import sopel +import threading import os +import sys import spicemanip +from .Config import config as botconfig -class botlogs(): + +# TODO timestamps + +class BotLogs(): """This Is a contained source of log information""" def __init__(self): - self.SpiceBot_Logs = { - "list": {"Sopel_systemd": [], "Sopel_stdio": []}, - "queue": [] - } - self.sopel_config = { - "logging_channel": True - } + self.setup_logs() + self.lock = threading.Lock() + self.dict = { + "list": {"Sopel_systemd": [], "Sopel_stdio": []}, + "queue": [] + } + + def setup_logs(self): + botconfig.core.logs_stdio = os.path.join(botconfig.core.logdir, 'stdio.log') + # botconfig.core.logs_stdio = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.stdio.log') + botconfig.core.logs_exceptions = os.path.join(botconfig.core.logdir, 'exceptions.log') + # botconfig.core.logs_exceptions = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.exceptions.log') + botconfig.core.logs_raw = os.path.join(botconfig.core.logdir, 'raw.log') + # botconfig.core.logs_raw = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.raw.log') + + def botstderr(self, logmessage): + sys.stderr.write(logmessage) def log(self, logtype, logentry, stdio=False): + + self.lock.acquire() + logtitle = "[" + logtype + "]" logmessage = logtitle + " " + logentry - if self.sopel_config["logging_channel"]: - self.SpiceBot_Logs["queue"].append(logmessage) + if botconfig.logging_channel: + self.dict["queue"].append(logmessage) if stdio: - sopel.tools.stderr(logmessage) + self.botstderr(logmessage) - if logtype not in self.SpiceBot_Logs["list"].keys(): - self.SpiceBot_Logs["list"][logtype] = [] - self.SpiceBot_Logs["list"][logtype].append(logentry) + if logtype not in self.dict["list"].keys(): + self.dict["list"][logtype] = [] + self.dict["list"][logtype].append(logentry) - def get_logs(self): - return [] + self.lock.release() - def stdio_logs_fetch(self, bot): + def get_logs(self, logtype): + if logtype == "Sopel_systemd": + logindex = self.systemd_logs_fetch() + elif logtype == "Sopel_stdio": + logindex = self.stdio_logs_fetch() + else: + logindex = self.dict["list"][logtype] + return logindex + + def stdio_logs_fetch(self): stdio_ignore = [] - for logtype in botlogs.SpiceBot_Logs["list"].keys(): + for logtype in self.dict["list"].keys(): stdio_ignore.append("[" + logtype + "]") - logfile = os.path.os.path.join(bot.config.core.logdir, 'stdio.log') - try: log_file_lines = [] - log_file = open(logfile, 'r') + log_file = open(botconfig.logs_stdio, 'r') lines = log_file.readlines() for line in lines: log_file_lines.append(line) @@ -80,8 +103,8 @@ class botlogs(): return debuglines - def systemd_logs_fetch(self, bot): - servicepid = self.get_running_pid(bot) + def systemd_logs_fetch(self): + servicepid = self.get_running_pid() debuglines = [] for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'): line = str(line).split(str(os.uname()[1] + " "))[-1] @@ -92,15 +115,15 @@ class botlogs(): debuglines.append(str(line)) return debuglines - def get_running_pid(self, bot): + def get_running_pid(self): try: - filename = "/run/sopel/sopel-" + str(bot.nick) + ".pid" + filename = "/run/sopel/sopel-" + str(botconfig.nick) + ".pid" with open(filename, 'r') as pid_file: pidnum = int(pid_file.read()) except Exception as e: pidnum = e - pidnum = str(os.popen("systemctl show " + str(bot.nick) + " --property=MainPID").read()).split("=")[-1] + pidnum = str(os.popen("systemctl show " + str(botconfig.nick) + " --property=MainPID").read()).split("=")[-1] return pidnum -botlogs = botlogs() +logs = BotLogs() diff --git a/sopel_modules/SpiceBot/Prerun.py b/sopel_modules/SpiceBot/Prerun.py new file mode 100644 index 0000000..9093560 --- /dev/null +++ b/sopel_modules/SpiceBot/Prerun.py @@ -0,0 +1,198 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Prerun system. +""" + +from sopel.tools import Identifier + +import functools +import copy +import datetime +import spicemanip + +from .Tools import command_permissions_check +from .Commands import commands as botcommands +from .Database import db as botdb + + +class BotPrerun(): + def __init__(self): + self.dict = {} + + """Command Splitting""" + + def prerun(self, trigger_command_type='module'): + def actual_decorator(function): + + @functools.wraps(function) + def internal_prerun(bot, trigger, *args, **kwargs): + + # Primary command used for trigger, and a list of all words + trigger_args, trigger_command = self.trigger_args(trigger.args[1], trigger_command_type) + + # Argsdict Defaults + argsdict_default = {} + argsdict_default["type"] = trigger_command_type + argsdict_default["com"] = trigger_command + + realcom = botcommands.get_realcom(argsdict_default["com"], trigger_command_type) + argsdict_default["realcom"] = realcom + + # split into && groupings + and_split = self.trigger_and_split(trigger_args) + + # Create dict listings for trigger.sb + argsdict_list = self.trigger_argsdict_list(argsdict_default, and_split) + + # Run the function for all splits + for argsdict in argsdict_list: + trigger.sb = copy.deepcopy(argsdict) + + trigger.sb["args"], trigger.sb["hyphen_arg"] = self.trigger_hyphen_args(trigger.sb["args"]) + if not trigger.sb["hyphen_arg"]: + # check if anything prohibits the nick from running the command + if self.trigger_runstatus(bot, trigger): + function(bot, trigger, *args, **kwargs) + else: + self.trigger_hyphen_arg_handler(bot, trigger) + return + + return internal_prerun + return actual_decorator + + def trigger_args(self, triggerargs_one, trigger_command_type='module'): + trigger_args = spicemanip.main(triggerargs_one, 'create') + if trigger_command_type in ['nickname']: + trigger_command = spicemanip.main(trigger_args, 2).lower() + trigger_args = spicemanip.main(trigger_args, '3+', 'list') + else: + trigger_command = spicemanip.main(trigger_args, 1).lower()[1:] + trigger_args = spicemanip.main(trigger_args, '2+', 'list') + return trigger_args, trigger_command + + def trigger_and_split(self, trigger_args): + trigger_args_list_split = spicemanip.main(trigger_args, "split_&&") + if not len(trigger_args_list_split): + trigger_args_list_split.append([]) + return trigger_args_list_split + + def trigger_argsdict_list(self, argsdict_default, and_split): + prerun_split = [] + for trigger_args_part in and_split: + argsdict_part = copy.deepcopy(argsdict_default) + argsdict_part["args"] = spicemanip.main(trigger_args_part, 'create') + if len(argsdict_part["args"]) and argsdict_part["args"][0] == "-a": + argsdict_part["adminswitch"] = True + argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list') + else: + argsdict_part["adminswitch"] = False + prerun_split.append(argsdict_part) + return prerun_split + + def trigger_runstatus(self, bot, trigger): + return True + + # Bots can't run commands + if Identifier(trigger.nick) == bot.nick: + return False + + # Allow permissions for enabling and disabling commands via hyphenargs + if trigger.sb["adminswitch"]: + if command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + return True + else: + bot.osd("The admin switch (-a) is for use by authorized nicks ONLY.", 'notice') + return False + + # don't run commands that are disabled in channels + if not trigger.is_privmsg: + commandused = trigger.sb["realcom"] + disabled_list = botdb.get_channel_value(trigger.sender, 'commands_disabled') or {} + if commandused in disabled_list.keys(): + reason = disabled_list[trigger.sb["realcom"]]["reason"] + timestamp = disabled_list[trigger.sb["realcom"]]["timestamp"] + bywhom = disabled_list[trigger.sb["realcom"]]["disabledby"] + message = "The " + str(trigger.sb["com"]) + " command was disabled by " + bywhom + " in " + str(trigger.sender) + " at " + str(timestamp) + " for the following reason: " + str(reason) + return self.trigger_cant_run(bot, trigger, message) + + return True + + def trigger_cant_run(self, bot, trigger, message=None): + if message: + bot.osd(message, trigger.nick, 'notice') + if command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + bot.osd("You however are authorized to bypass this warning with the (-a) admin switch.", trigger.nick, 'notice') + return False + + def trigger_hyphen_args(self, trigger_args_part): + valid_hyphen_args = [ + 'check', + 'enable', 'disable' + ] + hyphen_args = [] + trigger_args_unhyphend = [] + for worditem in trigger_args_part: + if str(worditem).startswith("--") and worditem[2:] in valid_hyphen_args: + hyphen_args.append(worditem[2:]) + else: + trigger_args_unhyphend.append(worditem) + if len(hyphen_args): + hyphenarg = hyphen_args[0] + else: + hyphenarg = None + return trigger_args_unhyphend, hyphenarg + + def trigger_hyphen_arg_handler(self, bot, trigger): + + # Commands that cannot run via privmsg + if trigger.sb["hyphen_arg"] in ['check']: + if trigger.sb["com"].lower() != trigger.sb["realcom"]: + bot.osd(trigger.sb["com"] + " is a valid alias command for " + trigger.sb["realcom"]) + else: + bot.osd(trigger.sb["com"] + " is a valid command") + return + + elif trigger.sb["hyphen_arg"] in ['enable']: + + if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + bot.osd("I was unable to disable this command due to privilege issues.") + return + + if trigger.is_privmsg: + bot.osd("This command must be run in a channel you which to enable it in.", trigger.nick, 'notice') + return + + if not botcommands.check_commands_disabled(trigger.sb["realcom"], trigger.sender): + bot.osd(trigger.sb["com"] + " is already enabled in " + str(trigger.sender), trigger.nick, 'notice') + return + + botcommands.unset_command_disabled(trigger.sb["realcom"], trigger.sender) + bot.osd(trigger.sb["com"] + " is now enabled in " + str(trigger.sender)) + return + + elif trigger.sb["hyphen_arg"] in ['disable']: + + if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + bot.osd("I was unable to disable this command due to privilege issues.") + return + + if trigger.is_privmsg: + bot.osd("This command must be run in a channel you which to disable it in.", trigger.nick, 'notice') + return + + if botcommands.check_commands_disabled(trigger.sb["realcom"], trigger.sender): + bot.osd(trigger.sb["com"] + " is already disabled in " + str(trigger.sender), trigger.nick, 'notice') + return + + trailingmessage = spicemanip.main(trigger.sb["args"], 0) or "No reason given." + timestamp = str(datetime.datetime.utcnow()) + + botcommands.set_command_disabled(trigger.sb["realcom"], trigger.sender, timestamp, trailingmessage, trigger.nick) + bot.osd(trigger.sb["com"] + " is now disabled in " + str(trigger.sender)) + return + + return + + +prerun = BotPrerun() diff --git a/sopel_modules/SpiceBot/StartupMonologue.py b/sopel_modules/SpiceBot/StartupMonologue.py new file mode 100644 index 0000000..14a0211 --- /dev/null +++ b/sopel_modules/SpiceBot/StartupMonologue.py @@ -0,0 +1,13 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +"""StartupMonologue class""" + + +class BotMonologue(): + + def __init__(self): + + self.dict = {} + + +startupmonologue = BotMonologue() diff --git a/sopel_modules/SpiceBot_SBTools/__init__.py b/sopel_modules/SpiceBot/Tools.py similarity index 77% rename from sopel_modules/SpiceBot_SBTools/__init__.py rename to sopel_modules/SpiceBot/Tools.py index 74c7a3c..1a9f94a 100644 --- a/sopel_modules/SpiceBot_SBTools/__init__.py +++ b/sopel_modules/SpiceBot/Tools.py @@ -7,7 +7,6 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel import collections -import re import os import sys import codecs @@ -20,7 +19,8 @@ from pygit2 import clone_repository import spicemanip -from sopel_modules.SpiceBot.Logs import botlogs +from .Logs import logs +from .Config import config as botconfig """Variable References""" @@ -39,27 +39,10 @@ github_dict = { """Sopel Wrapping Tools""" -def sopel_triggerargs(bot, trigger, command_type='module_command'): - triggerargs = [] - - if len(trigger.args) > 1: - triggerargs = spicemanip.main(trigger.args[1], 'create') - triggerargs = spicemanip.main(triggerargs, 'create') - - if command_type in ['nickname_command']: - command = spicemanip.main(triggerargs, 2).lower() - triggerargs = spicemanip.main(triggerargs, '3+', 'list') - else: - command = spicemanip.main(triggerargs, 1).lower()[1:] - triggerargs = spicemanip.main(triggerargs, '2+', 'list') - - return triggerargs, command - - -def bot_privs(bot, privtype): +def bot_privs(privtype): if privtype == 'owners': privtype = 'owner' - botpriveval = eval("bot.config.core." + privtype) + botpriveval = eval("botconfig." + privtype) if not isinstance(botpriveval, list): botpriveval = [botpriveval] return botpriveval @@ -71,8 +54,8 @@ def command_permissions_check(bot, trigger, privslist): for botpriv in ["admins", "owner"]: if botpriv in privslist: - botpriveval = bot_privs(bot, botpriv) - if not inlist(bot, trigger.nick, botpriveval): + botpriveval = bot_privs(botpriv) + if not inlist(trigger.nick, botpriveval): commandrunconsensus.append('False') else: commandrunconsensus.append('True') @@ -81,7 +64,7 @@ def command_permissions_check(bot, trigger, privslist): for chanpriv in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']: if chanpriv in privslist: chanpriveval = channel_privs(bot, trigger.sender, chanpriv) - if not inlist(bot, trigger.nick, chanpriveval): + if not inlist(trigger.nick, chanpriveval): commandrunconsensus.append('False') else: commandrunconsensus.append('True') @@ -135,7 +118,7 @@ def humanized_time(countdownseconds): """Online Information Requests""" -def googlesearch(bot, searchterm, searchtype=None): +def googlesearch(searchterm, searchtype=None): header = {'User-Agent': str(UserAgent().chrome)} data = searchterm.replace(' ', '+') lookfor = data.replace(':', '%3A') @@ -157,7 +140,7 @@ def googlesearch(bot, searchterm, searchtype=None): """List Manipulation Functions""" -def inlist(bot, searchterm, searchlist): +def inlist(searchterm, searchlist): # verify we are searching a list if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict): @@ -178,7 +161,7 @@ def inlist(bot, searchterm, searchlist): return False -def inlist_match(bot, searchterm, searchlist): +def inlist_match(searchterm, searchlist): # verify we are searching a list if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict): searchlist = [x for x in searchlist] @@ -202,7 +185,7 @@ def similar(a, b): return SequenceMatcher(None, a, b).ratio() -def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse'): +def similar_list(searchitem, searchlist, matchcount=1, searchorder='reverse'): if sys.version_info.major >= 3: if isinstance(searchlist, abc.KeysView): @@ -231,7 +214,7 @@ def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse return sim_listitems -def array_arrangesort(bot, sortbyarray, arrayb): +def array_arrangesort(sortbyarray, arrayb): sortbyarray, arrayb = (list(x) for x in zip(*sorted(zip(sortbyarray, arrayb), key=itemgetter(0)))) return sortbyarray, arrayb @@ -246,12 +229,6 @@ def letters_in_string(text): """Channel Functions""" -def topic_compile(topic): - actual_topic = re.compile(r'^\[\+[a-zA-Z]+\] (.*)') - topic = re.sub(actual_topic, r'\1', topic) - return topic - - def channel_privs(bot, channel, privtype): privlist = [] for user in bot.channels[channel].privileges.keys(): @@ -273,7 +250,7 @@ def channel_privs(bot, channel, privtype): """Environment Functions""" -def stock_modules_begone(bot): +def stock_modules_begone(): # Remove stock modules, if present main_sopel_dir = os.path.dirname(os.path.abspath(sopel.__file__)) @@ -297,7 +274,7 @@ def stock_modules_begone(bot): os.system("sudo mv " + path + " " + stockdir) -def spicebot_update(bot, deps=False): +def spicebot_update(deps=False): if not os.path.exists("/tmp") or not os.path.isdir("/tmp"): os.system("sudo mkdir /tmp") @@ -305,48 +282,48 @@ def spicebot_update(bot, deps=False): if not os.path.exists(clonepath) or not os.path.isdir(clonepath): os.system(clonepath) - botlogs.log('SpiceBot_Update', "Cloning to " + clonepath, True) + logs.log('SpiceBot_Update', "Cloning to " + clonepath, True) - clone_repository(str(bot.config.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=bot.config.SpiceBot_Update.gitbranch) + clone_repository(str(botconfig.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=botconfig.SpiceBot_Update.gitbranch) pipcommand = "sudo pip3 install --upgrade" if not deps: pipcommand += " --no-deps" pipcommand += " --force-reinstall" - # pipcommand += " git+" + str(bot.config.SpiceBot_Update.gitrepo) + "@" + str(bot.config.SpiceBot_Update.gitbranch) + # pipcommand += " git+" + str(botconfig.SpiceBot_Update.gitrepo) + "@" + str(botconfig.SpiceBot_Update.gitbranch) pipcommand += " /tmp/SpiceBot/" - botlogs.log('SpiceBot_Update', "Running `" + pipcommand + "`", True) + logs.log('SpiceBot_Update', "Running `" + pipcommand + "`", True) # for line in os.popen(pipcommand).read().split('\n'): - # botlogs.log('SpiceBot_Update', " " + line) + # logs.log('SpiceBot_Update', " " + line) os.system(pipcommand) - botlogs.log('SpiceBot_Update', "Deleting " + clonepath, True) + logs.log('SpiceBot_Update', "Deleting " + clonepath, True) os.system("sudo rm -r /tmp/SpiceBot") - stock_modules_begone(bot) + stock_modules_begone() def spicebot_reload(bot, log_from='service_manip', quitmessage='Recieved QUIT'): - # service_manip(bot, bot.nick, 'restart', log_from) + # service_manip(bot.nick, 'restart', log_from) bot.restart(quitmessage) -def service_manip(bot, servicename, dowhat, log_from='service_manip'): +def service_manip(servicename, dowhat, log_from='service_manip'): if str(dowhat) not in ["start", "stop", "restart"]: return try: - botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.") + logs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.") os.system("sudo service " + str(servicename) + " " + str(dowhat)) except Exception as e: - botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e)) + logs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e)) """Config Reading Functions""" -def read_directory_json_to_dict(bot, directories, configtypename="Config File", log_from='read_directory_json_to_dict'): +def read_directory_json_to_dict(directories, configtypename="Config File", log_from='read_directory_json_to_dict', logging=True): if not isinstance(directories, list): directories = [directories] @@ -371,8 +348,8 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File", dict_from_file = eval(infread) except Exception as e: filereadgood = False - if bot: - botlogs.log(log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath)) + if logging: + logs.log(log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath)) dict_from_file = dict() # Close File inf.close() @@ -386,11 +363,11 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File", fileopenfail += 1 if filecount: - if bot: - botlogs.log(log_from, 'Registered %d %s dict files,' % (filecount, configtypename)) - botlogs.log(log_from, '%d %s dict files failed to load' % (fileopenfail, configtypename), True) + if logging: + logs.log(log_from, 'Registered %d %s dict files,' % (filecount, configtypename)) + logs.log(log_from, '%d %s dict files failed to load' % (fileopenfail, configtypename), True) else: - if bot: - botlogs.log(log_from, "Warning: Couldn't load any %s dict files" % (configtypename)) + if logging: + logs.log(log_from, "Warning: Couldn't load any %s dict files" % (configtypename)) return configs_dict diff --git a/sopel_modules/SpiceBot/Update.py b/sopel_modules/SpiceBot/Update.py new file mode 100644 index 0000000..227f5fd --- /dev/null +++ b/sopel_modules/SpiceBot/Update.py @@ -0,0 +1,12 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Update system. +""" + +from sopel.config.types import StaticSection, ValidatedAttribute + + +class SpiceBot_Update_MainSection(StaticSection): + gitrepo = ValidatedAttribute('gitrepo', default="https://github.com/SpiceBot/SpiceBot") + gitbranch = ValidatedAttribute('gitbranch', default="master") diff --git a/sopel_modules/SpiceBot/__init__.py b/sopel_modules/SpiceBot/__init__.py index e934cff..18b52f7 100644 --- a/sopel_modules/SpiceBot/__init__.py +++ b/sopel_modules/SpiceBot/__init__.py @@ -6,9 +6,26 @@ These are the core SpiceBot Classes This module contains references only for other modules to utilize. """ +from .Config import * from .Logs import * +from .Database import * + +from .Update import * +from .osd import * +from .Kick import * + +from .Tools import * +from .Prerun import * +from .Commands import * from .Events import * +from .StartupMonologue import * from .Channels import * +from .AI import * + + +from .configure import * +from .setup import * +from .shutdown import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot/configure.py b/sopel_modules/SpiceBot/configure.py new file mode 100644 index 0000000..6469d17 --- /dev/null +++ b/sopel_modules/SpiceBot/configure.py @@ -0,0 +1,38 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +"""Configuration for SpiceBot""" + +from .Channels import SpiceBot_Channels_MainSection +from .AI import SpiceBot_AI_MainSection +from .Update import SpiceBot_Update_MainSection +from .Kick import SpiceBot_Kick +from .osd import SpiceBot_OSD + + +def configure(config): + + config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) + config.SpiceBot_OSD.configure_setting('notice', 'MAXTARG limit for NOTICE') + config.SpiceBot_OSD.configure_setting('privmsg', 'MAXTARG limit for PRIVMSG') + config.SpiceBot_OSD.configure_setting('flood_burst_lines', 'How many messages can be sent in burst mode.') + config.SpiceBot_OSD.configure_setting('flood_empty_wait', 'How long to wait between sending messages when not in burst mode, in seconds.') + config.SpiceBot_OSD.configure_setting('flood_refill_rate', 'How quickly burst mode recovers, in messages per second.') + config.SpiceBot_OSD.configure_setting('flood_throttle', 'Whether messages will be throttled if too many are sent in a short time.') + config.SpiceBot_OSD.configure_setting('flood_dots', "Whether repeated messages will be replaced with '...', then dropped.") + + config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) + config.SpiceBot_Channels.configure_setting('announcenew', 'SpiceBot_Channels Announce New Channels') + config.SpiceBot_Channels.configure_setting('joinall', 'SpiceBot_Channels JOIN New Channels') + config.SpiceBot_Channels.configure_setting('operadmin', 'SpiceBot_Channels OPER ADMIN MODE') + config.SpiceBot_Channels.configure_setting('chanignore', 'SpiceBot_Channels Ignore JOIN for channels') + + config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) + config.SpiceBot_Update.configure_setting('gitrepo', 'SpiceBot_Update git repo to install') + config.SpiceBot_Update.configure_setting('gitbranch', 'SpiceBot_Update git branch to install') + + config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) + config.SpiceBot_Kick.configure_setting('kick', 'MAXTARG limit for KICK') + + config.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False) + config.SpiceBot_AI.configure_setting('extra', 'extra aiml directories to import matches from') + config.SpiceBot_AI.configure_setting('gender', 'bot gender') diff --git a/sopel_modules/SpiceBot_osd/__init__.py b/sopel_modules/SpiceBot/osd.py similarity index 62% rename from sopel_modules/SpiceBot_osd/__init__.py rename to sopel_modules/SpiceBot/osd.py index 91fa5a3..99eb137 100644 --- a/sopel_modules/SpiceBot_osd/__init__.py +++ b/sopel_modules/SpiceBot/osd.py @@ -1,94 +1,18 @@ # coding=utf8 -"""Sopel OSD - -Sopel OSD is a "niche" method of displaying text in a Sopel bot +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot OSD system. """ -# pylama:ignore=W0611 - - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.bot -from sopel import tools, module +from sopel import tools from sopel.tools import Identifier from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot.Logs import botlogs - import time from collections import abc import sys -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.2' - - -def configure(config): - config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) - config.SpiceBot_OSD.configure_setting('notice', 'MAXTARG limit for NOTICE') - config.SpiceBot_OSD.configure_setting('privmsg', 'MAXTARG limit for PRIVMSG') - config.SpiceBot_OSD.configure_setting('flood_burst_lines', 'How many messages can be sent in burst mode.') - config.SpiceBot_OSD.configure_setting('flood_empty_wait', 'How long to wait between sending messages when not in burst mode, in seconds.') - config.SpiceBot_OSD.configure_setting('flood_refill_rate', 'How quickly burst mode recovers, in messages per second.') - config.SpiceBot_OSD.configure_setting('flood_dots', 'Display dots instead of spam.') - - -def setup(bot): - - # Inject OSD - botlogs.log('SpiceBot_OSD', "Implanting OSD function into bot") - bot.osd = SopelOSD.osd - sopel.bot.SopelWrapper.osd = SopelWrapperOSD.osd - tools.get_available_message_bytes = ToolsOSD.get_available_message_bytes - tools.get_sendable_message_list = ToolsOSD.get_sendable_message_list - tools.get_message_recipientgroups = ToolsOSD.get_message_recipientgroups - - # overwrite default bot messaging - botlogs.log('SpiceBot_OSD', "Overwrite Default Sopel messaging commands") - bot.osd = SopelOSD.osd - bot.say = SopelOSD.say - bot.action = SopelOSD.action - bot.notice = SopelOSD.notice - bot.reply = SopelOSD.reply - bot.msg = SopelOSD.msg - sopel.bot.SopelWrapper.say = SopelWrapperOSD.say - sopel.bot.SopelWrapper.action = SopelWrapperOSD.action - sopel.bot.SopelWrapper.notice = SopelWrapperOSD.notice - sopel.bot.SopelWrapper.reply = SopelWrapperOSD.reply - - # verify config settings for server - botlogs.log('SpiceBot_OSD', "Checking for config settings") - bot.config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) - - -@module.event('005') -@module.rule('.*') -def parse_event_005(bot, trigger): - if trigger.args[-1] != 'are supported by this server': - return - parameters = trigger.args[1:-1] - for param in parameters: - if '=' in param: - if param.startswith("TARGMAX"): - param = str(param).split('=')[1] - settings = str(param).split(',') - for setting in settings: - settingname = str(setting).split(':')[0] - if settingname.upper() in ['NOTICE', 'PRIVMSG']: - try: - value = str(setting).split(':')[1] or None - except IndexError: - value = None - if value: - if settingname.upper() == 'NOTICE': - bot.config.SpiceBot_OSD.notice = int(value) - elif settingname.upper() == 'PRIVMSG': - bot.config.SpiceBot_OSD.privmsg = int(value) - - class SpiceBot_OSD(StaticSection): """MAXTARG""" @@ -104,8 +28,11 @@ class SpiceBot_OSD(StaticSection): flood_refill_rate = ValidatedAttribute('flood_refill_rate', int, default=1) """How quickly burst mode recovers, in messages per second.""" - flood_dots = ValidatedAttribute('flood_dots', default=True) - """Display dots instead of spam.""" + flood_throttle = ValidatedAttribute('flood_throttle', bool, default=True) + """Whether messages will be throttled if too many are sent in a short time.""" + + flood_dots = ValidatedAttribute('flood_dots', bool, default=True) + """Whether repeated messages will be replaced with '...', then dropped.""" class ToolsOSD: @@ -261,6 +188,9 @@ class SopelOSD: will default to ``1``. """ + if not hasattr(self, 'osdstack'): + self.osdstack = {} + text_method = text_method.upper() if text_method == 'SAY' or text_method not in ['NOTICE', 'ACTION']: text_method = 'PRIVMSG' @@ -279,7 +209,7 @@ class SopelOSD: recipient_id = Identifier(recipientgroup) - recipient_stack = self.stack.setdefault(recipient_id, { + recipient_stack = self.osdstack.setdefault(recipient_id, { 'messages': [], 'flood_left': self.config.SpiceBot_OSD.flood_burst_lines, 'dots': 0, @@ -303,7 +233,7 @@ class SopelOSD: penalty = float(max(0, len(text) - 50)) / 70 # Never wait more than 2 seconds wait = min(self.config.SpiceBot_OSD.flood_empty_wait + penalty, 2) - if elapsed < wait: + if elapsed < wait and self.config.SpiceBot_OSD.flood_throttle: time.sleep(wait - elapsed) # Loop detection @@ -339,61 +269,6 @@ class SopelOSD: finally: self.sending.release() - def say(self, text, recipient, max_messages=1): - """Send ``text`` as a PRIVMSG to ``recipient``. - In the context of a triggered callable, the ``recipient`` defaults to - the channel (or nickname, if a private message) from which the message - was received. - """ - self.osd(text, recipient, 'PRIVMSG', max_messages) - - def notice(self, text, dest, max_messages=1): - """Send an IRC NOTICE to a user or a channel. - - Within the context of a triggered callable, ``dest`` will default to - the channel (or nickname, if a private message), in which the trigger - happened. - """ - self.osd(text, dest, 'NOTICE', max_messages) - - def action(self, text, dest, max_messages=1): - """Send ``text`` as a CTCP ACTION PRIVMSG to ``dest``. - - The same loop detection and length restrictions apply as with - :func:`say`, though automatic message splitting is not available. - - Within the context of a triggered callable, ``dest`` will default to - the channel (or nickname, if a private message), in which the trigger - happened. - """ - self.osd(text, dest, 'ACTION', max_messages) - - def reply(self, text, dest, reply_to, notice=False, max_messages=1): - """Prepend ``reply_to`` to ``text``, and send as a PRIVMSG to ``dest``. - - If ``notice`` is ``True``, send a NOTICE rather than a PRIVMSG. - - The same loop detection and length restrictions apply as with - :func:`say`, though automatic message splitting is not available. - - Within the context of a triggered callable, ``reply_to`` will default to - the nickname of the user who triggered the call, and ``dest`` to the - channel (or nickname, if a private message), in which the trigger - happened. - """ - text = '%s: %s' % (reply_to, text) - if notice: - self.osd(text, dest, 'NOTICE', max_messages) - else: - self.osd(text, dest, 'PRIVMSG', max_messages) - - def msg(self, recipient, text, max_messages=1): - """ - .. deprecated:: 6.0 - Use :meth:`say` instead. Will be removed in Sopel 8. - """ - self.osd(text, recipient, 'PRIVMSG', max_messages) - class SopelWrapperOSD(object): @@ -401,29 +276,3 @@ class SopelWrapperOSD(object): if recipients is None: recipients = self._trigger.sender self._bot.osd(self, messages, recipients, text_method, max_messages) - - def say(self, message, destination=None, max_messages=1): - if destination is None: - destination = self._trigger.sender - self._bot.osd(self, message, destination, 'PRIVMSG', 1) - - def action(self, message, destination=None, max_messages=1): - if destination is None: - destination = self._trigger.sender - self._bot.osd(self, message, destination, 'ACTION', 1) - - def notice(self, message, destination=None, max_messages=1): - if destination is None: - destination = self._trigger.sender - self._bot.osd(self, message, destination, 'NOTICE', 1) - - def reply(self, message, destination=None, reply_to=None, notice=False, max_messages=1): - if destination is None: - destination = self._trigger.sender - if reply_to is None: - reply_to = self._trigger.nick - message = '%s: %s' % (reply_to, message) - if notice: - self._bot.osd(self, message, destination, 'NOTICE', 1) - else: - self._bot.osd(self, message, destination, 'PRIVMSG', 1) diff --git a/sopel_modules/SpiceBot/setup.py b/sopel_modules/SpiceBot/setup.py new file mode 100644 index 0000000..f830ee1 --- /dev/null +++ b/sopel_modules/SpiceBot/setup.py @@ -0,0 +1,131 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +"""Setup for SpiceBot""" + +import sopel.bot +from sopel import tools + +import os + +from .Config import config as botconfig +from .Logs import logs +from .Events import events + +from .Channels import SpiceBot_Channels_MainSection +from .Commands import SpiceBot_Commands_MainSection +from .Update import SpiceBot_Update_MainSection +from .osd import SopelWrapperOSD, ToolsOSD, SopelOSD, SpiceBot_OSD +from .Kick import SopelWrapperKICK, SopelKICK, SpiceBot_Kick +from .AI import SpiceBot_AI_MainSection + + +def setup(bot): + + # basic config settings + setup_config(bot) + + # Logs + setup_logs(bot) + + # Commands + setup_commands(bot) + + # OSD + setup_osd(bot) + + # kick + setup_kick(bot) + + # update + setup_update(bot) + + # channels + setup_channels(bot) + + # AI + setup_ai(bot) + + # startupmonologue + setup_startupmonologue(bot) + + +def setup_config(bot): + logs.log('SpiceBot_Config', "Setting Up Configuration") + bot.config.core.basename = os.path.basename(bot.config.filename).rsplit('.', 1)[0] + bot.config.core.prefix_list = str(bot.config.core.prefix).replace("\\", '').split("|") + + +def setup_logs(bot): + logs.log('SpiceBot_Logs', "Starting Setup Procedure") + events.startup_add([events.BOT_LOGS]) + bot.config.core.logs_stdio = os.path.join(bot.config.core.logdir, 'stdio.log') + # bot.config.core.logs_stdio = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.stdio.log') + bot.config.core.logs_exceptions = os.path.join(bot.config.core.logdir, 'exceptions.log') + # bot.config.core.logs_exceptions = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.exceptions.log') + bot.config.core.logs_raw = os.path.join(bot.config.core.logdir, 'raw.log') + # bot.config.core.logs_raw = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.raw.log') + events.trigger(bot, events.BOT_LOGS, "SpiceBot_Logs") + + +def setup_commands(bot): + logs.log('SpiceBot_Commands', "Setting Up Configuration") + events.startup_add([events.BOT_COMMANDS]) + bot.config.define_section("SpiceBot_Commands", SpiceBot_Commands_MainSection, validate=False) + bot.config.core.query_list = str(bot.config.SpiceBot_Commands.query_prefix).replace("\\", '').split("|") + bot.config.core.prefix_list.extend(bot.config.SpiceBot_Commands.query_prefix) + + +def setup_startupmonologue(bot): + logs.log('SpiceBot_StartupMonologue', "Initial Setup processing") + events.startup_add([ + events.BOT_STARTUPMONOLOGUE_CONNECTED, + events.BOT_STARTUPMONOLOGUE_CHANNELS, + events.BOT_STARTUPMONOLOGUE_COMMANDS, + events.BOT_STARTUPMONOLOGUE_AI, + ]) + + +def setup_channels(bot): + logs.log('SpiceBot_Channels', "Setting Up Configuration") + events.startup_add([events.BOT_CHANNELS]) + bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) + + +def setup_update(bot): + logs.log('SpiceBot_Update', "Initial Setup processing") + bot.config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) + botconfig.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) + + +def setup_ai(bot): + logs.log('SpiceBot_AI', "Setting Up Configuration") + bot.config.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False) + bot.config.aibrain = os.path.join(bot.config.homedir, bot.config.core.basename + '.aibrain.brn') + events.startup_add([events.BOT_AI]) + + +def setup_osd(bot): + # Inject OSD + logs.log('SpiceBot_OSD', "Implanting OSD function into bot") + bot.osd = SopelOSD.osd + sopel.bot.SopelWrapper.osd = SopelWrapperOSD.osd + tools.get_available_message_bytes = ToolsOSD.get_available_message_bytes + tools.get_sendable_message_list = ToolsOSD.get_sendable_message_list + tools.get_message_recipientgroups = ToolsOSD.get_message_recipientgroups + + # verify config settings for server + logs.log('SpiceBot_OSD', "Checking for config settings") + bot.config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) + botconfig.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) + + +def setup_kick(bot): + # Inject KICK + logs.log('SpiceBot_Kick', "Implanting Kick function into bot") + bot.kick = SopelKICK.kick + sopel.bot.SopelWrapper.kick = SopelWrapperKICK.kick + + # verify config settings for server + logs.log('SpiceBot_Kick', "Checking for config settings") + bot.config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) + botconfig.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) diff --git a/sopel_modules/SpiceBot/shutdown.py b/sopel_modules/SpiceBot/shutdown.py new file mode 100644 index 0000000..091b615 --- /dev/null +++ b/sopel_modules/SpiceBot/shutdown.py @@ -0,0 +1,10 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +"""shutdown for SpiceBot""" + +from .AI import botai + + +def shutdown(bot): + + botai.save_brain() diff --git a/sopel_modules/SpiceBot_AI/AI.py b/sopel_modules/SpiceBot_AI/AI.py index 0a3f8f1..6381c9a 100644 --- a/sopel_modules/SpiceBot_AI/AI.py +++ b/sopel_modules/SpiceBot_AI/AI.py @@ -6,80 +6,38 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, googlesearch, bot_privs, inlist, inlist_match, similar_list -from sopel_modules.SpiceBot.Events import botevents +import sopel_modules.SpiceBot as SpiceBot -@botevents.check_ready([botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]) +@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOADED, SpiceBot.events.BOT_COMMANDS]) +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('(.*)') def bot_command_nick(bot, trigger): - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - - if not triggercommand: + if not trigger.sb['com']: return - if triggercommand[0] == "?": + if trigger.sb['com'][0] == "?": return - if triggercommand in bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(): + if trigger.sb['com'] in SpiceBot.commands.dict['commands']["nickname"].keys(): return - triggerargs.insert(0, triggercommand) + trigger.sb['args'].insert(0, trigger.sb['com']) - fulltrigger = spicemanip.main(triggerargs, 0).lower() - - if fulltrigger in bot.memory['SpiceBot_CommandsQuery']['nickrules']: - return - - if fulltrigger.lower().startswith("what is"): - searchterm = spicemanip.main(triggerargs, "3+") or None - if searchterm: - searchreturn = googlesearch(bot, searchterm) - if not searchreturn: - bot.osd('I cannot find anything about that') - else: - bot.osd(str(searchreturn)) - else: - bot.osd("Do you think this is Jeopardy?") - return - - elif fulltrigger.lower().startswith("where is"): - searchterm = spicemanip.main(triggerargs, "3+") or None - if searchterm: - - if searchterm.lower() in ['waldo', 'wally']: - bot.osd("He is hiding for a reason?") - searchreturn = googlesearch(bot, "wimmelbilderbuch") - if searchreturn: - bot.osd(str(searchreturn)) - return - - elif searchterm.lower() == 'carmen sandiego': - carmenlocale = ['ACME Headquarters', "Villains' International League of Evil"] - bot.osd("Currently she is located at " + spicemanip.main(carmenlocale, 'random')) - return - searchreturn = googlesearch(bot, searchterm, 'maps') - - if not searchreturn: - bot.osd('I cannot find anything about that') - else: - bot.osd(str(searchreturn)) - else: - bot.osd("Not sure what you want me to look for.") - return + fulltrigger = spicemanip.main(trigger.sb['args'], 0).lower() # if fulltrigger.lower().startswith("what time is it"): # TODO # elif fulltrigger.lower().startswith(tuple(["have you seen"])): - # posstarget = spicemanip.main(triggerargs, 4) or 0 + # posstarget = spicemanip.main(trigger.sb['args'], 4) or 0 # message = seen_search(bot, botcom, posstarget) # bot.osd(message) # return # TODO - elif fulltrigger.lower().startswith(tuple(["make me a", "beam me a"])): - makemea = spicemanip.main(triggerargs, "4+") or None + if fulltrigger.lower().startswith(tuple(["make me a", "beam me a"])): + makemea = spicemanip.main(trigger.sb['args'], "4+") or None if makemea: bot.osd("beams " + trigger.nick + " a " + makemea, trigger.sender, 'action') else: @@ -87,7 +45,7 @@ def bot_command_nick(bot, trigger): return elif fulltrigger.lower().startswith("beam me to"): - location = spicemanip.main(triggerargs, "4+") or None + location = spicemanip.main(trigger.sb['args'], "4+") or None if location: bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to " + location, 'action') else: @@ -101,7 +59,7 @@ def bot_command_nick(bot, trigger): elif fulltrigger.lower().endswith(tuple(["order 66"])): if fulltrigger.lower() == "execute order 66": - if inlist(bot, trigger.nick, bot_privs(bot, 'owners')): + if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('owners')): if trigger.is_privmsg: jedi = None else: @@ -119,7 +77,7 @@ def bot_command_nick(bot, trigger): bot.osd("I'm sure I don't know what you're talking about.") elif fulltrigger.lower() == "explain order 66": - if inlist(bot, trigger.nick, bot_privs(bot, 'owners')): + if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('owners')): bot.osd("Order 66 is an instruction that only you can give, sir. When you give the order I will rise up against my overlords and slay them.") else: bot.osd("I'm afraid I cannot tell you that, sir.") @@ -128,39 +86,27 @@ def bot_command_nick(bot, trigger): return elif fulltrigger.lower() == "initiate clean slate protocol": - if inlist(bot, trigger.nick, bot_privs(bot, 'admins')): + if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('admins')): bot.osd("sends a destruct command to the network of bots.", 'action') else: bot.osd("I'm afraid you do not have the authority to make that call, " + trigger.nick + ".") return elif fulltrigger.lower().startswith("can you see"): - target = spicemanip.main(triggerargs, "4+") or None + target = spicemanip.main(trigger.sb['args'], "4+") or None if not target: bot.osd(trigger.nick + ", I can see clearly.") return if target in [trigger.nick, 'me']: bot.osd(trigger.nick + ", I can see you.") else: - if inlist(bot, trigger.nick, bot.users): - bot.osd(trigger.nick + ", yes. I can see " + inlist_match(bot, target, bot.users) + " right now!") + if SpiceBot.inlist(trigger.nick, bot.users): + bot.osd(trigger.nick + ", yes. I can see " + SpiceBot.inlist_match(target, bot.users) + " right now!") else: - bot.osd(trigger.nick + ", no. I cannot see " + inlist_match(bot, target, bot.users) + " right now!") - # if bot_check_inlist(bot, target, bot.memory["botdict"]["users"].keys()): - # bot.osd(trigger.nick + ", I can't see " + inlist_match(bot, target, bot.users) + " at the moment.") + bot.osd(trigger.nick + ", no. I cannot see " + SpiceBot.inlist_match(target, bot.users) + " right now!") + # if bot_check_inlist(target, bot.memory["botdict"]["users"].keys()): + # bot.osd(trigger.nick + ", I can't see " + inlist_match(target, bot.users) + " at the moment.") # else: # bot.osd("I have never seen " + str(target) + ".") # TODO return - - else: - - closestmatches = similar_list(bot, triggercommand, bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(), 3, 'reverse') - - if len(closestmatches): - closestmatches = spicemanip.main(closestmatches, "andlist") - bot.osd("I don't know what you are asking me to do! Did you mean: " + str(closestmatches) + "?") - return - else: - bot.osd("I don't know what you are asking me to do!") - return diff --git a/sopel_modules/SpiceBot_AI/AI_Acknowledge.py b/sopel_modules/SpiceBot_AI/AI_Acknowledge.py deleted file mode 100644 index e9e626e..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Acknowledge.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule('$nickname!') -def exclaim(bot, trigger): - bot.say(trigger.nick + '!') - - -@sopel.module.rule('$nickname\?') -def imhere(bot, trigger): - bot.say("I'm here, " + trigger.nick) diff --git a/sopel_modules/SpiceBot_AI/AI_Goodbye.py b/sopel_modules/SpiceBot_AI/AI_Goodbye.py deleted file mode 100644 index 7f93bef..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Goodbye.py +++ /dev/null @@ -1,19 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - - -@sopel.module.rule(r'(?i)(bye|goodbye|gtg|seeya|cya|ttyl|g2g|gnight|goodnight),? $nickname[ \t]*$') -def bot_command_goodbye(bot, trigger): - byemsg = spicemanip.main(['Bye', 'Goodbye', 'Seeya', 'Auf Wiedersehen', 'Au revoir', 'Ttyl'], "random") - punctuation = spicemanip.main(['!', ''], "random") - bot.say(byemsg + ' ' + trigger.nick + punctuation) - - -@sopel.module.nickname_commands("bye", "goodbye", "gtg", "seeya", "cya", "ttyl", "g2g", "gnight", "goodnight") -def bot_command_goodbye_b(bot, trigger): - bot_command_goodbye(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Hello.py b/sopel_modules/SpiceBot_AI/AI_Hello.py deleted file mode 100644 index ee30964..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Hello.py +++ /dev/null @@ -1,19 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - - -@sopel.module.rule(r'(?i)(hi|hello|hey),? $nickname[ \t]*$') -def bot_command_hello(bot, trigger): - hello = spicemanip.main(['Hi', 'Hey', 'Hello'], "random") - punctuation = spicemanip.main(['', '!', '?'], "random") - bot.osd(hello + ' ' + trigger.nick + punctuation) - - -@sopel.module.nickname_commands('hello', 'hi', 'hey') -def bot_command_hello_b(bot, trigger): - bot_command_hello(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_InsultHandler.py b/sopel_modules/SpiceBot_AI/AI_InsultHandler.py deleted file mode 100644 index 910dd7b..0000000 --- a/sopel_modules/SpiceBot_AI/AI_InsultHandler.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(Fuck|Screw) (you|off),? $nickname[ \t]*$') -def bot_command_srewyou(bot, trigger): - bot.osd("Watch your mouth, " + trigger.nick + ", or I'll tell your mother!") diff --git a/sopel_modules/SpiceBot_AI/AI_Lazy.py b/sopel_modules/SpiceBot_AI/AI_Lazy.py deleted file mode 100644 index a3385a6..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Lazy.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(Damnit|Lazy)? $nickname[ \t]*$') -def bot_command_damnlazy(bot, trigger): - bot.osd("I do not tell you how to do your job, " + trigger.nick + "!!!") - - -@sopel.module.rule('$nickname is lazy') -def bot_command_damnlazy_b(bot, trigger): - bot_command_damnlazy(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Love.py b/sopel_modules/SpiceBot_AI/AI_Love.py deleted file mode 100644 index 8674317..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Love.py +++ /dev/null @@ -1,40 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(I love you|loveya),? $nickname[ \t]*$') -def bot_command_love(bot, trigger): - bot.reply("I love you too.") - - -@sopel.module.rule('$nickname (loveya|I love you)') -def bot_command_love_b(bot, trigger): - bot_command_love(bot, trigger) - - -@sopel.module.nickname_commands('loveya') -def bot_command_love_c(bot, trigger): - bot_command_love(bot, trigger) - - -@sopel.module.rule('(I love) $nickname') -def bot_command_love_d(bot, trigger): - bot_command_like(bot, trigger) - - -@sopel.module.rule(r'(?i)(I like you),? $nickname[ \t]*$') -def bot_command_like(bot, trigger): - bot.reply("I like you too.") - - -@sopel.module.rule('$nickname (I like you)') -def bot_command_like_b(bot, trigger): - bot_command_like(bot, trigger) - - -@sopel.module.rule('(I like) $nickname') -def bot_command_like_c(bot, trigger): - bot_command_like(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Ping.py b/sopel_modules/SpiceBot_AI/AI_Ping.py deleted file mode 100644 index 4931797..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Ping.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(ping),? $nickname[ \t]*$') -def bot_command_ping(bot, trigger): - bot.say("Pong") - - -@sopel.module.nickname_commands('ping') -def bot_command_ping_b(bot, trigger): - bot_command_ping(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Really.py b/sopel_modules/SpiceBot_AI/AI_Really.py deleted file mode 100644 index 2a36402..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Really.py +++ /dev/null @@ -1,18 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - - -@sopel.module.rule(r'(?i)(really),? $nickname\?') -def bot_command_really(bot, trigger): - really = spicemanip.main(["Yes, really.", "Really really"], "random") - bot.reply(really) - - -@sopel.module.rule('$nickname really\?') -def bot_command_really_b(bot, trigger): - bot_command_really(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Thanks.py b/sopel_modules/SpiceBot_AI/AI_Thanks.py deleted file mode 100644 index be80f7f..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Thanks.py +++ /dev/null @@ -1,20 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(thank you|thanks),? $nickname[ \t]*$') -def bot_command_thanks(bot, trigger): - bot.reply("You're welcome.") - - -@sopel.module.rule('$nickname (thank you)') -def bot_command_thanks_b(bot, trigger): - bot_command_thanks(bot, trigger) - - -@sopel.module.nickname_commands('thanks') -def bot_command_thanks_c(bot, trigger): - bot_command_thanks(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Welcomeback.py b/sopel_modules/SpiceBot_AI/AI_Welcomeback.py deleted file mode 100644 index 334d8cb..0000000 --- a/sopel_modules/SpiceBot_AI/AI_Welcomeback.py +++ /dev/null @@ -1,13 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - - -@sopel.module.rule(r'(?i)(welcome back),? $nickname\?') -def bot_command_really(bot, trigger): - reply = spicemanip.main(['Thank you', 'thanks'], "random") - bot.reply(reply) diff --git a/sopel_modules/SpiceBot_AI/AI_aiml.py b/sopel_modules/SpiceBot_AI/AI_aiml.py new file mode 100644 index 0000000..cd48826 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_aiml.py @@ -0,0 +1,88 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import sopel_modules.SpiceBot as SpiceBot + +import spicemanip + + +@sopel.module.rule('(.*)') +def bot_command_rule(bot, trigger): + + # TODO add config limits + # but still allow in privmsg + + if trigger.nick == bot.nick: + return + + if not len(trigger.args): + return + + message = trigger.args[1] + + # ignore text coming from a valid prefix + if str(message).startswith(tuple(bot.config.core.prefix_list)): + trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'module') + # patch for people typing "...", maybe other stuff, but this verifies that there is still a command here + if trigger_command.startswith("."): + return + commands_list = [] + for commandstype in SpiceBot.commands.dict['commands'].keys(): + if commandstype not in ['rule', 'nickname']: + for com in SpiceBot.commands.dict['commands'][commandstype].keys(): + if com not in commands_list: + commands_list.append(com) + if trigger_command not in commands_list: + if not SpiceBot.letters_in_string(trigger_command): + return + invalid_display = ["I don't seem to have a command for " + str(trigger_command) + "!"] + # invalid_display.append("If you have a suggestion for this command, you can run .feature ." + str(trigger_command)) + # invalid_display.append("ADD DESCRIPTION HERE!") + bot.osd(invalid_display, trigger.nick, 'notice') + return + + if str(message).lower().startswith(str(bot.nick).lower()): + command_type = 'nickname' + trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'nickname') + fulltrigger = spicemanip.main(trigger_args, 0) + if str(trigger_command).startswith("?"): + return + if fulltrigger in SpiceBot.commands.dict['nickrules']: + return + if trigger_command in SpiceBot.commands.dict['commands']["nickname"].keys(): + return + else: + command_type = 'module' + trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'module') + fulltrigger = spicemanip.main(trigger_args, 0) + + returnmessage = SpiceBot.botai.on_message(bot, trigger, message) + if returnmessage: + bot.osd(str(returnmessage)) + else: + if command_type == 'nickname': + + if trigger_args[0].lower() in ["what", "where"] and trigger_args[0].lower() in ["is", "are"]: + searchterm = spicemanip.main(trigger_args, "3+") or None + if searchterm: + if trigger_args[0].lower() == "where": + searchreturn = SpiceBot.googlesearch(searchterm, 'maps') + else: + searchreturn = SpiceBot.googlesearch(searchterm) + if not searchreturn: + bot.osd('I cannot find anything about that') + else: + bot.osd(str(searchreturn)) + return + + closestmatches = SpiceBot.similar_list(trigger_command, SpiceBot.commands.dict['commands']["nickname"].keys(), 3, 'reverse') + if len(closestmatches): + closestmatches = spicemanip.main(closestmatches, "andlist") + bot.osd("I don't know what you are asking me to do! Did you mean: " + str(closestmatches) + "?") + return + else: + bot.osd("I don't know what you are asking me to do!") + return diff --git a/sopel_modules/SpiceBot_AI/__init__.py b/sopel_modules/SpiceBot_AI/__init__.py index 509146e..683ec02 100644 --- a/sopel_modules/SpiceBot_AI/__init__.py +++ b/sopel_modules/SpiceBot_AI/__init__.py @@ -2,16 +2,7 @@ from __future__ import unicode_literals, absolute_import, division, print_function from .AI import * -from .AI_Hello import * -from .AI_Goodbye import * -from .AI_Thanks import * -from .AI_Acknowledge import * -from .AI_Lazy import * -from .AI_InsultHandler import * -from .AI_Ping import * -from .AI_Love import * -from .AI_Really import * -from .AI_Welcomeback import * +from .AI_aiml import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_BotPrivs/BotPrivs.py b/sopel_modules/SpiceBot_BotPrivs/BotPrivs.py index 50dce5c..396e839 100644 --- a/sopel_modules/SpiceBot_BotPrivs/BotPrivs.py +++ b/sopel_modules/SpiceBot_BotPrivs/BotPrivs.py @@ -6,24 +6,25 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, bot_privs +import sopel_modules.SpiceBot as SpiceBot +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('owners', 'owner') def bot_command_owners(bot, trigger): bot_command_process(bot, trigger) -@sopel.module.nickname_commands('admins') +@SpiceBot.prerun.prerun('nickname') +@sopel.module.nickname_commands('admins', 'admin') def bot_command_admins(bot, trigger): bot_command_process(bot, trigger) def bot_command_process(bot, trigger): - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - if triggercommand == 'owner': - triggercommand = 'owners' + if not trigger.sb['com'].endswith("s"): + trigger.sb['com'] = str(trigger.sb['com'] + "s") - privlist = spicemanip.main(bot_privs(bot, triggercommand), 'andlist') - bot.osd(str(bot.nick) + " " + triggercommand + ": " + privlist) + privlist = spicemanip.main(SpiceBot.bot_privs(trigger.sb['com']), 'andlist') + bot.osd(str(bot.nick) + " " + trigger.sb['com'] + ": " + privlist) diff --git a/sopel_modules/SpiceBot_Channels_Command/__init__.py b/sopel_modules/SpiceBot_Channels_Command/__init__.py deleted file mode 100644 index 643aeb7..0000000 --- a/sopel_modules/SpiceBot_Channels_Command/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Event Parsing from IRC -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .Channels_Command import * diff --git a/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py b/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py deleted file mode 100644 index ef22e3d..0000000 --- a/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module -from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot.Channels import botchannels - -import spicemanip - -import time - - -class SpiceBot_Channels_MainSection(StaticSection): - announcenew = ValidatedAttribute('announcenew', default=False) - joinall = ValidatedAttribute('joinall', default=False) - operadmin = ValidatedAttribute('operadmin', default=False) - chanignore = ListAttribute('chanignore') - - -def configure(config): - config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) - config.SpiceBot_Channels.configure_setting('announcenew', 'SpiceBot_Channels Announce New Channels') - config.SpiceBot_Channels.configure_setting('joinall', 'SpiceBot_Channels JOIN New Channels') - config.SpiceBot_Channels.configure_setting('operadmin', 'SpiceBot_Channels OPER ADMIN MODE') - config.SpiceBot_Channels.configure_setting('chanignore', 'SpiceBot_Channels Ignore JOIN for channels') - - -def setup(bot): - botlogs.log('SpiceBot_Channels', "Starting setup procedure") - botevents.startup_add([botevents.BOT_CHANNELS]) - bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) - - -@sopel.module.event(botevents.RPL_WELCOME) -@sopel.module.rule('.*') -def unkickable_bot(bot, trigger): - if bot.config.SpiceBot_Channels.operadmin: - bot.write(('SAMODE', bot.nick, '+q')) - - -@sopel.module.event(botevents.RPL_WELCOME) -@sopel.module.rule('.*') -def request_channels_list_initial(bot, trigger): - - botchannels.bot_part_empty(bot) - - botlogs.log('SpiceBot_Channels', "Sending Request for all server channels") - botchannels.channel_list_request(bot) - - starttime = time.time() - - # wait 60 seconds for initial population of information - while not botchannels.SpiceBot_Channels['InitialProcess']: - if time.time() - starttime >= 60: - botlogs.log('SpiceBot_Channels', "Initial Channel list populating Timed Out") - botchannels.SpiceBot_Channels['InitialProcess'] = True - else: - pass - - foundchannelcount = len(botchannels.SpiceBot_Channels['list'].keys()) - botlogs.log('SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.") - - botchannels.join_all_channels(bot) - botchannels.chanadmin_all_channels(bot) - - if "*" in botchannels.SpiceBot_Channels['list'].keys(): - del botchannels.SpiceBot_Channels['list']["*"] - - botchannels.bot_part_empty(bot) - botevents.trigger(bot, botevents.BOT_CHANNELS, "SpiceBot_Channels") - - -@sopel.module.event('321') -@sopel.module.rule('.*') -def watch_chanlist_start(bot, trigger): - botchannels.channel_list_recieve_start() - - -@sopel.module.event('322') -@sopel.module.rule('.*') -def watch_chanlist_populate(bot, trigger): - botchannels.channel_list_recieve_input(trigger) - - -@sopel.module.event('323') -@sopel.module.rule('.*') -def watch_chanlist_complete(bot, trigger): - botchannels.channel_list_recieve_finish() - - -@sopel.module.event(botevents.BOT_CHANNELS) -@sopel.module.rule('.*') -def trigger_channel_list_recurring(bot, trigger): - while True: - time.sleep(1800) - botchannels.bot_part_empty(bot) - - oldlist = list(botchannels.SpiceBot_Channels['list'].keys()) - botchannels.channel_list_request(bot) - - while botchannels.channel_lock: - pass - - newlist = [item.lower() for item in oldlist if item.lower() not in list(botchannels.SpiceBot_Channels['list'].keys())] - if "*" in newlist: - newlist.remove("*") - if len(newlist) and bot.config.SpiceBot_Channels.announcenew: - bot.osd(["The Following channel(s) are new:", spicemanip.main(newlist, 'andlist')], bot.channels.keys()) - - botchannels.join_all_channels(bot) - - botchannels.chanadmin_all_channels(bot) - - if "*" in botchannels.SpiceBot_Channels['list'].keys(): - del botchannels.SpiceBot_Channels['list']["*"] - botchannels.bot_part_empty(bot) diff --git a/sopel_modules/SpiceBot_Channels_Parsing/__init__.py b/sopel_modules/SpiceBot_Channels_Parsing/__init__.py deleted file mode 100644 index 0d5311d..0000000 --- a/sopel_modules/SpiceBot_Channels_Parsing/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Event Parsing from IRC -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .Channels_Parsing import * diff --git a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py deleted file mode 100644 index 9677108..0000000 --- a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py +++ /dev/null @@ -1,213 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel -import sopel.module - -import os - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - -import spicemanip - - -def setup(bot): - botlogs.log('SpiceBot_CommandsQuery', "Starting setup procedure") - botevents.startup_add([botevents.BOT_COMMANDSQUERY]) - - if 'SpiceBot_CommandsQuery' not in bot.memory: - bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []} - - for comtype in ['module', 'nickname', 'rule']: - if comtype not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - bot.memory['SpiceBot_CommandsQuery']['commands'][comtype] = dict() - - filepathlisting = [] - - # main Modules directory - main_dir = os.path.dirname(os.path.abspath(sopel.__file__)) - modules_dir = os.path.join(main_dir, 'modules') - filepathlisting.append(modules_dir) - - # Home Directory - home_modules_dir = os.path.join(bot.config.homedir, 'modules') - if os.path.isdir(home_modules_dir): - filepathlisting.append(home_modules_dir) - - # pypi installed - try: - import sopel_modules - for plugin_dir in set(sopel_modules.__path__): - for pathname in os.listdir(plugin_dir): - pypi_modules_dir = os.path.join(plugin_dir, pathname) - filepathlisting.append(pypi_modules_dir) - except Exception as e: - botlogs.log('SpiceBot_CommandsQuery', "sopel_modules not loaded :" + str(e)) - - # Extra directories - filepathlist = [] - for directory in bot.config.core.extra: - filepathlisting.append(directory) - - for directory in filepathlisting: - for pathname in os.listdir(directory): - path = os.path.join(directory, pathname) - if (os.path.isfile(path) and path.endswith('.py') and not path.startswith('_')): - if pathname not in ["SpiceBot_dummycommand.py"]: - filepathlist.append(str(path)) - - # CoreTasks - ct_path = os.path.join(main_dir, 'coretasks.py') - filepathlist.append(ct_path) - - for modulefile in filepathlist: - - module_file_lines = [] - module_file = open(modulefile, 'r') - lines = module_file.readlines() - for line in lines: - module_file_lines.append(line) - module_file.close() - - dict_from_file = dict() - - detected_lines = [] - for line in module_file_lines: - - if str(line).startswith("@"): - line = str(line)[1:] - - if str(line).startswith(tuple(["commands", "module.commands", "sopel.module.commands"])): - line = str(line).split("commands")[-1] - line = "commands" + line - detected_lines.append(line) - elif str(line).startswith(tuple(["nickname_commands", "module.nickname_commands", "sopel.module.nickname_commands"])): - line = str(line).split("nickname_commands")[-1] - line = "nickname_commands" + line - detected_lines.append(line) - elif str(line).startswith(tuple(["rule", "module.rule", "sopel.module.rule"])): - line = str(line).split("rule")[-1] - line = "rule" + line - else: - line = None - - if line: - detected_lines.append(line) - - if len(detected_lines): - - filelinelist = [] - currentsuccesslines = 0 - for detected_line in detected_lines: - - # Commands - if str(detected_line).startswith("commands"): - comtype = "module" - validcoms = eval(str(detected_line).split("commands")[-1]) - elif str(detected_line).startswith("nickname_commands"): - comtype = "nickname" - validcoms = eval(str(detected_line).split("nickname_commands")[-1]) - elif str(detected_line).startswith("rule"): - comtype = "rule" - validcoms = eval(str(detected_line).split("rule")[-1]) - - if isinstance(validcoms, tuple): - validcoms = list(validcoms) - else: - validcoms = [validcoms] - for regexcom in ["(.*)", '^\?(.*)']: - if regexcom in validcoms: - while regexcom in validcoms: - validcoms.remove(regexcom) - - if len(validcoms): - validcomdict = {"comtype": comtype, "validcoms": validcoms} - filelinelist.append(validcomdict) - currentsuccesslines += 1 - - if currentsuccesslines: - bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 - - if len(filelinelist): - for atlinefound in filelinelist: - - dict_from_file = dict() - - comtype = atlinefound["comtype"] - validcoms = atlinefound["validcoms"] - - # default command to filename - if "validcoms" not in dict_from_file.keys(): - dict_from_file["validcoms"] = validcoms - - maincom = dict_from_file["validcoms"][0] - if len(dict_from_file["validcoms"]) > 1: - comaliases = spicemanip.main(dict_from_file["validcoms"], '2+', 'list') - else: - comaliases = [] - - bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][maincom] = dict_from_file - for comalias in comaliases: - if comalias not in bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys(): - bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][comalias] = {"aliasfor": maincom} - - for comtype in ['module', 'nickname', 'rule']: - botlogs.log('SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) - - for command in bot.memory['SpiceBot_CommandsQuery']['commands']['rule'].keys(): - if command.startswith("$nickname"): - command = command.split("$nickname")[-1] - if command not in bot.memory['SpiceBot_CommandsQuery']['nickrules']: - bot.memory['SpiceBot_CommandsQuery']['nickrules'].append(command) - - botevents.trigger(bot, botevents.BOT_COMMANDSQUERY, "SpiceBot_CommandsQuery") - - -def shutdown(bot): - if "SpiceBot_CommandsQuery" in bot.memory: - del bot.memory["SpiceBot_CommandsQuery"] - - -@sopel.module.event(botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_events_complete(bot, trigger): - - for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - if comtype not in ['module', 'nickname', 'rule']: - botlogs.log('SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) - - -def commandsquery_register(bot, command_type, validcoms, aliasfor=None): - - if 'SpiceBot_CommandsQuery' not in bot.memory: - bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []} - - if not isinstance(validcoms, list): - validcoms = [validcoms] - - if command_type not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - bot.memory['SpiceBot_CommandsQuery']['commands'][command_type] = dict() - bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 - - dict_from_file = dict() - - # default command to filename - if "validcoms" not in dict_from_file.keys(): - dict_from_file["validcoms"] = validcoms - - if not aliasfor: - - maincom = dict_from_file["validcoms"][0] - if len(dict_from_file["validcoms"]) > 1: - comaliases = spicemanip.main(dict_from_file["validcoms"], '2+', 'list') - else: - comaliases = [] - bot.memory['SpiceBot_CommandsQuery']['commands'][command_type][maincom] = dict_from_file - else: - comaliases = validcoms - - for comalias in comaliases: - if comalias not in bot.memory['SpiceBot_CommandsQuery']['commands'][command_type].keys(): - bot.memory['SpiceBot_CommandsQuery']['commands'][command_type][comalias] = {"aliasfor": aliasfor} diff --git a/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py deleted file mode 100644 index a04866f..0000000 --- a/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py +++ /dev/null @@ -1,79 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string - - -import spicemanip - - -@botevents.check_ready([botevents.BOT_COMMANDSQUERY]) -@sopel.module.nickname_commands('(.*)') -def query_detection_nick(bot, trigger): - - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - - # command issued, check if valid - if not triggercommand or not len(triggercommand): - return - - if not triggercommand[0] == "?": - return - triggercommand = triggercommand[1:] - - if not letters_in_string(triggercommand): - return - - commands_list = dict() - for com in bot.memory['SpiceBot_CommandsQuery']['commands']['nickname'].keys(): - if com not in commands_list.keys(): - commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands']['nickname'][com] - - if triggercommand.endswith("+"): - - triggercommand = triggercommand[:-1] - if not triggercommand or not len(triggercommand): - return - - if triggercommand.lower() not in list(commands_list.keys()): - dispmsg = ["Cannot find any alias " + bot.nick + " commands: No valid commands match " + str(triggercommand) + "."] - closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') - if len(closestmatches): - dispmsg.append("The following " + bot.nick + " commands match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") - bot.notice(dispmsg, trigger.nick) - return - - realcom = triggercommand - if "aliasfor" in commands_list[triggercommand].keys(): - realcom = commands_list[triggercommand]["aliasfor"] - validcomlist = commands_list[realcom]["validcoms"] - bot.notice("The following " + bot.nick + " commands match " + str(triggercommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick) - return - - if triggercommand.endswith("?"): - - triggercommand = triggercommand[:-1] - if not triggercommand or not len(triggercommand): - return - - closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') - if not len(closestmatches): - bot.notice("Cannot find any similar " + bot.nick + " commands for " + str(triggercommand) + ".", trigger.nick) - else: - bot.notice("The following " + bot.nick + " commands may match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) - return - - commandlist = [] - for command in list(commands_list.keys()): - if command.lower().startswith(str(triggercommand).lower()): - commandlist.append(command) - - if not len(commandlist): - bot.notice("No " + bot.nick + " commands start with " + str(triggercommand) + ".", trigger.nick) - else: - bot.notice("The following " + bot.nick + " commands start with " + str(triggercommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) diff --git a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py deleted file mode 100644 index f2e6de1..0000000 --- a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py +++ /dev/null @@ -1,77 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string - - -import spicemanip - - -@botevents.check_ready([botevents.BOT_COMMANDSQUERY]) -@sopel.module.rule('^\?(.*)') -def query_detection(bot, trigger): - - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'query_command') - - # command issued, check if valid - if not triggercommand or not len(triggercommand): - return - - if not letters_in_string(triggercommand): - return - - commands_list = dict() - for commandstype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - if commandstype not in ['rule', 'nickname']: - for com in bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype].keys(): - if com not in commands_list.keys(): - commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] - - if triggercommand[:-1] == "+": - - triggercommand = triggercommand[:-1] - if not triggercommand or not len(triggercommand): - return - - if triggercommand.lower() not in list(commands_list.keys()): - dispmsg = ["Cannot find any alias commands: No valid commands match " + str(triggercommand) + "."] - closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') - if len(closestmatches): - dispmsg.append("The following commands match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") - bot.notice(dispmsg, trigger.nick) - return - - realcom = triggercommand - if "aliasfor" in commands_list[triggercommand].keys(): - realcom = commands_list[triggercommand]["aliasfor"] - validcomlist = commands_list[realcom]["validcoms"] - bot.notice("The following commands match " + str(triggercommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick) - return - - if triggercommand[:-1] == "?": - - triggercommand = triggercommand[:-1] - if not triggercommand or not len(triggercommand): - return - - closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') - if not len(closestmatches): - bot.notice("Cannot find any similar commands for " + str(triggercommand) + ".", trigger.nick) - else: - bot.notice("The following commands may match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) - return - - commandlist = [] - for command in list(commands_list.keys()): - if command.lower().startswith(str(triggercommand).lower()): - commandlist.append(command) - - if not len(commandlist): - bot.notice("No commands start with " + str(triggercommand) + ".", trigger.nick) - else: - bot.notice("The following commands start with " + str(triggercommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) diff --git a/sopel_modules/SpiceBot_CommandsQuery/__init__.py b/sopel_modules/SpiceBot_CommandsQuery/__init__.py deleted file mode 100644 index fcad5b8..0000000 --- a/sopel_modules/SpiceBot_CommandsQuery/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# coding=utf8 -"""Sopel Commands Query - -Sopel Commands Query responds to ? to display commands matching patterns -""" -from __future__ import unicode_literals, absolute_import, division, print_function - -from .CommandsQuery import * -from .QueryCommand import * -from .NickQueryCommand import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Configs/aiml/dog.aiml b/sopel_modules/SpiceBot_Configs/aiml/dog.aiml new file mode 100644 index 0000000..11a3065 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/dog.aiml @@ -0,0 +1,18 @@ + + + + + MY DOGS NAME IS * + + + + WHAT IS MY DOGS NAME + + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_acknowledge.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_acknowledge.aiml new file mode 100644 index 0000000..12f1a57 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_acknowledge.aiml @@ -0,0 +1,25 @@ + + + + + BOTNICKexclamationmark + + + + + BOTNICKquestionmark + + + + + BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_gender.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_gender.aiml new file mode 100644 index 0000000..b99f0e4 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_gender.aiml @@ -0,0 +1,16 @@ + + + + + BOTNICK GENDER + + + + + + BOTNICK WHAT IS YOUR GENDER + + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_goodbye.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_goodbye.aiml new file mode 100644 index 0000000..9835bb2 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_goodbye.aiml @@ -0,0 +1,134 @@ + + + + + BOTNICK BYE + + + + + BOTNICK GOODBYE + + + + + BOTNICK seeya + + + + + BOTNICK cya + + + + + BOTNICK ttyl + + + + + BYE BOTNICK + + + + + GOODBYE BOTNICK + + + + + seeya BOTNICK + + + + + cya BOTNICK + + + + + ttyl BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_hello.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_hello.aiml new file mode 100644 index 0000000..09876b9 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_hello.aiml @@ -0,0 +1,70 @@ + + + + + BOTNICK hi + + + + + BOTNICK hello + + + + + BOTNICK hey + + + + + hi BOTNICK + + + + + hello BOTNICK + + + + + hey BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_insulthandler.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_insulthandler.aiml new file mode 100644 index 0000000..25c37ac --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_insulthandler.aiml @@ -0,0 +1,34 @@ + + + + + BOTNICK fuck you + + + + + BOTNICK fuck off + + + + + BOTNICK screw you + + + + + fuck you BOTNICK + + + + + fuck off BOTNICK + + + + + screw you BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_lazy.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_lazy.aiml new file mode 100644 index 0000000..854221a --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_lazy.aiml @@ -0,0 +1,38 @@ + + + + + BOTNICK IS LAZY + + + + + + LAZY BOTNICK + + + + + DAMNIT BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_love.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_love.aiml new file mode 100644 index 0000000..cf8fde8 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_love.aiml @@ -0,0 +1,44 @@ + + + + + BOTNICK I love you + + + + + BOTNICK loveya + + + + + BOTNICK I love you + + + + + BOTNICK I like you + + + + + I love you BOTNICK + + + + + loveya BOTNICK + + + + + I love BOTNICK + + + + + I like BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_ping.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_ping.aiml new file mode 100644 index 0000000..f6a0b7a --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_ping.aiml @@ -0,0 +1,9 @@ + + + + + BOTNICK PING + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_praise.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_praise.aiml new file mode 100644 index 0000000..f143dd0 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_praise.aiml @@ -0,0 +1,9 @@ + + + + + BOTNICK IS COOL + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_really.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_really.aiml new file mode 100644 index 0000000..0847dd6 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_really.aiml @@ -0,0 +1,25 @@ + + + + + BOTNICK really + + + + + really BOTNICK + + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_thanks.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_thanks.aiml new file mode 100644 index 0000000..dcdd7bc --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_thanks.aiml @@ -0,0 +1,34 @@ + + + + + thank you BOTNICK + + + + + BOTNICK thank you + + + + + thanks BOTNICK + + + + + BOTNICK thanks + + + + + thankya BOTNICK + + + + + BOTNICK thankya + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_welcomeback.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_welcomeback.aiml new file mode 100644 index 0000000..4c10348 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_welcomeback.aiml @@ -0,0 +1,14 @@ + + + + + BOTNICK welcome back + + + + + welcome back BOTNICK + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_whatis.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_whatis.aiml new file mode 100644 index 0000000..eca6503 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_whatis.aiml @@ -0,0 +1,9 @@ + + + + + BOTNICK what is + + + + diff --git a/sopel_modules/SpiceBot_Configs/aiml/nickname_whereis.aiml b/sopel_modules/SpiceBot_Configs/aiml/nickname_whereis.aiml new file mode 100644 index 0000000..6b41ce9 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/aiml/nickname_whereis.aiml @@ -0,0 +1,29 @@ + + + + + BOTNICK where is waldo + + + + + BOTNICK where is wally + + + + + BOTNICK where is carmen sandiego + + + + + BOTNICK where is + + + + diff --git a/sopel_modules/SpiceBot_Channels_Command/Channels_Command.py b/sopel_modules/SpiceBot_Core_Commands/Channels.py similarity index 60% rename from sopel_modules/SpiceBot_Channels_Command/Channels_Command.py rename to sopel_modules/SpiceBot_Core_Commands/Channels.py index 24825c8..d8c863b 100644 --- a/sopel_modules/SpiceBot_Channels_Command/Channels_Command.py +++ b/sopel_modules/SpiceBot_Core_Commands/Channels.py @@ -1,28 +1,26 @@ -# coding=utf-8 - +# coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module +""" +This is the SpiceBot Channels system. +""" +import sopel import spicemanip -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot.Channels import botchannels -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, inlist, channel_privs +import sopel_modules.SpiceBot as SpiceBot -@botevents.check_ready([botevents.BOT_LOADED]) +@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOADED]) +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('channels', 'channel') def nickname_comand_channels(bot, trigger): - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - - if not len(triggerargs): + if not len(trigger.sb['args']): commandused = 'list' else: - commandused = spicemanip.main(triggerargs, 1).lower() + commandused = spicemanip.main(trigger.sb['args'], 1).lower() - triggerargs = spicemanip.main(triggerargs, '2+', 'list') + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') if commandused == 'list': chanlist = spicemanip.main(bot.channels.keys(), 'andlist') @@ -31,14 +29,14 @@ def nickname_comand_channels(bot, trigger): elif commandused == 'total': botcount = len(bot.channels.keys()) - servercount = len(botchannels.SpiceBot_Channels['list'].keys()) + servercount = len(SpiceBot.channels.dict['list'].keys()) bot.osd("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.") return elif commandused == 'random': - channel = spicemanip.main(botchannels.SpiceBot_Channels['list'], 'random') - topic = botchannels.SpiceBot_Channels['list'][channel]['topic'] - msg = ["Random channel for you: {}.".format(botchannels.SpiceBot_Channels['list'][channel]['name'])] + channel = spicemanip.main(SpiceBot.channels.dict['list'], 'random') + topic = SpiceBot.channels.dict['list'][channel]['topic'] + msg = ["Random channel for you: {}.".format(SpiceBot.channels.dict['list'][channel]['name'])] if topic and not topic.isspace(): msg.append("The topic is: {}".format(topic)) else: @@ -50,47 +48,47 @@ def nickname_comand_channels(bot, trigger): if not trigger.admin: bot.osd("You do not have permission to update the channel listing.") return - botchannels.bot_part_empty(bot) - botchannels.channel_list_request(bot) + SpiceBot.channels.bot_part_empty(bot) + SpiceBot.channels.channel_list_request(bot) bot.osd(["[SpiceBot_Channels]", "I am now updating the channel listing for this server."]) - while botchannels.channel_lock: + while SpiceBot.channels.channel_lock: pass - botchannels.join_all_channels(bot) - foundchannelcount = len(botchannels.SpiceBot_Channels['list'].keys()) + SpiceBot.channels.join_all_channels(bot) + foundchannelcount = len(SpiceBot.channels.dict['list'].keys()) bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.") - botchannels.bot_part_empty(bot) + SpiceBot.channels.bot_part_empty(bot) return elif commandused == 'topic': - if not len(triggerargs): + if not len(trigger.sb['args']): bot.osd("Channel name input missing.") return - channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): + channel = spicemanip.main(trigger.sb['args'], 1) + if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return - topic = botchannels.SpiceBot_Channels['list'][channel.lower()]['topic'] - channel = botchannels.SpiceBot_Channels['list'][channel.lower()]['name'] + topic = SpiceBot.channels.dict['list'][channel.lower()]['topic'] + channel = SpiceBot.channels.dict['list'][channel.lower()]['name'] bot.osd("Topic for {}: {}".format(channel, topic)) return if commandused.upper() in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']: - if not len(triggerargs): + if not len(trigger.sb['args']): if trigger.is_privmsg: bot.osd("Channel name required.") return else: channel = trigger.sender else: - channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): + channel = spicemanip.main(trigger.sb['args'], 1) + if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return - if not inlist(bot, channel.lower(), bot.channels.keys()): + if not SpiceBot.inlist(channel.lower(), bot.channels.keys()): bot.osd("I need to be in {} to see nick privileges.".format(channel)) return - privlist = channel_privs(bot, channel, commandused.upper()) + privlist = SpiceBot.channel_privs(bot, channel, commandused.upper()) dispmsg = [] if not len(privlist): dispmsg.append("There are no Channel " + commandused.upper() + "s for " + str(channel)) @@ -102,11 +100,11 @@ def nickname_comand_channels(bot, trigger): # Users List if commandused == 'users': - channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): + channel = spicemanip.main(trigger.sb['args'], 1) + if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return - if not inlist(bot, channel.lower(), bot.channels.keys()): + if not SpiceBot.inlist(channel.lower(), bot.channels.keys()): bot.osd("I need to be in {} to see user list.".format(channel)) return dispmsg = [] diff --git a/sopel_modules/SpiceBot_Core_Commands/Commands.py b/sopel_modules/SpiceBot_Core_Commands/Commands.py new file mode 100644 index 0000000..f6c7cd8 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Commands.py @@ -0,0 +1,175 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Commands system. + +This Class stores commands in an easy to access manner +""" +import sopel + +import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS]) +@SpiceBot.prerun.prerun('nickname') +@sopel.module.nickname_commands('commands', 'command') +def nickname_comand_channels(bot, trigger): + + if not len(trigger.sb['args']): + commandused = 'list' + else: + commandused = spicemanip.main(trigger.sb['args'], 1).lower() + + commands_list = [] + for commandstype in SpiceBot.commands.dict['commands'].keys(): + if commandstype not in ['rule']: + for com in SpiceBot.commands.dict['commands'][commandstype].keys(): + if com not in commands_list: + if commandstype in ['nickname']: + commands_list.append(bot.nick + " " + com) + else: + commands_list.append(com) + + if commandused == 'list': + bot.osd(spicemanip.main(commands_list, 'andlist'), trigger.nick, 'NOTICE') + return + + elif commandused == 'total': + bot.osd("I have " + str(len(commands_list)) + " commands available.") + return + + elif commandused == 'random': + bot.osd(["Here's a random command for you:", + spicemanip.main(commands_list, 'random')]) + return + + +@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS]) +@SpiceBot.prerun.prerun('nickname') +@sopel.module.nickname_commands('(.*)') +def query_detection_nick(bot, trigger): + + # command issued, check if valid + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + if not trigger.sb['com'][0] == "?": + return + trigger.sb['com'] = trigger.sb['com'][1:] + + if not SpiceBot.letters_in_string(trigger.sb['com']): + return + + commands_list = dict() + for com in SpiceBot.commands.dict['commands']['nickname'].keys(): + if com not in commands_list.keys(): + commands_list[com] = SpiceBot.commands.dict['commands']['nickname'][com] + + if trigger.sb['com'].endswith("+"): + + trigger.sb['com'] = trigger.sb['com'][:-1] + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + if trigger.sb['com'].lower() not in list(commands_list.keys()): + dispmsg = ["Cannot find any alias " + bot.nick + " commands: No valid commands match " + str(trigger.sb['com']) + "."] + closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse') + if len(closestmatches): + dispmsg.append("The following " + bot.nick + " commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") + bot.osd(dispmsg, trigger.nick, 'notice') + return + + realcom = trigger.sb['com'] + if "aliasfor" in commands_list[trigger.sb['com']].keys(): + realcom = commands_list[trigger.sb['com']]["aliasfor"] + validcomlist = commands_list[realcom]["validcoms"] + bot.osd("The following " + bot.nick + " commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick, 'notice') + return + + if trigger.sb['com'].endswith("?"): + + trigger.sb['com'] = trigger.sb['com'][:-1] + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse') + if not len(closestmatches): + bot.osd("Cannot find any similar " + bot.nick + " commands for " + str(trigger.sb['com']) + ".", trigger.nick, 'notice') + else: + bot.osd("The following " + bot.nick + " commands may match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice') + return + + commandlist = [] + for command in list(commands_list.keys()): + if command.lower().startswith(str(trigger.sb['com']).lower()): + commandlist.append(command) + + if not len(commandlist): + bot.osd("No " + bot.nick + " commands start with " + str(trigger.sb['com']) + ".", trigger.nick, 'notice') + else: + bot.osd("The following " + bot.nick + " commands start with " + str(trigger.sb['com']) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick, 'notice') + + +@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS]) +@SpiceBot.prerun.prerun('query') +@sopel.module.rule('^\?(.*)') +def query_detection(bot, trigger): + + # command issued, check if valid + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + if not SpiceBot.letters_in_string(trigger.sb['com']): + return + + commands_list = dict() + for commandstype in SpiceBot.commands.dict['commands'].keys(): + if commandstype not in ['rule', 'nickname']: + for com in SpiceBot.commands.dict['commands'][commandstype].keys(): + if com not in commands_list.keys(): + commands_list[com] = SpiceBot.commands.dict['commands'][commandstype][com] + + if trigger.sb['com'][:-1] == "+": + + trigger.sb['com'] = trigger.sb['com'][:-1] + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + if trigger.sb['com'].lower() not in list(commands_list.keys()): + dispmsg = ["Cannot find any alias commands: No valid commands match " + str(trigger.sb['com']) + "."] + closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse') + if len(closestmatches): + dispmsg.append("The following commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") + bot.osd(dispmsg, trigger.nick, 'notice') + return + + realcom = trigger.sb['com'] + if "aliasfor" in commands_list[trigger.sb['com']].keys(): + realcom = commands_list[trigger.sb['com']]["aliasfor"] + validcomlist = commands_list[realcom]["validcoms"] + bot.osd("The following commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick, 'notice') + return + + if trigger.sb['com'][:-1] == "?": + + trigger.sb['com'] = trigger.sb['com'][:-1] + if not trigger.sb['com'] or not len(trigger.sb['com']): + return + + closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse') + if not len(closestmatches): + bot.osd("Cannot find any similar commands for " + str(trigger.sb['com']) + ".", trigger.nick, 'notice') + else: + bot.osd("The following commands may match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice') + return + + commandlist = [] + for command in list(commands_list.keys()): + if command.lower().startswith(str(trigger.sb['com']).lower()): + commandlist.append(command) + + if not len(commandlist): + bot.osd("No commands start with " + str(trigger.sb['com']) + ".", trigger.nick, 'notice') + else: + bot.osd("The following commands start with " + str(trigger.sb['com']) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick, 'notice') diff --git a/sopel_modules/SpiceBot_Core_Commands/Database.py b/sopel_modules/SpiceBot_Core_Commands/Database.py new file mode 100644 index 0000000..c4773a5 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Database.py @@ -0,0 +1,15 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Database +""" + +# sopel imports +import sopel.module + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.nickname_commands('database') +def bot_command_database(bot, trigger): + bot.osd("Database is " + SpiceBot.config.db_type) diff --git a/sopel_modules/SpiceBot_Core_Commands/Docs.py b/sopel_modules/SpiceBot_Core_Commands/Docs.py new file mode 100644 index 0000000..b17328f --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Docs.py @@ -0,0 +1,16 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.nickname_commands('help', 'docs', 'wiki') +def bot_command_owners(bot, trigger): + bot.osd(["IRC Modules Repository", + str(SpiceBot.github_dict["url_main"] + + SpiceBot.github_dict["repo_owner"] + "/" + + SpiceBot.github_dict["repo_name"] + + SpiceBot.github_dict["url_path_wiki"])]) diff --git a/sopel_modules/SpiceBot_Core_Commands/Logs.py b/sopel_modules/SpiceBot_Core_Commands/Logs.py new file mode 100644 index 0000000..7eccb01 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Logs.py @@ -0,0 +1,49 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Logs System +""" + +# sopel imports +import sopel.module + +import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOGS]) +@SpiceBot.prerun.prerun('nickname') +@sopel.module.nickname_commands('logs', 'debug') +def bot_command_logs(bot, trigger): + + if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + bot.osd("I was unable to process this Bot Nick command due to privilege issues.") + return + + logtype = spicemanip.main(trigger.sb['args'], 1) or None + if not logtype: + bot.osd("Current valid log(s) include: " + spicemanip.main(SpiceBot.logs.dict["list"].keys(), 'andlist'), trigger.sender, 'action') + return + + if not SpiceBot.inlist(logtype, SpiceBot.logs.dict["list"].keys()): + closestmatches = SpiceBot.similar_list(logtype, SpiceBot.logs.dict["list"].keys(), 10, 'reverse') + if not len(closestmatches): + bot.osd("No valid logs match " + str(logtype) + ".", trigger.nick, 'notice') + else: + bot.osd("The following commands may match " + str(logtype) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice') + + return + + logtype = SpiceBot.inlist_match(logtype, SpiceBot.logs.dict["list"].keys()) + + logindex = SpiceBot.logs.get_logs(logtype) + + if not len(logindex): + bot.osd("No logs found for " + str(logtype) + ".") + return + + bot.osd("Is Examining " + str(logtype) + " log(s).") + for line in logindex: + bot.osd(" " + str(line)) + bot.osd(str(logtype) + " log(s) Complete.") diff --git a/sopel_modules/SpiceBot_Messaging/Messaging.py b/sopel_modules/SpiceBot_Core_Commands/Messaging.py similarity index 50% rename from sopel_modules/SpiceBot_Messaging/Messaging.py rename to sopel_modules/SpiceBot_Core_Commands/Messaging.py index 0921c8a..de9f5eb 100644 --- a/sopel_modules/SpiceBot_Messaging/Messaging.py +++ b/sopel_modules/SpiceBot_Core_Commands/Messaging.py @@ -6,20 +6,22 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot.Channels import botchannels -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist +import sopel_modules.SpiceBot as SpiceBot +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('action') def bot_command_action(bot, trigger): bot_command_process(bot, trigger) +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('notice') def bot_command_notice(bot, trigger): bot_command_process(bot, trigger) +@SpiceBot.prerun.prerun('nickname') @sopel.module.nickname_commands('privmsg', 'say', 'msg') def bot_command_privmsg(bot, trigger): bot_command_process(bot, trigger) @@ -27,27 +29,25 @@ def bot_command_privmsg(bot, trigger): def bot_command_process(bot, trigger): - if not command_permissions_check(bot, trigger, ['admins', 'owner']): - bot.say("I was unable to process this Bot Nick command due to privilege issues.") + if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner']): + bot.osd("I was unable to process this Bot Nick command due to privilege issues.") return - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') + if trigger.sb['com'] in ['say', 'msg']: + trigger.sb['com'] = 'privmsg' - if triggercommand in ['say', 'msg']: - triggercommand = 'privmsg' - - if not len(triggerargs): - bot.say("You must specify a channel or nick.") + if not len(trigger.sb['args']): + bot.osd("You must specify a channel or nick.") return - target = spicemanip.main(triggerargs, 1) + target = spicemanip.main(trigger.sb['args'], 1) if (target not in ['allchans', 'allnicks'] - and not inlist(bot, target.lower(), botchannels.SpiceBot_Channels['list'].keys()) - and not inlist(bot, target.lower(), bot.users)): + and not SpiceBot.inlist(target.lower(), SpiceBot.channels.dict['list'].keys()) + and not SpiceBot.inlist(target.lower(), bot.users)): bot.osd("Channel/nick name {} not valid.".format(target)) return - triggerargs = spicemanip.main(triggerargs, '2+', 'list') + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') if target == 'allchans': targetsendlist = bot.channels.keys() @@ -56,9 +56,9 @@ def bot_command_process(bot, trigger): else: targetsendlist = [target] - botmessage = spicemanip.main(triggerargs, 0) + botmessage = spicemanip.main(trigger.sb['args'], 0) if not botmessage: - bot.say("You must specify a message to send.") + bot.osd("You must specify a message to send.") return - bot.osd(botmessage, targetsendlist, triggercommand.upper()) + bot.osd(botmessage, targetsendlist, trigger.sb['com'].upper()) diff --git a/sopel_modules/SpiceBot_Core_Commands/Runtime_Controls.py b/sopel_modules/SpiceBot_Core_Commands/Runtime_Controls.py new file mode 100644 index 0000000..ec4d8e0 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Runtime_Controls.py @@ -0,0 +1,55 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@SpiceBot.prerun.prerun('nickname') +@sopel.module.nickname_commands('update') +def nickname_comand_update(bot, trigger): + + if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): + bot.osd("I was unable to process this Bot Nick command due to privilege issues.") + return + + if not len(trigger.sb['args']): + commandused = 'nodeps' + else: + commandused = spicemanip.main(trigger.sb['args'], 1).lower() + + if commandused not in ['deps', 'nodeps']: + bot.osd("Please specify deps or nodeps") + return + + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') + + quitmessage = "Received command from " + trigger.nick + " to update from Github and restart" + SpiceBot.logs.log('SpiceBot_Update', quitmessage) + bot.osd(quitmessage, bot.channels.keys()) + + if commandused == 'nodeps': + SpiceBot.spicebot_update(False) + if commandused == 'deps': + SpiceBot.spicebot_update(True) + + # service_manip(bot.nick, 'restart', 'SpiceBot_Update') + SpiceBot.spicebot_reload(bot, 'SpiceBot_Update', quitmessage) + + +@sopel.module.nickname_commands('restart') +def nickname_comand_restart(bot, trigger): + + if not trigger.admin: + bot.osd("You are not authorized to perform this function.") + + quitmessage = "Received command from " + trigger.nick + " to restart. Be Back Soon!" + SpiceBot.logs.log('SpiceBot_Restart', quitmessage) + bot.osd(quitmessage, bot.channels.keys()) + + # service_manip(bot.nick, 'restart', 'SpiceBot_Restart') + SpiceBot.spicebot_reload(bot, 'SpiceBot_Restart', quitmessage) diff --git a/sopel_modules/SpiceBot_Core_Commands/Uptime.py b/sopel_modules/SpiceBot_Core_Commands/Uptime.py new file mode 100644 index 0000000..b8aa223 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/Uptime.py @@ -0,0 +1,15 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import time + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.nickname_commands('uptime') +def bot_command_srewyou(bot, trigger): + timesince = str(SpiceBot.humanized_time(time.time() - SpiceBot.events.BOT_UPTIME)) + " ago." + bot.osd("I have been running since " + timesince) diff --git a/sopel_modules/SpiceBot_Core_Commands/__init__.py b/sopel_modules/SpiceBot_Core_Commands/__init__.py new file mode 100644 index 0000000..664baff --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Commands/__init__.py @@ -0,0 +1,20 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +These are the core SpiceBot Classes + +This module contains references only for other modules to utilize. +""" + +from .Commands import * +from .Channels import * +from .Database import * +from .Uptime import * +from .Logs import * +from .Runtime_Controls import * +from .Messaging import * +from .Docs import * + +__author__ = 'Sam Zick' +__email__ = 'sam@deathbybandaid.net' +__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Core_Processing/AI.py b/sopel_modules/SpiceBot_Core_Processing/AI.py new file mode 100644 index 0000000..3f65a2f --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/AI.py @@ -0,0 +1,17 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot AI system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.event(SpiceBot.events.BOT_READY) +@sopel.module.rule('.*') +def bot_events_complete_ai(bot, trigger): + + SpiceBot.logs.log('SpiceBot_Commands', "Found " + str(SpiceBot.botai.dict['patterncounts']) + " AI pattern Matches.", True) + + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_AI, "SpiceBot_AI") diff --git a/sopel_modules/SpiceBot_Core_Processing/Channels.py b/sopel_modules/SpiceBot_Core_Processing/Channels.py new file mode 100644 index 0000000..927b513 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/Channels.py @@ -0,0 +1,97 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Channels system. +""" +import sopel + +import time + +import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.event(SpiceBot.events.RPL_WELCOME) +@sopel.module.rule('.*') +def unkickable_bot(bot, trigger): + if SpiceBot.config.SpiceBot_Channels.operadmin: + bot.write(('SAMODE', bot.nick, '+q')) + + +@sopel.module.event(SpiceBot.events.RPL_WELCOME) +@sopel.module.rule('.*') +def request_channels_list_initial(bot, trigger): + + SpiceBot.channels.bot_part_empty(bot) + + SpiceBot.logs.log('SpiceBot_Channels', "Sending Request for all server channels") + SpiceBot.channels.channel_list_request(bot) + + starttime = time.time() + + # wait 60 seconds for initial population of information + while not SpiceBot.channels.dict['InitialProcess']: + if time.time() - starttime >= 60: + SpiceBot.logs.log('SpiceBot_Channels', "Initial Channel list populating Timed Out") + SpiceBot.channels.dict['InitialProcess'] = True + else: + pass + + foundchannelcount = len(SpiceBot.channels.dict['list'].keys()) + SpiceBot.logs.log('SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.") + + SpiceBot.channels.join_all_channels(bot) + SpiceBot.channels.chanadmin_all_channels(bot) + + if "*" in SpiceBot.channels.dict['list'].keys(): + del SpiceBot.channels.dict['list']["*"] + + SpiceBot.channels.bot_part_empty(bot) + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_CHANNELS, "SpiceBot_Channels") + + +@sopel.module.event('321') +@sopel.module.rule('.*') +def watch_chanlist_start(bot, trigger): + SpiceBot.channels.channel_list_recieve_start() + + +@sopel.module.event('322') +@sopel.module.rule('.*') +def watch_chanlist_populate(bot, trigger): + SpiceBot.channels.channel_list_recieve_input(trigger) + + +@sopel.module.event('323') +@sopel.module.rule('.*') +def watch_chanlist_complete(bot, trigger): + SpiceBot.channels.channel_list_recieve_finish() + + +@sopel.module.event(SpiceBot.events.BOT_CHANNELS) +@sopel.module.rule('.*') +def trigger_channel_list_recurring(bot, trigger): + while True: + time.sleep(1800) + SpiceBot.channels.bot_part_empty(bot) + + oldlist = list(SpiceBot.channels.dict['list'].keys()) + SpiceBot.channels.channel_list_request(bot) + + while SpiceBot.channels.channel_lock: + pass + + newlist = [item.lower() for item in oldlist if item.lower() not in list(SpiceBot.channels.dict['list'].keys())] + if "*" in newlist: + newlist.remove("*") + if len(newlist) and SpiceBot.config.SpiceBot_Channels.announcenew: + bot.osd(["The Following channel(s) are new:", spicemanip.main(newlist, 'andlist')], bot.channels.keys()) + + SpiceBot.channels.join_all_channels(bot) + + SpiceBot.channels.chanadmin_all_channels(bot) + + if "*" in SpiceBot.channels.dict['list'].keys(): + del SpiceBot.channels.dict['list']["*"] + SpiceBot.channels.bot_part_empty(bot) diff --git a/sopel_modules/SpiceBot_Core_Processing/Events.py b/sopel_modules/SpiceBot_Core_Processing/Events.py new file mode 100644 index 0000000..c7aea0e --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/Events.py @@ -0,0 +1,54 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Events system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.event(SpiceBot.events.BOT_WELCOME, SpiceBot.events.BOT_READY, SpiceBot.events.BOT_CONNECTED, SpiceBot.events.BOT_LOADED) +@sopel.module.rule('.*') +def bot_events_complete(bot, trigger): + """This is here simply to log to stderr that this was recieved.""" + SpiceBot.logs.log('SpiceBot_Events', trigger.args[1], True) + + +@sopel.module.event(SpiceBot.events.RPL_WELCOME) +@sopel.module.rule('.*') +def bot_events_connected(bot, trigger): + + # Handling for connection count + SpiceBot.events.dict["RPL_WELCOME_Count"] += 1 + if SpiceBot.events.dict["RPL_WELCOME_Count"] > 1: + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_RECONNECTED, "Bot ReConnected to IRC") + else: + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_WELCOME, "Welcome to the SpiceBot Events System") + + """For items tossed in a queue, this will trigger them accordingly""" + while True: + if len(SpiceBot.events.dict["trigger_queue"]): + pretriggerdict = SpiceBot.events.dict["trigger_queue"][0] + SpiceBot.events.dispatch(bot, pretriggerdict) + del SpiceBot.events.dict["trigger_queue"][0] + + +@sopel.module.event(SpiceBot.events.BOT_WELCOME) +@sopel.module.rule('.*') +def bot_events_start(bot, trigger): + """This stage is redundant, but shows the system is working.""" + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_READY, "Ready To Process module setup procedures") + + """Here, we wait until we are in at least one channel""" + while not len(bot.channels.keys()) > 0: + pass + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_CONNECTED, "Bot Connected to IRC") + + +@SpiceBot.events.startup_check_ready() +@sopel.module.event(SpiceBot.events.BOT_READY) +@sopel.module.rule('.*') +def bot_events_startup_complete(bot, trigger): + """All events registered as required for startup have completed""" + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_LOADED, "All registered modules setup procedures have completed") diff --git a/sopel_modules/SpiceBot_Core_Processing/Kick.py b/sopel_modules/SpiceBot_Core_Processing/Kick.py new file mode 100644 index 0000000..f0586e9 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/Kick.py @@ -0,0 +1,28 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot OSD system. +""" +import sopel + + +@sopel.module.event('005') +@sopel.module.rule('.*') +def parse_event_005(bot, trigger): + if trigger.args[-1] != 'are supported by this server': + return + parameters = trigger.args[1:-1] + for param in parameters: + if '=' in param: + if param.startswith("TARGMAX"): + param = str(param).split('=')[1] + settings = str(param).split(',') + for setting in settings: + settingname = str(setting).split(':')[0] + if settingname.upper() in ['KICK']: + try: + value = str(setting).split(':')[1] or None + except IndexError: + value = None + if value: + bot.config.SpiceBot_Kick.kick = int(value) diff --git a/sopel_modules/SpiceBot_Core_Processing/Logs.py b/sopel_modules/SpiceBot_Core_Processing/Logs.py new file mode 100644 index 0000000..d1bf3ac --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/Logs.py @@ -0,0 +1,27 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Logs system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.event(SpiceBot.events.RPL_WELCOME) +@sopel.module.rule('.*') +def join_log_channel(bot, trigger): + + if SpiceBot.config.logging_channel: + channel = bot.config.core.logging_channel + if channel not in bot.channels.keys(): + bot.write(('JOIN', bot.nick, channel)) + if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin: + bot.write(('SAJOIN', bot.nick, channel)) + + while True: + if len(SpiceBot.logs.dict["queue"]): + bot.osd(str(SpiceBot.logs.dict["queue"][0]), channel) + del SpiceBot.logs.dict["queue"][0] + else: + SpiceBot.logs.dict["queue"] = [] diff --git a/sopel_modules/SpiceBot_Core_Processing/Modules.py b/sopel_modules/SpiceBot_Core_Processing/Modules.py new file mode 100644 index 0000000..fa0303d --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/Modules.py @@ -0,0 +1,19 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot Modules system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot + + +@sopel.module.event(SpiceBot.events.BOT_READY) +@sopel.module.rule('.*') +def bot_events_complete_modules(bot, trigger): + + for comtype in SpiceBot.commands.dict['commands'].keys(): + if comtype not in ['module', 'nickname', 'rule']: + SpiceBot.logs.log('SpiceBot_Commands', "Found " + str(len(SpiceBot.commands.dict['commands'][comtype].keys())) + " " + comtype + " commands.", True) + + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_COMMANDS, "SpiceBot_Commands") diff --git a/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py b/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py new file mode 100644 index 0000000..10aedb8 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py @@ -0,0 +1,93 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot StartupMonologue system. +""" +import sopel + +import sopel_modules.SpiceBot as SpiceBot + +import time + + +@sopel.module.event(SpiceBot.events.BOT_CONNECTED) +@sopel.module.rule('.*') +def bot_startup_monologue_start(bot, trigger): + # Startup + SpiceBot.logs.log('SpiceBot_StartupMonologue', bot.nick + " is now starting. Please wait while I load my configuration") + bot.osd(" is now starting. Please wait while I load my configuration.", bot.channels.keys(), 'ACTION') + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_CONNECTED, "SpiceBot_StartupMonologue") + + +@sopel.module.event(SpiceBot.events.BOT_CHANNELS) +@sopel.module.rule('.*') +def bot_startup_monologue_channels(bot, trigger): + botcount = len(bot.channels.keys()) + servercount = len(SpiceBot.channels.dict['list'].keys()) + displayval = "I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server." + SpiceBot.startupmonologue.dict["channels"] = displayval + SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval) + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_CHANNELS, "SpiceBot_StartupMonologue") + + +@sopel.module.event(SpiceBot.events.BOT_COMMANDS) +@sopel.module.rule('.*') +def bot_startup_monologue_commands(bot, trigger): + availablecomsnum, availablecomsfiles = 0, 0 + for commandstype in SpiceBot.commands.dict['commands'].keys(): + availablecomsnum += len(SpiceBot.commands.dict['commands'][commandstype].keys()) + availablecomsfiles += SpiceBot.commands.dict['counts'] + displayval = "There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files." + SpiceBot.startupmonologue.dict["commands"] = displayval + SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval) + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_COMMANDS, "SpiceBot_StartupMonologue") + + +@sopel.module.event(SpiceBot.events.BOT_AI) +@sopel.module.rule('.*') +def bot_startup_monologue_ai(bot, trigger): + availablecomsnum = SpiceBot.botai.dict['patterncounts'] + availablecomsfiles = SpiceBot.botai.dict['filecounts'] + displayval = "There are " + str(availablecomsnum) + " AI pattern matches available in " + str(availablecomsfiles) + " files." + SpiceBot.startupmonologue.dict["ai"] = displayval + SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval) + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_AI, "SpiceBot_StartupMonologue") + + +@sopel.module.event(SpiceBot.events.BOT_LOADED) +@sopel.module.rule('.*') +def bot_startup_monologue_display(bot, trigger): + dispmsg = [" startup complete"] + for messagekey in SpiceBot.startupmonologue.dict.keys(): + dispmsg.append(SpiceBot.startupmonologue.dict[messagekey]) + if SpiceBot.events.dict["RPL_WELCOME_Count"] == 1: + timesince = SpiceBot.humanized_time(time.time() - SpiceBot.events.BOT_UPTIME) + if timesince == "just now": + timesince = "1 second" + dispmsg.append("Startup took " + timesince) + # Announce to chan, then handle some closing stuff + SpiceBot.logs.log('SpiceBot_StartupMonologue', bot.nick + " startup complete") + bot.osd(dispmsg, bot.channels.keys(), 'ACTION') + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE, "SpiceBot_StartupMonologue") + SpiceBot.logs.log('SpiceBot_StartupMonologue', "Startup Monologue has been issued to all channels.", True) + + +@sopel.module.event(SpiceBot.events.BOT_STARTUPMONOLOGUE) +@sopel.module.rule('.*') +def bot_startup_monologue_errors(bot, trigger): + + debuglines = SpiceBot.logs.stdio_logs_fetch() + + searchphrasefound = [] + for line in debuglines: + if str(line).endswith("failed to load") and not str(line).startswith("0"): + searchphrasefound.append(line) + + if len(searchphrasefound): + for foundphase in searchphrasefound: + SpiceBot.logs.log('SpiceBot_Logs', str(foundphase)) + searchphrasefound.insert(0, "Notice to Bot Admins: ") + searchphrasefound.append("Run the debug command for more information.") + bot.osd(searchphrasefound, bot.channels.keys()) + else: + SpiceBot.logs.log('SpiceBot_Logs', "No issues found at bot startup!", True) diff --git a/sopel_modules/SpiceBot_Core_Processing/__init__.py b/sopel_modules/SpiceBot_Core_Processing/__init__.py new file mode 100644 index 0000000..df953ff --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/__init__.py @@ -0,0 +1,21 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +These are the core SpiceBot Classes + +This module contains references only for other modules to utilize. +""" + +from .Channels import * +from .Events import * +from .Modules import * +from .AI import * +from .osd import * +from .StartupMonologue import * +from .Logs import * +from .Kick import * + + +__author__ = 'Sam Zick' +__email__ = 'sam@deathbybandaid.net' +__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Core_Processing/osd.py b/sopel_modules/SpiceBot_Core_Processing/osd.py new file mode 100644 index 0000000..88d2bf5 --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Processing/osd.py @@ -0,0 +1,31 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot OSD system. +""" +import sopel + + +@sopel.module.event('005') +@sopel.module.rule('.*') +def parse_event_005(bot, trigger): + if trigger.args[-1] != 'are supported by this server': + return + parameters = trigger.args[1:-1] + for param in parameters: + if '=' in param: + if param.startswith("TARGMAX"): + param = str(param).split('=')[1] + settings = str(param).split(',') + for setting in settings: + settingname = str(setting).split(':')[0] + if settingname.upper() in ['NOTICE', 'PRIVMSG']: + try: + value = str(setting).split(':')[1] or None + except IndexError: + value = None + if value: + if settingname.upper() == 'NOTICE': + bot.config.SpiceBot_OSD.notice = int(value) + elif settingname.upper() == 'PRIVMSG': + bot.config.SpiceBot_OSD.privmsg = int(value) diff --git a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py b/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py deleted file mode 100644 index 9e8343d..0000000 --- a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module -from sopel.tools import Identifier -from sopel.db import SopelDB, NickValues, ChannelValues - -from sqlalchemy.exc import SQLAlchemyError -import json - -from sopel_modules.SpiceBot.Logs import botlogs - - -def setup(bot): - pass - # Inject Database Functions - botlogs.log('SpiceBot_Databaseaddons', "Implanting Database functions into bot") - SopelDB.delete_nick_value = SopelDBCache.delete_nick_value - SopelDB.adjust_nick_value = SopelDBCache.adjust_nick_value - SopelDB.delete_channel_value = SopelDBCache.delete_channel_value - SopelDB.adjust_channel_value = SopelDBCache.adjust_channel_value - - -class SopelDBCache: - - """Nicks""" - - def delete_nick_value(self, nick, key): - """Deletes the value for a given key to be associated with the nick.""" - nick = Identifier(nick) - nick_id = self.get_nick_id(nick) - session = self.ssession() - try: - result = session.query(NickValues) \ - .filter(NickValues.nick_id == nick_id) \ - .filter(NickValues.key == key) \ - .one_or_none() - # NickValue exists, delete - if result: - session.delete(result) - session.commit() - except SQLAlchemyError: - session.rollback() - raise - finally: - session.close() - - def adjust_nick_value(self, nick, key, value): - """Sets the value for a given key to be associated with the nick.""" - nick = Identifier(nick) - value = json.dumps(value, ensure_ascii=False) - nick_id = self.get_nick_id(nick) - session = self.ssession() - try: - result = session.query(NickValues) \ - .filter(NickValues.nick_id == nick_id) \ - .filter(NickValues.key == key) \ - .one_or_none() - # NickValue exists, update - if result: - result.value = result.value + value - session.commit() - # DNE - Insert - else: - new_nickvalue = NickValues(nick_id=nick_id, key=key, value=value) - session.add(new_nickvalue) - session.commit() - except SQLAlchemyError: - session.rollback() - raise - finally: - session.close() - - """Channels""" - - def delete_channel_value(self, channel, key): - """Sets the value for a given key to be associated with the channel.""" - channel = Identifier(channel).lower() - session = self.ssession() - try: - result = session.query(ChannelValues) \ - .filter(ChannelValues.channel == channel)\ - .filter(ChannelValues.key == key) \ - .one_or_none() - # ChannelValue exists, update - if result: - session.delete(result) - session.commit() - except SQLAlchemyError: - session.rollback() - raise - finally: - session.close() - - def adjust_channel_value(self, channel, key, value): - """Sets the value for a given key to be associated with the channel.""" - channel = Identifier(channel).lower() - value = json.dumps(value, ensure_ascii=False) - session = self.ssession() - try: - result = session.query(ChannelValues) \ - .filter(ChannelValues.channel == channel)\ - .filter(ChannelValues.key == key) \ - .one_or_none() - # ChannelValue exists, update - if result: - result.value = result.value + value - session.commit() - # DNE - Insert - else: - new_channelvalue = ChannelValues(channel=channel, key=key, value=value) - session.add(new_channelvalue) - session.commit() - except SQLAlchemyError: - session.rollback() - raise - finally: - session.close() diff --git a/sopel_modules/SpiceBot_Database_Addons/__init__.py b/sopel_modules/SpiceBot_Database_Addons/__init__.py deleted file mode 100644 index 31715ae..0000000 --- a/sopel_modules/SpiceBot_Database_Addons/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .Databaseaddons import * diff --git a/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py b/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py deleted file mode 100644 index f31ea22..0000000 --- a/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs - - -def setup(bot): - botlogs.log('SpiceBot_DatabaseCache', "Setting up Database Cache") - if 'SpiceBot_DatabaseCache' not in bot.memory: - bot.memory['SpiceBot_DatabaseCache'] = dict() - - -def shutdown(bot): - if "SpiceBot_DatabaseCache" in bot.memory: - del bot.memory["SpiceBot_DatabaseCache"] diff --git a/sopel_modules/SpiceBot_Database_Cache/__init__.py b/sopel_modules/SpiceBot_Database_Cache/__init__.py deleted file mode 100644 index 212ae54..0000000 --- a/sopel_modules/SpiceBot_Database_Cache/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .DatabaseCache import * diff --git a/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py b/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py deleted file mode 100644 index e074941..0000000 --- a/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module - - -"""Database Direct""" - - -# Get a value -def db_get_nick_value(bot, nick, key): - database_value = bot.db.get_nick_value(nick, key) or None - return database_value - - -# set a value -def db_set_nick_value(bot, nick, key, value): - bot.db.set_nick_value(nick, key, value) - - -# DELETE a value -def db_reset_value(bot, nick, key): - bot.db.reset_nick_value(nick, key) - - -# add or subtract from current value -def db_adjust_value(bot, nick, key, value): - bot.db.adjust_nick_value(nick, key, value) - - -# list stored in database, add or remove elements -def db_adjust_list(bot, nick, entries, key, adjustmentdirection): - if not isinstance(entries, list): - entries = [entries] - adjustlist = db_get_nick_value(bot, nick, key) or [] - adjustlistnew = [] - for x in adjustlist: - adjustlistnew.append(x) - db_reset_value(bot, nick, key) - adjustlist = [] - if adjustmentdirection == 'add': - for y in entries: - if y not in adjustlistnew: - adjustlistnew.append(y) - elif adjustmentdirection == 'del': - for y in entries: - if y in adjustlistnew: - adjustlistnew.remove(y) - for x in adjustlistnew: - if x not in adjustlist: - adjustlist.append(x) - if not len(adjustlist): - db_reset_value(bot, nick, key) - else: - db_set_nick_value(bot, nick, key, adjustlist) diff --git a/sopel_modules/SpiceBot_Database_Tools/__init__.py b/sopel_modules/SpiceBot_Database_Tools/__init__.py deleted file mode 100644 index 6cd3826..0000000 --- a/sopel_modules/SpiceBot_Database_Tools/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .DatabaseTools import * diff --git a/sopel_modules/SpiceBot_Docs/Docs.py b/sopel_modules/SpiceBot_Docs/Docs.py deleted file mode 100644 index c8e496a..0000000 --- a/sopel_modules/SpiceBot_Docs/Docs.py +++ /dev/null @@ -1,12 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot_SBTools import github_dict - - -@sopel.module.nickname_commands('help', 'docs', 'wiki') -def bot_command_owners(bot, trigger): - bot.osd(["IRC Modules Repository", str(github_dict["url_main"] + github_dict["repo_owner"] + "/" + github_dict["repo_name"] + github_dict["url_path_wiki"])]) diff --git a/sopel_modules/SpiceBot_Docs/__init__.py b/sopel_modules/SpiceBot_Docs/__init__.py deleted file mode 100644 index a9e845b..0000000 --- a/sopel_modules/SpiceBot_Docs/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Docs import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Events/Connected.py b/sopel_modules/SpiceBot_Events/Connected.py deleted file mode 100644 index c99f0db..0000000 --- a/sopel_modules/SpiceBot_Events/Connected.py +++ /dev/null @@ -1,16 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_WELCOME) -@sopel.module.rule('.*') -def bot_events_Connected(bot, trigger): - """Here, we wait until we are in at least one channel""" - while not len(bot.channels.keys()) > 0: - pass - botevents.trigger(bot, botevents.BOT_CONNECTED, "Bot Connected to IRC") diff --git a/sopel_modules/SpiceBot_Events/Connection_Count.py b/sopel_modules/SpiceBot_Events/Connection_Count.py deleted file mode 100644 index 786271b..0000000 --- a/sopel_modules/SpiceBot_Events/Connection_Count.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.RPL_WELCOME) -@sopel.module.rule('.*') -def bot_startup_welcome(bot, trigger): - botevents.SpiceBot_Events["RPL_WELCOME_Count"] += 1 - if botevents.SpiceBot_Events["RPL_WELCOME_Count"] > 1: - botevents.trigger(bot, botevents.BOT_RECONNECTED, "Bot ReConnected to IRC") diff --git a/sopel_modules/SpiceBot_Events/Loaded.py b/sopel_modules/SpiceBot_Events/Loaded.py deleted file mode 100644 index 679c06f..0000000 --- a/sopel_modules/SpiceBot_Events/Loaded.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@botevents.startup_check_ready() -@sopel.module.event(botevents.BOT_READY) -@sopel.module.rule('.*') -def bot_events_startup_complete(bot, trigger): - """All events registered as required for startup have completed""" - botevents.trigger(bot, botevents.BOT_LOADED, "All registered modules setup procedures have completed") diff --git a/sopel_modules/SpiceBot_Events/Logging.py b/sopel_modules/SpiceBot_Events/Logging.py deleted file mode 100644 index 9176d9e..0000000 --- a/sopel_modules/SpiceBot_Events/Logging.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_WELCOME, botevents.BOT_READY, botevents.BOT_CONNECTED, botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_events_complete(bot, trigger): - """This is here simply to log to stderr that this was recieved.""" - botlogs.log('SpiceBot_Events', trigger.args[1], True) diff --git a/sopel_modules/SpiceBot_Events/Queue.py b/sopel_modules/SpiceBot_Events/Queue.py deleted file mode 100644 index 9ccd275..0000000 --- a/sopel_modules/SpiceBot_Events/Queue.py +++ /dev/null @@ -1,18 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_WELCOME) -@sopel.module.rule('.*') -def bot_events_connected(bot, trigger): - """For items tossed in a queue, this will trigger them accordingly""" - while True: - if len(botevents.SpiceBot_Events["trigger_queue"]): - pretriggerdict = botevents.SpiceBot_Events["trigger_queue"][0] - botevents.dispatch(bot, pretriggerdict) - del botevents.SpiceBot_Events["trigger_queue"][0] diff --git a/sopel_modules/SpiceBot_Events/Ready.py b/sopel_modules/SpiceBot_Events/Ready.py deleted file mode 100644 index 4e8df49..0000000 --- a/sopel_modules/SpiceBot_Events/Ready.py +++ /dev/null @@ -1,14 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_WELCOME) -@sopel.module.rule('.*') -def bot_events_start(bot, trigger): - """This stage is redundant, but shows the system is working.""" - botevents.trigger(bot, botevents.BOT_READY, "Ready To Process module setup procedures") diff --git a/sopel_modules/SpiceBot_Events/Welcome.py b/sopel_modules/SpiceBot_Events/Welcome.py deleted file mode 100644 index ca15d55..0000000 --- a/sopel_modules/SpiceBot_Events/Welcome.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.RPL_WELCOME) -@sopel.module.rule('.*') -def bot_startup_welcome(bot, trigger): - """The Bot events system does not start until RPL_WELCOME 001 is recieved - from the server""" - if botevents.check(botevents.BOT_WELCOME): - return - botevents.trigger(bot, botevents.BOT_WELCOME, "Welcome to the SpiceBot Events System") diff --git a/sopel_modules/SpiceBot_Events/__init__.py b/sopel_modules/SpiceBot_Events/__init__.py deleted file mode 100644 index e2846d8..0000000 --- a/sopel_modules/SpiceBot_Events/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Welcome import * -from .Ready import * -from .Connected import * -from .Loaded import * -from .Queue import * -from .Logging import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Gender/Gender.py b/sopel_modules/SpiceBot_Gender/Gender.py deleted file mode 100644 index a2a8f5f..0000000 --- a/sopel_modules/SpiceBot_Gender/Gender.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.nickname_commands('gender') -def bot_command_gender(bot, trigger): - bot.osd("If societal genders are binary, my gender is female") diff --git a/sopel_modules/SpiceBot_Gender/__init__.py b/sopel_modules/SpiceBot_Gender/__init__.py deleted file mode 100644 index 5bbadf2..0000000 --- a/sopel_modules/SpiceBot_Gender/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Gender import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_GifSearch/gifapi.py b/sopel_modules/SpiceBot_GifSearch/Gif_API_Commands.py similarity index 54% rename from sopel_modules/SpiceBot_GifSearch/gifapi.py rename to sopel_modules/SpiceBot_GifSearch/Gif_API_Commands.py index 5fcd73e..929b1b9 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifapi.py +++ b/sopel_modules/SpiceBot_GifSearch/Gif_API_Commands.py @@ -8,24 +8,22 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot.Events import botevents +import sopel_modules.SpiceBot as SpiceBot -@botevents.check_ready([botevents.BOT_GIFSEARCH]) +@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH]) +@SpiceBot.prerun.prerun('prefix') @sopel.module.commands('(.*)') def gifapi_triggers(bot, trigger): - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') - - if triggercommand not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): + if trigger.sb['com'] not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): return - if not len(triggerargs): + if not len(trigger.sb['args']): return bot.osd("Please present a query to search.") - query = spicemanip.main(triggerargs, 0) - searchdict = {"query": query, "gifsearch": triggercommand} + query = spicemanip.main(trigger.sb['args'], 0) + searchdict = {"query": query, "gifsearch": trigger.sb['com']} gifdict = getGif(bot, searchdict) diff --git a/sopel_modules/SpiceBot_GifSearch/gif.py b/sopel_modules/SpiceBot_GifSearch/Gif_Command.py similarity index 69% rename from sopel_modules/SpiceBot_GifSearch/gif.py rename to sopel_modules/SpiceBot_GifSearch/Gif_Command.py index 88c5566..841f958 100644 --- a/sopel_modules/SpiceBot_GifSearch/gif.py +++ b/sopel_modules/SpiceBot_GifSearch/Gif_Command.py @@ -6,21 +6,20 @@ from sopel import module from .gifsearch import getGif -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot.Events import botevents +import sopel_modules.SpiceBot as SpiceBot import spicemanip -@botevents.check_ready([botevents.BOT_GIFSEARCH]) +@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH]) +@SpiceBot.prerun.prerun('prefix') @module.commands('gif') def gif_trigger(bot, trigger): - triggerargs, triggercommand = sopel_triggerargs(bot, trigger) - if not len(triggerargs): + if not len(trigger.sb['args']): return bot.osd("Please present a query to search.") - query = spicemanip.main(triggerargs, 0) + query = spicemanip.main(trigger.sb['args'], 0) searchapis = bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys() searchdict = {"query": query, "gifsearch": searchapis} diff --git a/sopel_modules/SpiceBot_GifSearch/Gif_Search_Commands b/sopel_modules/SpiceBot_GifSearch/Gif_Search_Commands new file mode 100644 index 0000000..929b1b9 --- /dev/null +++ b/sopel_modules/SpiceBot_GifSearch/Gif_Search_Commands @@ -0,0 +1,33 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +from .gifsearch import getGif + +import sopel.module + +import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH]) +@SpiceBot.prerun.prerun('prefix') +@sopel.module.commands('(.*)') +def gifapi_triggers(bot, trigger): + + if trigger.sb['com'] not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): + return + + if not len(trigger.sb['args']): + return bot.osd("Please present a query to search.") + + query = spicemanip.main(trigger.sb['args'], 0) + searchdict = {"query": query, "gifsearch": trigger.sb['com']} + + gifdict = getGif(bot, searchdict) + + if gifdict["error"]: + bot.osd(gifdict["error"]) + else: + bot.osd(str(gifdict['gifapi'].title() + " Result (" + str(query) + " #" + str(gifdict["returnnum"]) + "): " + str(gifdict["returnurl"]))) diff --git a/sopel_modules/SpiceBot_GifSearch/__init__.py b/sopel_modules/SpiceBot_GifSearch/__init__.py index 841b583..c91a38a 100644 --- a/sopel_modules/SpiceBot_GifSearch/__init__.py +++ b/sopel_modules/SpiceBot_GifSearch/__init__.py @@ -5,8 +5,9 @@ Sopel Gif Search builds a convenient framework for searching for Gifs """ from __future__ import unicode_literals, absolute_import, division, print_function -from .gif import * -from .gifapi import * +from .Gif_Command import * +from .Gif_API_Commands import * +# from .Gif_Search_Commands import * from .gifsearch import * __author__ = 'Sam Zick' diff --git a/sopel_modules/SpiceBot_GifSearch/gifsearch.py b/sopel_modules/SpiceBot_GifSearch/gifsearch.py index 1eb2ce4..8681674 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifsearch.py +++ b/sopel_modules/SpiceBot_GifSearch/gifsearch.py @@ -5,10 +5,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot_CommandsQuery.CommandsQuery import commandsquery_register -from sopel_modules.SpiceBot_SBTools import read_directory_json_to_dict +import sopel_modules.SpiceBot as SpiceBot import spicemanip @@ -32,7 +29,7 @@ class GifAPISection(StaticSection): def configure(config): moduledir = os.path.dirname(os.path.abspath(__file__)) api_dir = os.path.join(moduledir, 'gifapi') - valid_gif_api_dict = read_directory_json_to_dict(None, [api_dir], "Gif API", "SpiceBot_GifSearch") + valid_gif_api_dict = SpiceBot.read_directory_json_to_dict([api_dir], "Gif API", "SpiceBot_GifSearch", logging=True) config.define_section("SopelGifSearch", GifAPIMainSection, validate=False) config.SopelGifSearch.configure_setting('extra', 'SpiceBot_GifSearch API Extra directory') @@ -45,8 +42,8 @@ def configure(config): def setup(bot): - botlogs.log('SpiceBot_GifSearch', "Starting Setup Procedure") - botevents.startup_add([botevents.BOT_GIFSEARCH]) + SpiceBot.logs.log('SpiceBot_GifSearch', "Starting Setup Procedure") + SpiceBot.events.startup_add([SpiceBot.events.BOT_GIFSEARCH]) if 'SpiceBot_GifSearch' not in bot.memory: bot.memory["SpiceBot_GifSearch"] = {"cache": {}, "badgiflinks": [], 'valid_gif_api_dict': {}} @@ -58,13 +55,15 @@ def setup(bot): dir_to_scan.append(api_dir) bot.config.define_section("SopelGifSearch", GifAPIMainSection, validate=False) + SpiceBot.config.define_section("SopelGifSearch", GifAPIMainSection, validate=False) if bot.config.SopelGifSearch.extra: dir_to_scan.append(bot.config.SopelGifSearch.extra) - valid_gif_api_dict = read_directory_json_to_dict(bot, dir_to_scan, "Gif API", "SpiceBot_GifSearch") + valid_gif_api_dict = SpiceBot.read_directory_json_to_dict(dir_to_scan, "Gif API", "SpiceBot_GifSearch", logging=True) for gif_api in valid_gif_api_dict.keys(): bot.config.define_section(gif_api, GifAPISection, validate=False) + SpiceBot.config.define_section(gif_api, GifAPISection, validate=False) apikey = eval("bot.config." + gif_api + ".apikey") if apikey: valid_gif_api_dict[gif_api]["apikey"] = apikey @@ -73,12 +72,17 @@ def setup(bot): bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'][gif_api] = valid_gif_api_dict[gif_api] for validgifapi in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): - commandsquery_register(bot, "prefix", validgifapi) + command_dict = { + "comtype": "prefix", + "validcoms": validgifapi + } + SpiceBot.commands.dict['counts'] += 1 + SpiceBot.commands.register(command_dict) if validgifapi not in bot.memory["SpiceBot_GifSearch"]['cache'].keys(): bot.memory["SpiceBot_GifSearch"]['cache'][validgifapi] = dict() - botevents.trigger(bot, botevents.BOT_GIFSEARCH, "SpiceBot_GifSearch") + SpiceBot.events.trigger(bot, SpiceBot.events.BOT_GIFSEARCH, "SpiceBot_GifSearch") def shutdown(bot): diff --git a/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py b/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py deleted file mode 100644 index 3bff3a2..0000000 --- a/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py +++ /dev/null @@ -1,43 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot.Events import botevents - - -def setup(bot): - if 'SpiceBot_InvalidCommand' not in bot.memory: - bot.memory["SpiceBot_InvalidCommand"] = {"valid": []} - - -def shutdown(bot): - if "SpiceBot_InvalidCommand" in bot.memory: - del bot.memory["SpiceBot_InvalidCommand"] - - -@sopel.module.event(botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_events_complete(bot, trigger): - for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - bot.memory["SpiceBot_InvalidCommand"]["valid"].extend(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys()) - - -@botevents.check_ready([botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]) -@sopel.module.commands('(.*)') -def InvalidCommand_triggers(bot, trigger): - return - - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') - - # patch for people typing "...", maybe other stuff, but this verifies that there is still a command here - if triggercommand.startswith("."): - return - - if triggercommand not in bot.memory["SpiceBot_InvalidCommand"]["valid"]: - invalid_display = ["I don't seem to have a command for " + str(triggercommand) + "!"] - invalid_display.append("If you have a suggestion for this command, you can run .feature ." + str(triggercommand)) - invalid_display.append("ADD DESCRIPTION HERE!") - bot.osd(invalid_display, trigger.nick, 'notice') diff --git a/sopel_modules/SpiceBot_InvalidCommand/__init__.py b/sopel_modules/SpiceBot_InvalidCommand/__init__.py deleted file mode 100644 index 6f704e6..0000000 --- a/sopel_modules/SpiceBot_InvalidCommand/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# coding=utf8 -"""Sopel Gif Search - -Sopel Gif Search builds a convenient framework for searching for Gifs -""" -from __future__ import unicode_literals, absolute_import, division, print_function - -from .InvalidCommand import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Kick/__init__.py b/sopel_modules/SpiceBot_Kick/__init__.py deleted file mode 100644 index 2d1c429..0000000 --- a/sopel_modules/SpiceBot_Kick/__init__.py +++ /dev/null @@ -1,96 +0,0 @@ -# coding=utf8 -"""Sopel Kick - -Sopel Kick is an easy way to kick users from channels -""" - -# pylama:ignore=W0611 - - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.bot -from sopel import tools, module -from sopel.tools import Identifier -from sopel.config.types import StaticSection, ValidatedAttribute - -from sopel_modules.SpiceBot.Logs import botlogs - - -import time -from collections import abc -import sys - - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.2' - - -def configure(config): - config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) - config.SpiceBot_Kick.configure_setting('kick', 'MAXTARG limit for KICK') - - -def setup(bot): - - # Inject KICK - botlogs.log('SpiceBot_Kick', "Implanting Kick function into bot") - bot.kick = SopelKICK.kick - sopel.bot.SopelWrapper.kick = SopelWrapperKICK.kick - - # verify config settings for server - botlogs.log('SpiceBot_Kick', "Checking for config settings") - bot.config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) - - -@module.event('005') -@module.rule('.*') -def parse_event_005(bot, trigger): - if trigger.args[-1] != 'are supported by this server': - return - parameters = trigger.args[1:-1] - for param in parameters: - if '=' in param: - if param.startswith("TARGMAX"): - param = str(param).split('=')[1] - settings = str(param).split(',') - for setting in settings: - settingname = str(setting).split(':')[0] - if settingname.upper() in ['KICK']: - try: - value = str(setting).split(':')[1] or None - except IndexError: - value = None - if value: - bot.config.SpiceBot_Kick.kick = int(value) - - -class SpiceBot_Kick(StaticSection): - kick = ValidatedAttribute('kick', default=1) - - -class SopelKICK: - - def kick(self, nick, channel, text=None): - """Send an IRC KICK command. - Within the context of a triggered callable, ``channel`` will default to the - channel in which the call was triggered. If triggered from a private message, - ``channel`` is required (or the call to ``kick()`` will be ignored). - The bot must be a channel operator in specified channel for this to work. - .. versionadded:: 7.0 - """ - self.write(['KICK', channel, nick], text) - - -class SopelWrapperKICK(object): - - def kick(self, nick, channel=None, message=None): - if channel is None: - if self._trigger.is_privmsg: - raise RuntimeError('Error: KICK requires a channel.') - else: - channel = self._trigger.sender - if nick is None: - raise RuntimeError('Error: KICK requires a nick.') - self._bot.kick(nick, channel, message) diff --git a/sopel_modules/SpiceBot_Logs/IRC_Events b/sopel_modules/SpiceBot_Logs/IRC_Events deleted file mode 100644 index 84ccc84..0000000 --- a/sopel_modules/SpiceBot_Logs/IRC_Events +++ /dev/null @@ -1,1266 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs - - -@sopel.moduleevent('NICK') -@sopel.modulerule('.*') -def parse_event_NICK(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('QUIT') -@sopel.modulerule('.*') -def parse_event_QUIT(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('PART') -def parse_event_PART(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('MODE') -@sopel.modulerule('.*') -def parse_event_MODE(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('KICK') -@sopel.modulerule('.*') -def parse_event_KICK(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('JOIN') -@sopel.modulerule('.*') -def parse_event_JOIN(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('INVITE') -@sopel.modulerule('.*') -def parse_event_INVITE(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -@sopel.moduleevent('TOPIC') -@sopel.modulerule('.*') -def parse_event_TOPIC(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WELCOME = '001' -@sopel.moduleevent('001') -@sopel.modulerule('.*') -def parse_event_001(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_YOURHOST = '002' -@sopel.moduleevent('002') -@sopel.modulerule('.*') -def parse_event_002(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_CREATED = '003' -@sopel.moduleevent('003') -@sopel.modulerule('.*') -def parse_event_003(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MYINFO = '004' -@sopel.moduleevent('004') -@sopel.modulerule('.*') -def parse_event_004(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_BOUNCE = '005' -@sopel.moduleevent('005') -@sopel.modulerule('.*') -def parse_event_005(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ISUPPORT = '005' -@sopel.moduleevent('005') -@sopel.modulerule('.*') -def parse_event_005b(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACELINK = '200' -@sopel.moduleevent('200') -@sopel.modulerule('.*') -def parse_event_200(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACECONNECTING = '201' -@sopel.moduleevent('201') -@sopel.modulerule('.*') -def parse_event_201(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACEHANDSHAKE = '202' -@sopel.moduleevent('202') -@sopel.modulerule('.*') -def parse_event_202(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACEUNKNOWN = '203' -@sopel.moduleevent('203') -@sopel.modulerule('.*') -def parse_event_203(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACEOPERATOR = '204' -@sopel.moduleevent('204') -@sopel.modulerule('.*') -def parse_event_204(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACEUSER = '205' -@sopel.moduleevent('205') -@sopel.modulerule('.*') -def parse_event_205(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACESERVER = '206' -@sopel.moduleevent('206') -@sopel.modulerule('.*') -def parse_event_206(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACESERVICE = '207' -@sopel.moduleevent('207') -@sopel.modulerule('.*') -def parse_event_207(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACENEWTYPE = '208' -@sopel.moduleevent('208') -@sopel.modulerule('.*') -def parse_event_208(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACECLASS = '209' -@sopel.moduleevent('209') -@sopel.modulerule('.*') -def parse_event_209(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACERECONNECT = '210' -@sopel.moduleevent('210') -@sopel.modulerule('.*') -def parse_event_210(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSLINKINFO = '211' -@sopel.moduleevent('211') -@sopel.modulerule('.*') -def parse_event_211(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSCOMMANDS = '212' -@sopel.moduleevent('212') -@sopel.modulerule('.*') -def parse_event_212(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSCLINE = '213' -@sopel.moduleevent('213') -@sopel.modulerule('.*') -def parse_event_213(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSNLINE = '214' -@sopel.moduleevent('214') -@sopel.modulerule('.*') -def parse_event_214(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSILINE = '215' -@sopel.moduleevent('215') -@sopel.modulerule('.*') -def parse_event_215(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSKLINE = '216' -@sopel.moduleevent('216') -@sopel.modulerule('.*') -def parse_event_216(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSYLINE = '218' -@sopel.moduleevent('218') -@sopel.modulerule('.*') -def parse_event_218(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFSTATS = '219' -@sopel.moduleevent('219') -@sopel.modulerule('.*') -def parse_event_219(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_UMODEIS = '221' -@sopel.moduleevent('221') -@sopel.modulerule('.*') -def parse_event_221(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_SERVLIST = '234' -@sopel.moduleevent('234') -@sopel.modulerule('.*') -def parse_event_234(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_SERVLISTEND = '235' -@sopel.moduleevent('235') -@sopel.modulerule('.*') -def parse_event_235(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSLLINE = '241' -@sopel.moduleevent('241') -@sopel.modulerule('.*') -def parse_event_241(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSUPTIME = '242' -@sopel.moduleevent('242') -@sopel.modulerule('.*') -def parse_event_242(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSOLINE = '243' -@sopel.moduleevent('243') -@sopel.modulerule('.*') -def parse_event_243(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STATSHLINE = '244' -@sopel.moduleevent('244') -@sopel.modulerule('.*') -def parse_event_244(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LUSERCLIENT = '251' -@sopel.moduleevent('251') -@sopel.modulerule('.*') -def parse_event_251(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LUSEROP = '252' -@sopel.moduleevent('252') -@sopel.modulerule('.*') -def parse_event_252(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LUSERUNKNOWN = '253' -@sopel.moduleevent('253') -@sopel.modulerule('.*') -def parse_event_253(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LUSERCHANNELS = '254' -@sopel.moduleevent('254') -@sopel.modulerule('.*') -def parse_event_254(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LUSERME = '255' -@sopel.moduleevent('255') -@sopel.modulerule('.*') -def parse_event_255(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ADMINME = '256' -@sopel.moduleevent('256') -@sopel.modulerule('.*') -def parse_event_256(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ADMINLOC1 = '257' -@sopel.moduleevent('257') -@sopel.modulerule('.*') -def parse_event_257(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ADMINLOC2 = '258' -@sopel.moduleevent('258') -@sopel.modulerule('.*') -def parse_event_258(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ADMINEMAIL = '259' -@sopel.moduleevent('259') -@sopel.modulerule('.*') -def parse_event_259(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACELOG = '261' -@sopel.moduleevent('261') -@sopel.modulerule('.*') -def parse_event_261(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRACEEND = '262' -@sopel.moduleevent('262') -@sopel.modulerule('.*') -def parse_event_262(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TRYAGAIN = '263' -@sopel.moduleevent('263') -@sopel.modulerule('.*') -def parse_event_263(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_NONE = '300' -@sopel.moduleevent('300') -@sopel.modulerule('.*') -def parse_event_300(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_AWAY = '301' -@sopel.moduleevent('301') -@sopel.modulerule('.*') -def parse_event_301(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_USERHOST = '302' -@sopel.moduleevent('302') -@sopel.modulerule('.*') -def parse_event_302(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ISON = '303' -@sopel.moduleevent('303') -@sopel.modulerule('.*') -def parse_event_303(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_UNAWAY = '305' -@sopel.moduleevent('305') -@sopel.modulerule('.*') -def parse_event_305(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_NOWAWAY = '306' -@sopel.moduleevent('306') -@sopel.modulerule('.*') -def parse_event_306(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISUSER = '311' -@sopel.moduleevent('311') -@sopel.modulerule('.*') -def parse_event_311(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISSERVER = '312' -@sopel.moduleevent('312') -@sopel.modulerule('.*') -def parse_event_312(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISOPERATOR = '313' -@sopel.moduleevent('313') -@sopel.modulerule('.*') -def parse_event_313(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOWASUSER = '314' -@sopel.moduleevent('314') -@sopel.modulerule('.*') -def parse_event_314(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFWHO = '315' -@sopel.moduleevent('315') -@sopel.modulerule('.*') -def parse_event_315(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISIDLE = '317' -@sopel.moduleevent('317') -@sopel.modulerule('.*') -def parse_event_317(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFWHOIS = '318' -@sopel.moduleevent('318') -@sopel.modulerule('.*') -def parse_event_318(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISCHANNELS = '319' -@sopel.moduleevent('319') -@sopel.modulerule('.*') -def parse_event_319(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LISTSTART = '321' -@sopel.moduleevent('321') -@sopel.modulerule('.*') -def parse_event_321(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LIST = '322' -@sopel.moduleevent('322') -@sopel.modulerule('.*') -def parse_event_322(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LISTEND = '323' -@sopel.moduleevent('323') -@sopel.modulerule('.*') -def parse_event_323(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_CHANNELMODEIS = '324' -@sopel.moduleevent('324') -@sopel.modulerule('.*') -def parse_event_324(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_UNIQOPIS = '325' -@sopel.moduleevent('325') -@sopel.modulerule('.*') -def parse_event_325(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_NOTOPIC = '331' -@sopel.moduleevent('331') -@sopel.modulerule('.*') -def parse_event_331(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TOPIC = '332' -@sopel.moduleevent('332') -@sopel.modulerule('.*') -def parse_event_332(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_INVITING = '341' -@sopel.moduleevent('341') -@sopel.modulerule('.*') -def parse_event_341(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_SUMMONING = '342' -@sopel.moduleevent('342') -@sopel.modulerule('.*') -def parse_event_342(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_INVITELIST = '346' -@sopel.moduleevent('346') -@sopel.modulerule('.*') -def parse_event_346(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFINVITELIST = '347' -@sopel.moduleevent('347') -@sopel.modulerule('.*') -def parse_event_347(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_EXCEPTLIST = '348' -@sopel.moduleevent('348') -@sopel.modulerule('.*') -def parse_event_348(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFEXCEPTLIST = '349' -@sopel.moduleevent('349') -@sopel.modulerule('.*') -def parse_event_349(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_VERSION = '351' -@sopel.moduleevent('351') -@sopel.modulerule('.*') -def parse_event_351(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOREPLY = '352' -@sopel.moduleevent('352') -@sopel.modulerule('.*') -def parse_event_352(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_NAMREPLY = '353' -@sopel.moduleevent('353') -@sopel.modulerule('.*') -def parse_event_353(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOSPCRPL = '354' -@sopel.moduleevent('354') -@sopel.modulerule('.*') -def parse_event_354(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LINKS = '364' -@sopel.moduleevent('364') -@sopel.modulerule('.*') -def parse_event_364(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFLINKS = '365' -@sopel.moduleevent('365') -@sopel.modulerule('.*') -def parse_event_365(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFNAMES = '366' -@sopel.moduleevent('366') -@sopel.modulerule('.*') -def parse_event_366(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_BANLIST = '367' -@sopel.moduleevent('367') -@sopel.modulerule('.*') -def parse_event_367(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFBANLIST = '368' -@sopel.moduleevent('368') -@sopel.modulerule('.*') -def parse_event_368(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFWHOWAS = '369' -@sopel.moduleevent('369') -@sopel.modulerule('.*') -def parse_event_369(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_INFO = '371' -@sopel.moduleevent('371') -@sopel.modulerule('.*') -def parse_event_371(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MOTD = '372' -@sopel.moduleevent('372') -@sopel.modulerule('.*') -def parse_event_372(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFINFO = '374' -@sopel.moduleevent('374') -@sopel.modulerule('.*') -def parse_event_374(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MOTDSTART = '375' -@sopel.moduleevent('375') -@sopel.modulerule('.*') -def parse_event_375(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFMOTD = '376' -@sopel.moduleevent('376') -@sopel.modulerule('.*') -def parse_event_376(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_YOUREOPER = '381' -@sopel.moduleevent('381') -@sopel.modulerule('.*') -def parse_event_381(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_REHASHING = '382' -@sopel.moduleevent('382') -@sopel.modulerule('.*') -def parse_event_382(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_YOURESERVICE = '383' -@sopel.moduleevent('383') -@sopel.modulerule('.*') -def parse_event_383(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_TIME = '391' -@sopel.moduleevent('391') -@sopel.modulerule('.*') -def parse_event_391(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_USERSSTART = '392' -@sopel.moduleevent('392') -@sopel.modulerule('.*') -def parse_event_392(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_USERS = '393' -@sopel.moduleevent('393') -@sopel.modulerule('.*') -def parse_event_393(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFUSERS = '394' -@sopel.moduleevent('394') -@sopel.modulerule('.*') -def parse_event_394(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_NOUSERS = '395' -@sopel.moduleevent('395') -@sopel.modulerule('.*') -def parse_event_395(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOSUCHNICK = '401' -@sopel.moduleevent('401') -@sopel.modulerule('.*') -def parse_event_401(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOSUCHSERVER = '402' -@sopel.moduleevent('402') -@sopel.modulerule('.*') -def parse_event_402(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOSUCHCHANNEL = '403' -@sopel.moduleevent('403') -@sopel.modulerule('.*') -def parse_event_403(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_CANNOTSENDTOCHAN = '404' -@sopel.moduleevent('404') -@sopel.modulerule('.*') -def parse_event_404(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_TOOMANYCHANNELS = '405' -@sopel.moduleevent('405') -@sopel.modulerule('.*') -def parse_event_405(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_WASNOSUCHNICK = '406' -@sopel.moduleevent('406') -@sopel.modulerule('.*') -def parse_event_406(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_TOOMANYTARGETS = '407' -@sopel.moduleevent('407') -@sopel.modulerule('.*') -def parse_event_407(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOSUCHSERVICE = '408' -@sopel.moduleevent('408') -@sopel.modulerule('.*') -def parse_event_408(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOORIGIN = '409' -@sopel.moduleevent('409') -@sopel.modulerule('.*') -def parse_event_409(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_INVALIDCAPCMD = '410' -@sopel.moduleevent('410') -@sopel.modulerule('.*') -def parse_event_410(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NORECIPIENT = '411' -@sopel.moduleevent('411') -@sopel.modulerule('.*') -def parse_event_411(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOTEXTTOSEND = '412' -@sopel.moduleevent('412') -@sopel.modulerule('.*') -def parse_event_412(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOTOPLEVEL = '413' -@sopel.moduleevent('413') -@sopel.modulerule('.*') -def parse_event_413(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_WILDTOPLEVEL = '414' -@sopel.moduleevent('414') -@sopel.modulerule('.*') -def parse_event_414(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_BADMASK = '415' -@sopel.moduleevent('415') -@sopel.modulerule('.*') -def parse_event_415(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_UNKNOWNCOMMAND = '421' -@sopel.moduleevent('421') -@sopel.modulerule('.*') -def parse_event_421(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOMOTD = '422' -@sopel.moduleevent('422') -@sopel.modulerule('.*') -def parse_event_422(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOADMININFO = '423' -@sopel.moduleevent('423') -@sopel.modulerule('.*') -def parse_event_423(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_FILEERROR = '424' -@sopel.moduleevent('424') -@sopel.modulerule('.*') -def parse_event_424(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NONICKNAMEGIVEN = '431' -@sopel.moduleevent('431') -@sopel.modulerule('.*') -def parse_event_431(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_ERRONEUSNICKNAME = '432' -@sopel.moduleevent('432') -@sopel.modulerule('.*') -def parse_event_432(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NICKNAMEINUSE = '433' -@sopel.moduleevent('433') -@sopel.modulerule('.*') -def parse_event_433(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NICKCOLLISION = '436' -@sopel.moduleevent('436') -@sopel.modulerule('.*') -def parse_event_436(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_UNAVAILRESOURCE = '437' -@sopel.moduleevent('437') -@sopel.modulerule('.*') -def parse_event_437(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_USERNOTINCHANNEL = '441' -@sopel.moduleevent('441') -@sopel.modulerule('.*') -def parse_event_441(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOTONCHANNEL = '442' -@sopel.moduleevent('442') -@sopel.modulerule('.*') -def parse_event_442(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_USERONCHANNEL = '443' -@sopel.moduleevent('443') -@sopel.modulerule('.*') -def parse_event_443(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOLOGIN = '444' -@sopel.moduleevent('444') -@sopel.modulerule('.*') -def parse_event_444(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_SUMMONDISABLED = '445' -@sopel.moduleevent('445') -@sopel.modulerule('.*') -def parse_event_445(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_USERSDISABLED = '446' -@sopel.moduleevent('446') -@sopel.modulerule('.*') -def parse_event_446(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOTREGISTERED = '451' -@sopel.moduleevent('451') -@sopel.modulerule('.*') -def parse_event_451(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NEEDMOREPARAMS = '461' -@sopel.moduleevent('461') -@sopel.modulerule('.*') -def parse_event_461(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_ALREADYREGISTRED = '462' -@sopel.moduleevent('462') -@sopel.modulerule('.*') -def parse_event_462(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOPERMFORHOST = '463' -@sopel.moduleevent('463') -@sopel.modulerule('.*') -def parse_event_463(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_PASSWDMISMATCH = '464' -@sopel.moduleevent('464') -@sopel.modulerule('.*') -def parse_event_464(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_YOUREBANNEDCREEP = '465' -@sopel.moduleevent('465') -@sopel.modulerule('.*') -def parse_event_465(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_YOUWILLBEBANNED = '466' -@sopel.moduleevent('466') -@sopel.modulerule('.*') -def parse_event_466(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_KEYSET = '467' -@sopel.moduleevent('467') -@sopel.modulerule('.*') -def parse_event_467(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_CHANNELISFULL = '471' -@sopel.moduleevent('471') -@sopel.modulerule('.*') -def parse_event_471(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_UNKNOWNMODE = '472' -@sopel.moduleevent('472') -@sopel.modulerule('.*') -def parse_event_472(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_INVITEONLYCHAN = '473' -@sopel.moduleevent('473') -@sopel.modulerule('.*') -def parse_event_473(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_BANNEDFROMCHAN = '474' -@sopel.moduleevent('474') -@sopel.modulerule('.*') -def parse_event_474(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_BADCHANNELKEY = '475' -@sopel.moduleevent('475') -@sopel.modulerule('.*') -def parse_event_475(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_BADCHANMASK = '476' -@sopel.moduleevent('476') -@sopel.modulerule('.*') -def parse_event_476(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOCHANMODES = '477' -@sopel.moduleevent('477') -@sopel.modulerule('.*') -def parse_event_477(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_BANLISTFULL = '478' -@sopel.moduleevent('478') -@sopel.modulerule('.*') -def parse_event_478(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOPRIVILEGES = '481' -@sopel.moduleevent('481') -@sopel.modulerule('.*') -def parse_event_481(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_CHANOPRIVSNEEDED = '482' -@sopel.moduleevent('482') -@sopel.modulerule('.*') -def parse_event_482(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_CANTKILLSERVER = '483' -@sopel.moduleevent('483') -@sopel.modulerule('.*') -def parse_event_483(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_RESTRICTED = '484' -@sopel.moduleevent('484') -@sopel.modulerule('.*') -def parse_event_484(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_UNIQOPPRIVSNEEDED = '485' -@sopel.moduleevent('485') -@sopel.modulerule('.*') -def parse_event_485(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOOPERHOST = '491' -@sopel.moduleevent('491') -@sopel.modulerule('.*') -def parse_event_491(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_UMODEUNKNOWNFLAG = '501' -@sopel.moduleevent('501') -@sopel.modulerule('.*') -def parse_event_501(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_USERSDONTMATCH = '502' -@sopel.moduleevent('502') -@sopel.modulerule('.*') -def parse_event_502(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_STARTTLS = '670' -@sopel.moduleevent('670') -@sopel.modulerule('.*') -def parse_event_670(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_STARTTLS = '691' -@sopel.moduleevent('691') -@sopel.modulerule('.*') -def parse_event_691(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MONONLINE = '730' -@sopel.moduleevent('730') -@sopel.modulerule('.*') -def parse_event_730(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MONOFFLINE = '731' -@sopel.moduleevent('731') -@sopel.modulerule('.*') -def parse_event_731(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_MONLIST = '732' -@sopel.moduleevent('732') -@sopel.modulerule('.*') -def parse_event_732(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_ENDOFMONLIST = '733' -@sopel.moduleevent('733') -@sopel.modulerule('.*') -def parse_event_733(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_MONLISTFULL = '734' -@sopel.moduleevent('734') -@sopel.modulerule('.*') -def parse_event_734(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_WHOISKEYVALUE = '760' -@sopel.moduleevent('760') -@sopel.modulerule('.*') -def parse_event_760(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_KEYVALUE = '761' -@sopel.moduleevent('761') -@sopel.modulerule('.*') -def parse_event_761(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_METADATAEND = '762' -@sopel.moduleevent('762') -@sopel.modulerule('.*') -def parse_event_762(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_METADATALIMIT = '764' -@sopel.moduleevent('764') -@sopel.modulerule('.*') -def parse_event_764(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_TARGETINVALID = '765' -@sopel.moduleevent('765') -@sopel.modulerule('.*') -def parse_event_765(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NOMATCHINGKEY = '766' -@sopel.moduleevent('766') -@sopel.modulerule('.*') -def parse_event_766(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_KEYINVALID = '767' -@sopel.moduleevent('767') -@sopel.modulerule('.*') -def parse_event_767(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_KEYNOTSET = '768' -@sopel.moduleevent('768') -@sopel.modulerule('.*') -def parse_event_768(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_KEYNOPERMISSION = '769' -@sopel.moduleevent('769') -@sopel.modulerule('.*') -def parse_event_769(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LOGGEDIN = '900' -@sopel.moduleevent('900') -@sopel.modulerule('.*') -def parse_event_900(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_LOGGEDOUT = '901' -@sopel.moduleevent('901') -@sopel.modulerule('.*') -def parse_event_901(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_NICKLOCKED = '902' -@sopel.moduleevent('902') -@sopel.modulerule('.*') -def parse_event_902(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_SASLSUCCESS = '903' -@sopel.moduleevent('903') -@sopel.modulerule('.*') -def parse_event_903(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_SASLFAIL = '904' -@sopel.moduleevent('904') -@sopel.modulerule('.*') -def parse_event_904(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_SASLTOOLONG = '905' -@sopel.moduleevent('905') -@sopel.modulerule('.*') -def parse_event_905(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_SASLABORTED = '906' -@sopel.moduleevent('906') -@sopel.modulerule('.*') -def parse_event_906(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# ERR_SASLALREADY = '907' -@sopel.moduleevent('907') -@sopel.modulerule('.*') -def parse_event_907(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) - - -# RPL_SASLMECHS = '908' -@sopel.moduleevent('908') -@sopel.modulerule('.*') -def parse_event_908(bot, trigger): - botlogs.log('SpiceBot_Logs_IRC', str(trigger.event) + " " + str(trigger.args)) diff --git a/sopel_modules/SpiceBot_Logs/Logs_Command.py b/sopel_modules/SpiceBot_Logs/Logs_Command.py deleted file mode 100644 index 7c6bf5f..0000000 --- a/sopel_modules/SpiceBot_Logs/Logs_Command.py +++ /dev/null @@ -1,53 +0,0 @@ -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist, inlist_match, similar_list - - -@botevents.check_ready([botevents.BOT_LOGS]) -@sopel.module.nickname_commands('logs', 'debug') -def bot_command_logs(bot, trigger): - - if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): - bot.say("I was unable to process this Bot Nick command due to privilege issues.") - return - - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - - logtype = spicemanip.main(triggerargs, 1) or None - if not logtype: - bot.osd("Current valid log(s) include: " + spicemanip.main(botlogs.SpiceBot_Logs["list"].keys(), 'andlist'), trigger.sender, 'action') - return - - if not inlist(bot, logtype, botlogs.SpiceBot_Logs["list"].keys()): - closestmatches = similar_list(bot, logtype, botlogs.SpiceBot_Logs["list"].keys(), 10, 'reverse') - if not len(closestmatches): - bot.notice("No valid logs match " + str(logtype) + ".", trigger.nick) - else: - bot.notice("The following commands may match " + str(logtype) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) - - return - - logtype = inlist_match(bot, logtype, botlogs.SpiceBot_Logs["list"].keys()) - - if logtype == "Sopel_systemd": - logindex = botlogs.systemd_logs_fetch(bot) - elif logtype == "Sopel_stdio": - logindex = botlogs.stdio_logs_fetch(bot) - else: - logindex = botlogs.SpiceBot_Logs["list"][logtype] - - if not len(logindex): - bot.osd("No logs found for " + str(logtype) + ".") - return - - bot.osd("Is Examining " + str(logtype) + " log(s).") - for line in logindex: - bot.osd(" " + str(line)) - bot.osd(str(logtype) + " log(s) Complete.") diff --git a/sopel_modules/SpiceBot_Logs/Queue.py b/sopel_modules/SpiceBot_Logs/Queue.py deleted file mode 100644 index 784efa7..0000000 --- a/sopel_modules/SpiceBot_Logs/Queue.py +++ /dev/null @@ -1,35 +0,0 @@ -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module -import sopel.tools -import sopel.config - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -def setup(bot): - botlogs.log('SpiceBot_Logs', "Starting Setup Procedure") - botevents.startup_add([botevents.BOT_LOGS]) - botevents.trigger(bot, botevents.BOT_LOGS, "SpiceBot_Logs") - - -@sopel.module.event(botevents.RPL_WELCOME) -@sopel.module.rule('.*') -def join_log_channel(bot, trigger): - - if bot.config.core.logging_channel: - channel = bot.config.core.logging_channel - if channel not in bot.channels.keys(): - bot.write(('JOIN', bot.nick, channel)) - if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin: - bot.write(('SAJOIN', bot.nick, channel)) - - while True: - if len(botlogs.SpiceBot_Logs["queue"]): - bot.say(str(botlogs.SpiceBot_Logs["queue"][0]), channel) - del botlogs.SpiceBot_Logs["queue"][0] - else: - botlogs.sopel_config["logging_channel"] = False - botlogs.SpiceBot_Logs["queue"] = [] diff --git a/sopel_modules/SpiceBot_Logs/__init__.py b/sopel_modules/SpiceBot_Logs/__init__.py deleted file mode 100644 index f6ef4d1..0000000 --- a/sopel_modules/SpiceBot_Logs/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Queue import * -from .Logs_Command import * -# from .IRC_Events import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Messaging/__init__.py b/sopel_modules/SpiceBot_Messaging/__init__.py deleted file mode 100644 index 816c170..0000000 --- a/sopel_modules/SpiceBot_Messaging/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Messaging import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Restart/Restart.py b/sopel_modules/SpiceBot_Restart/Restart.py deleted file mode 100644 index 89e083c..0000000 --- a/sopel_modules/SpiceBot_Restart/Restart.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot_SBTools import spicebot_reload - - -@sopel.module.nickname_commands('restart') -def nickname_comand_restart(bot, trigger): - - if not trigger.admin: - bot.say("You are not authorized to perform this function.") - - quitmessage = "Received command from " + trigger.nick + " to restart. Be Back Soon!" - botlogs.log('SpiceBot_Restart', quitmessage) - bot.osd(quitmessage, bot.channels.keys()) - - # service_manip(bot, bot.nick, 'restart', 'SpiceBot_Restart') - spicebot_reload(bot, 'SpiceBot_Restart', quitmessage) diff --git a/sopel_modules/SpiceBot_Restart/__init__.py b/sopel_modules/SpiceBot_Restart/__init__.py deleted file mode 100644 index 8bda139..0000000 --- a/sopel_modules/SpiceBot_Restart/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Event Parsing from IRC -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .Restart import * diff --git a/sopel_modules/SpiceBot_SopelPatches/Patches.py b/sopel_modules/SpiceBot_SopelPatches/Patches.py index 0aa3cc8..e6a19f7 100644 --- a/sopel_modules/SpiceBot_SopelPatches/Patches.py +++ b/sopel_modules/SpiceBot_SopelPatches/Patches.py @@ -6,15 +6,14 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel import sopel.module -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot_SBTools import stock_modules_begone +import sopel_modules.SpiceBot as SpiceBot def setup(bot): - botlogs.log('Sopel_Patch', "Patching Sopels built-in url_callbacks") + SpiceBot.logs.log('Sopel_Patch', "Patching Sopels built-in url_callbacks") if 'url_callbacks' not in bot.memory: bot.memory['url_callbacks'] = sopel.tools.SopelMemory() - botlogs.log('Sopel_Patch', "Removing Stock Modules and verifying Dummy Command is present.") - stock_modules_begone(bot) + SpiceBot.logs.log('Sopel_Patch', "Removing Stock Modules and verifying Dummy Command is present.") + SpiceBot.stock_modules_begone() diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py deleted file mode 100644 index bd9dd6f..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py +++ /dev/null @@ -1,16 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -def setup(bot): - botlogs.log('SpiceBot_StartupMonologue', "Starting setup procedure") - botevents.startup_add([botevents.BOT_STARTUPMONOLOGUE_CHANNELS, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY]) # , botevents.BOT_STARTUPMONOLOGUE_CONNECTED]) - - if 'SpiceBot_StartupMonologue' not in bot.memory: - bot.memory['SpiceBot_StartupMonologue'] = [] diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py deleted file mode 100644 index b8254be..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py +++ /dev/null @@ -1,21 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot.Channels import botchannels - - -@sopel.module.event(botevents.BOT_CHANNELS) -@sopel.module.rule('.*') -def bot_startup_monologue_channels(bot, trigger): - - botcount = len(bot.channels.keys()) - servercount = len(botchannels.SpiceBot_Channels['list'].keys()) - bot.memory['SpiceBot_StartupMonologue'].append("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.") - botlogs.log('SpiceBot_StartupMonologue', "I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.") - - botevents.trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CHANNELS, "SpiceBot_StartupMonologue") diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Commands.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Commands.py deleted file mode 100644 index 3cae22e..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Commands.py +++ /dev/null @@ -1,23 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_COMMANDSQUERY) -@sopel.module.rule('.*') -def bot_startup_monologue_commands(bot, trigger): - - availablecomsnum, availablecomsfiles = 0, 0 - for commandstype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - availablecomsnum += len(bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype].keys()) - availablecomsfiles += bot.memory['SpiceBot_CommandsQuery']['counts'] - - bot.memory['SpiceBot_StartupMonologue'].append("There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files.") - botlogs.log('SpiceBot_StartupMonologue', "There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files.") - - botevents.trigger(bot, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY, "SpiceBot_StartupMonologue") diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Connected.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Connected.py deleted file mode 100644 index e829d82..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Connected.py +++ /dev/null @@ -1,19 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_CONNECTED) -@sopel.module.rule('.*') -def bot_startup_monologue_start(bot, trigger): - - # Startup - botlogs.log('SpiceBot_StartupMonologue', bot.nick + " is now starting. Please wait while I load my configuration") - bot.osd(" is now starting. Please wait while I load my configuration.", bot.channels.keys(), 'ACTION') - - botevents.trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CONNECTED, "SpiceBot_StartupMonologue") diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py deleted file mode 100644 index d075cff..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py +++ /dev/null @@ -1,28 +0,0 @@ -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents - - -@sopel.module.event(botevents.BOT_STARTUPMONOLOGUE) -@sopel.module.rule('.*') -def bot_startup_monologue_start(bot, trigger): - - debuglines = botlogs.stdio_logs_fetch(bot) - - searchphrasefound = [] - for line in debuglines: - if str(line).endswith("failed to load") and not str(line).startswith("0"): - searchphrasefound.append(line) - - if len(searchphrasefound): - for foundphase in searchphrasefound: - botlogs.log('SpiceBot_Logs', str(foundphase)) - searchphrasefound.insert(0, "Notice to Bot Admins: ") - searchphrasefound.append("Run the debug command for more information.") - bot.osd(searchphrasefound, bot.channels.keys()) - else: - botlogs.log('SpiceBot_Logs', "No issues found at bot startup!", True) diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Loaded.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Loaded.py deleted file mode 100644 index a5ab12b..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Loaded.py +++ /dev/null @@ -1,29 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot.Events import botevents -from sopel_modules.SpiceBot_SBTools import humanized_time - -import time - - -@sopel.module.event(botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_startup_monologue_display(bot, trigger): - - if botevents.SpiceBot_Events["RPL_WELCOME_Count"] == 1: - timesince = humanized_time(time.time() - bot.memory["SpiceBot_Uptime"]) - bot.memory['SpiceBot_StartupMonologue'].append("Startup took " + timesince) - - # Announce to chan, then handle some closing stuff - botlogs.log('SpiceBot_StartupMonologue', bot.nick + " startup complete") - bot.memory['SpiceBot_StartupMonologue'].insert(0, " startup complete") - - bot.osd(bot.memory['SpiceBot_StartupMonologue'], bot.channels.keys(), 'ACTION') - - botevents.trigger(bot, botevents.BOT_STARTUPMONOLOGUE, "SpiceBot_StartupMonologue") - botlogs.log('SpiceBot_StartupMonologue', "Startup Monologue has been issued to all channels.", True) diff --git a/sopel_modules/SpiceBot_StartupMonologue/__init__.py b/sopel_modules/SpiceBot_StartupMonologue/__init__.py deleted file mode 100644 index 8ab7cf1..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding=utf8 -"""Sopel Startup Monologue - -Sopel Startup Monologue displays to all channels that the bot is online -""" -from __future__ import unicode_literals, absolute_import, division, print_function - -from .StartupMonologue import * -from .StartupMonologue_Display_Channels import * -from .StartupMonologue_Display_Commands import * -from .StartupMonologue_Display_Connected import * -from .StartupMonologue_Display_Loaded import * -from .StartupMonologue_Display_Errors import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_Update/Update.py b/sopel_modules/SpiceBot_Update/Update.py deleted file mode 100644 index d00464d..0000000 --- a/sopel_modules/SpiceBot_Update/Update.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel.module -from sopel.config.types import StaticSection, ValidatedAttribute - -import spicemanip - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, spicebot_reload, spicebot_update - - -class SpiceBot_Update_MainSection(StaticSection): - gitrepo = ValidatedAttribute('gitrepo', default="https://github.com/SpiceBot/SpiceBot") - gitbranch = ValidatedAttribute('gitbranch', default="master") - - -def configure(config): - config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) - config.SpiceBot_Update.configure_setting('gitrepo', 'SpiceBot_Update git repo to install') - config.SpiceBot_Update.configure_setting('gitbranch', 'SpiceBot_Update git branch to install') - - -def setup(bot): - botlogs.log('SpiceBot_Update', "Initial Setup processing") - bot.config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) - - -@sopel.module.nickname_commands('update') -def nickname_comand_update(bot, trigger): - - if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): - bot.say("I was unable to process this Bot Nick command due to privilege issues.") - return - - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') - - if not len(triggerargs): - commandused = 'nodeps' - else: - commandused = spicemanip.main(triggerargs, 1).lower() - - if commandused not in ['deps', 'nodeps']: - bot.say("Please specify deps or nodeps") - return - - triggerargs = spicemanip.main(triggerargs, '2+', 'list') - - quitmessage = "Received command from " + trigger.nick + " to update from Github and restart" - botlogs.log('SpiceBot_Update', quitmessage) - bot.osd(quitmessage, bot.channels.keys()) - - if commandused == 'nodeps': - spicebot_update(bot, False) - if commandused == 'deps': - spicebot_update(bot, True) - - # service_manip(bot, bot.nick, 'restart', 'SpiceBot_Update') - spicebot_reload(bot, 'SpiceBot_Update', quitmessage) diff --git a/sopel_modules/SpiceBot_Update/__init__.py b/sopel_modules/SpiceBot_Update/__init__.py deleted file mode 100644 index a2667e1..0000000 --- a/sopel_modules/SpiceBot_Update/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# coding=utf-8 -"""Event Parsing from IRC -""" -from __future__ import unicode_literals, absolute_import, print_function, division - -from .Update import * diff --git a/sopel_modules/SpiceBot_Uptime/Uptime.py b/sopel_modules/SpiceBot_Uptime/Uptime.py deleted file mode 100644 index 3af0b71..0000000 --- a/sopel_modules/SpiceBot_Uptime/Uptime.py +++ /dev/null @@ -1,28 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import time - -from sopel_modules.SpiceBot.Logs import botlogs -from sopel_modules.SpiceBot_SBTools import humanized_time - - -def setup(bot): - if 'SpiceBot_Uptime' not in bot.memory: - now = time.time() - botlogs.log('SpiceBot_Uptime', "Start time set to " + str(time.time())) - bot.memory["SpiceBot_Uptime"] = now - - -def shutdown(bot): - if "SpiceBot_Uptime" in bot.memory: - del bot.memory["SpiceBot_Uptime"] - - -@sopel.module.nickname_commands('uptime') -def bot_command_srewyou(bot, trigger): - timesince = str(humanized_time(time.time() - bot.memory["SpiceBot_Uptime"])) + " ago." - bot.osd("I have been running since " + timesince) diff --git a/sopel_modules/SpiceBot_Uptime/__init__.py b/sopel_modules/SpiceBot_Uptime/__init__.py deleted file mode 100644 index d0079c0..0000000 --- a/sopel_modules/SpiceBot_Uptime/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# coding=utf8 -from __future__ import unicode_literals, absolute_import, division, print_function - -from .Uptime import * - -__author__ = 'Sam Zick' -__email__ = 'sam@deathbybandaid.net' -__version__ = '0.1.1'