diff --git a/sopel_modules/SpiceBot/Translate.py b/sopel_modules/SpiceBot/Translate.py new file mode 100644 index 0000000..380e5dc --- /dev/null +++ b/sopel_modules/SpiceBot/Translate.py @@ -0,0 +1,195 @@ +# coding=utf8 +from __future__ import unicode_literals, absolute_import, division, print_function + +import spicemanip + +import re +from num2words import num2words + + +class Translate(): + + def __init__(self): + self.dict = {} + + def bot_translate_process(self, totranslate, translationtypes): + + # just in case + if not isinstance(translationtypes, list): + translationtypes = [translationtypes] + + for translationtype in translationtypes: + + if translationtype == "hyphen": + totranslate = spicemanip.main(totranslate, 0).replace(' ', '-') + + elif translationtype == "underscore": + totranslate = spicemanip.main(totranslate, 0).replace(' ', '_') + + elif translationtype == "ermahgerd": + totranslate = self.trernslert(totranslate) + + elif translationtype == "obscure": + totranslate = self.text_obscure(totranslate) + + elif translationtype == "piglatin": + totranslate = self.text_piglatin(totranslate) + + elif translationtype == "binaryinvert": + totranslate = self.text_binary_swap(totranslate) + + elif translationtype == "onetozero": + totranslate = self.text_one_to_zero_swap(totranslate) + + elif translationtype == "upper": + totranslate = spicemanip.main(totranslate, 0).upper() + + elif translationtype == "lower": + totranslate = spicemanip.main(totranslate, 0).lower() + + return totranslate + + def text_obscure(self, words): + amountofletters = len(words) + mystring = "*" * amountofletters + return mystring + + def text_piglatin(self, words): + if not isinstance(words, list): + words = [words] + rebuildarray = [] + for word in words: + word = word.lower() + first = word[:1] + if first in ['a', 'e', 'i', 'o', 'u']: + new_word = word + 'ay' + else: + new_word = word[1:] + first + 'ay' + rebuildarray.append(new_word) + words = spicemanip.main(rebuildarray, 0) + return words + + def trernslert(self, werds): + terkerns = werds.split() + er = '' + for terk in terkerns: + + if terk.endswith(','): + terk = re.sub(r"[,]+", '', terk) + cermmer = 'true' + else: + cermmer = 'false' + + if terk.startswith('('): + terk = re.sub(r"[(]+", '', terk) + lerftperernthersers = 'true' + else: + lerftperernthersers = 'false' + + if terk.endswith(')'): + terk = re.sub(r"[)]+", '', terk) + rerghtperernthersers = 'true' + else: + rerghtperernthersers = 'false' + + if terk.endswith('%'): + terk = re.sub(r"[%]+", '', terk) + percernt = 'true' + else: + percernt = 'false' + + werd = self.ermergerd(terk) + + if lerftperernthersers == 'true': + werd = str('(' + werd) + + if percernt == 'true': + werd = str(werd + ' PERCERNT') + + if rerghtperernthersers == 'true': + werd = str(werd + ')') + + if cermmer == 'true': + werd = str(werd + ',') + cermmer + + er = er + ' ' + werd + return er + + def ermergerd(self, w): + w = w.strip().lower() + derctshernerer = {'me': 'meh', 'you': 'u', 'are': 'er', "you're": "yer", "i'm": "erm", "i've": "erv", "my": "mah", "the": "da", "omg": "ermahgerd"} + if w in derctshernerer: + return derctshernerer[w].upper() + else: + w = re.sub(r"[\.,/;:!@#$%^&*\?)(]+", '', w) + if w[0].isdigit(): + w = num2words(int(w)) + w = re.sub(r"tion", "shun", w) + pat = r"[aeiouy]+" + er = re.sub(pat, "er", w) + if w.startswith('y'): + er = 'y' + re.sub(pat, "er", w[1:]) + if w.endswith('e') and not w.endswith('ee') and len(w) > 3: + er = re.sub(pat, "er", w[:-1]) + if w.endswith('ing'): + er = re.sub(pat, "er", w[:-3]) + 'in' + er = er[0] + er[1:].replace('y', 'er') + er = er.replace('rr', 'r') + return er.upper() + + def text_one_to_zero_swap(self, words): + if not words or words == []: + return "No input provided" + if not isinstance(words, list): + words = [words] + words = spicemanip.main(words, 0).split(" ") + outputarray = [] + for word in words: + if not self.isitbinary(word): + word = self.text_binary_swap(word) + word = str(word).replace('1', '2') + word = str(word).replace('0', '1') + word = str(word).replace('2', '0') + outputarray.append(str(word)) + outputarray = spicemanip.main(outputarray, 0) + return outputarray + + def text_binary_swap(self, words): + if not words or words == []: + return "No input provided" + if not isinstance(words, list): + words = [words] + words = spicemanip.main(words, 0).split(" ") + outputarray = [] + for word in words: + if self.isitbinary(word): + word = self.bits2string(word) or 'error' + else: + word = self.string2bits(word) or 1 + word = spicemanip.main(word, 0) + outputarray.append(str(word)) + outputarray = spicemanip.main(outputarray, 0) + return outputarray + + def unicode_string_cleanup(string): + for r in (("\u2013", "-"), ("\u2019", "'"), ("\u2026", "...")): + string = string.replace(*r) + return string + + def isitbinary(self, string): + p = set(string) + s = {'0', '1'} + if s == p or p == {'0'} or p == {'1'}: + return True + else: + return False + + def string2bits(self, s=''): + return [bin(ord(x))[2:].zfill(8) for x in s] + + def bits2string(self, b=None): + return ''.join(chr(int(b[i*8:i*8+8], 2)) for i in range(len(b)//8)) + + +translate = Translate() diff --git a/sopel_modules/SpiceBot/Users.py b/sopel_modules/SpiceBot/Users.py index 6fe13f4..97bdfc1 100644 --- a/sopel_modules/SpiceBot/Users.py +++ b/sopel_modules/SpiceBot/Users.py @@ -5,7 +5,10 @@ from __future__ import unicode_literals, absolute_import, division, print_functi from sopel.tools import Identifier from .Database import db as botdb -from .Tools import is_number +from .Tools import is_number, inlist, similar, array_arrangesort +from .Channels import channels as botchannels + +import spicemanip # TODO timestamp for new .seen @@ -45,9 +48,13 @@ class BotUsers(): nick_id = self.whois_ident(nickinput) return nick_id - def whois_ident(self, nick): + def whois_ident(self, nick, usercreate=True): nick = Identifier(nick) - nick_id = botdb.db.get_nick_id(nick, create=True) + try: + nick_id = botdb.db.get_nick_id(nick, create=usercreate) + except Exception as e: + nick_id = e + nick_id = None return int(nick_id) def save_user_db(self): @@ -84,8 +91,8 @@ class BotUsers(): # set current nick self.dict["current"][nick_id]["nick"] = user # add joined channel to nick list - if channel not in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].append(channel) + if str(channel).lower() not in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].append(str(channel).lower()) # mark user as online if nick_id not in self.dict["online"]: self.dict["online"].append(int(nick_id)) @@ -104,8 +111,8 @@ class BotUsers(): # set current nick self.dict["current"][nick_id]["nick"] = user # add joined channel to nick list - if trigger.sender not in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].append(trigger.sender) + if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower()) # mark user as online if nick_id not in self.dict["online"]: self.dict["online"].append(int(nick_id)) @@ -121,8 +128,8 @@ class BotUsers(): # set current nick self.dict["current"][nick_id]["nick"] = trigger.nick # add joined channel to nick list - if trigger.sender not in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].append(trigger.sender) + if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower()) # mark user as online if nick_id not in self.dict["online"]: self.dict["online"].append(int(nick_id)) @@ -139,8 +146,8 @@ class BotUsers(): # Verify nick is in the all list self.add_to_current(trigger.nick, nick_id) # empty nicks channel list - if trigger.sender in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].remove(trigger.sender) + if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower()) self.dict["current"][nick_id]["channels"] = [] # mark user as offline if nick_id in self.dict["online"]: @@ -151,8 +158,8 @@ class BotUsers(): def part(self, bot, trigger): if trigger.nick == bot.nick: for nick_id in list(self.dict["current"].keys()): - if trigger.sender in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].remove(trigger.sender) + if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower()) # mark offline if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]: self.dict["online"].remove(nick_id) @@ -166,8 +173,8 @@ class BotUsers(): # Verify nick is in the all list self.add_to_current(trigger.nick, nick_id) # remove channel from nick list - if trigger.sender in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].remove(trigger.sender) + if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower()) # mark offline if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]: self.dict["online"].remove(nick_id) @@ -178,8 +185,8 @@ class BotUsers(): targetnick = Identifier(str(trigger.args[1])) if targetnick == bot.nick: for nick_id in list(self.dict["current"].keys()): - if trigger.sender in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].remove(trigger.sender) + if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower()) # mark offline if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]: self.dict["online"].remove(nick_id) @@ -193,8 +200,8 @@ class BotUsers(): # Verify nick is in the all list self.add_to_current(targetnick, nick_id) # remove channel from nick list - if trigger.sender in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].remove(trigger.sender) + if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower()) # mark offline if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]: self.dict["online"].remove(nick_id) @@ -217,8 +224,8 @@ class BotUsers(): # set current nick self.dict["current"][nick_id]["nick"] = newnick # add joined channel to nick list - if trigger.sender not in self.dict["current"][nick_id]["channels"]: - self.dict["current"][nick_id]["channels"].append(trigger.sender) + if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]: + self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower()) # mark user as online if nick_id not in self.dict["online"]: self.dict["online"].append(int(nick_id)) @@ -228,12 +235,104 @@ class BotUsers(): def mode(self, bot, trigger): return - def targetcheck(self): + def targetcheck(self, posstarget): return True # idk whois if not botdb.check_nick_id(posstarget): return + def nick_actual(self, nick, altlist=None): + nick_id = self.whois_ident(nick) + nick_actual = self.ID(nick_id) + return nick_actual + + def target_online(self, nick, nick_id=None): + if not nick_id: + nick_id = self.ID(nick) + if nick_id in self.dict["online"]: + return True + else: + return False + + def target_check(self, bot, trigger, target, targetbypass): + targetgood = {"targetgood": True, "error": "None", "reason": None} + + if not isinstance(targetbypass, list): + targetbypass = [targetbypass] + + if "notarget" not in targetbypass: + if not target or target == '': + return {"targetgood": False, "error": "No target Given.", "reason": "notarget"} + + # Optional don't allow self-target + if "self" not in targetbypass: + if inlist(target, trigger.nick): + return {"targetgood": False, "error": "This command does not allow you to target yourself.", "reason": "self"} + + # cannot target bots + if "bot" not in targetbypass: + if inlist(target, bot.nick): + return {"targetgood": False, "error": "I am a bot and cannot be targeted.", "reason": "bot"} + if "bots" not in targetbypass: + if inlist(target, bot.nick): + return {"targetgood": False, "error": self.nick_actual(bot, target) + " is a bot and cannot be targeted.", "reason": "bots"} + + nick_id = self.whois_ident(target, usercreate=False) + + # Not a valid user + if "unknown" not in targetbypass: + if not nick_id: + sim_user, sim_num = [], [] + for nick_id in list(self.dict["all"].keys()): + nick_list = self.dict["all"][nick_id] + for nick in nick_list: + similarlevel = similar(str(target).lower(), nick.lower()) + if similarlevel >= .75: + sim_user.append(nick) + sim_num.append(similarlevel) + if sim_user != [] and sim_num != []: + sim_num, sim_user = array_arrangesort(bot, sim_num, sim_user) + closestmatch = spicemanip.main(sim_user, 'reverse', "list") + listnumb, relist = 1, [] + for item in closestmatch: + if listnumb <= 3: + relist.append(str(item)) + listnumb += 1 + closestmatches = spicemanip.main(relist, "andlist") + targetgooderror = "It looks like you're trying to target someone! Did you mean: " + str(closestmatches) + "?" + else: + targetgooderror = "I am not sure who that is." + return {"targetgood": False, "error": targetgooderror, "reason": "unknown"} + + # User offline + if "offline" not in targetbypass: + if not self.target_online(target, nick_id): + return {"targetgood": False, "error": "It looks like " + self.nick_actual(bot, target) + " is offline right now!", "reason": "offline"} + + # Private Message + if "privmsg" not in targetbypass: + if trigger.is_privmsg and not inlist(target, trigger.nick): + return {"targetgood": False, "error": "Leave " + self.nick_actual(bot, target) + " out of this private conversation!", "reason": "privmsg"} + + # not in the same channel + if "diffchannel" not in targetbypass: + if not trigger.is_privmsg and self.target_online(target, nick_id): + if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]: + return {"targetgood": False, "error": "It looks like " + self.nick_actual(bot, target) + " is online right now, but in a different channel.", "reason": "diffchannel"} + + return targetgood + + def random_valid_target(self, bot, trigger, outputtype): + validtargs = [] + if trigger.is_privmsg: + validtargs.extend([str(bot.nick), trigger.nick]) + else: + validtargs.extend(botchannels.dict["list"][str(trigger.sender).lower()]['users']) + if outputtype == 'list': + return validtargs + elif outputtype == 'random': + return spicemanip.main(validtargs, 'random') + users = BotUsers() diff --git a/sopel_modules/SpiceBot_Core_Commands/DictComs.py b/sopel_modules/SpiceBot_Core_Commands/DictComs.py index ffff1a4..0516897 100644 --- a/sopel_modules/SpiceBot_Core_Commands/DictComs.py +++ b/sopel_modules/SpiceBot_Core_Commands/DictComs.py @@ -9,6 +9,11 @@ import sopel.module import sopel_modules.SpiceBot as SpiceBot +import spicemanip + +from word2number import w2n +from random import randint + @SpiceBot.prerun('module', 'dictcom') @sopel.module.commands('(.*)') @@ -17,5 +22,387 @@ def command_dictcom(bot, trigger): if trigger.sb['com'] not in list(SpiceBot.commands.dict['commands']["dictcom"].keys()): return - trigger.sb = SpiceBot.dictcoms.get_dict(trigger.sb) - bot.osd(str(trigger.sb)) + bot_dictcom_process(bot, trigger) + + +def bot_dictcom_process(bot, trigger): + + # use the default key, unless otherwise specified + trigger.sb["responsekey"] = "?default" + + # handling for special cases + posscom = spicemanip.main(trigger.sb['args'], 1) + if posscom.lower() in [command.lower() for command in trigger.sb["dict"].keys()]: + for command in trigger.sb["dict"].keys(): + if command.lower() == posscom.lower(): + posscom = command + trigger.sb["responsekey"] = posscom + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') + trigger.sb["dict"][trigger.sb["responsekey"]]["type"] = trigger.sb["dict"][trigger.sb["responsekey"]]["type"] + + trigger.sb["nonstockoptions"] = [] + for command in trigger.sb["dict"].keys(): + if command not in ["?default", "validcoms", "type", "hardcoded_channel_block"]: + trigger.sb["nonstockoptions"].append(command) + + # This allows users to specify which reply by number by using an ! and a digit (first or last in string) + validspecifides = ['last', 'random', 'count', 'view', 'add', 'del', 'remove', 'special'] + trigger.sb["specified"] = None + argone = spicemanip.main(trigger.sb['args'], 1) + if str(argone).startswith("--") and len(str(argone)) > 2: + if str(argone[2:]).isdigit(): + trigger.sb["specified"] = int(argone[2:]) + elif SpiceBot.inlist(str(argone[2:]), validspecifides): + trigger.sb["specified"] = str(argone[2:]).lower() + elif SpiceBot.inlist(str(argone[2:]), trigger.sb["nonstockoptions"]): + trigger.sb["specified"] = str(argone[2:]).lower() + trigger.sb["responsekey"] = trigger.sb["specified"] + else: + try: + trigger.sb["specified"] = w2n.word_to_num(str(argone[1:])) + trigger.sb["specified"] = int(trigger.sb["specified"]) + except ValueError: + trigger.sb["specified"] = None + if trigger.sb["specified"]: + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') + + # commands that can be updated + if trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"]: + if trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "shared": + SpiceBot.dictcoms.adjust_nick_array(str(SpiceBot.config.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), trigger.sb["dict"][trigger.sb["responsekey"]]["responses"], 'startup') + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = SpiceBot.get_nick_value(str(bot.nick), trigger.sb["dict"]["validcoms"][0] + "_" + str(trigger.sb["responsekey"]), 'sayings') or [] + elif trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "user": + SpiceBot.dictcoms.adjust_nick_array(str(trigger.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), trigger.sb["dict"][trigger.sb["responsekey"]]["responses"], 'startup') + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = SpiceBot.get_nick_value(str(trigger.nick), trigger.sb["dict"]["validcoms"][0] + "_" + str(trigger.sb["responsekey"]), 'sayings') or [] + + if trigger.sb["specified"] == 'special': + nonstockoptions = spicemanip.main(trigger.sb["nonstockoptions"], "andlist") + return bot.osd("The special options for " + str(trigger.sb["realcom"]) + " command include: " + str(nonstockoptions) + ".") + + elif trigger.sb["specified"] == 'count': + return bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " command has " + str(len(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"])) + " entries.") + + elif trigger.sb["specified"] == 'view': + if trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] == []: + return bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " command appears to have no entries!") + else: + bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " command contains:", trigger.nick, 'notice') + listnumb, relist = 1, [] + for item in trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]: + if isinstance(item, dict): + relist.append(str("[#" + str(listnumb) + "] COMPLEX dict Entry")) + elif isinstance(item, list): + relist.append(str("[#" + str(listnumb) + "] COMPLEX list Entry")) + else: + relist.append(str("[#" + str(listnumb) + "] " + str(item))) + bot.osd(relist, trigger.nick) + return + + elif trigger.sb["specified"] == 'add': + + if not trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"]: + return bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list cannot be updated.") + + fulltext = spicemanip.main(trigger.sb['args'], 0) + if not fulltext: + return bot.osd("What would you like to add to the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list?") + + if fulltext in trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]: + return bot.osd("The following was already in the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list: '" + str(fulltext) + "'") + + if trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "shared": + SpiceBot.dictcoms.adjust_nick_array(str(bot.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), fulltext, trigger.sb["specified"]) + elif trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "user": + SpiceBot.dictcoms.adjust_nick_array(str(trigger.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), fulltext, trigger.sb["specified"]) + + return bot.osd("The following was added to the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list: '" + str(fulltext) + "'") + + elif trigger.sb["specified"] in ['del', 'remove']: + + if not trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"]: + return bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list cannot be updated.") + + fulltext = spicemanip.main(trigger.sb['args'], 0) + if not fulltext: + return bot.osd("What would you like to remove from the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list?") + + if fulltext not in trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]: + return bot.osd("The following was already not in the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list: '" + str(fulltext) + "'") + + if trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "shared": + SpiceBot.dictcoms.adjust_nick_array(str(bot.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), fulltext, trigger.sb["specified"]) + elif trigger.sb["dict"][trigger.sb["responsekey"]]["updates_enabled"] == "user": + SpiceBot.dictcoms.adjust_nick_array(str(trigger.nick), 'sayings', trigger.sb["realcom"] + "_" + str(trigger.sb["responsekey"]), fulltext, trigger.sb["specified"]) + + return bot.osd("The following was removed from the " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " entry list: '" + str(fulltext) + "'") + + elif trigger.sb["specified"] and not trigger.sb["dict"][trigger.sb["responsekey"]]["selection_allowed"]: + return bot.osd("The " + str(trigger.sb["realcom"]) + " " + str(trigger.sb["responsekey"] or '') + " response list cannot be specified.") + + trigger.sb["target"] = False + + trigger.sb["success"] = True + if trigger.sb["dict"][trigger.sb["responsekey"]]["type"] in ['simple', 'fillintheblank', "target", 'targetplusreason', 'sayings', "readfromfile", "readfromurl", "ascii_art", "translate", "responses"]: + return bot_dictcom_responses(bot, trigger) + else: + command_function_run = str('bot_dictcom_' + trigger.sb["dict"][trigger.sb["responsekey"]]["type"] + '(bot, botcom)') + eval(command_function_run) + + +def bot_dictcom_responses(bot, trigger): + + commandrunconsensus = [] + reaction = False + + # A target is required + if trigger.sb["dict"][trigger.sb["responsekey"]]["target_required"]: + + # try first term as a target + posstarget = spicemanip.main(trigger.sb['args'], 1) or 0 + targetbypass = trigger.sb["dict"][trigger.sb["responsekey"]]["target_bypass"] + targetchecking = SpiceBot.users.target_check(bot, trigger, posstarget, targetbypass) + if not targetchecking["targetgood"]: + + if trigger.sb["dict"][trigger.sb["responsekey"]]["target_backup"]: + trigger.sb["target"] = trigger.sb["dict"][trigger.sb["responsekey"]]["target_backup"] + if trigger.sb["target"] == 'instigator': + trigger.sb["target"] = trigger.nick + elif trigger.sb["target"] == 'random': + trigger.sb["target"] = SpiceBot.users.random_valid_target(bot, trigger, 'random') + else: + for reason in ['self', 'bot', 'bots', 'offline', 'unknown', 'privmsg', 'diffchannel', 'diffbot']: + if targetchecking["reason"] == reason and trigger.sb["dict"][trigger.sb["responsekey"]]["react_"+reason]: + reaction = True + commandrunconsensus.append(trigger.sb["dict"][trigger.sb["responsekey"]]["react_"+reason]) + if not reaction: + commandrunconsensus.append([targetchecking["error"]]) + else: + trigger.sb["target"] = spicemanip.main(trigger.sb['args'], 1) + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') + + # $blank input + trigger.sb["completestring"] = spicemanip.main(trigger.sb['args'], 0) or '' + if trigger.sb["dict"][trigger.sb["responsekey"]]["blank_required"]: + + if trigger.sb["completestring"] == '' or not trigger.sb["completestring"]: + + if trigger.sb["dict"][trigger.sb["responsekey"]]["blank_backup"]: + trigger.sb["completestring"] = trigger.sb["dict"][trigger.sb["responsekey"]]["blank_backup"] + else: + commandrunconsensus.append(trigger.sb["dict"][trigger.sb["responsekey"]]["blank_fail"]) + + if trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"]: + if trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"] != []: + if spicemanip.main(trigger.sb["completestring"], 1).lower() not in trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"]: + trigger.sb["completestring"] = trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"][0] + " " + trigger.sb["completestring"] + elif spicemanip.main(trigger.sb["completestring"], 1).lower() in trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"]: + if spicemanip.main(trigger.sb["completestring"], 1).lower() != trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"][0]: + trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list') + if trigger.sb['args'] != []: + trigger.sb["completestring"] = trigger.sb["dict"][trigger.sb["responsekey"]]["blank_phrasehandle"][0] + " " + spicemanip.main(trigger.sb['args'], 0) + + if commandrunconsensus != []: + trigger.sb["success"] = False + if trigger.sb["dict"][trigger.sb["responsekey"]]["response_fail"] and not reaction: + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = trigger.sb["dict"][trigger.sb["responsekey"]]["response_fail"] + else: + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = commandrunconsensus[0] + + bot_dictcom_reply_shared(bot, trigger) + + +def bot_dictcom_reply_shared(bot, trigger): + + if trigger.sb["specified"]: + if trigger.sb["specified"] > len(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]): + currentspecified = len(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]) + else: + currentspecified = trigger.sb["specified"] + trigger.sb["replies"] = spicemanip.main(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"], currentspecified, 'return') + trigger.sb["replynum"] = currentspecified + else: + trigger.sb["replies"] = spicemanip.main(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"], 'random', 'return') + try: + trigger.sb["replynum"] = trigger.sb["dict"][trigger.sb["responsekey"]]["responses"].index(trigger.sb["replies"]) + except Exception as e: + trigger.sb["replynum"] = e + trigger.sb["replynum"] = 0 + trigger.sb["replynum"] += 1 + trigger.sb["totalreplies"] = len(trigger.sb["dict"][trigger.sb["responsekey"]]["responses"]) + + # This handles responses in list form + if not isinstance(trigger.sb["replies"], list): + trigger.sb["replies"] = [trigger.sb["replies"]] + + for rply in trigger.sb["replies"]: + + # replies that can be evaluated as code + if rply.startswith("time.sleep"): + eval(rply) + else: + + # random number + if "$randnum" in rply: + if trigger.sb["dict"][trigger.sb["responsekey"]]["randnum"]: + randno = randint(trigger.sb["dict"][trigger.sb["responsekey"]]["randnum"][0], trigger.sb["dict"][trigger.sb["responsekey"]]["randnum"][1]) + else: + randno = randint(0, 50) + rply = rply.replace("$randnum", str(randno)) + + # blank + if "$blank" in rply: + rply = rply.replace("$blank", trigger.sb["completestring"] or '') + + # the remaining input + if "$input" in rply: + rply = rply.replace("$input", spicemanip.main(trigger.sb['args'], 0) or trigger.sb["realcom"]) + + # translation + if trigger.sb["dict"][trigger.sb["responsekey"]]["translations"]: + rply = SpiceBot.translate.bot_translate_process(bot, rply, trigger.sb["dict"][trigger.sb["responsekey"]]["translations"]) + + # text to precede the output + if trigger.sb["dict"][trigger.sb["responsekey"]]["prefixtext"] and trigger.sb["success"]: + rply = spicemanip.main(trigger.sb["dict"][trigger.sb["responsekey"]]["prefixtext"], 'random') + rply + + # text to follow the output + if trigger.sb["dict"][trigger.sb["responsekey"]]["suffixtext"] and trigger.sb["success"]: + rply = rply + spicemanip.main(trigger.sb["dict"][trigger.sb["responsekey"]]["suffixtext"], 'random') + + # trigger.nick + if "$instigator" in rply: + rply = rply.replace("$instigator", trigger.nick or '') + + # random user + if "$randuser" in rply: + if not trigger.is_privmsg: + randuser = spicemanip.main(SpiceBot.users.random_valid_target(bot, trigger, 'random')) + else: + randuser = trigger.nick + rply = rply.replace("$randuser", randuser) + + # current channel + if "$channel" in rply: + rply = rply.replace("$channel", trigger.sender or '') + + # bot.nick + if "$botnick" in rply: + rply = rply.replace("$botnick", bot.nick or '') + + # target + if "$target" in rply: + targetnames = trigger.sb["target"] or '' + if "$targets" in rply: + if targetnames.lower() == "your": + targetnames = targetnames + elif targetnames.endswith("s"): + targetnames = targetnames + "'" + else: + targetnames = targetnames + "s" + rply = rply.replace("$targets", targetnames) + else: + targetnames = targetnames + rply = rply.replace("$target", targetnames) + + # smaller variations for the text + if "$replyvariation" in rply: + if trigger.sb["dict"][trigger.sb["responsekey"]]["replyvariation"] != []: + variation = spicemanip.main(trigger.sb["dict"][trigger.sb["responsekey"]]["replyvariation"], 'random') + rply = rply.replace("$replyvariation", variation) + else: + rply = rply.replace("$replyvariation", '') + + # smaller variations for the text + if "$responsekey" in rply: + rply = rply.replace("$responsekey", str(trigger.sb["responsekey"])) + + if "$index" in rply: + rply = rply.replace("$index", str(str(trigger.sb["replynum"]) + "/" + str(trigger.sb["totalreplies"]))) + + # display special options for this command + if "$specialoptions" in rply: + nonstockoptions = [] + for command in trigger.sb["dict"].keys(): + if command not in ["?default", "validcoms", "contributors", "author", "type", "filepath", "filename", "hardcoded_channel_block", "description", "exampleresponse", "example", "usage", "privs"]: + nonstockoptions.append(command) + nonstockoptions = spicemanip.main(nonstockoptions, "andlist") + rply = rply.replace("$specialoptions", nonstockoptions) + + # saying, or action? + if rply.startswith("*a "): + rplytype = 'action' + rply = rply.replace("*a ", "") + else: + rplytype = 'say' + + bot.osd(rply, trigger.sender, rplytype) + + +def bot_dictcom_gif(bot, trigger): + + if trigger.sb["dict"][trigger.sb["responsekey"]]["blank_required"] and not trigger.sb["completestring"]: + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = trigger.sb["dict"][trigger.sb["responsekey"]]["blank_fail"] + return bot_dictcom_reply_shared(bot, trigger) + elif trigger.sb["dict"][trigger.sb["responsekey"]]["blank_required"] and trigger.sb["completestring"]: + queries = [trigger.sb["completestring"]] + else: + queries = trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] + + # which api's are we using to search + if "queryapi" in trigger.sb["dict"].keys(): + searchapis = trigger.sb["dict"][trigger.sb["responsekey"]]["queryapi"] + else: + searchapis = bot.memory["botdict"]["tempvals"]['valid_gif_api_dict'].keys() + + if trigger.sb["specified"]: + if trigger.sb["specified"] > len(queries): + trigger.sb["specified"] = len(queries) + query = spicemanip.main(queries, trigger.sb["specified"], 'return') + else: + query = spicemanip.main(queries, 'random', 'return') + + searchdict = {"query": query, "gifsearch": searchapis} + + # nsfwenabled = get_database_value(bot, bot.nick, 'channels_nsfw') or [] + # if trigger.sender in nsfwenabled: + # searchdict['nsfw'] = True + # TODO + + gifdict = SpiceBot.gif.get_gif(searchdict) + + if gifdict["error"]: + trigger.sb["success"] = False + if trigger.sb["dict"][trigger.sb["responsekey"]]["search_fail"]: + gifdict["error"] = trigger.sb["dict"][trigger.sb["responsekey"]]["search_fail"] + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = [gifdict["error"]] + else: + trigger.sb["dict"][trigger.sb["responsekey"]]["responses"] = [str(gifdict['gifapi'].title() + " Result (" + str(query) + " #" + str(gifdict["returnnum"]) + "): " + str(gifdict["returnurl"]))] + + trigger.sb["specified"] = False + bot_dictcom_reply_shared(bot, trigger) + + +def bot_dictcom_feeds(bot, trigger): + return bot.osd("WIP") + """ + + if "feeds" not in bot.memory: + feed_configs(bot) + + bot_startup_requirements_set(bot, "feeds") + + feed = trigger.sb["dict"][trigger.sb["responsekey"]]["responses"][0] + if feed not in bot.memory['feeds'].keys(): + return bot.osd(feed + " does not appear to be a valid feed.") + + dispmsg = bot_dictcom_feeds_handler(bot, feed, True) + if dispmsg == []: + bot.osd(feed + " appears to have had an unknown error.") + else: + bot.osd(dispmsg) + + """ + + +def bot_dictcom_search(bot, botcom): + bot.say("testing done")