diff --git a/sopel_modules/SpiceBot/AI.py b/sopel_modules/SpiceBot/AI.py index dd6da2d..3e6b6a2 100644 --- a/sopel_modules/SpiceBot/AI.py +++ b/sopel_modules/SpiceBot/AI.py @@ -14,6 +14,7 @@ import aiml from .Database import db as botdb from .Config import config as botconfig from .Read import read as botread +from .Users import users as botusers from sopel_modules.spicemanip import spicemanip @@ -116,7 +117,7 @@ class SpiceBot_AI(): def on_message(self, bot, trigger, message): nick = Identifier(trigger.nick) - nick_id = botdb.get_nick_id(nick, create=True) + nick_id = botusers.get_nick_id(nick, True) self.check_user_import(nick, nick_id) message = self.bot_message_precipher(bot, trigger, message) @@ -207,13 +208,13 @@ class SpiceBot_AI(): def getPredicate(self, predicate, nick, nick_id=None): if not nick_id: nick = Identifier(nick) - nick_id = botdb.get_nick_id(nick, create=True) + nick_id = botusers.get_nick_id(nick, True) self.aiml_kernel.getPredicate(predicate, nick_id) def check_user_import(self, nick, nick_id=None): if not nick_id: nick = Identifier(nick) - nick_id = botdb.get_nick_id(nick, create=True) + nick_id = botusers.get_nick_id(nick, True) if nick_id not in list(self.dict["sessioncache"].keys()): self.dict["sessioncache"][nick_id] = botdb.get_nick_value(nick, 'botai') or {} for predicate in list(self.dict["sessioncache"][nick_id].keys()): @@ -228,7 +229,7 @@ class SpiceBot_AI(): def save_nick_session(self, nick, nick_id=None): if not nick_id: nick = Identifier(nick) - nick_id = botdb.get_nick_id(nick, create=True) + nick_id = botusers.get_nick_id(nick, True) sessionData = self.aiml_kernel.getSessionData(nick_id) botdb.set_nick_value(nick, 'botai', sessionData) diff --git a/sopel_modules/SpiceBot/Channels.py b/sopel_modules/SpiceBot/Channels.py index 160cd25..76429a2 100644 --- a/sopel_modules/SpiceBot/Channels.py +++ b/sopel_modules/SpiceBot/Channels.py @@ -21,44 +21,76 @@ class SpiceBot_Channels_MainSection(StaticSection): operadmin = ValidatedAttribute('operadmin', default=False) chanignore = ListAttribute('chanignore') +# replace process lock with uuid list system + class BotChannels(): """This Logs all channels known to the server""" def __init__(self): + + # bot config setup self.setup_channels() - self.who_reqs = {} + + # Locking self.lock = threading.Lock() self.channel_lock = False - self.channels = [] - self.dict = { - "list": {}, - "InitialProcess": False - } - def __getattr__(self, name): - ''' will only get called for undefined attributes ''' - """We will try to find a dict value, or return None""" - if name.lower() in list(self.dict.keys()): - return self.dict[str(name).lower()] + # list of channels + self.chandict = {} + + # list of uuids to process + self.server_recieved = [] + + # initial process + self.InitialProcess = False + + self.who_reqs = {} + + def total_channels(self): + totalcount = len(list(self.chandict.keys())) + return totalcount + + def total_bot_channels(self): + totalcount = 0 + for channel in list(self.chandict.keys()): + if self.chandict[channel]["joined"]: + totalcount += 1 + return totalcount + + def chanlist(self): + return list(self.chandict.keys()) + + def chanlist_bot(self): + chanlist_return = [] + for channel in list(self.chandict.keys()): + if self.chandict[channel]["joined"]: + chanlist_return.append(channel) + return chanlist_return + + def ischannel(self, channel): + + # channel names case-sensitivity should never be an issue + channel = str(channel).lower() + + if channel in list(self.chandict.keys()): + return True else: - raise Exception('Channel dict does not contain a function or key ' + str(name.lower())) + return False - def get_channel_users(self, channel, idtype="nick"): + def get_channel_users(self, channel): - if channel.lower() not in list(self.dict["list"].keys()): - raise Exception('Channel ' + str(channel.lower()) + " does not seem to be on this server") - if 'users' not in list(self.dict["list"][channel.lower()].keys()) or not self.check_channel_bot(channel): - raise Exception('Channel ' + str(channel.lower()) + " does not seem to be a channel the bot is in") + # channel names case-sensitivity should never be an issue + channel = str(channel).lower() - nick_ids = self.dict["list"][channel.lower()]['users'] - if idtype.upper() == "ID": - return nick_ids - else: - nick_list = [] - for nick_id in nick_ids: - nickname = botusers.ID(nick_id) - nick_list.append(nickname) - return nick_list + # channel not on server + if channel not in list(self.chandict.keys()): + raise Exception('Channel ' + str(channel) + " does not seem to be on this server") + + # bot is not in channel + if not self.chandict[channel]["joined"]: + raise Exception('Channel ' + str(channel) + " does not seem to be a channel the bot is in") + + return self.chandict[channel]["users"] def setup_channels(self): botconfig.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) @@ -70,125 +102,169 @@ class BotChannels(): self.channel_lock = True def channel_list_recieve_input(self, trigger): - self.lock.acquire() + + # parse info channel, _, topic = trigger.args[1:] - if channel.lower() not in list(self.dict['list'].keys()): - self.dict['list'][channel.lower()] = dict() - self.dict['list'][channel.lower()]['name'] = channel - self.dict['list'][channel.lower()]['topic'] = self.topic_compile(topic) + + # check channel existance + if channel not in list(self.chandict.keys()): + self.channeldict_append(channel) + + self.lock.acquire() + + # get proper name of channel + self.chandict[channel.lower()]['name'] = channel + self.chandict[channel.lower()]['topic'] = self.topic_compile(topic) self.channel_lock = True self.lock.release() def channel_list_recieve_finish(self): self.lock.acquire() - if not self.dict['InitialProcess']: - self.dict['InitialProcess'] = True - self.lock.release() + if not self.InitialProcess: + self.InitialProcess = True self.channel_lock = False + self.lock.release() def topic_compile(self, topic): actual_topic = re.compile(r'^\[\+[a-zA-Z]+\] (.*)') topic = re.sub(actual_topic, r'\1', topic) + if topic.isspace(): + topic = None return topic - def add_channel(self, channel): + def channeldict_append(self, channel): + + # channel names case-sensitivity should never be an issue channel = str(channel).lower() + + # create basic components of the channel dict self.lock.acquire() - if channel not in self.channels: - self.channels.append(channel) + if channel not in list(self.chandict.keys()): + self.chandict[channel] = { + "name": channel, + "topic": None, + "joined": False, + "reason": "appended", + "users": [], + } self.lock.release() - def remove_channel(self, channel): + def add_channel(self, channel, reason=None): + + # channel names case-sensitivity should never be an issue channel = str(channel).lower() + + # check channel existance + if channel not in list(self.chandict.keys()): + self.channeldict_append(channel) + self.lock.acquire() - if channel in self.channels: - self.channels.remove(channel) + self.chandict[channel]["joined"] = True + if reason != "check": + self.chandict[channel]["reason"] = reason + self.lock.release() + + def remove_channel(self, channel, reason=None): + + # channel names case-sensitivity should never be an issue + channel = str(channel).lower() + + # check channel existance + if channel not in list(self.chandict.keys()): + self.channeldict_append(channel) + + self.lock.acquire() + self.chandict[channel]["joined"] = False + if reason != "check": + self.chandict[channel]["reason"] = reason self.lock.release() def bot_part_empty(self, bot): """Don't stay in empty channels""" - ignorepartlist = [] + ignorepartlist = [] # TODO add bot.config channels to ignore if bot.config.core.logging_channel: ignorepartlist.append(bot.config.core.logging_channel) for channel in list(bot.channels.keys()): - if len(list(bot.channels[channel].privileges.keys())) == 1 and channel not in ignorepartlist and channel.startswith("#"): - bot.part(channel, "Leaving Empty Channel") - if channel.lower() in self.dict['list']: - self.lock.acquire() - del self.dict['list'][channel.lower()] - self.lock.release() - self.remove_channel(channel) + if channel.startswith("#") and channel not in ignorepartlist: + if len(list(bot.channels[channel].privileges.keys())) == 1: + bot.part(channel, "Leaving Empty Channel") + if channel.lower() in list(self.chandict.keys()): + self.lock.acquire() + self.chandict[channel]["joined"] = False + self.chandict[channel]["reason"] = "empty_chan_part" + self.lock.release() + self.remove_channel(channel) def join_all_channels(self, bot): if botconfig.SpiceBot_Channels.joinall: - for channel in list(self.dict['list'].keys()): - if channel.startswith("#"): - if channel not in list(bot.channels.keys()) and channel not in botconfig.SpiceBot_Channels.chanignore: - bot.write(('JOIN', bot.nick, self.dict['list'][channel]['name'])) - if channel not in list(bot.channels.keys()) and botconfig.SpiceBot_Channels.operadmin: - bot.write(('SAJOIN', bot.nick, self.dict['list'][channel]['name'])) + for channel in list(self.chandict.keys()): + if channel.startswith("#") and channel not in botconfig.SpiceBot_Channels.chanignore: + if channel.lower() not in [chan.lower() for chan in list(bot.channels.keys())]: + self.bot_join(bot, channel) + if channel.lower() not in [chan.lower() for chan in list(bot.channels.keys())]: + self.bot_sajoin(bot, channel) - if channel in list(bot.channels.keys()): - self.add_channel(channel) + def bot_join(self, bot, channel): + bot.write(('JOIN', bot.nick, channel)) - def chanadmin_all_channels(self, bot): + def bot_sajoin(self, bot, channel): + if botconfig.SpiceBot_Channels.operadmin: + bot.write(('SAJOIN', bot.nick, channel)) + + def chanadmin_channel(self, bot, channel): # Chan ADMIN +a - for channel in list(bot.channels.keys()): - if channel.startswith("#"): - self.add_channel(channel) - if channel not in botconfig.SpiceBot_Channels.chanignore: - if botconfig.SpiceBot_Channels.operadmin: - if not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN: - bot.write(('SAMODE', channel, "+a", bot.nick)) - else: - bot.part(channel) - - if channel not in list(bot.channels.keys()): - self.remove_channel(channel) + if botconfig.SpiceBot_Channels.operadmin: + if not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN: + bot.write(('SAMODE', channel, "+a", bot.nick)) def whois_ident(self, nick): nick = Identifier(nick) - nick_id = botdb.db.get_nick_id(nick, create=True) + nick_id = botusers.get_nick_id(nick, True) return nick_id def add_to_channel(self, channel, nick, nick_id=None): + + # channel names case-sensitivity should never be an issue channel = str(channel).lower() + + # Verify Channel is in list + if channel not in list(self.chandict.keys()): + self.add_channel(channel, "error_handling") + self.lock.acquire() if not nick_id: nick_id = self.whois_ident(nick) - if channel.lower() not in list(self.dict['list'].keys()): - self.dict['list'][channel.lower()] = dict() - if 'users' not in self.dict['list'][channel.lower()]: - self.dict['list'][channel.lower()]['users'] = [] - if int(nick_id) not in self.dict['list'][channel.lower()]['users']: - self.dict['list'][channel.lower()]['users'].append(int(nick_id)) - if channel.lower() not in self.channels: - self.channels.append(channel.lower()) + if int(nick_id) not in self.chandict[channel]["users"]: + self.chandict[channel]["users"].append(int(nick_id)) self.lock.release() def remove_from_channel(self, channel, nick, nick_id=None): + + # channel names case-sensitivity should never be an issue channel = str(channel).lower() + + # Verify Channel is in list + if channel not in list(self.chandict.keys()): + self.add_channel(channel, "error_handling") + self.lock.acquire() if not nick_id: nick_id = self.whois_ident(nick) - if channel.lower() not in list(self.dict['list'].keys()): - self.dict['list'][channel.lower()] = dict() - if 'users' not in self.dict['list'][channel.lower()]: - self.dict['list'][channel.lower()]['users'] = [] - if int(nick_id) in self.dict['list'][channel.lower()]['users']: - self.dict['list'][channel.lower()]['users'].remove(int(nick_id)) + if int(nick_id) in self.chandict[channel.lower()]['users']: + self.chandict[channel.lower()]['users'].remove(int(nick_id)) self.lock.release() def remove_all_from_channel(self, channel): + + # channel names case-sensitivity should never be an issue channel = str(channel).lower() + + # Verify Channel is in list + if channel not in list(self.chandict.keys()): + self.add_channel(channel, "error_handling") + self.lock.acquire() - if channel.lower() not in list(self.dict['list'].keys()): - self.dict['list'][channel.lower()] = dict() - if 'users' not in self.dict['list'][channel.lower()]: - self.dict['list'][channel.lower()]['users'] = [] - self.dict['list'][channel.lower()]['users'] = [] - if channel.lower() in self.channels: - self.channels.remove(channel.lower()) + self.chandict[channel.lower()]['users'] = [] self.lock.release() def channel_scan(self, bot): @@ -199,6 +275,7 @@ class BotChannels(): def join(self, bot, trigger): # bot block if trigger.nick == bot.nick: + self.chanadmin_channel(bot, trigger.sender) for user in list(bot.channels[trigger.sender].privileges.keys()): self.add_to_channel(trigger.sender, user) return @@ -211,6 +288,10 @@ class BotChannels(): # bot block if trigger.nick == bot.nick: self.remove_all_from_channel(trigger.sender) + self.lock.acquire() + self.chandict[trigger.sender]["joined"] = False + self.chandict[trigger.sender]["reason"] = "quit" + self.lock.release() return # Identify nick_id = self.whois_ident(trigger.nick) @@ -221,6 +302,10 @@ class BotChannels(): # bot block if trigger.nick == bot.nick: self.remove_all_from_channel(trigger.sender) + self.lock.acquire() + self.chandict[trigger.sender]["joined"] = False + self.chandict[trigger.sender]["reason"] = "bot_part" + self.lock.release() return # Identify nick_id = self.whois_ident(trigger.nick) @@ -232,6 +317,10 @@ class BotChannels(): # bot block if targetnick == bot.nick: self.remove_all_from_channel(trigger.sender) + self.lock.acquire() + self.chandict[trigger.sender]["joined"] = False + self.chandict[trigger.sender]["reason"] = "kicked" + self.lock.release() return # Identify nick_id = self.whois_ident(targetnick) @@ -263,7 +352,7 @@ class BotChannels(): if not channels: return channel = Identifier(channels.group(1)) - self.add_channel(channel) + self.add_channel(channel, " check") mapping = {'+': sopel.module.VOICE, '%': sopel.module.HALFOP, @@ -287,9 +376,9 @@ class BotChannels(): self.add_to_channel(channel, nick) def check_channel_bot(self, channel, allchan=False): - if str(channel).lower() in self.channels: + if str(channel).lower() in self.chanlist_bot(): return True - elif allchan and str(channel).lower() in list(self.dict['list'].keys()): + elif allchan and str(channel).lower() in self.chanlist(): return True else: return False diff --git a/sopel_modules/SpiceBot/HTTP_Codes.py b/sopel_modules/SpiceBot/HTTP_Codes.py new file mode 100644 index 0000000..69cfd0f --- /dev/null +++ b/sopel_modules/SpiceBot/HTTP_Codes.py @@ -0,0 +1,80 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function +""" +This is the SpiceBot HTTP Codes system. +""" + +import re +import requests +from lxml import html + + +class Bothttpcodes(): + + def __init__(self): + self.api_url = 'https://httpstatuses.com/' + self.basic_xpath = "/html/body/article/h1[1]/text()" + self.explain_xpath = "/html/body/article/p[1]/text()" + + def fetch_result(self, query): + returndict = { + "basic": "", + "explanation": "", + } + if not re.match('^[1-5]\d{2}$', query): + returndict["basic"] = "Invalid HTTP status code:" + returndict["explanation"] = str(query) + return returndict + + url = self.api_url + query + try: + r = requests.get(url=url, timeout=(10.0, 4.0)) + except requests.exceptions.ConnectTimeout: + returndict["basic"] = "Connection timed out." + return returndict + except requests.exceptions.ConnectionError: + returndict["basic"] = "Couldn't connect to server." + return returndict + except requests.exceptions.ReadTimeout: + returndict["basic"] = "Server took too long to send data." + return returndict + if r.status_code == 404: + returndict["basic"] = "Unknown HTTP status code:" + returndict["explanation"] = str(query) + return returndict + try: + r.raise_for_status() + except requests.exceptions.HTTPError as e: + returndict["basic"] = "HTTP error:" + returndict["explanation"] = str(e.message) + return returndict + + tree = html.fromstring(r.content) + try: + title = tree.xpath((self.basic_xpath)) + if isinstance(title, list): + title = title[0] + except Exception as e: + title = None + if title: + returndict["basic"] = str(title) + else: + returndict["basic"] = "An Error Occured:" + returndict["explanation"] = "Xpath for basic yeilded no information" + return returndict + + try: + explanation = tree.xpath((self.explain_xpath)) + if isinstance(explanation, list): + explanation = explanation[0] + except Exception as e: + explanation = None + if explanation: + returndict["explanation"] = str(explanation) + else: + returndict["explanation"] = "Xpath for explanation yeilded no information" + + return returndict + + +httpcodes = Bothttpcodes() diff --git a/sopel_modules/SpiceBot/Prerun.py b/sopel_modules/SpiceBot/Prerun.py index 7a5e5c7..305c443 100644 --- a/sopel_modules/SpiceBot/Prerun.py +++ b/sopel_modules/SpiceBot/Prerun.py @@ -212,7 +212,7 @@ def verify_user(bot, trigger): def verify_channel(trigger): - botchannels.add_channel(trigger.sender) + botchannels.add_channel(trigger.sender, "check") # Identify nick_id = botchannels.whois_ident(trigger.nick) # Verify nick is in the channel list diff --git a/sopel_modules/SpiceBot/Users.py b/sopel_modules/SpiceBot/Users.py index 4ccf102..1f8008a 100644 --- a/sopel_modules/SpiceBot/Users.py +++ b/sopel_modules/SpiceBot/Users.py @@ -65,10 +65,19 @@ class BotUsers(): nick_id = self.whois_ident(nickinput) return int(nick_id) + def get_nick_id(self, nick, usercreate=True): + try: + nick_id = botdb.db.get_nick_id(nick, create=usercreate) + except Exception as e: + nick_id = e + nick_id = None + return None + return nick_id + def whois_ident(self, nick, usercreate=True): nick = Identifier(nick) try: - nick_id = botdb.db.get_nick_id(nick, create=usercreate) + nick_id = self.get_nick_id(nick, usercreate) except Exception as e: nick_id = e nick_id = None @@ -267,6 +276,7 @@ class BotUsers(): def nick(self, bot, trigger): oldnick = trigger.nick old_nick_id = self.whois_ident(oldnick) + self.whois_identify_forget(old_nick_id) newnick = Identifier(trigger) if oldnick == bot.nick or newnick == bot.nick: return @@ -283,11 +293,11 @@ class BotUsers(): # mark user as online self.mark_user_online(old_nick_id) # alias the nick - try: - botdb.alias_nick(oldnick, newnick) - except Exception as e: - old_nick_id = e - return + # try: + # botdb.alias_nick(oldnick, newnick) + # except Exception as e: + # old_nick_id = e + # return def mode(self, bot, trigger): return diff --git a/sopel_modules/SpiceBot/Version.py b/sopel_modules/SpiceBot/Version.py index ad308de..a6c4a0b 100644 --- a/sopel_modules/SpiceBot/Version.py +++ b/sopel_modules/SpiceBot/Version.py @@ -1,7 +1,7 @@ # coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function """ -This is the SpiceBot Update system. +This is the SpiceBot Version system. """ import sopel diff --git a/sopel_modules/SpiceBot/__init__.py b/sopel_modules/SpiceBot/__init__.py index 90f1629..556fa86 100644 --- a/sopel_modules/SpiceBot/__init__.py +++ b/sopel_modules/SpiceBot/__init__.py @@ -40,6 +40,7 @@ from .Translate import * from .Version import * from .RegNicks import * from .ReleaseNotes import * +from .HTTP_Codes import * __author__ = 'Sam Zick' diff --git a/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/Core.txt b/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/Core.txt index 641d73a..c7ae173 100644 --- a/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/Core.txt +++ b/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/Core.txt @@ -1,2 +1,3 @@ First release of Release Notes OSD updated to more accurately reflect IRC 512 byte limit +Channel Class cleaned up diff --git a/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/HTTP_Codes.txt b/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/HTTP_Codes.txt new file mode 100644 index 0000000..c6ba1d6 --- /dev/null +++ b/sopel_modules/SpiceBot_Configs/SpiceBot_Release_Notes/HTTP_Codes.txt @@ -0,0 +1,2 @@ +Added Tool to check HTTP code meanings, accessible via `.httpcodes` command +Migrated Functionality into a SpiceBot class for other tools to use diff --git a/sopel_modules/SpiceBot_Core_Commands/Channels.py b/sopel_modules/SpiceBot_Core_Commands/Channels.py index 83cd269..ccd3d9b 100644 --- a/sopel_modules/SpiceBot_Core_Commands/Channels.py +++ b/sopel_modules/SpiceBot_Core_Commands/Channels.py @@ -22,23 +22,23 @@ def nickname_comand_channels(bot, trigger, botcom): botcom.dict['args'] = spicemanip(botcom.dict['args'], '2+', 'list') if commandused == 'list': - botcount = len(list(bot.channels.keys())) - servercount = len(list(SpiceBot.channels.dict['list'].keys())) + botcount = SpiceBot.channels.total_bot_channels() + servercount = SpiceBot.channels.total_channels() displayval = "I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server." - chanlist = spicemanip(list(bot.channels.keys()), 'andlist') + chanlist = spicemanip(SpiceBot.channels.chanlist_bot(), 'andlist') bot.osd([displayval, "You can find me in " + chanlist]) return elif commandused == 'total': - botcount = len(list(bot.channels.keys())) - servercount = len(list(SpiceBot.channels.dict['list'].keys())) + botcount = SpiceBot.channels.total_bot_channels() + servercount = SpiceBot.channels.total_channels() bot.osd("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.") return elif commandused == 'random': - channel = spicemanip(SpiceBot.channels.dict['list'], 'random') - topic = SpiceBot.channels.dict['list'][channel]['topic'] - msg = ["Random channel for you: {}.".format(SpiceBot.channels.dict['list'][channel]['name'])] + channel = spicemanip(list(SpiceBot.channels.chandict), 'random') + topic = SpiceBot.channels.chandict[channel]['topic'] + msg = ["Random channel for you: {}.".format(SpiceBot.channels.chandict[channel]['name'])] if topic and not topic.isspace(): msg.append("The topic is: {}".format(topic)) else: @@ -47,7 +47,7 @@ def nickname_comand_channels(bot, trigger, botcom): return elif commandused == 'update': - if not trigger.admin: + if not trigger.admin: # TODO SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "You do not have permission to update the channel listing.") return SpiceBot.channels.bot_part_empty(bot) @@ -56,7 +56,7 @@ def nickname_comand_channels(bot, trigger, botcom): while SpiceBot.channels.channel_lock: pass SpiceBot.channels.join_all_channels(bot) - foundchannelcount = len(list(SpiceBot.channels.dict['list'].keys())) + foundchannelcount = len(list(SpiceBot.channels.chandict.keys())) bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.") SpiceBot.channels.bot_part_empty(bot) return @@ -66,12 +66,13 @@ def nickname_comand_channels(bot, trigger, botcom): SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "Channel name input missing.") return channel = spicemanip(botcom.dict['args'], 1) - if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.dict['list'].keys())): + if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.chandict.keys())): SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "Channel name {} not valid.".format(channel)) return - topic = SpiceBot.channels.dict['list'][channel.lower()]['topic'] - channel = SpiceBot.channels.dict['list'][channel.lower()]['name'] - bot.osd("Topic for {}: {}".format(channel, topic)) + channel = str(channel).lower() + topic = SpiceBot.channels.chandict[channel]['topic'] + channelname = SpiceBot.channels.chandict[channel]['name'] + bot.osd("Topic for {}: {}".format(channelname, topic)) return if commandused.upper() in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']: @@ -83,7 +84,7 @@ def nickname_comand_channels(bot, trigger, botcom): channel = trigger.sender else: channel = spicemanip(botcom.dict['args'], 1) - if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.dict['list'].keys())): + if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.chandict.keys())): SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "Channel name {} not valid.".format(channel)) return if not SpiceBot.inlist(channel.lower(), list(bot.channels.keys())): @@ -103,7 +104,7 @@ def nickname_comand_channels(bot, trigger, botcom): # Users List if commandused == 'users': channel = spicemanip(botcom.dict['args'], 1) - if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.dict['list'].keys())): + if not SpiceBot.inlist(channel.lower(), list(SpiceBot.channels.chandict.keys())): SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "Channel name {} not valid.".format(channel)) return if not SpiceBot.inlist(channel.lower(), list(bot.channels.keys())): diff --git a/sopel_modules/SpiceBot_Core_Commands/Messaging.py b/sopel_modules/SpiceBot_Core_Commands/Messaging.py index 29e59a6..f89783b 100644 --- a/sopel_modules/SpiceBot_Core_Commands/Messaging.py +++ b/sopel_modules/SpiceBot_Core_Commands/Messaging.py @@ -42,7 +42,7 @@ def bot_command_process(bot, trigger, botcom): target = spicemanip(botcom.dict['args'], 1) if (target not in ['allchans', 'allnicks'] - and not SpiceBot.inlist(target.lower(), list(SpiceBot.channels.dict['list'].keys())) + and not SpiceBot.channels.ischannel(target) and not SpiceBot.inlist(target.lower(), bot.users)): SpiceBot.messagelog.messagelog_error(botcom.dict["log_id"], "Channel/nick name {} not valid.".format(target)) return diff --git a/sopel_modules/SpiceBot_Core_Processing/Channels.py b/sopel_modules/SpiceBot_Core_Processing/Channels.py index c82ec7e..c8f4dd6 100644 --- a/sopel_modules/SpiceBot_Core_Processing/Channels.py +++ b/sopel_modules/SpiceBot_Core_Processing/Channels.py @@ -31,21 +31,17 @@ def request_channels_list_initial(bot, trigger): starttime = time.time() # wait 60 seconds for initial population of information - while not SpiceBot.channels.dict['InitialProcess']: + while not SpiceBot.channels.InitialProcess: if time.time() - starttime >= 60: SpiceBot.logs.log('SpiceBot_Channels', "Initial Channel list populating Timed Out") - SpiceBot.channels.dict['InitialProcess'] = True + SpiceBot.channels.InitialProcess = True else: pass - foundchannelcount = len(list(SpiceBot.channels.dict['list'].keys())) + foundchannelcount = SpiceBot.channels.total_channels() SpiceBot.logs.log('SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.") SpiceBot.channels.join_all_channels(bot) - SpiceBot.channels.chanadmin_all_channels(bot) - - if "*" in SpiceBot.channels.dict['list'].keys(): - del SpiceBot.channels.dict['list']["*"] SpiceBot.channels.bot_part_empty(bot) SpiceBot.events.trigger(bot, SpiceBot.events.BOT_CHANNELS, "SpiceBot_Channels") @@ -76,13 +72,17 @@ def trigger_channel_list_recurring(bot, trigger): time.sleep(1800) SpiceBot.channels.bot_part_empty(bot) - oldlist = list(SpiceBot.channels.dict['list'].keys()) + oldlist = SpiceBot.channels.chanlist() SpiceBot.channels.channel_list_request(bot) while SpiceBot.channels.channel_lock: pass - newlist = [item.lower() for item in oldlist if item.lower() not in list(SpiceBot.channels.dict['list'].keys())] + currentlist = SpiceBot.channels.chanlist() + newlist = [] + for channel in currentlist: + if channel not in oldlist: + newlist.append(channel) if "*" in newlist: newlist.remove("*") if len(newlist) and SpiceBot.config.SpiceBot_Channels.announcenew: @@ -90,10 +90,6 @@ def trigger_channel_list_recurring(bot, trigger): SpiceBot.channels.join_all_channels(bot) - SpiceBot.channels.chanadmin_all_channels(bot) - - if "*" in list(SpiceBot.channels.dict['list'].keys()): - del SpiceBot.channels.dict['list']["*"] SpiceBot.channels.bot_part_empty(bot) diff --git a/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py b/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py index 2e50bdb..61fb9d9 100644 --- a/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py +++ b/sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py @@ -30,8 +30,8 @@ def bot_startup_monologue_sopel_version(bot, trigger): @sopel.module.event(SpiceBot.events.BOT_CHANNELS) @sopel.module.rule('.*') def bot_startup_monologue_channels(bot, trigger): - botcount = len(list(bot.channels.keys())) - servercount = len(list(SpiceBot.channels.dict['list'].keys())) + botcount = SpiceBot.channels.total_bot_channels() + servercount = SpiceBot.channels.total_channels() displayval = "I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server." SpiceBot.startupmonologue.dict["channels"] = displayval SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval) diff --git a/sopel_modules/SpiceBot_Core_Tools/HTTP_Codes.py b/sopel_modules/SpiceBot_Core_Tools/HTTP_Codes.py new file mode 100644 index 0000000..7279ada --- /dev/null +++ b/sopel_modules/SpiceBot_Core_Tools/HTTP_Codes.py @@ -0,0 +1,21 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function + +# sopel imports +import sopel.module + +from sopel_modules.spicemanip import spicemanip + +import sopel_modules.SpiceBot as SpiceBot + + +@SpiceBot.prerun('module') +@sopel.module.commands('httpcode') +def bot_command_http_codes(bot, trigger, botcom): + query = spicemanip(botcom.dict["args"], 1) or None + if not query: + return bot.osd("You must provide a HTTP status code to look up.") + message = ["[HTTP code search for " + str(query) + "]"] + result = SpiceBot.httpcodes.fetch_result(str(query)) + message.extend([result["basic"], result["explanation"]]) + bot.osd(message) diff --git a/sopel_modules/SpiceBot_Core_Tools/__init__.py b/sopel_modules/SpiceBot_Core_Tools/__init__.py index b8a59da..04c0f61 100644 --- a/sopel_modules/SpiceBot_Core_Tools/__init__.py +++ b/sopel_modules/SpiceBot_Core_Tools/__init__.py @@ -6,6 +6,7 @@ from .Gif import * from .Sherlock import * from .Reddit import * from .Search import * +from .HTTP_Codes import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net'