diff --git a/Installation Files/requirements-os.sh b/Installation Files/requirements-os.sh index 0df25d2..0c980a2 100644 --- a/Installation Files/requirements-os.sh +++ b/Installation Files/requirements-os.sh @@ -20,7 +20,8 @@ rm dev-requirements.txt wget https://raw.githubusercontent.com/SpiceBot/SpiceBot/development/Installation%20Files/requirements.txt pip3 install -r requirements.txt rm requirements.txt -pip3 install sopel +# pip3 install sopel +pip3 install --upgrade --force-reinstall git+https://github.com/sopel-irc/sopel@master mkdir /usr/local/lib/python3.6/dist-packages/sopel/modules/stock mv /usr/local/lib/python3.6/dist-packages/sopel/modules/* /usr/local/lib/python3.6/dist-packages/sopel/modules/stock/ diff --git a/sopel_modules/SpiceBot/Channels.py b/sopel_modules/SpiceBot/Channels.py new file mode 100644 index 0000000..c8f8d72 --- /dev/null +++ b/sopel_modules/SpiceBot/Channels.py @@ -0,0 +1,77 @@ +# 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 +""" +import sopel +import re + + +class BotChannels(): + """This Logs all channels known to the server""" + def __init__(self): + self.channel_lock = False + self.SpiceBot_Channels = { + "list": {}, + "InitialProcess": False + } + + def channel_list_request(self, bot): + bot.write(['LIST']) + + def channel_list_recieve_start(self): + self.channel_lock = True + + def channel_list_recieve_input(self, trigger): + 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) + self.channel_lock = True + + def channel_list_recieve_finish(self): + if not self.SpiceBot_Channels['InitialProcess']: + self.SpiceBot_Channels['InitialProcess'] = True + self.channel_lock = False + + def topic_compile(self, topic): + actual_topic = re.compile(r'^\[\+[a-zA-Z]+\] (.*)') + topic = re.sub(actual_topic, r'\1', topic) + return topic + + def bot_part_empty(self, bot): + """Don't stay in empty channels""" + ignorepartlist = [] + if bot.config.core.logging_channel: + ignorepartlist.append(bot.config.core.logging_channel) + 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()] + + def join_all_channels(self, bot): + if bot.config.SpiceBot_Channels.joinall: + for channel in botchannels.SpiceBot_Channels['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'])) + + 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 not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN: + bot.write(('SAMODE', channel, "+a", bot.nick)) + else: + bot.part(channel) + + +botchannels = BotChannels() diff --git a/sopel_modules/SpiceBot/Events.py b/sopel_modules/SpiceBot/Events.py new file mode 100644 index 0000000..34dfc54 --- /dev/null +++ b/sopel_modules/SpiceBot/Events.py @@ -0,0 +1,129 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot events system. + +We utilize the Sopel code for event numbers and +self-trigger the bot into performing actions +""" + + +import sopel +import functools + + +class BotEvents(object): + """A dynamic listing of all the notable Bot numeric events. + + Events will be assigned a 4-digit number above 1000. + + This allows you to do, ``@module.event(botevents.BOT_WELCOME)```` + + Triggers handled by this module will be processed immediately. + Others will be placed into a queue. + + Triggers will be logged by ID and content + """ + + def __init__(self): + self.RPL_WELCOME = '001' # This is a defined IRC event + 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 + } + + 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) + setattr(self, name, str(eventnumber)) + return str(eventnumber) + + def trigger(self, bot, number, message="SpiceBot_Events"): + pretriggerdict = {"number": str(number), "message": message} + if number in self.defaultevents: + self.dispatch(bot, pretriggerdict) + else: + self.SpiceBot_Events["trigger_queue"].append(pretriggerdict) + + def dispatch(self, bot, pretriggerdict): + number = pretriggerdict["number"] + message = pretriggerdict["message"] + pretrigger = sopel.trigger.PreTrigger( + bot.nick, + ":SpiceBot_Events " + str(number) + " " + str(bot.nick) + " :" + message + ) + bot.dispatch(pretrigger) + self.recieved({"number": number, "message": message}) + + def recieved(self, trigger): + 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) + + 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(): + return False + return True + + def startup_add(self, startlist): + if not isinstance(startlist, list): + startlist = [str(startlist)] + self.SpiceBot_Events["startup_required"].extend(startlist) + + def startup_check(self): + for number in self.SpiceBot_Events["startup_required"]: + if str(number) not in self.SpiceBot_Events["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(): + not_done.append(int(number)) + reference_not_done = [] + for item in not_done: + reference_not_done.append(str(self.SpiceBot_Events["assigned_IDs"][item])) + return reference_not_done + + def check_ready(self, checklist): + def actual_decorator(function): + @functools.wraps(function) + def _nop(*args, **kwargs): + while not self.check(checklist): + pass + return function(*args, **kwargs) + return _nop + return actual_decorator + + def startup_check_ready(self): + def actual_decorator(function): + @functools.wraps(function) + def _nop(*args, **kwargs): + while not self.startup_check(): + pass + return function(*args, **kwargs) + return _nop + return actual_decorator + + +botevents = BotEvents() diff --git a/sopel_modules/SpiceBot/Logs.py b/sopel_modules/SpiceBot/Logs.py new file mode 100644 index 0000000..da458ae --- /dev/null +++ b/sopel_modules/SpiceBot/Logs.py @@ -0,0 +1,106 @@ +# 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 +""" + + +import sopel +import os +import spicemanip + + +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 + } + + def log(self, logtype, logentry, stdio=False): + logtitle = "[" + logtype + "]" + logmessage = logtitle + " " + logentry + + if self.sopel_config["logging_channel"]: + self.SpiceBot_Logs["queue"].append(logmessage) + + if stdio: + sopel.tools.stderr(logmessage) + + if logtype not in self.SpiceBot_Logs["list"].keys(): + self.SpiceBot_Logs["list"][logtype] = [] + self.SpiceBot_Logs["list"][logtype].append(logentry) + + def get_logs(self): + return [] + + def stdio_logs_fetch(self, bot): + + stdio_ignore = [] + for logtype in botlogs.SpiceBot_Logs["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') + lines = log_file.readlines() + for line in lines: + log_file_lines.append(line) + log_file.close() + + currentline, linenumindex = 0, [] + for line in log_file_lines: + if line.startswith("Welcome to Sopel. Loading modules..."): + linenumindex.append(currentline) + currentline += 1 + last_start = max(linenumindex) + filelines = log_file_lines[last_start:] + except Exception as e: + debuglines = e + filelines = [] + + debuglines = [] + loadedmodules = [] + for line in filelines: + if line.startswith("Loaded:"): + loadedmodules.append(str(line).split("Loaded:")[-1]) + else: + if not line.startswith(tuple(stdio_ignore)) and not line.isspace(): + debuglines.append(str(line)) + loadedmodules = "Loaded: " + spicemanip.main(loadedmodules, 'andlist') + debuglines.insert(1, loadedmodules) + + return debuglines + + def systemd_logs_fetch(self, bot): + servicepid = self.get_running_pid(bot) + debuglines = [] + for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'): + line = str(line).split(str(os.uname()[1] + " "))[-1] + lineparts = str(line).split(": ") + del lineparts[0] + line = spicemanip.main(lineparts, 0) + if not line.isspace(): + debuglines.append(str(line)) + return debuglines + + def get_running_pid(self, bot): + try: + filename = "/run/sopel/sopel-" + str(bot.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] + return pidnum + + +botlogs = botlogs() diff --git a/sopel_modules/SpiceBot/__init__.py b/sopel_modules/SpiceBot/__init__.py new file mode 100644 index 0000000..e934cff --- /dev/null +++ b/sopel_modules/SpiceBot/__init__.py @@ -0,0 +1,15 @@ +# 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 .Logs import * +from .Events import * +from .Channels import * + +__author__ = 'Sam Zick' +__email__ = 'sam@deathbybandaid.net' +__version__ = '0.1.1' diff --git a/sopel_modules/SpiceBot_AI/AI.py b/sopel_modules/SpiceBot_AI/AI.py index 7ae029b..0a3f8f1 100644 --- a/sopel_modules/SpiceBot_AI/AI.py +++ b/sopel_modules/SpiceBot_AI/AI.py @@ -7,15 +7,13 @@ 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.System import bot_events_check, botevents +from sopel_modules.SpiceBot.Events import botevents +@botevents.check_ready([botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]) @sopel.module.nickname_commands('(.*)') def bot_command_nick(bot, trigger): - while not bot_events_check(bot, [botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') if not triggercommand: diff --git a/sopel_modules/SpiceBot_AI/AI_Really.py b/sopel_modules/SpiceBot_AI/AI_Really.py new file mode 100644 index 0000000..2a36402 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Really.py @@ -0,0 +1,18 @@ +# 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_Welcomeback.py b/sopel_modules/SpiceBot_AI/AI_Welcomeback.py new file mode 100644 index 0000000..334d8cb --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Welcomeback.py @@ -0,0 +1,13 @@ +# 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/__init__.py b/sopel_modules/SpiceBot_AI/__init__.py index 93aecc7..509146e 100644 --- a/sopel_modules/SpiceBot_AI/__init__.py +++ b/sopel_modules/SpiceBot_AI/__init__.py @@ -10,6 +10,8 @@ from .AI_Lazy import * from .AI_InsultHandler import * from .AI_Ping import * from .AI_Love import * +from .AI_Really import * +from .AI_Welcomeback import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Channels/Channels.py b/sopel_modules/SpiceBot_Channels/Channels.py deleted file mode 100644 index 5bb11d6..0000000 --- a/sopel_modules/SpiceBot_Channels/Channels.py +++ /dev/null @@ -1,129 +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_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents -from sopel_modules.SpiceBot_SBTools import ( - join_all_channels, chanadmin_all_channels, channel_list_current, - bot_logging - ) - -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('announcenew', 'SpiceBot_Channels JOIN New Channels') - config.SpiceBot_Channels.configure_setting('announcenew', 'SpiceBot_Channels OPER ADMIN MODE') - config.SpiceBot_Channels.configure_setting('chanignore', 'SpiceBot_Channels Ignore JOIN for channels') - - -def setup(bot): - bot_logging(bot, 'SpiceBot_Channels', "Starting setup procedure") - bot_events_startup_register(bot, [botevents.BOT_CHANNELS]) - - bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) - - if "SpiceBot_Channels" not in bot.memory: - bot.memory["SpiceBot_Channels"] = {"channels": {}, "InitialProcess": False, "ProcessLock": False} - - -def shutdown(bot): - if "SpiceBot_Channels" in bot.memory: - del bot.memory["SpiceBot_Channels"] - - -@sopel.module.event(botevents.BOT_CONNECTED) -@sopel.module.rule('.*') -def trigger_channel_list_initial(bot, trigger): - bot_events_recieved(bot, trigger.event) - - # Unkickable - bot.write(('SAMODE', bot.nick, '+q')) - - bot_part_empty(bot) - - bot.write(['LIST']) - bot.memory['SpiceBot_Channels']['ProcessLock'] = True - - bot_logging(bot, 'SpiceBot_Channels', "Initial Channel list populating") - starttime = time.time() - - while not bot.memory['SpiceBot_Channels']['InitialProcess']: - timesince = time.time() - starttime - if timesince < 60: - pass - else: - bot_logging(bot, 'SpiceBot_Channels', "Initial Channel list populating Timed Out") - bot.memory['SpiceBot_Channels']['InitialProcess'] = True - - channel_list_current(bot) - foundchannelcount = len(bot.memory['SpiceBot_Channels']['channels'].keys()) - bot_logging(bot, 'SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.") - bot_events_trigger(bot, botevents.BOT_CHANNELS, "SpiceBot_Channels") - - join_all_channels(bot) - chanadmin_all_channels(bot) - - if "*" in bot.memory['SpiceBot_Channels']['channels']: - del bot.memory['SpiceBot_Channels']['channels']["*"] - - bot_part_empty(bot) - - while True: - try: - time.sleep(1800) - bot_part_empty(bot) - oldlist = list(bot.memory['SpiceBot_Channels']['channels'].keys()) - bot.write(['LIST']) - bot.memory['SpiceBot_Channels']['ProcessLock'] = True - - while bot.memory['SpiceBot_Channels']['ProcessLock']: - pass - - newlist = [item.lower() for item in oldlist if item.lower() not in bot.memory['SpiceBot_Channels']['channels']] - 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()) - - join_all_channels(bot) - - chanadmin_all_channels(bot) - - if "*" in bot.memory['SpiceBot_Channels']['channels']: - del bot.memory['SpiceBot_Channels']['channels']["*"] - bot_part_empty(bot) - except KeyError: - return - - -def bot_part_empty(bot): - ignorepartlist = [] - if bot.config.SpiceBot_Logs.logging_channel: - ignorepartlist.append(bot.config.SpiceBot_Logs.logging_channel) - for channel in bot.channels.keys(): - if len(bot.channels[channel].privileges.keys()) == 1 and channel not in ignorepartlist: - bot.part(channel, "Leaving Empty Channel") - if channel.lower() in bot.memory['SpiceBot_Channels']['channels']: - del bot.memory['SpiceBot_Channels']['channels'][channel.lower()] - - -@sopel.module.event(botevents.BOT_CHANNELS) -@sopel.module.rule('.*') -def bot_events_setup(bot, trigger): - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_Channels/Channels_Parsing.py b/sopel_modules/SpiceBot_Channels/Channels_Parsing.py deleted file mode 100644 index 6998524..0000000 --- a/sopel_modules/SpiceBot_Channels/Channels_Parsing.py +++ /dev/null @@ -1,32 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot_SBTools import topic_compile - - -@sopel.module.event('321') -@sopel.module.rule('.*') -def watch_chanlist_start(bot, trigger): - bot.memory['SpiceBot_Channels']['ProcessLock'] = True - - -@sopel.module.event('322') -@sopel.module.rule('.*') -def watch_chanlist_populate(bot, trigger): - channel, _, topic = trigger.args[1:] - if channel.lower() not in bot.memory['SpiceBot_Channels']['channels']: - bot.memory['SpiceBot_Channels']['channels'][channel.lower()] = dict() - bot.memory['SpiceBot_Channels']['channels'][channel.lower()]['name'] = channel - bot.memory['SpiceBot_Channels']['channels'][channel.lower()]['topic'] = topic_compile(topic) - bot.memory['SpiceBot_Channels']['ProcessLock'] = True - - -@sopel.module.event('323') -@sopel.module.rule('.*') -def watch_chanlist_complete(bot, trigger): - bot.memory['SpiceBot_Channels']['ProcessLock'] = False - if not bot.memory['SpiceBot_Channels']['InitialProcess']: - bot.memory['SpiceBot_Channels']['InitialProcess'] = True diff --git a/sopel_modules/SpiceBot_Channels/Channels_Command.py b/sopel_modules/SpiceBot_Channels_Command/Channels_Command.py similarity index 69% rename from sopel_modules/SpiceBot_Channels/Channels_Command.py rename to sopel_modules/SpiceBot_Channels_Command/Channels_Command.py index c7e69bc..24825c8 100644 --- a/sopel_modules/SpiceBot_Channels/Channels_Command.py +++ b/sopel_modules/SpiceBot_Channels_Command/Channels_Command.py @@ -6,20 +6,15 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents -from sopel_modules.SpiceBot_SBTools import ( - sopel_triggerargs, inlist, channel_privs, - join_all_channels, channel_list_current, - ) -from .Channels import bot_part_empty +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 +@botevents.check_ready([botevents.BOT_LOADED]) @sopel.module.nickname_commands('channels', 'channel') def nickname_comand_channels(bot, trigger): - while not bot_events_check(bot, botevents.BOT_LOADED): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') if not len(triggerargs): @@ -29,8 +24,6 @@ def nickname_comand_channels(bot, trigger): triggerargs = spicemanip.main(triggerargs, '2+', 'list') - channel_list_current(bot) - if commandused == 'list': chanlist = spicemanip.main(bot.channels.keys(), 'andlist') bot.osd("You can find me in " + chanlist) @@ -38,14 +31,14 @@ def nickname_comand_channels(bot, trigger): elif commandused == 'total': botcount = len(bot.channels.keys()) - servercount = len(bot.memory['SpiceBot_Channels']['channels'].keys()) + servercount = len(botchannels.SpiceBot_Channels['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(bot.memory['SpiceBot_Channels']['channels'], 'random') - topic = bot.memory['SpiceBot_Channels']['channels'][channel]['topic'] - msg = ["Random channel for you: {}.".format(bot.memory['SpiceBot_Channels']['channels'][channel]['name'])] + 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'])] if topic and not topic.isspace(): msg.append("The topic is: {}".format(topic)) else: @@ -57,16 +50,15 @@ def nickname_comand_channels(bot, trigger): if not trigger.admin: bot.osd("You do not have permission to update the channel listing.") return - bot_part_empty(bot) - bot.write(['LIST']) + botchannels.bot_part_empty(bot) + botchannels.channel_list_request(bot) bot.osd(["[SpiceBot_Channels]", "I am now updating the channel listing for this server."]) - bot.memory['SpiceBot_Channels']['ProcessLock'] = True - while bot.memory['SpiceBot_Channels']['ProcessLock']: + while botchannels.channel_lock: pass - join_all_channels(bot) - foundchannelcount = len(bot.memory['SpiceBot_Channels']['channels'].keys()) + botchannels.join_all_channels(bot) + foundchannelcount = len(botchannels.SpiceBot_Channels['list'].keys()) bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.") - bot_part_empty(bot) + botchannels.bot_part_empty(bot) return elif commandused == 'topic': @@ -74,11 +66,11 @@ def nickname_comand_channels(bot, trigger): bot.osd("Channel name input missing.") return channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), bot.memory['SpiceBot_Channels']['channels'].keys()): + if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return - topic = bot.memory['SpiceBot_Channels']['channels'][channel.lower()]['topic'] - channel = bot.memory['SpiceBot_Channels']['channels'][channel.lower()]['name'] + topic = botchannels.SpiceBot_Channels['list'][channel.lower()]['topic'] + channel = botchannels.SpiceBot_Channels['list'][channel.lower()]['name'] bot.osd("Topic for {}: {}".format(channel, topic)) return @@ -91,7 +83,7 @@ def nickname_comand_channels(bot, trigger): channel = trigger.sender else: channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), bot.memory['SpiceBot_Channels']['channels'].keys()): + if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return if not inlist(bot, channel.lower(), bot.channels.keys()): @@ -111,7 +103,7 @@ def nickname_comand_channels(bot, trigger): # Users List if commandused == 'users': channel = spicemanip.main(triggerargs, 1) - if not inlist(bot, channel.lower(), bot.memory['SpiceBot_Channels']['channels'].keys()): + if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()): bot.osd("Channel name {} not valid.".format(channel)) return if not inlist(bot, channel.lower(), bot.channels.keys()): diff --git a/sopel_modules/SpiceBot_Channels/__init__.py b/sopel_modules/SpiceBot_Channels_Command/__init__.py similarity index 74% rename from sopel_modules/SpiceBot_Channels/__init__.py rename to sopel_modules/SpiceBot_Channels_Command/__init__.py index 6d0a4e4..643aeb7 100644 --- a/sopel_modules/SpiceBot_Channels/__init__.py +++ b/sopel_modules/SpiceBot_Channels_Command/__init__.py @@ -3,6 +3,4 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from .Channels import * from .Channels_Command import * -from .Channels_Parsing import * diff --git a/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py b/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py new file mode 100644 index 0000000..ef22e3d --- /dev/null +++ b/sopel_modules/SpiceBot_Channels_Parsing/Channels_Parsing.py @@ -0,0 +1,121 @@ +#!/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 new file mode 100644 index 0000000..0d5311d --- /dev/null +++ b/sopel_modules/SpiceBot_Channels_Parsing/__init__.py @@ -0,0 +1,6 @@ +# 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 index 434630e..9677108 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py +++ b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py @@ -7,15 +7,15 @@ import sopel.module import os -from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents -from sopel_modules.SpiceBot_SBTools import bot_logging +from sopel_modules.SpiceBot.Logs import botlogs +from sopel_modules.SpiceBot.Events import botevents import spicemanip def setup(bot): - bot_logging(bot, 'SpiceBot_CommandsQuery', "Starting setup procedure") - bot_events_startup_register(bot, [botevents.BOT_COMMANDSQUERY]) + 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": []} @@ -44,7 +44,7 @@ def setup(bot): pypi_modules_dir = os.path.join(plugin_dir, pathname) filepathlisting.append(pypi_modules_dir) except Exception as e: - bot_logging(bot, 'SpiceBot_CommandsQuery', "sopel_modules not loaded :" + str(e)) + botlogs.log('SpiceBot_CommandsQuery', "sopel_modules not loaded :" + str(e)) # Extra directories filepathlist = [] @@ -154,7 +154,7 @@ def setup(bot): bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][comalias] = {"aliasfor": maincom} for comtype in ['module', 'nickname', 'rule']: - bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) + 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"): @@ -162,7 +162,7 @@ def setup(bot): if command not in bot.memory['SpiceBot_CommandsQuery']['nickrules']: bot.memory['SpiceBot_CommandsQuery']['nickrules'].append(command) - bot_events_trigger(bot, botevents.BOT_COMMANDSQUERY, "SpiceBot_CommandsQuery") + botevents.trigger(bot, botevents.BOT_COMMANDSQUERY, "SpiceBot_CommandsQuery") def shutdown(bot): @@ -173,11 +173,10 @@ def shutdown(bot): @sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_events_complete(bot, trigger): - bot_events_recieved(bot, trigger.event) for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): if comtype not in ['module', 'nickname', 'rule']: - bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) + 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): @@ -212,9 +211,3 @@ def commandsquery_register(bot, command_type, validcoms, aliasfor=None): 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} - - -@sopel.module.event(botevents.BOT_COMMANDSQUERY) -@sopel.module.rule('.*') -def bot_events_setup(bot, trigger): - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py index 67782f3..a04866f 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py +++ b/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py @@ -5,19 +5,17 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel import sopel.module -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +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): - while not bot_events_check(bot, botevents.BOT_COMMANDSQUERY): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') # command issued, check if valid diff --git a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py index 8f8011b..f2e6de1 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py +++ b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py @@ -5,19 +5,17 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel import sopel.module -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +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): - while not bot_events_check(bot, botevents.BOT_COMMANDSQUERY): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'query_command') # command issued, check if valid diff --git a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py b/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py index 26fc511..9e8343d 100644 --- a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py +++ b/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py @@ -5,21 +5,22 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi # sopel imports import sopel.module from sopel.tools import Identifier -from sopel_modules.SpiceBot_SBTools import bot_logging from sopel.db import SopelDB, NickValues, ChannelValues -from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.exc import SQLAlchemyError import json +from sopel_modules.SpiceBot.Logs import botlogs + def setup(bot): pass # Inject Database Functions - bot_logging(bot, 'SpiceBot_Databaseaddons', "Implanting Database functions into bot") + 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.adjust_nick_value = SopelDBCache.adjust_nick_value SopelDB.delete_channel_value = SopelDBCache.delete_channel_value - # SopelDB.adjust_channel_value = SopelDBCache.adjust_channel_value + SopelDB.adjust_channel_value = SopelDBCache.adjust_channel_value class SopelDBCache: @@ -38,7 +39,7 @@ class SopelDBCache: .one_or_none() # NickValue exists, delete if result: - session.delete(result.value) + session.delete(result) session.commit() except SQLAlchemyError: session.rollback() @@ -85,7 +86,7 @@ class SopelDBCache: .one_or_none() # ChannelValue exists, update if result: - session.delete(result.value) + session.delete(result) session.commit() except SQLAlchemyError: session.rollback() diff --git a/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py b/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py index 1811877..f31ea22 100644 --- a/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py +++ b/sopel_modules/SpiceBot_Database_Cache/DatabaseCache.py @@ -4,11 +4,12 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi # sopel imports import sopel.module -from sopel_modules.SpiceBot_SBTools import bot_logging + +from sopel_modules.SpiceBot.Logs import botlogs def setup(bot): - bot_logging(bot, 'SpiceBot_DatabaseCache', "Setting up Database Cache") + botlogs.log('SpiceBot_DatabaseCache', "Setting up Database Cache") if 'SpiceBot_DatabaseCache' not in bot.memory: bot.memory['SpiceBot_DatabaseCache'] = dict() diff --git a/sopel_modules/SpiceBot_Events/Connected.py b/sopel_modules/SpiceBot_Events/Connected.py new file mode 100644 index 0000000..c99f0db --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Connected.py @@ -0,0 +1,16 @@ +# 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 new file mode 100644 index 0000000..786271b --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Connection_Count.py @@ -0,0 +1,15 @@ +# 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/Events.py b/sopel_modules/SpiceBot_Events/Events.py deleted file mode 100644 index 730cb4f..0000000 --- a/sopel_modules/SpiceBot_Events/Events.py +++ /dev/null @@ -1,72 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module -from sopel.trigger import PreTrigger - -from .System import bot_events_trigger, bot_events_recieved, bot_events_startup_check, bot_events_setup_check, botevents -from sopel_modules.SpiceBot_SBTools import bot_logging - -import time - - -@sopel.module.event('001') -@sopel.module.rule('.*') -def bot_startup_connection(bot, trigger): - bot_events_trigger(bot, botevents.BOT_WELCOME, "Welcome to the SpiceBot Events System") - - while not len(bot.channels.keys()) > 0: - pass - time.sleep(1) - bot_events_trigger(bot, botevents.BOT_CONNECTED, "Bot Connected to IRC") - - -@sopel.module.event(botevents.BOT_WELCOME) -@sopel.module.rule('.*') -def bot_events_start(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) - bot_events_recieved(bot, trigger.event) - - bot_events_trigger(bot, botevents.BOT_READY, "Ready To Process module setup procedures") - - while not bot_events_startup_check(bot): - pass - bot_events_trigger(bot, botevents.BOT_LOADED, "All registered modules setup procedures have completed") - - -@sopel.module.event(botevents.BOT_READY) -@sopel.module.rule('.*') -def bot_events_ready(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) - bot_events_recieved(bot, trigger.event) - - -@sopel.module.event(botevents.BOT_CONNECTED) -@sopel.module.rule('.*') -def bot_events_connected(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) - bot_events_recieved(bot, trigger.event) - - bot_events_setup_check(bot) - - while True: - try: - if len(bot.memory['SpiceBot_Events']["queue"]): - number = bot.memory['SpiceBot_Events']["queue"][0]["number"] - message = bot.memory['SpiceBot_Events']["queue"][0]["message"] - pretrigger = PreTrigger( - bot.nick, - ":SpiceBot_Events " + str(number) + " " + str(bot.nick) + " :" + message - ) - bot.dispatch(pretrigger) - del bot.memory['SpiceBot_Events']["queue"][0] - except KeyError: - return - - -@sopel.module.event(botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_events_complete(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_Events/Loaded.py b/sopel_modules/SpiceBot_Events/Loaded.py new file mode 100644 index 0000000..679c06f --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Loaded.py @@ -0,0 +1,15 @@ +# 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 new file mode 100644 index 0000000..9176d9e --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Logging.py @@ -0,0 +1,15 @@ +# 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 new file mode 100644 index 0000000..9ccd275 --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Queue.py @@ -0,0 +1,18 @@ +# 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 new file mode 100644 index 0000000..4e8df49 --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Ready.py @@ -0,0 +1,14 @@ +# 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/System.py b/sopel_modules/SpiceBot_Events/System.py deleted file mode 100644 index cd7a874..0000000 --- a/sopel_modules/SpiceBot_Events/System.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -#coding=utf-8 -from __future__ import unicode_literals, absolute_import, print_function, division - -# sopel imports -import sopel -from sopel.trigger import PreTrigger - -from sopel_modules.SpiceBot_SBTools import bot_logging - - -class BotEvents(object): - """A dynamic listing of all the notable Bot numeric events. - - Events will be assigned a 4-digit number above 1000. - - This allows you to do, ``@module.event(botevents.BOT_WELCOME)```` - """ - - def __init__(self): - self.usednumbers = [1000] - - def __getattr__(self, name): - ''' will only get called for undefined attributes ''' - eventnumber = max(self.usednumbers) + 1 - self.usednumbers.append(eventnumber) - setattr(self, name, str(eventnumber)) - return str(eventnumber) - - -botevents = BotEvents() - - -def setup(bot): - bot_logging(bot, 'SpiceBot_Events', "Starting setup procedure") - bot_events_setup_check(bot) - bot_events_startup_register(bot, [botevents.BOT_WELCOME, botevents.BOT_READY, botevents.BOT_CONNECTED]) - - -def shutdown(bot): - if "SpiceBot_Events" in bot.memory: - del bot.memory["SpiceBot_Events"] - - -def bot_events_trigger(bot, number, message): - - bot_events_setup_check(bot) - - bot.memory["SpiceBot_Events"]["triggers"][str(number)] = message - if str(number) in [botevents.BOT_WELCOME, botevents.BOT_READY, botevents.BOT_CONNECTED]: - pretrigger = PreTrigger( - bot.nick, - ":SpiceBot_Events " + str(number) + " " + str(bot.nick) + " :" + message - ) - bot.dispatch(pretrigger) - else: - pretriggerdict = {"number": number, "message": message} - bot.memory['SpiceBot_Events']["queue"].append(pretriggerdict) - - -def bot_events_setup_check(bot): - if "SpiceBot_Events" not in bot.memory: - bot.memory["SpiceBot_Events"] = {"triggers": {}, "startup": [], "loaded": [], "queue": []} - - -def bot_events_check(bot, listreq): - - bot_events_setup_check(bot) - - if not isinstance(listreq, list): - listreq = [str(listreq)] - - for requirement in listreq: - if requirement not in bot.memory["SpiceBot_Events"]["loaded"]: - return False - - return True - - -def bot_events_startup_register(bot, addonreq): - - bot_events_setup_check(bot) - - if not isinstance(addonreq, list): - addonreq = [str(addonreq)] - - bot.memory["SpiceBot_Events"]["startup"].extend(addonreq) - - -def bot_events_recieved(bot, number): - - bot_events_setup_check(bot) - - if str(number) not in bot.memory["SpiceBot_Events"]["loaded"]: - bot.memory["SpiceBot_Events"]["loaded"].append(str(number)) - - -def bot_events_startup_check(bot): - - bot_events_setup_check(bot) - - notcomplete = [] - - for startupitem in bot.memory["SpiceBot_Events"]["startup"]: - if str(startupitem) not in bot.memory["SpiceBot_Events"]["loaded"]: - notcomplete.append(str(startupitem)) - - if len(notcomplete): - return False - else: - return True diff --git a/sopel_modules/SpiceBot_Events/Welcome.py b/sopel_modules/SpiceBot_Events/Welcome.py new file mode 100644 index 0000000..ca15d55 --- /dev/null +++ b/sopel_modules/SpiceBot_Events/Welcome.py @@ -0,0 +1,17 @@ +# 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 index 532880f..e2846d8 100644 --- a/sopel_modules/SpiceBot_Events/__init__.py +++ b/sopel_modules/SpiceBot_Events/__init__.py @@ -1,8 +1,12 @@ # coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function -from .System import * -from .Events import * +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' diff --git a/sopel_modules/SpiceBot_GifSearch/gif.py b/sopel_modules/SpiceBot_GifSearch/gif.py index 6c344a9..88c5566 100644 --- a/sopel_modules/SpiceBot_GifSearch/gif.py +++ b/sopel_modules/SpiceBot_GifSearch/gif.py @@ -7,17 +7,15 @@ from sopel import module from .gifsearch import getGif from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +from sopel_modules.SpiceBot.Events import botevents import spicemanip +@botevents.check_ready([botevents.BOT_GIFSEARCH]) @module.commands('gif') def gif_trigger(bot, trigger): - while not bot_events_check(bot, botevents.BOT_GIFSEARCH): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger) if not len(triggerargs): return bot.osd("Please present a query to search.") diff --git a/sopel_modules/SpiceBot_GifSearch/gifapi.py b/sopel_modules/SpiceBot_GifSearch/gifapi.py index fa500b9..5fcd73e 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifapi.py +++ b/sopel_modules/SpiceBot_GifSearch/gifapi.py @@ -9,15 +9,13 @@ import sopel.module import spicemanip from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +from sopel_modules.SpiceBot.Events import botevents +@botevents.check_ready([botevents.BOT_GIFSEARCH]) @sopel.module.commands('(.*)') def gifapi_triggers(bot, trigger): - while not bot_events_check(bot, botevents.BOT_GIFSEARCH): - pass - triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') if triggercommand not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): diff --git a/sopel_modules/SpiceBot_GifSearch/gifsearch.py b/sopel_modules/SpiceBot_GifSearch/gifsearch.py index 884bd11..1eb2ce4 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifsearch.py +++ b/sopel_modules/SpiceBot_GifSearch/gifsearch.py @@ -5,11 +5,10 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents - +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, bot_logging +from sopel_modules.SpiceBot_SBTools import read_directory_json_to_dict import spicemanip @@ -46,8 +45,8 @@ def configure(config): def setup(bot): - bot_logging(bot, 'SpiceBot_GifSearch', "Starting Setup Procedure") - bot_events_startup_register(bot, [botevents.BOT_GIFSEARCH]) + botlogs.log('SpiceBot_GifSearch', "Starting Setup Procedure") + botevents.startup_add([botevents.BOT_GIFSEARCH]) if 'SpiceBot_GifSearch' not in bot.memory: bot.memory["SpiceBot_GifSearch"] = {"cache": {}, "badgiflinks": [], 'valid_gif_api_dict': {}} @@ -79,7 +78,7 @@ def setup(bot): if validgifapi not in bot.memory["SpiceBot_GifSearch"]['cache'].keys(): bot.memory["SpiceBot_GifSearch"]['cache'][validgifapi] = dict() - bot_events_trigger(bot, botevents.BOT_GIFSEARCH, "SpiceBot_GifSearch") + botevents.trigger(bot, botevents.BOT_GIFSEARCH, "SpiceBot_GifSearch") def shutdown(bot): @@ -249,9 +248,3 @@ def getGif(bot, searchdict): # return dict gifdict['error'] = None return gifdict - - -@sopel.module.event(botevents.BOT_GIFSEARCH) -@sopel.module.rule('.*') -def bot_events_setup(bot, trigger): - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py b/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py index 73250cb..3bff3a2 100644 --- a/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py +++ b/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module from sopel_modules.SpiceBot_SBTools import sopel_triggerargs -from sopel_modules.SpiceBot_Events.System import bot_events_check, bot_events_recieved, botevents +from sopel_modules.SpiceBot.Events import botevents def setup(bot): @@ -21,19 +21,15 @@ def shutdown(bot): @sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_events_complete(bot, trigger): - bot_events_recieved(bot, trigger.event) - 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 - while not bot_events_check(bot, [botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]): - pass - 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 diff --git a/sopel_modules/SpiceBot_Kick/__init__.py b/sopel_modules/SpiceBot_Kick/__init__.py index c752bd4..2d1c429 100644 --- a/sopel_modules/SpiceBot_Kick/__init__.py +++ b/sopel_modules/SpiceBot_Kick/__init__.py @@ -12,10 +12,10 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.bot from sopel import tools, module from sopel.tools import Identifier -from sopel.module import HALFOP from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot_SBTools import bot_logging +from sopel_modules.SpiceBot.Logs import botlogs + import time from collections import abc @@ -28,20 +28,20 @@ __version__ = '0.1.2' def configure(config): - config.define_section("MAXTARGCONFIG_KICK", MAXTARGCONFIG_KICK, validate=False) - config.MAXTARGCONFIG_KICK.configure_setting('kick', 'MAXTARG limit for KICK') + config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) + config.SpiceBot_Kick.configure_setting('kick', 'MAXTARG limit for KICK') def setup(bot): # Inject KICK - bot_logging(bot, 'SpiceBot_Kick', "Implanting Kick function into bot") + botlogs.log('SpiceBot_Kick', "Implanting Kick function into bot") bot.kick = SopelKICK.kick sopel.bot.SopelWrapper.kick = SopelWrapperKICK.kick # verify config settings for server - bot_logging(bot, 'SpiceBot_Kick', "Checking for config settings") - bot.config.define_section("MAXTARGCONFIG_KICK", MAXTARGCONFIG_KICK, validate=False) + botlogs.log('SpiceBot_Kick', "Checking for config settings") + bot.config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False) @module.event('005') @@ -63,10 +63,10 @@ def parse_event_005(bot, trigger): except IndexError: value = None if value: - bot.config.MAXTARGCONFIG_KICK.kick = int(value) + bot.config.SpiceBot_Kick.kick = int(value) -class MAXTARGCONFIG_KICK(StaticSection): +class SpiceBot_Kick(StaticSection): kick = ValidatedAttribute('kick', default=1) @@ -80,8 +80,7 @@ class SopelKICK: The bot must be a channel operator in specified channel for this to work. .. versionadded:: 7.0 """ - if self.channels[channel].privileges[self.nick] < HALFOP: - self.write(['KICK', channel, nick], text) + self.write(['KICK', channel, nick], text) class SopelWrapperKICK(object): @@ -89,9 +88,9 @@ class SopelWrapperKICK(object): def kick(self, nick, channel=None, message=None): if channel is None: if self._trigger.is_privmsg: - return + raise RuntimeError('Error: KICK requires a channel.') else: channel = self._trigger.sender if nick is None: - return + 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 new file mode 100644 index 0000000..84ccc84 --- /dev/null +++ b/sopel_modules/SpiceBot_Logs/IRC_Events @@ -0,0 +1,1266 @@ +#!/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.py b/sopel_modules/SpiceBot_Logs/Logs.py deleted file mode 100644 index e764855..0000000 --- a/sopel_modules/SpiceBot_Logs/Logs.py +++ /dev/null @@ -1,137 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module -from sopel.config.types import StaticSection, ValidatedAttribute - -from sopel_modules.SpiceBot_SBTools import bot_logging -from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents - -import os - -import spicemanip - - -def configure(config): - config.define_section("SpiceBot_Logs", SpiceBot_Logs_MainSection, validate=False) - config.SpiceBot_Logs.configure_setting('logging_channel', 'SpiceBot_Logs channels') - - -class SpiceBot_Logs_MainSection(StaticSection): - logging_channel = ValidatedAttribute('logging_channel', default=False) - - -def setup(bot): - bot_logging(bot, 'SpiceBot_Logs', "Starting Setup Procedure") - bot.config.define_section("SpiceBot_Logs", SpiceBot_Logs_MainSection, validate=False) - - bot_events_startup_register(bot, [botevents.BOT_LOGS]) - - bot_logs_setup_check(bot) - - bot_events_trigger(bot, botevents.BOT_LOGS, "SpiceBot_Logs") - - -def bot_logs_setup_check(bot): - if 'SpiceBot_Logs' not in bot.memory: - bot.memory['SpiceBot_Logs'] = {"logs": {"Sopel_systemd": [], "Sopel_stdio": []}, "queue": []} - - -def shutdown(bot): - if "SpiceBot_Logs" in bot.memory: - del bot.memory["SpiceBot_Logs"] - - -@sopel.module.event(botevents.BOT_CONNECTED) -@sopel.module.rule('.*') -def join_log_channel(bot, trigger): - bot_events_recieved(bot, trigger.event) - - if bot.config.SpiceBot_Logs.logging_channel: - channel = bot.config.SpiceBot_Logs.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)) - - bot_logs_setup_check(bot) - - while True: - try: - if len(bot.memory['SpiceBot_Logs']["queue"]): - bot.say(str(bot.memory['SpiceBot_Logs']["queue"][0]), channel) - del bot.memory['SpiceBot_Logs']["queue"][0] - except KeyError: - return - - -def stdio_logs_fetch(bot): - - stdio_ignore = [] - for logtype in bot.memory['SpiceBot_Logs']["logs"].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') - lines = log_file.readlines() - for line in lines: - log_file_lines.append(line) - log_file.close() - - currentline, linenumindex = 0, [] - for line in log_file_lines: - if line.startswith("Welcome to Sopel. Loading modules..."): - linenumindex.append(currentline) - currentline += 1 - last_start = max(linenumindex) - filelines = log_file_lines[last_start:] - except Exception as e: - debuglines = e - filelines = [] - - debuglines = [] - loadedmodules = [] - for line in filelines: - if line.startswith("Loaded:"): - loadedmodules.append(str(line).split("Loaded:")[-1]) - else: - if not line.startswith(tuple(stdio_ignore)) and not line.isspace(): - debuglines.append(str(line)) - loadedmodules = "Loaded: " + spicemanip.main(loadedmodules, 'andlist') - debuglines.insert(1, loadedmodules) - - return debuglines - - -def systemd_logs_fetch(bot): - servicepid = get_running_pid(bot) - debuglines = [] - for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'): - line = str(line).split(str(os.uname()[1] + " "))[-1] - lineparts = str(line).split(": ") - del lineparts[0] - line = spicemanip.main(lineparts, 0) - if not line.isspace(): - debuglines.append(str(line)) - return debuglines - - -def get_running_pid(bot): - try: - filename = "/run/sopel/" + str(bot.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] - return pidnum - - -@sopel.module.event(botevents.BOT_LOGS) -@sopel.module.rule('.*') -def bot_events_setup(bot, trigger): - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_Logs/Logs_Command.py b/sopel_modules/SpiceBot_Logs/Logs_Command.py index a095e39..7c6bf5f 100644 --- a/sopel_modules/SpiceBot_Logs/Logs_Command.py +++ b/sopel_modules/SpiceBot_Logs/Logs_Command.py @@ -1,22 +1,19 @@ # 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 -from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents -from .Logs import systemd_logs_fetch, stdio_logs_fetch +@botevents.check_ready([botevents.BOT_LOGS]) @sopel.module.nickname_commands('logs', 'debug') def bot_command_logs(bot, trigger): - while not bot_events_check(bot, botevents.BOT_LOGS): - pass - 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 @@ -25,11 +22,11 @@ def bot_command_logs(bot, trigger): logtype = spicemanip.main(triggerargs, 1) or None if not logtype: - bot.osd("Current valid log(s) include: " + spicemanip.main(bot.memory['SpiceBot_Logs']["logs"].keys(), 'andlist'), trigger.sender, 'action') + bot.osd("Current valid log(s) include: " + spicemanip.main(botlogs.SpiceBot_Logs["list"].keys(), 'andlist'), trigger.sender, 'action') return - if not inlist(bot, logtype, bot.memory['SpiceBot_Logs']["logs"].keys()): - closestmatches = similar_list(bot, logtype, bot.memory['SpiceBot_Logs']["logs"].keys(), 10, 'reverse') + 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: @@ -37,14 +34,14 @@ def bot_command_logs(bot, trigger): return - logtype = inlist_match(bot, logtype, bot.memory['SpiceBot_Logs']["logs"].keys()) + logtype = inlist_match(bot, logtype, botlogs.SpiceBot_Logs["list"].keys()) if logtype == "Sopel_systemd": - logindex = systemd_logs_fetch(bot) + logindex = botlogs.systemd_logs_fetch(bot) elif logtype == "Sopel_stdio": - logindex = stdio_logs_fetch(bot) + logindex = botlogs.stdio_logs_fetch(bot) else: - logindex = bot.memory['SpiceBot_Logs']["logs"][logtype] + logindex = botlogs.SpiceBot_Logs["list"][logtype] if not len(logindex): bot.osd("No logs found for " + str(logtype) + ".") diff --git a/sopel_modules/SpiceBot_Logs/Queue.py b/sopel_modules/SpiceBot_Logs/Queue.py new file mode 100644 index 0000000..784efa7 --- /dev/null +++ b/sopel_modules/SpiceBot_Logs/Queue.py @@ -0,0 +1,35 @@ +# 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 index 091f24f..f6ef4d1 100644 --- a/sopel_modules/SpiceBot_Logs/__init__.py +++ b/sopel_modules/SpiceBot_Logs/__init__.py @@ -1,9 +1,9 @@ # coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function -from .Logs import * +from .Queue import * from .Logs_Command import * -from .ErrorDisplay import * +# from .IRC_Events import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Messaging/Messaging.py b/sopel_modules/SpiceBot_Messaging/Messaging.py index 5425bed..0921c8a 100644 --- a/sopel_modules/SpiceBot_Messaging/Messaging.py +++ b/sopel_modules/SpiceBot_Messaging/Messaging.py @@ -6,6 +6,7 @@ import sopel.module import spicemanip +from sopel_modules.SpiceBot.Channels import botchannels from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist @@ -41,7 +42,7 @@ def bot_command_process(bot, trigger): target = spicemanip.main(triggerargs, 1) if (target not in ['allchans', 'allnicks'] - and not inlist(bot, target.lower(), bot.memory['SpiceBot_Channels']['channels'].keys()) + and not inlist(bot, target.lower(), botchannels.SpiceBot_Channels['list'].keys()) and not inlist(bot, target.lower(), bot.users)): bot.osd("Channel/nick name {} not valid.".format(target)) return diff --git a/sopel_modules/SpiceBot_Restart/Restart.py b/sopel_modules/SpiceBot_Restart/Restart.py index b6870ee..89e083c 100644 --- a/sopel_modules/SpiceBot_Restart/Restart.py +++ b/sopel_modules/SpiceBot_Restart/Restart.py @@ -5,7 +5,8 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi # sopel imports import sopel.module -from sopel_modules.SpiceBot_SBTools import bot_logging, spicebot_reload +from sopel_modules.SpiceBot.Logs import botlogs +from sopel_modules.SpiceBot_SBTools import spicebot_reload @sopel.module.nickname_commands('restart') @@ -15,7 +16,7 @@ def nickname_comand_restart(bot, trigger): bot.say("You are not authorized to perform this function.") quitmessage = "Received command from " + trigger.nick + " to restart. Be Back Soon!" - bot_logging(bot, 'SpiceBot_Restart', quitmessage) + botlogs.log('SpiceBot_Restart', quitmessage) bot.osd(quitmessage, bot.channels.keys()) # service_manip(bot, bot.nick, 'restart', 'SpiceBot_Restart') diff --git a/sopel_modules/SpiceBot_SBTools/__init__.py b/sopel_modules/SpiceBot_SBTools/__init__.py index 1bb1bed..74c7a3c 100644 --- a/sopel_modules/SpiceBot_SBTools/__init__.py +++ b/sopel_modules/SpiceBot_SBTools/__init__.py @@ -20,6 +20,8 @@ from pygit2 import clone_repository import spicemanip +from sopel_modules.SpiceBot.Logs import botlogs + """Variable References""" @@ -93,29 +95,6 @@ def command_permissions_check(bot, trigger, privslist): return True -"""Logging""" - - -def bot_logging(bot, logtype, logentry, stdio=False): - - if 'SpiceBot_Logs' not in bot.memory: - bot.memory['SpiceBot_Logs'] = {"logs": {"Sopel_systemd": [], "Sopel_stdio": []}, "queue": []} - - logmessage = "[" + logtype + "] " + logentry + "" - - bot.memory['SpiceBot_Logs']["queue"].append(logmessage) - - if stdio: - sopel.tools.stderr(logmessage) - - if logtype not in bot.memory['SpiceBot_Logs']["logs"].keys(): - bot.memory['SpiceBot_Logs']["logs"][logtype] = [] - - bot.memory['SpiceBot_Logs']["logs"][logtype].append(logentry) - if len(bot.memory['SpiceBot_Logs']["logs"][logtype]) > 10: - del bot.memory['SpiceBot_Logs']["logs"][logtype][0] - - """ Time """ @@ -291,38 +270,6 @@ def channel_privs(bot, channel, privtype): return privlist -def join_all_channels(bot): - if bot.config.SpiceBot_Channels.joinall: - for channel in bot.memory['SpiceBot_Channels']['channels'].keys(): - if channel not in bot.channels.keys() and channel not in bot.config.SpiceBot_Channels.chanignore: - bot.write(('JOIN', bot.nick, bot.memory['SpiceBot_Channels']['channels'][channel]['name'])) - if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin: - bot.write(('SAJOIN', bot.nick, bot.memory['SpiceBot_Channels']['channels'][channel]['name'])) - - -def chanadmin_all_channels(bot): - # Chan ADMIN +a - for channel in bot.channels.keys(): - if channel not in bot.config.SpiceBot_Channels.chanignore: - if bot.config.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) - - -def channel_list_current(bot): - newlist = [item for item in bot.channels.keys() if item.lower() not in bot.memory['SpiceBot_Channels']['channels']] - for channel in newlist: - topic = bot.channels[channel].topic - bot.memory['SpiceBot_Channels']['channels'][str(channel).lower()] = dict() - bot.memory['SpiceBot_Channels']['channels'][str(channel).lower()]['name'] = str(channel) - bot.memory['SpiceBot_Channels']['channels'][str(channel).lower()]['topic'] = topic_compile(topic) - - if "*" in bot.memory['SpiceBot_Channels']: - bot.memory['SpiceBot_Channels'].remove("*") - - """Environment Functions""" @@ -358,7 +305,7 @@ def spicebot_update(bot, deps=False): if not os.path.exists(clonepath) or not os.path.isdir(clonepath): os.system(clonepath) - bot_logging(bot, 'SpiceBot_Update', "Cloning to " + clonepath, True) + botlogs.log('SpiceBot_Update', "Cloning to " + clonepath, True) clone_repository(str(bot.config.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=bot.config.SpiceBot_Update.gitbranch) @@ -369,12 +316,12 @@ def spicebot_update(bot, deps=False): # pipcommand += " git+" + str(bot.config.SpiceBot_Update.gitrepo) + "@" + str(bot.config.SpiceBot_Update.gitbranch) pipcommand += " /tmp/SpiceBot/" - bot_logging(bot, 'SpiceBot_Update', "Running `" + pipcommand + "`", True) + botlogs.log('SpiceBot_Update', "Running `" + pipcommand + "`", True) # for line in os.popen(pipcommand).read().split('\n'): - # bot_logging(bot, 'SpiceBot_Update', " " + line) + # botlogs.log('SpiceBot_Update', " " + line) os.system(pipcommand) - bot_logging(bot, 'SpiceBot_Update', "Deleting " + clonepath, True) + botlogs.log('SpiceBot_Update', "Deleting " + clonepath, True) os.system("sudo rm -r /tmp/SpiceBot") @@ -390,10 +337,10 @@ def service_manip(bot, servicename, dowhat, log_from='service_manip'): if str(dowhat) not in ["start", "stop", "restart"]: return try: - bot_logging(bot, log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.") + botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.") os.system("sudo service " + str(servicename) + " " + str(dowhat)) except Exception as e: - bot_logging(bot, log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e)) + botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e)) """Config Reading Functions""" @@ -425,7 +372,7 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File", except Exception as e: filereadgood = False if bot: - bot_logging(bot, log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath)) + botlogs.log(log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath)) dict_from_file = dict() # Close File inf.close() @@ -440,10 +387,10 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File", if filecount: if bot: - bot_logging(bot, log_from, 'Registered %d %s dict files,' % (filecount, configtypename)) - bot_logging(bot, log_from, '%d %s dict files failed to load' % (fileopenfail, configtypename), True) + 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) else: if bot: - bot_logging(bot, log_from, "Warning: Couldn't load any %s dict files" % (configtypename)) + botlogs.log(log_from, "Warning: Couldn't load any %s dict files" % (configtypename)) return configs_dict diff --git a/sopel_modules/SpiceBot_SopelPatches/Patches.py b/sopel_modules/SpiceBot_SopelPatches/Patches.py index ee7fc20..0aa3cc8 100644 --- a/sopel_modules/SpiceBot_SopelPatches/Patches.py +++ b/sopel_modules/SpiceBot_SopelPatches/Patches.py @@ -6,16 +6,15 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel import sopel.module -from sopel_modules.SpiceBot_SBTools import bot_logging, stock_modules_begone - -import os +from sopel_modules.SpiceBot.Logs import botlogs +from sopel_modules.SpiceBot_SBTools import stock_modules_begone def setup(bot): - bot_logging(bot, 'Sopel_Patch', "Patching Sopels built-in url_callbacks") + botlogs.log('Sopel_Patch', "Patching Sopels built-in url_callbacks") if 'url_callbacks' not in bot.memory: bot.memory['url_callbacks'] = sopel.tools.SopelMemory() - bot_logging(bot, 'Sopel_Patch', "Removing Stock Modules and verifying Dummy Command is present.") + botlogs.log('Sopel_Patch', "Removing Stock Modules and verifying Dummy Command is present.") stock_modules_begone(bot) diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py index fd5b640..bd9dd6f 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py @@ -4,19 +4,13 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module -from sopel_modules.SpiceBot_Events.System import bot_events_recieved, bot_events_startup_register, botevents -from sopel_modules.SpiceBot_SBTools import bot_logging +from sopel_modules.SpiceBot.Logs import botlogs +from sopel_modules.SpiceBot.Events import botevents def setup(bot): - bot_logging(bot, 'SpiceBot_StartupMonologue', "Starting setup procedure") - bot_events_startup_register(bot, [botevents.BOT_STARTUPMONOLOGUE_CHANNELS, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY, botevents.BOT_STARTUPMONOLOGUE_CONNECTED]) + 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'] = [] - - -@sopel.module.event(botevents.BOT_STARTUPMONOLOGUE, botevents.BOT_STARTUPMONOLOGUE_CHANNELS, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY, botevents.BOT_STARTUPMONOLOGUE_CONNECTED) -@sopel.module.rule('.*') -def bot_events_setup(bot, trigger): - bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py deleted file mode 100644 index 77e15f5..0000000 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py +++ /dev/null @@ -1,68 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -from sopel_modules.SpiceBot_Events.System import bot_events_recieved, bot_events_trigger, botevents -from sopel_modules.SpiceBot_SBTools import humanized_time, bot_logging - -import time - - -@sopel.module.event(botevents.BOT_CONNECTED) -@sopel.module.rule('.*') -def bot_startup_monologue_start(bot, trigger): - bot_events_recieved(bot, trigger.event) - - # Startup - bot_logging(bot, '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') - - bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CONNECTED, "SpiceBot_StartupMonologue") - - -@sopel.module.event(botevents.BOT_COMMANDSQUERY) -@sopel.module.rule('.*') -def bot_startup_monologue_commands(bot, trigger): - bot_events_recieved(bot, trigger.event) - - 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.") - bot_logging(bot, 'SpiceBot_StartupMonologue', "There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files.") - - bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY, "SpiceBot_StartupMonologue") - - -@sopel.module.event(botevents.BOT_CHANNELS) -@sopel.module.rule('.*') -def bot_startup_monologue_channels(bot, trigger): - bot_events_recieved(bot, trigger.event) - - botcount = len(bot.channels.keys()) - servercount = len(bot.memory['SpiceBot_Channels']['channels'].keys()) - bot.memory['SpiceBot_StartupMonologue'].append("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.") - - bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CHANNELS, "SpiceBot_StartupMonologue") - - -@sopel.module.event(botevents.BOT_LOADED) -@sopel.module.rule('.*') -def bot_startup_monologue_display(bot, trigger): - bot_events_recieved(bot, trigger.event) - - 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 - bot_logging(bot, 'SpiceBot_StartupMonologue', bot.nick + " startup complete") - bot.memory['SpiceBot_StartupMonologue'].insert(0, " startup complete") - - bot.osd(bot.memory['SpiceBot_StartupMonologue'], bot.channels.keys(), 'ACTION') - - bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE, "SpiceBot_StartupMonologue") - bot_logging(bot, 'SpiceBot_StartupMonologue', "Startup Monologue has been issued to all channels.", True) diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py new file mode 100644 index 0000000..b8254be --- /dev/null +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Channels.py @@ -0,0 +1,21 @@ +# 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 new file mode 100644 index 0000000..3cae22e --- /dev/null +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Commands.py @@ -0,0 +1,23 @@ +# 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 new file mode 100644 index 0000000..e829d82 --- /dev/null +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Connected.py @@ -0,0 +1,19 @@ +# 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_Logs/ErrorDisplay.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py similarity index 64% rename from sopel_modules/SpiceBot_Logs/ErrorDisplay.py rename to sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py index 1a18456..d075cff 100644 --- a/sopel_modules/SpiceBot_Logs/ErrorDisplay.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Errors.py @@ -1,20 +1,17 @@ # coding=utf-8 - from __future__ import unicode_literals, absolute_import, division, print_function import sopel.module -from sopel_modules.SpiceBot_Events.System import bot_events_recieved, botevents -from sopel_modules.SpiceBot_SBTools import bot_logging -from .Logs import stdio_logs_fetch +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): - bot_events_recieved(bot, trigger.event) - debuglines = stdio_logs_fetch(bot) + debuglines = botlogs.stdio_logs_fetch(bot) searchphrasefound = [] for line in debuglines: @@ -23,9 +20,9 @@ def bot_startup_monologue_start(bot, trigger): if len(searchphrasefound): for foundphase in searchphrasefound: - bot_logging(bot, 'SpiceBot_Logs', str(foundphase)) + 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: - bot_logging(bot, 'SpiceBot_Logs', "No issues found at bot startup!", True) + 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 new file mode 100644 index 0000000..a5ab12b --- /dev/null +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display_Loaded.py @@ -0,0 +1,29 @@ +# 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 index abf0a53..8ab7cf1 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/__init__.py +++ b/sopel_modules/SpiceBot_StartupMonologue/__init__.py @@ -6,7 +6,11 @@ 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 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' diff --git a/sopel_modules/SpiceBot_Update/Update.py b/sopel_modules/SpiceBot_Update/Update.py index 6d58141..d00464d 100644 --- a/sopel_modules/SpiceBot_Update/Update.py +++ b/sopel_modules/SpiceBot_Update/Update.py @@ -8,7 +8,8 @@ from sopel.config.types import StaticSection, ValidatedAttribute import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, bot_logging, spicebot_reload, spicebot_update +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): @@ -23,7 +24,7 @@ def configure(config): def setup(bot): - bot_logging(bot, 'SpiceBot_Update', "Initial Setup processing") + botlogs.log('SpiceBot_Update', "Initial Setup processing") bot.config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False) @@ -48,7 +49,7 @@ def nickname_comand_update(bot, trigger): triggerargs = spicemanip.main(triggerargs, '2+', 'list') quitmessage = "Received command from " + trigger.nick + " to update from Github and restart" - bot_logging(bot, 'SpiceBot_Update', quitmessage) + botlogs.log('SpiceBot_Update', quitmessage) bot.osd(quitmessage, bot.channels.keys()) if commandused == 'nodeps': diff --git a/sopel_modules/SpiceBot_Uptime/Uptime.py b/sopel_modules/SpiceBot_Uptime/Uptime.py index 2dbaf32..3af0b71 100644 --- a/sopel_modules/SpiceBot_Uptime/Uptime.py +++ b/sopel_modules/SpiceBot_Uptime/Uptime.py @@ -6,15 +6,14 @@ import sopel.module import time +from sopel_modules.SpiceBot.Logs import botlogs from sopel_modules.SpiceBot_SBTools import humanized_time -from sopel_modules.SpiceBot_SBTools import bot_logging - def setup(bot): if 'SpiceBot_Uptime' not in bot.memory: now = time.time() - bot_logging(bot, 'SpiceBot_Uptime', "Start time set to " + str(time.time())) + botlogs.log('SpiceBot_Uptime', "Start time set to " + str(time.time())) bot.memory["SpiceBot_Uptime"] = now diff --git a/sopel_modules/SpiceBot_osd/__init__.py b/sopel_modules/SpiceBot_osd/__init__.py index 7bd3142..91fa5a3 100644 --- a/sopel_modules/SpiceBot_osd/__init__.py +++ b/sopel_modules/SpiceBot_osd/__init__.py @@ -14,7 +14,7 @@ from sopel import tools, module from sopel.tools import Identifier from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot_SBTools import bot_logging +from sopel_modules.SpiceBot.Logs import botlogs import time from collections import abc @@ -27,15 +27,19 @@ __version__ = '0.1.2' def configure(config): - config.define_section("MAXTARGCONFIG", MAXTARGCONFIG, validate=False) - config.MAXTARGCONFIG.configure_setting('notice', 'MAXTARG limit for NOTICE') - config.MAXTARGCONFIG.configure_setting('privmsg', 'MAXTARG limit for PRIVMSG') + 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 - bot_logging(bot, 'SpiceBot_OSD', "Implanting OSD function into bot") + 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 @@ -43,7 +47,7 @@ def setup(bot): tools.get_message_recipientgroups = ToolsOSD.get_message_recipientgroups # overwrite default bot messaging - bot_logging(bot, 'SpiceBot_OSD', "Overwrite Default Sopel messaging commands") + botlogs.log('SpiceBot_OSD', "Overwrite Default Sopel messaging commands") bot.osd = SopelOSD.osd bot.say = SopelOSD.say bot.action = SopelOSD.action @@ -56,8 +60,8 @@ def setup(bot): sopel.bot.SopelWrapper.reply = SopelWrapperOSD.reply # verify config settings for server - bot_logging(bot, 'SpiceBot_OSD', "Checking for config settings") - bot.config.define_section("MAXTARGCONFIG", MAXTARGCONFIG, validate=False) + botlogs.log('SpiceBot_OSD', "Checking for config settings") + bot.config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False) @module.event('005') @@ -80,15 +84,29 @@ def parse_event_005(bot, trigger): value = None if value: if settingname.upper() == 'NOTICE': - bot.config.MAXTARGCONFIG.notice = int(value) + bot.config.SpiceBot_OSD.notice = int(value) elif settingname.upper() == 'PRIVMSG': - bot.config.MAXTARGCONFIG.privmsg = int(value) + bot.config.SpiceBot_OSD.privmsg = int(value) -class MAXTARGCONFIG(StaticSection): +class SpiceBot_OSD(StaticSection): + + """MAXTARG""" notice = ValidatedAttribute('notice', default=1) privmsg = ValidatedAttribute('privmsg', default=1) + flood_burst_lines = ValidatedAttribute('flood_burst_lines', int, default=4) + """How many messages can be sent in burst mode.""" + + flood_empty_wait = ValidatedAttribute('flood_empty_wait', float, default=0.7) + """How long to wait between sending messages when not in burst mode, in seconds.""" + + 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.""" + class ToolsOSD: @@ -117,9 +135,9 @@ class ToolsOSD: raise ValueError("Recipients list empty.") if text_method == 'NOTICE': - maxtargets = bot.config.MAXTARGCONFIG.notice + maxtargets = bot.config.SpiceBot_OSD.notice elif text_method in ['PRIVMSG', 'ACTION']: - maxtargets = bot.config.MAXTARGCONFIG.privmsg + maxtargets = bot.config.SpiceBot_OSD.privmsg maxtargets = int(maxtargets) recipientgroups = [] @@ -259,17 +277,12 @@ class SopelOSD: for recipientgroup in recipientgroups: text_method = text_method_orig - # No messages within the last 3 seconds? Go ahead! - # Otherwise, wait so it's been at least 0.8 seconds + penalty - recipient_id = Identifier(recipientgroup) recipient_stack = self.stack.setdefault(recipient_id, { 'messages': [], - 'flood_left': 4, + 'flood_left': self.config.SpiceBot_OSD.flood_burst_lines, 'dots': 0, - # TODO - # 'flood_left': self.config.core.flood_burst_lines, }) recipient_stack['dots'] = 0 @@ -281,32 +294,30 @@ class SopelOSD: if not recipient_stack['flood_left']: elapsed = time.time() - recipient_stack['messages'][-1][0] - # TODO - # recipient_stack['flood_left'] = min( - # self.config.core.flood_burst_lines, - # int(elapsed) * self.config.core.flood_refill_rate) - recipient_stack['flood_left'] = min(4, int(elapsed) * 1) + recipient_stack['flood_left'] = min( + self.config.SpiceBot_OSD.flood_burst_lines, + int(elapsed) * self.config.SpiceBot_OSD.flood_refill_rate) if not recipient_stack['flood_left']: elapsed = time.time() - recipient_stack['messages'][-1][0] penalty = float(max(0, len(text) - 50)) / 70 # Never wait more than 2 seconds - # wait = min(self.config.core.flood_empty_wait + penalty, 2) # TODO - wait = min(0.7 + penalty, 2) + wait = min(self.config.SpiceBot_OSD.flood_empty_wait + penalty, 2) if elapsed < wait: time.sleep(wait - elapsed) # Loop detection messages = [m[1] for m in recipient_stack['messages'][-8:]] - # If what we about to send repeated at least 5 times in the - # last 2 minutes, replace with '...' - if messages.count(text) >= 5 and elapsed < 120: - recipient_stack['dots'] += 1 - else: - recipient_stack['dots'] = 0 + if self.config.SpiceBot_OSD.flood_dots: + # If what we about to send repeated at least 5 times in the + # last 2 minutes, replace with '...' + if messages.count(text) >= 5 and elapsed < 120: + recipient_stack['dots'] += 1 + else: + recipient_stack['dots'] = 0 - if not recipient_stack['dots'] >= 3: + if recipient_stack['dots'] <= 3: recipient_stack['flood_left'] = max(0, recipient_stack['flood_left'] - 1) recipient_stack['messages'].append((time.time(), self.safe(text))) @@ -377,7 +388,10 @@ class SopelOSD: self.osd(text, dest, 'PRIVMSG', max_messages) def msg(self, recipient, text, max_messages=1): - # Deprecated, but way too much of a pain to remove. + """ + .. deprecated:: 6.0 + Use :meth:`say` instead. Will be removed in Sopel 8. + """ self.osd(text, recipient, 'PRIVMSG', max_messages) @@ -392,19 +406,16 @@ class SopelWrapperOSD(object): if destination is None: destination = self._trigger.sender self._bot.osd(self, message, destination, 'PRIVMSG', 1) - # self._bot.say(message, destination, max_messages) 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) - # self._bot.action(message, destination, max_messages) 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) - # self._bot.notice(message, destination, max_messages) def reply(self, message, destination=None, reply_to=None, notice=False, max_messages=1): if destination is None: @@ -416,4 +427,3 @@ class SopelWrapperOSD(object): self._bot.osd(self, message, destination, 'NOTICE', 1) else: self._bot.osd(self, message, destination, 'PRIVMSG', 1) - # self._bot.reply(message, destination, reply_to, notice, max_messages)