diff --git a/Installation Files/requirements-os.sh b/Installation Files/requirements-os.sh index 31f9763..0df25d2 100644 --- a/Installation Files/requirements-os.sh +++ b/Installation Files/requirements-os.sh @@ -39,6 +39,9 @@ mkdir /run/sopel echo $$ > /run/sopel/sopel-SpiceBotSERV.pid chmod -R 777 /run/sopel/ +apt install mysql-server libmysqlclient-dev -y +pip3 install mysql + cp /home/sopel/SpiceBot/System-Files/Config/SpiceBot.cfg /home/sopel/SpiceBot.cfg cp /home/sopel/SpiceBot/System-Files/systemd/SpiceBot.service /lib/systemd/system/SpiceBot.service diff --git a/sopel_modules/SpiceBot_AI/AI.py b/sopel_modules/SpiceBot_AI/AI.py index 19e0772..7ae029b 100644 --- a/sopel_modules/SpiceBot_AI/AI.py +++ b/sopel_modules/SpiceBot_AI/AI.py @@ -7,62 +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 - - -@sopel.module.rule(r'(?i)(hi|hello|hey),? $nickname[ \t]*$') -def bot_command_hello(bot, trigger): - hello = spicemanip.main(['Hi', 'Hey', 'Hello'], "random") - punctuation = spicemanip.main(['', '!', '?'], "random") - bot.osd(hello + ' ' + trigger.nick + punctuation) - - -@sopel.module.nickname_commands('hello', 'hi', 'hey') -def bot_command_hello_b(bot, trigger): - bot_command_hello(bot, trigger) - - -@sopel.module.rule(r'(?i)(bye|goodbye|gtg|seeya|cya|ttyl|g2g|gnight|goodnight),? $nickname[ \t]*$') -def bot_command_goodbye(bot, trigger): - byemsg = spicemanip.main(['Bye', 'Goodbye', 'Seeya', 'Auf Wiedersehen', 'Au revoir', 'Ttyl'], "random") - punctuation = spicemanip.main(['!', ''], "random") - bot.say(byemsg + ' ' + trigger.nick + punctuation) - - -@sopel.module.nickname_commands("bye", "goodbye", "gtg", "seeya", "cya", "ttyl", "g2g", "gnight", "goodnight") -def bot_command_goodbye_b(bot, trigger): - bot_command_goodbye(bot, trigger) - - -@sopel.module.rule('$nickname!') -def exclaim(bot, trigger): - bot.say(trigger.nick + '!') - - -@sopel.module.rule('$nickname\?') -def imhere(bot, trigger): - bot.say("I'm here, " + trigger.nick) - - -@sopel.module.rule(r'(?i)(Fuck|Screw) (you|off),? $nickname[ \t]*$') -def bot_command_srewyou(bot, trigger): - bot.osd("Watch your mouth, " + trigger.nick + ", or I'll tell your mother!") - - -@sopel.module.rule(r'(?i)(Damnit|Lazy)? $nickname[ \t]*$') -def bot_command_damnlazy(bot, trigger): - bot.osd("I do not tell you how to do your job, " + trigger.nick + "!!!") - - -@sopel.module.rule('$nickname is lazy') -def bot_command_damnlazy_b(bot, trigger): - bot.osd("I do not tell you how to do your job, " + trigger.nick + "!!!") +from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents @sopel.module.nickname_commands('(.*)') def bot_command_nick(bot, trigger): - while not bot_events_check(bot, ['1004', '2002']): + while not bot_events_check(bot, [botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]): pass triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') @@ -70,6 +21,9 @@ def bot_command_nick(bot, trigger): if not triggercommand: return + if triggercommand[0] == "?": + return + if triggercommand in bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(): return triggerargs.insert(0, triggercommand) @@ -134,7 +88,7 @@ def bot_command_nick(bot, trigger): bot.osd(trigger.nick + ", what would you like me to beam you?") return - elif fulltrigger.lower().startswith(tuple(["beam me to"])): + elif fulltrigger.lower().startswith("beam me to"): location = spicemanip.main(triggerargs, "4+") or None if location: bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to " + location, 'action') @@ -142,7 +96,7 @@ def bot_command_nick(bot, trigger): bot.osd(trigger.nick + ", where would you like me to beam you?") return - elif fulltrigger.lower().startswith(tuple(["beam me up"])): + elif fulltrigger.lower().startswith("beam me up"): bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to the transporter room.", 'action') return @@ -153,7 +107,7 @@ def bot_command_nick(bot, trigger): if trigger.is_privmsg: jedi = None else: - jedilist = bot.channels[trigger.sender].privileges.keys() + jedilist = list(bot.channels[trigger.sender].privileges.keys()) for nonjedi in [bot.nick, trigger.nick]: if nonjedi in jedilist: jedilist.remove(nonjedi) @@ -185,7 +139,8 @@ def bot_command_nick(bot, trigger): elif fulltrigger.lower().startswith("can you see"): target = spicemanip.main(triggerargs, "4+") or None if not target: - target = 'me' + bot.osd(trigger.nick + ", I can see clearly.") + return if target in [trigger.nick, 'me']: bot.osd(trigger.nick + ", I can see you.") else: @@ -200,7 +155,7 @@ def bot_command_nick(bot, trigger): # TODO return - if not inlist(bot, triggercommand, bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys()): + else: closestmatches = similar_list(bot, triggercommand, bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(), 3, 'reverse') diff --git a/sopel_modules/SpiceBot_AI/AI_Acknowledge.py b/sopel_modules/SpiceBot_AI/AI_Acknowledge.py new file mode 100644 index 0000000..e9e626e --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Acknowledge.py @@ -0,0 +1,15 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule('$nickname!') +def exclaim(bot, trigger): + bot.say(trigger.nick + '!') + + +@sopel.module.rule('$nickname\?') +def imhere(bot, trigger): + bot.say("I'm here, " + trigger.nick) diff --git a/sopel_modules/SpiceBot_AI/AI_Goodbye.py b/sopel_modules/SpiceBot_AI/AI_Goodbye.py new file mode 100644 index 0000000..7f93bef --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Goodbye.py @@ -0,0 +1,19 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import spicemanip + + +@sopel.module.rule(r'(?i)(bye|goodbye|gtg|seeya|cya|ttyl|g2g|gnight|goodnight),? $nickname[ \t]*$') +def bot_command_goodbye(bot, trigger): + byemsg = spicemanip.main(['Bye', 'Goodbye', 'Seeya', 'Auf Wiedersehen', 'Au revoir', 'Ttyl'], "random") + punctuation = spicemanip.main(['!', ''], "random") + bot.say(byemsg + ' ' + trigger.nick + punctuation) + + +@sopel.module.nickname_commands("bye", "goodbye", "gtg", "seeya", "cya", "ttyl", "g2g", "gnight", "goodnight") +def bot_command_goodbye_b(bot, trigger): + bot_command_goodbye(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Hello.py b/sopel_modules/SpiceBot_AI/AI_Hello.py new file mode 100644 index 0000000..ee30964 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Hello.py @@ -0,0 +1,19 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +import spicemanip + + +@sopel.module.rule(r'(?i)(hi|hello|hey),? $nickname[ \t]*$') +def bot_command_hello(bot, trigger): + hello = spicemanip.main(['Hi', 'Hey', 'Hello'], "random") + punctuation = spicemanip.main(['', '!', '?'], "random") + bot.osd(hello + ' ' + trigger.nick + punctuation) + + +@sopel.module.nickname_commands('hello', 'hi', 'hey') +def bot_command_hello_b(bot, trigger): + bot_command_hello(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_InsultHandler.py b/sopel_modules/SpiceBot_AI/AI_InsultHandler.py new file mode 100644 index 0000000..910dd7b --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_InsultHandler.py @@ -0,0 +1,10 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule(r'(?i)(Fuck|Screw) (you|off),? $nickname[ \t]*$') +def bot_command_srewyou(bot, trigger): + bot.osd("Watch your mouth, " + trigger.nick + ", or I'll tell your mother!") diff --git a/sopel_modules/SpiceBot_AI/AI_Lazy.py b/sopel_modules/SpiceBot_AI/AI_Lazy.py new file mode 100644 index 0000000..a3385a6 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Lazy.py @@ -0,0 +1,15 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule(r'(?i)(Damnit|Lazy)? $nickname[ \t]*$') +def bot_command_damnlazy(bot, trigger): + bot.osd("I do not tell you how to do your job, " + trigger.nick + "!!!") + + +@sopel.module.rule('$nickname is lazy') +def bot_command_damnlazy_b(bot, trigger): + bot_command_damnlazy(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Love.py b/sopel_modules/SpiceBot_AI/AI_Love.py new file mode 100644 index 0000000..8674317 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Love.py @@ -0,0 +1,40 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule(r'(?i)(I love you|loveya),? $nickname[ \t]*$') +def bot_command_love(bot, trigger): + bot.reply("I love you too.") + + +@sopel.module.rule('$nickname (loveya|I love you)') +def bot_command_love_b(bot, trigger): + bot_command_love(bot, trigger) + + +@sopel.module.nickname_commands('loveya') +def bot_command_love_c(bot, trigger): + bot_command_love(bot, trigger) + + +@sopel.module.rule('(I love) $nickname') +def bot_command_love_d(bot, trigger): + bot_command_like(bot, trigger) + + +@sopel.module.rule(r'(?i)(I like you),? $nickname[ \t]*$') +def bot_command_like(bot, trigger): + bot.reply("I like you too.") + + +@sopel.module.rule('$nickname (I like you)') +def bot_command_like_b(bot, trigger): + bot_command_like(bot, trigger) + + +@sopel.module.rule('(I like) $nickname') +def bot_command_like_c(bot, trigger): + bot_command_like(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Ping.py b/sopel_modules/SpiceBot_AI/AI_Ping.py new file mode 100644 index 0000000..4931797 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Ping.py @@ -0,0 +1,15 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule(r'(?i)(ping),? $nickname[ \t]*$') +def bot_command_ping(bot, trigger): + bot.say("Pong") + + +@sopel.module.nickname_commands('ping') +def bot_command_ping_b(bot, trigger): + bot_command_ping(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/AI_Thanks.py b/sopel_modules/SpiceBot_AI/AI_Thanks.py new file mode 100644 index 0000000..be80f7f --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI_Thanks.py @@ -0,0 +1,20 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + + +@sopel.module.rule(r'(?i)(thank you|thanks),? $nickname[ \t]*$') +def bot_command_thanks(bot, trigger): + bot.reply("You're welcome.") + + +@sopel.module.rule('$nickname (thank you)') +def bot_command_thanks_b(bot, trigger): + bot_command_thanks(bot, trigger) + + +@sopel.module.nickname_commands('thanks') +def bot_command_thanks_c(bot, trigger): + bot_command_thanks(bot, trigger) diff --git a/sopel_modules/SpiceBot_AI/__init__.py b/sopel_modules/SpiceBot_AI/__init__.py index b1447b6..93aecc7 100644 --- a/sopel_modules/SpiceBot_AI/__init__.py +++ b/sopel_modules/SpiceBot_AI/__init__.py @@ -2,6 +2,14 @@ from __future__ import unicode_literals, absolute_import, division, print_function from .AI import * +from .AI_Hello import * +from .AI_Goodbye import * +from .AI_Thanks import * +from .AI_Acknowledge import * +from .AI_Lazy import * +from .AI_InsultHandler import * +from .AI_Ping import * +from .AI_Love import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Channels/Channels.py b/sopel_modules/SpiceBot_Channels/Channels.py index 1aec6aa..5bb11d6 100644 --- a/sopel_modules/SpiceBot_Channels/Channels.py +++ b/sopel_modules/SpiceBot_Channels/Channels.py @@ -6,8 +6,7 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi 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 - +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 @@ -35,7 +34,7 @@ def configure(config): def setup(bot): bot_logging(bot, 'SpiceBot_Channels', "Starting setup procedure") - bot_events_startup_register(bot, ['2001']) + bot_events_startup_register(bot, [botevents.BOT_CHANNELS]) bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False) @@ -48,7 +47,7 @@ def shutdown(bot): del bot.memory["SpiceBot_Channels"] -@sopel.module.event('1003') +@sopel.module.event(botevents.BOT_CONNECTED) @sopel.module.rule('.*') def trigger_channel_list_initial(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -75,7 +74,7 @@ def trigger_channel_list_initial(bot, trigger): 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, 2001, "SpiceBot_Channels") + bot_events_trigger(bot, botevents.BOT_CHANNELS, "SpiceBot_Channels") join_all_channels(bot) chanadmin_all_channels(bot) @@ -124,7 +123,7 @@ def bot_part_empty(bot): del bot.memory['SpiceBot_Channels']['channels'][channel.lower()] -@sopel.module.event('2001') +@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_Command.py b/sopel_modules/SpiceBot_Channels/Channels_Command.py index 65858f9..c7e69bc 100644 --- a/sopel_modules/SpiceBot_Channels/Channels_Command.py +++ b/sopel_modules/SpiceBot_Channels/Channels_Command.py @@ -6,7 +6,7 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_Events.System import bot_events_check +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, @@ -17,7 +17,7 @@ from .Channels import bot_part_empty @sopel.module.nickname_commands('channels', 'channel') def nickname_comand_channels(bot, trigger): - while not bot_events_check(bot, '1004'): + while not bot_events_check(bot, botevents.BOT_LOADED): pass triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') diff --git a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py index 548d746..434630e 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py +++ b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py @@ -7,7 +7,7 @@ import sopel.module import os -from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger +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 import spicemanip @@ -15,7 +15,7 @@ import spicemanip def setup(bot): bot_logging(bot, 'SpiceBot_CommandsQuery', "Starting setup procedure") - bot_events_startup_register(bot, ['2002']) + bot_events_startup_register(bot, [botevents.BOT_COMMANDSQUERY]) if 'SpiceBot_CommandsQuery' not in bot.memory: bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []} @@ -97,9 +97,9 @@ def setup(bot): detected_lines.append(line) if len(detected_lines): - bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 filelinelist = [] + currentsuccesslines = 0 for detected_line in detected_lines: # Commands @@ -117,31 +117,41 @@ def setup(bot): validcoms = list(validcoms) else: validcoms = [validcoms] + for regexcom in ["(.*)", '^\?(.*)']: + if regexcom in validcoms: + while regexcom in validcoms: + validcoms.remove(regexcom) - validcomdict = {"comtype": comtype, "validcoms": validcoms} - filelinelist.append(validcomdict) + if len(validcoms): + validcomdict = {"comtype": comtype, "validcoms": validcoms} + filelinelist.append(validcomdict) + currentsuccesslines += 1 - for atlinefound in filelinelist: + if currentsuccesslines: + bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 - dict_from_file = dict() + if len(filelinelist): + for atlinefound in filelinelist: - comtype = atlinefound["comtype"] - validcoms = atlinefound["validcoms"] + dict_from_file = dict() - # default command to filename - if "validcoms" not in dict_from_file.keys(): - dict_from_file["validcoms"] = validcoms + comtype = atlinefound["comtype"] + validcoms = atlinefound["validcoms"] - maincom = dict_from_file["validcoms"][0] - if len(dict_from_file["validcoms"]) > 1: - comaliases = spicemanip.main(dict_from_file["validcoms"], '2+', 'list') - else: - comaliases = [] + # default command to filename + if "validcoms" not in dict_from_file.keys(): + dict_from_file["validcoms"] = validcoms - bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][maincom] = dict_from_file - for comalias in comaliases: - if comalias not in bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys(): - bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][comalias] = {"aliasfor": maincom} + maincom = dict_from_file["validcoms"][0] + if len(dict_from_file["validcoms"]) > 1: + comaliases = spicemanip.main(dict_from_file["validcoms"], '2+', 'list') + else: + comaliases = [] + + bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][maincom] = dict_from_file + for comalias in comaliases: + if comalias not in bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys(): + bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][comalias] = {"aliasfor": maincom} for comtype in ['module', 'nickname', 'rule']: bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) @@ -152,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, 2002, "SpiceBot_CommandsQuery") + bot_events_trigger(bot, botevents.BOT_COMMANDSQUERY, "SpiceBot_CommandsQuery") def shutdown(bot): @@ -160,7 +170,7 @@ def shutdown(bot): del bot.memory["SpiceBot_CommandsQuery"] -@sopel.module.event('1004') +@sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_events_complete(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -204,7 +214,7 @@ def commandsquery_register(bot, command_type, validcoms, aliasfor=None): bot.memory['SpiceBot_CommandsQuery']['commands'][command_type][comalias] = {"aliasfor": aliasfor} -@sopel.module.event('2002') +@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 new file mode 100644 index 0000000..67782f3 --- /dev/null +++ b/sopel_modules/SpiceBot_CommandsQuery/NickQueryCommand.py @@ -0,0 +1,81 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel +import sopel.module + +from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string + + +import spicemanip + + +@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 + if not triggercommand or not len(triggercommand): + return + + if not triggercommand[0] == "?": + return + triggercommand = triggercommand[1:] + + if not letters_in_string(triggercommand): + return + + commands_list = dict() + for com in bot.memory['SpiceBot_CommandsQuery']['commands']['nickname'].keys(): + if com not in commands_list.keys(): + commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands']['nickname'][com] + + if triggercommand.endswith("+"): + + triggercommand = triggercommand[:-1] + if not triggercommand or not len(triggercommand): + return + + if triggercommand.lower() not in list(commands_list.keys()): + dispmsg = ["Cannot find any alias " + bot.nick + " commands: No valid commands match " + str(triggercommand) + "."] + closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') + if len(closestmatches): + dispmsg.append("The following " + bot.nick + " commands match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") + bot.notice(dispmsg, trigger.nick) + return + + realcom = triggercommand + if "aliasfor" in commands_list[triggercommand].keys(): + realcom = commands_list[triggercommand]["aliasfor"] + validcomlist = commands_list[realcom]["validcoms"] + bot.notice("The following " + bot.nick + " commands match " + str(triggercommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick) + return + + if triggercommand.endswith("?"): + + triggercommand = triggercommand[:-1] + if not triggercommand or not len(triggercommand): + return + + closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') + if not len(closestmatches): + bot.notice("Cannot find any similar " + bot.nick + " commands for " + str(triggercommand) + ".", trigger.nick) + else: + bot.notice("The following " + bot.nick + " commands may match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) + return + + commandlist = [] + for command in list(commands_list.keys()): + if command.lower().startswith(str(triggercommand).lower()): + commandlist.append(command) + + if not len(commandlist): + bot.notice("No " + bot.nick + " commands start with " + str(triggercommand) + ".", trigger.nick) + else: + bot.notice("The following " + bot.nick + " commands start with " + str(triggercommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) diff --git a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py index bd3dd48..8f8011b 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py +++ b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py @@ -5,10 +5,9 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel import sopel.module -from difflib import SequenceMatcher -from operator import itemgetter +from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents +from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string -from sopel_modules.SpiceBot_Events.System import bot_events_check import spicemanip @@ -16,78 +15,65 @@ import spicemanip @sopel.module.rule('^\?(.*)') def query_detection(bot, trigger): - while not bot_events_check(bot, '2002'): + while not bot_events_check(bot, botevents.BOT_COMMANDSQUERY): pass + triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'query_command') + + # command issued, check if valid + if not triggercommand or not len(triggercommand): + return + + if not letters_in_string(triggercommand): + return + commands_list = dict() for commandstype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): - for com in bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype].keys(): - if com not in commands_list.keys(): - if commandstype == 'nickname': - commands_list[str(bot.nick) + " " + com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] - else: + if commandstype not in ['rule', 'nickname']: + for com in bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype].keys(): + if com not in commands_list.keys(): commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] - triggerargsarray = spicemanip.main(trigger, 'create') + if triggercommand[:-1] == "+": - # command issued, check if valid - querycommand = spicemanip.main(triggerargsarray, 1).lower()[1:] - if len(querycommand) == 1: - commandlist = [] - for command in commands_list.keys(): - if command.lower().startswith(querycommand): - commandlist.append(command) - if commandlist == []: - bot.notice("No commands match " + str(querycommand) + ".", trigger.nick) - return - else: - bot.notice("The following commands match " + str(querycommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) + triggercommand = triggercommand[:-1] + if not triggercommand or not len(triggercommand): return - elif querycommand.endswith(tuple(["+"])): - querycommand = querycommand[:-1] - if querycommand not in commands_list.keys(): - bot.notice("The " + str(querycommand) + " does not appear to be valid.") + if triggercommand.lower() not in list(commands_list.keys()): + dispmsg = ["Cannot find any alias commands: No valid commands match " + str(triggercommand) + "."] + closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') + if len(closestmatches): + dispmsg.append("The following commands match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".") + bot.notice(dispmsg, trigger.nick) return - realcom = querycommand - if "aliasfor" in commands_list[querycommand].keys(): - realcom = commands_list[querycommand]["aliasfor"] + + realcom = triggercommand + if "aliasfor" in commands_list[triggercommand].keys(): + realcom = commands_list[triggercommand]["aliasfor"] validcomlist = commands_list[realcom]["validcoms"] - bot.notice("The following commands match " + str(querycommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick) + bot.notice("The following commands match " + str(triggercommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick) return - elif querycommand.endswith(tuple(['?'])): - querycommand = querycommand[:-1] - sim_com, sim_num = [], [] - for com in commands_list.keys(): - similarlevel = SequenceMatcher(None, querycommand.lower(), com.lower()).ratio() - sim_com.append(com) - sim_num.append(similarlevel) - sim_num, sim_com = (list(x) for x in zip(*sorted(zip(sim_num, sim_com), key=itemgetter(0)))) - closestmatch = spicemanip.main(sim_com, 'reverse', "list") - listnumb, relist = 1, [] - for item in closestmatch: - if listnumb <= 10: - relist.append(str(item)) - listnumb += 1 - bot.notice("The following commands may match " + str(querycommand) + ": " + spicemanip.main(relist, 'andlist') + ".", trigger.nick) - return + if triggercommand[:-1] == "?": - elif querycommand in commands_list.keys(): - bot.notice("The following commands match " + str(querycommand) + ": " + str(querycommand) + ".", trigger.nick) - return - - elif not querycommand: - return - - else: - commandlist = [] - for command in commands_list.keys(): - if command.lower().startswith(querycommand): - commandlist.append(command) - if commandlist == []: - bot.notice("No commands match " + str(querycommand) + ".", trigger.nick) + triggercommand = triggercommand[:-1] + if not triggercommand or not len(triggercommand): return + + closestmatches = similar_list(bot, triggercommand, list(commands_list.keys()), 10, 'reverse') + if not len(closestmatches): + bot.notice("Cannot find any similar commands for " + str(triggercommand) + ".", trigger.nick) else: - bot.notice("The following commands match " + str(querycommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) - return + bot.notice("The following commands may match " + str(triggercommand) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) + return + + commandlist = [] + for command in list(commands_list.keys()): + if command.lower().startswith(str(triggercommand).lower()): + commandlist.append(command) + + if not len(commandlist): + bot.notice("No commands start with " + str(triggercommand) + ".", trigger.nick) + else: + bot.notice("The following commands start with " + str(triggercommand) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick) diff --git a/sopel_modules/SpiceBot_CommandsQuery/__init__.py b/sopel_modules/SpiceBot_CommandsQuery/__init__.py index 55dadea..fcad5b8 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/__init__.py +++ b/sopel_modules/SpiceBot_CommandsQuery/__init__.py @@ -7,6 +7,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi from .CommandsQuery import * from .QueryCommand import * +from .NickQueryCommand import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py b/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py index 7c07129..26fc511 100644 --- a/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py +++ b/sopel_modules/SpiceBot_Database_Addons/Databaseaddons.py @@ -6,72 +6,114 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel.module from sopel.tools import Identifier from sopel_modules.SpiceBot_SBTools import bot_logging -from sopel.db import _deserialize, SopelDB +from sopel.db import SopelDB, NickValues, ChannelValues +from sqlalchemy.exc import SQLAlchemyError import json def setup(bot): + pass # Inject Database Functions bot_logging(bot, 'SpiceBot_Databaseaddons', "Implanting Database functions into bot") - SopelDB.reset_nick_value = SopelDBCache.reset_nick_value - SopelDB.adjust_nick_value = SopelDBCache.adjust_nick_value - SopelDB.reset_channel_value = SopelDBCache.reset_channel_value - SopelDB.adjust_channel_value = SopelDBCache.adjust_channel_value - SopelDB._create_table = SopelDBCache._create_table + SopelDB.delete_nick_value = SopelDBCache.delete_nick_value + # SopelDB.adjust_nick_value = SopelDBCache.adjust_nick_value + SopelDB.delete_channel_value = SopelDBCache.delete_channel_value + # SopelDB.adjust_channel_value = SopelDBCache.adjust_channel_value class SopelDBCache: - """Dynamic Table Creation""" - - def _create_table(self, tablename): - self.execute('CREATE TABLE IF NOT EXISTS ? (mainid STRING, key STRING, value STRING, PRIMARY KEY (mainid, key))', tablename) - """Nicks""" - def reset_nick_value(self, nick, key): - """Resets the value for a given key to be associated with the nick.""" + def delete_nick_value(self, nick, key): + """Deletes the value for a given key to be associated with the nick.""" nick = Identifier(nick) nick_id = self.get_nick_id(nick) - self.execute('DELETE FROM nick_values WHERE nick_id = ? AND key = ?', [nick_id, key]) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, delete + if result: + session.delete(result.value) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() def adjust_nick_value(self, nick, key, value): - """Adjusts the value for a given key to be associated with the nick.""" + """Sets the value for a given key to be associated with the nick.""" nick = Identifier(nick) - result = self.execute( - 'SELECT value FROM nicknames JOIN nick_values ' - 'ON nicknames.nick_id = nick_values.nick_id ' - 'WHERE slug = ? AND key = ?', - [nick.lower(), key] - ).fetchone() - if result is not None: - result = result[0] - current_value = _deserialize(result) - value = current_value + value value = json.dumps(value, ensure_ascii=False) nick_id = self.get_nick_id(nick) - self.execute('INSERT OR REPLACE INTO nick_values VALUES (?, ?, ?)', - [nick_id, key, value]) + session = self.ssession() + try: + result = session.query(NickValues) \ + .filter(NickValues.nick_id == nick_id) \ + .filter(NickValues.key == key) \ + .one_or_none() + # NickValue exists, update + if result: + result.value = result.value + value + session.commit() + # DNE - Insert + else: + new_nickvalue = NickValues(nick_id=nick_id, key=key, value=value) + session.add(new_nickvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() """Channels""" - def reset_channel_value(self, channel, key): - """Resets the value for a given key to be associated with a channel.""" + def delete_channel_value(self, channel, key): + """Sets the value for a given key to be associated with the channel.""" channel = Identifier(channel).lower() - self.execute('DELETE FROM channel_values WHERE channel = ? AND key = ?', [channel, key]) + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + session.delete(result.value) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() def adjust_channel_value(self, channel, key, value): - """Adjusts the value for a given key to be associated with the channel.""" + """Sets the value for a given key to be associated with the channel.""" channel = Identifier(channel).lower() - result = self.execute( - 'SELECT value FROM channel_values WHERE channel = ? AND key = ?', - [channel, key] - ).fetchone() - if result is not None: - result = result[0] - current_value = _deserialize(result) - value = current_value + value value = json.dumps(value, ensure_ascii=False) - self.execute('INSERT OR REPLACE INTO channel_values VALUES (?, ?, ?)', - [channel, key, value]) + session = self.ssession() + try: + result = session.query(ChannelValues) \ + .filter(ChannelValues.channel == channel)\ + .filter(ChannelValues.key == key) \ + .one_or_none() + # ChannelValue exists, update + if result: + result.value = result.value + value + session.commit() + # DNE - Insert + else: + new_channelvalue = ChannelValues(channel=channel, key=key, value=value) + session.add(new_channelvalue) + session.commit() + except SQLAlchemyError: + session.rollback() + raise + finally: + session.close() diff --git a/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py b/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py index 816c56f..e074941 100644 --- a/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py +++ b/sopel_modules/SpiceBot_Database_Tools/DatabaseTools.py @@ -6,13 +6,6 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel.module -"""Dyanmic Table Creation""" - - -def db_create_table(bot, tablename): - bot.db._create_table(tablename) - - """Database Direct""" @@ -58,7 +51,7 @@ def db_adjust_list(bot, nick, entries, key, adjustmentdirection): for x in adjustlistnew: if x not in adjustlist: adjustlist.append(x) - if adjustlist == []: + if not len(adjustlist): db_reset_value(bot, nick, key) else: db_set_nick_value(bot, nick, key, adjustlist) diff --git a/sopel_modules/SpiceBot_Events/Events.py b/sopel_modules/SpiceBot_Events/Events.py index 9613516..730cb4f 100644 --- a/sopel_modules/SpiceBot_Events/Events.py +++ b/sopel_modules/SpiceBot_Events/Events.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi 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 +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 @@ -14,35 +14,35 @@ import time @sopel.module.event('001') @sopel.module.rule('.*') def bot_startup_connection(bot, trigger): - bot_events_trigger(bot, 1001, "Welcome to the SpiceBot Events System") + 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, 1003, "Bot Connected to IRC") + bot_events_trigger(bot, botevents.BOT_CONNECTED, "Bot Connected to IRC") -@sopel.module.event('1001') +@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, 1002, "Ready To Process module setup procedures") + 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, 1004, "All registered modules setup procedures have completed") + bot_events_trigger(bot, botevents.BOT_LOADED, "All registered modules setup procedures have completed") -@sopel.module.event('1002') +@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('1003') +@sopel.module.event(botevents.BOT_CONNECTED) @sopel.module.rule('.*') def bot_events_connected(bot, trigger): bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) @@ -65,7 +65,7 @@ def bot_events_connected(bot, trigger): return -@sopel.module.event('1004') +@sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_events_complete(bot, trigger): bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) diff --git a/sopel_modules/SpiceBot_Events/System.py b/sopel_modules/SpiceBot_Events/System.py index b4e0dce..cd7a874 100644 --- a/sopel_modules/SpiceBot_Events/System.py +++ b/sopel_modules/SpiceBot_Events/System.py @@ -9,10 +9,32 @@ 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, ['1001', '1002', '1003']) + bot_events_startup_register(bot, [botevents.BOT_WELCOME, botevents.BOT_READY, botevents.BOT_CONNECTED]) def shutdown(bot): @@ -25,7 +47,7 @@ def bot_events_trigger(bot, number, message): bot_events_setup_check(bot) bot.memory["SpiceBot_Events"]["triggers"][str(number)] = message - if str(number) in ['1001', '1002', '1003']: + 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 @@ -84,7 +106,6 @@ def bot_events_startup_check(bot): notcomplete.append(str(startupitem)) if len(notcomplete): - # bot_logging(bot, 'SpiceBot_Events', str(notcomplete)) return False else: return True diff --git a/sopel_modules/SpiceBot_GifSearch/gif.py b/sopel_modules/SpiceBot_GifSearch/gif.py index 9a93975..6c344a9 100644 --- a/sopel_modules/SpiceBot_GifSearch/gif.py +++ b/sopel_modules/SpiceBot_GifSearch/gif.py @@ -7,7 +7,7 @@ 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 +from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents import spicemanip @@ -15,11 +15,11 @@ import spicemanip @module.commands('gif') def gif_trigger(bot, trigger): - while not bot_events_check(bot, '2003'): + while not bot_events_check(bot, botevents.BOT_GIFSEARCH): pass triggerargs, triggercommand = sopel_triggerargs(bot, trigger) - if triggerargs == []: + if not len(triggerargs): return bot.osd("Please present a query to search.") query = spicemanip.main(triggerargs, 0) diff --git a/sopel_modules/SpiceBot_GifSearch/gifapi.py b/sopel_modules/SpiceBot_GifSearch/gifapi.py index 6748cae..fa500b9 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifapi.py +++ b/sopel_modules/SpiceBot_GifSearch/gifapi.py @@ -9,13 +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 +from sopel_modules.SpiceBot_Events.System import bot_events_check, botevents @sopel.module.commands('(.*)') def gifapi_triggers(bot, trigger): - while not bot_events_check(bot, '2003'): + while not bot_events_check(bot, botevents.BOT_GIFSEARCH): pass triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') @@ -23,7 +23,7 @@ def gifapi_triggers(bot, trigger): if triggercommand not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys(): return - if triggerargs == []: + if not len(triggerargs): return bot.osd("Please present a query to search.") query = spicemanip.main(triggerargs, 0) diff --git a/sopel_modules/SpiceBot_GifSearch/gifsearch.py b/sopel_modules/SpiceBot_GifSearch/gifsearch.py index 7f8ba88..884bd11 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifsearch.py +++ b/sopel_modules/SpiceBot_GifSearch/gifsearch.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module from sopel.config.types import StaticSection, ValidatedAttribute -from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger +from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents from sopel_modules.SpiceBot_CommandsQuery.CommandsQuery import commandsquery_register @@ -47,7 +47,7 @@ def configure(config): def setup(bot): bot_logging(bot, 'SpiceBot_GifSearch', "Starting Setup Procedure") - bot_events_startup_register(bot, ['2003']) + bot_events_startup_register(bot, [botevents.BOT_GIFSEARCH]) if 'SpiceBot_GifSearch' not in bot.memory: bot.memory["SpiceBot_GifSearch"] = {"cache": {}, "badgiflinks": [], 'valid_gif_api_dict': {}} @@ -79,7 +79,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, 2003, "SpiceBot_GifSearch") + bot_events_trigger(bot, botevents.BOT_GIFSEARCH, "SpiceBot_GifSearch") def shutdown(bot): @@ -167,7 +167,7 @@ def getGif(bot, searchdict): if str(searchdict["searchquery"]) not in bot.memory["SpiceBot_GifSearch"]['cache'][currentapi].keys(): bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])] = [] - if bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])] == []: + if not len(bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])]): try: page = requests.get(url, headers=header) @@ -195,7 +195,7 @@ def getGif(bot, searchdict): resultsarray.append(cururl) # make sure there are results - if resultsarray != []: + if len(resultsarray): # Create Temp dict for every result tempresultnum = 0 @@ -215,10 +215,10 @@ def getGif(bot, searchdict): verifygoodlinks.append(gifresult) bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])] = verifygoodlinks - if bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])] != []: + if len(bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])]): gifapiresults.extend(bot.memory["SpiceBot_GifSearch"]['cache'][currentapi][str(searchdict["searchquery"])]) - if gifapiresults == []: + if not len(gifapiresults): return {"error": "No Results were found for '" + searchdict["query"] + "' in the " + str(spicemanip.main(searchdict['gifsearch'], 'orlist')) + " api(s)"} random.shuffle(gifapiresults) @@ -243,7 +243,7 @@ def getGif(bot, searchdict): newlist.append(tempdict) gifapiresults = newlist - if gifapiresults == []: + if not len(gifapiresults): return {"error": "No Results were found for '" + searchdict["query"] + "' in the " + str(spicemanip.main(searchdict['gifsearch'], 'orlist')) + " api(s)"} # return dict @@ -251,7 +251,7 @@ def getGif(bot, searchdict): return gifdict -@sopel.module.event('2003') +@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 23c8231..73250cb 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 +from sopel_modules.SpiceBot_Events.System import bot_events_check, bot_events_recieved, botevents def setup(bot): @@ -18,7 +18,7 @@ def shutdown(bot): del bot.memory["SpiceBot_InvalidCommand"] -@sopel.module.event('1004') +@sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_events_complete(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -31,7 +31,7 @@ def bot_events_complete(bot, trigger): def InvalidCommand_triggers(bot, trigger): return - while not bot_events_check(bot, ['1004', '2002']): + while not bot_events_check(bot, [botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY]): pass triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') diff --git a/sopel_modules/SpiceBot_Kick/__init__.py b/sopel_modules/SpiceBot_Kick/__init__.py new file mode 100644 index 0000000..c752bd4 --- /dev/null +++ b/sopel_modules/SpiceBot_Kick/__init__.py @@ -0,0 +1,97 @@ +# coding=utf8 +"""Sopel Kick + +Sopel Kick is an easy way to kick users from channels +""" + +# pylama:ignore=W0611 + + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.bot +from sopel import tools, module +from sopel.tools import Identifier +from sopel.module import HALFOP +from sopel.config.types import StaticSection, ValidatedAttribute + +from sopel_modules.SpiceBot_SBTools import bot_logging + +import time +from collections import abc +import sys + + +__author__ = 'Sam Zick' +__email__ = 'sam@deathbybandaid.net' +__version__ = '0.1.2' + + +def configure(config): + config.define_section("MAXTARGCONFIG_KICK", MAXTARGCONFIG_KICK, validate=False) + config.MAXTARGCONFIG_KICK.configure_setting('kick', 'MAXTARG limit for KICK') + + +def setup(bot): + + # Inject KICK + bot_logging(bot, '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) + + +@module.event('005') +@module.rule('.*') +def parse_event_005(bot, trigger): + if trigger.args[-1] != 'are supported by this server': + return + parameters = trigger.args[1:-1] + for param in parameters: + if '=' in param: + if param.startswith("TARGMAX"): + param = str(param).split('=')[1] + settings = str(param).split(',') + for setting in settings: + settingname = str(setting).split(':')[0] + if settingname.upper() in ['KICK']: + try: + value = str(setting).split(':')[1] or None + except IndexError: + value = None + if value: + bot.config.MAXTARGCONFIG_KICK.kick = int(value) + + +class MAXTARGCONFIG_KICK(StaticSection): + kick = ValidatedAttribute('kick', default=1) + + +class SopelKICK: + + def kick(self, nick, channel, text=None): + """Send an IRC KICK command. + Within the context of a triggered callable, ``channel`` will default to the + channel in which the call was triggered. If triggered from a private message, + ``channel`` is required (or the call to ``kick()`` will be ignored). + The bot must be a channel operator in specified channel for this to work. + .. versionadded:: 7.0 + """ + if self.channels[channel].privileges[self.nick] < HALFOP: + self.write(['KICK', channel, nick], text) + + +class SopelWrapperKICK(object): + + def kick(self, nick, channel=None, message=None): + if channel is None: + if self._trigger.is_privmsg: + return + else: + channel = self._trigger.sender + if nick is None: + return + self._bot.kick(nick, channel, message) diff --git a/sopel_modules/SpiceBot_Logs/ErrorDisplay.py b/sopel_modules/SpiceBot_Logs/ErrorDisplay.py index 39e50a3..1a18456 100644 --- a/sopel_modules/SpiceBot_Logs/ErrorDisplay.py +++ b/sopel_modules/SpiceBot_Logs/ErrorDisplay.py @@ -4,11 +4,12 @@ from __future__ import unicode_literals, absolute_import, division, print_functi import sopel.module -from sopel_modules.SpiceBot_Events.System import bot_events_recieved +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 -@sopel.module.event('2005') +@sopel.module.event(botevents.BOT_STARTUPMONOLOGUE) @sopel.module.rule('.*') def bot_startup_monologue_start(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -17,14 +18,14 @@ def bot_startup_monologue_start(bot, trigger): searchphrasefound = [] for line in debuglines: - if "modules failed to load" in str(line) and "0 modules failed to load" not in str(line): - searchphrase = str(line).replace(" modules failed to load", "") - searchphrasefound.append(str(searchphrase) + " module(s) failed") - elif "dict files failed to load" in str(line) and "0 dict files failed to load" not in str(line): - searchphrase = str(line).replace(" dict files failed to load", "") - searchphrasefound.append(str(searchphrase) + " dict file(s) failed") + if str(line).endswith("failed to load") and not str(line).startswith("0"): + searchphrasefound.append(line) if len(searchphrasefound): + for foundphase in searchphrasefound: + bot_logging(bot, '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) diff --git a/sopel_modules/SpiceBot_Logs/Logs.py b/sopel_modules/SpiceBot_Logs/Logs.py index 3fdc3ed..e764855 100644 --- a/sopel_modules/SpiceBot_Logs/Logs.py +++ b/sopel_modules/SpiceBot_Logs/Logs.py @@ -6,7 +6,7 @@ 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 +from sopel_modules.SpiceBot_Events.System import bot_events_startup_register, bot_events_recieved, bot_events_trigger, botevents import os @@ -26,11 +26,11 @@ 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, ['2004']) + bot_events_startup_register(bot, [botevents.BOT_LOGS]) bot_logs_setup_check(bot) - bot_events_trigger(bot, 2004, "SpiceBot_Logs") + bot_events_trigger(bot, botevents.BOT_LOGS, "SpiceBot_Logs") def bot_logs_setup_check(bot): @@ -43,7 +43,7 @@ def shutdown(bot): del bot.memory["SpiceBot_Logs"] -@sopel.module.event('1003') +@sopel.module.event(botevents.BOT_CONNECTED) @sopel.module.rule('.*') def join_log_channel(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -68,7 +68,7 @@ def join_log_channel(bot, trigger): def stdio_logs_fetch(bot): - stdio_ignore = ["Loaded:"] + stdio_ignore = [] for logtype in bot.memory['SpiceBot_Logs']["logs"].keys(): stdio_ignore.append("[" + logtype + "]") @@ -94,10 +94,15 @@ def stdio_logs_fetch(bot): filelines = [] debuglines = [] + loadedmodules = [] for line in filelines: - if not line.startswith(tuple(stdio_ignore)): - if not line.isspace(): + 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 @@ -126,7 +131,7 @@ def get_running_pid(bot): return pidnum -@sopel.module.event('2004') +@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 3014765..a095e39 100644 --- a/sopel_modules/SpiceBot_Logs/Logs_Command.py +++ b/sopel_modules/SpiceBot_Logs/Logs_Command.py @@ -6,15 +6,15 @@ import sopel.module import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist, inlist_match -from sopel_modules.SpiceBot_Events.System import bot_events_check +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 @sopel.module.nickname_commands('logs', 'debug') def bot_command_logs(bot, trigger): - while not bot_events_check(bot, '2004'): + while not bot_events_check(bot, botevents.BOT_LOGS): pass if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): @@ -24,11 +24,20 @@ def bot_command_logs(bot, trigger): triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') logtype = spicemanip.main(triggerargs, 1) or None - if not logtype or not inlist(bot, logtype, bot.memory['SpiceBot_Logs']["logs"].keys()): + if not logtype: bot.osd("Current valid log(s) include: " + spicemanip.main(bot.memory['SpiceBot_Logs']["logs"].keys(), 'andlist'), trigger.sender, 'action') return - logtype = inlist_match(bot, logtype, bot.memory['SpiceBot_Logs'].keys()) + 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 len(closestmatches): + bot.notice("No valid logs match " + str(logtype) + ".", trigger.nick) + else: + bot.notice("The following commands may match " + str(logtype) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick) + + return + + logtype = inlist_match(bot, logtype, bot.memory['SpiceBot_Logs']["logs"].keys()) if logtype == "Sopel_systemd": logindex = systemd_logs_fetch(bot) diff --git a/sopel_modules/SpiceBot_SBTools/__init__.py b/sopel_modules/SpiceBot_SBTools/__init__.py index fb4054b..1bb1bed 100644 --- a/sopel_modules/SpiceBot_SBTools/__init__.py +++ b/sopel_modules/SpiceBot_SBTools/__init__.py @@ -84,7 +84,7 @@ def command_permissions_check(bot, trigger, privslist): else: commandrunconsensus.append('True') - if privslist == []: + if not len(privslist): commandrunconsensus.append('True') if 'True' not in commandrunconsensus: @@ -236,13 +236,13 @@ def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse sim_listitems, sim_num = [], [] for listitem in searchlist: - similarlevel = similar(searchitem.lower(), listitem.lower()) + similarlevel = SequenceMatcher(None, searchitem.lower(), listitem.lower()).ratio() if similarlevel >= .75: sim_listitems.append(listitem) sim_num.append(similarlevel) if len(sim_listitems) and len(sim_num): - sim_num, sim_listitems = array_arrangesort(bot, sim_num, sim_listitems) + sim_num, sim_listitems = (list(x) for x in zip(*sorted(zip(sim_num, sim_listitems), key=itemgetter(0)))) if searchorder == 'reverse': sim_listitems = spicemanip.main(sim_listitems, 'reverse', "list") @@ -257,6 +257,13 @@ def array_arrangesort(bot, sortbyarray, arrayb): return sortbyarray, arrayb +def letters_in_string(text): + if text.isupper() or text.islower(): + return True + else: + return False + + """Channel Functions""" @@ -433,10 +440,10 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File", if filecount: if bot: - bot_logging(bot, log_from, 'Registered %d %s files,' % (filecount, configtypename)) - bot_logging(bot, log_from, '%d %s files failed to load' % (fileopenfail, configtypename)) + 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) else: if bot: - bot_logging(bot, log_from, "Warning: Couldn't load any %s files" % (configtypename)) + bot_logging(bot, log_from, "Warning: Couldn't load any %s dict files" % (configtypename)) return configs_dict diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py index c036231..fd5b640 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py @@ -4,19 +4,19 @@ 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 +from sopel_modules.SpiceBot_Events.System import bot_events_recieved, bot_events_startup_register, botevents from sopel_modules.SpiceBot_SBTools import bot_logging def setup(bot): bot_logging(bot, 'SpiceBot_StartupMonologue', "Starting setup procedure") - bot_events_startup_register(bot, ['2010', '2011', '2012']) + bot_events_startup_register(bot, [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('2005', '2010', '2011', '2012') +@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 index 6f1310c..77e15f5 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py @@ -4,12 +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_trigger +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('1003') +@sopel.module.event(botevents.BOT_CONNECTED) @sopel.module.rule('.*') def bot_startup_monologue_start(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -18,10 +19,10 @@ def bot_startup_monologue_start(bot, trigger): 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, 2012, "SpiceBot_StartupMonologue") + bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CONNECTED, "SpiceBot_StartupMonologue") -@sopel.module.event('2002') +@sopel.module.event(botevents.BOT_COMMANDSQUERY) @sopel.module.rule('.*') def bot_startup_monologue_commands(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -34,10 +35,10 @@ def bot_startup_monologue_commands(bot, trigger): 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, 2011, "SpiceBot_StartupMonologue") + bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_COMMANDSQUERY, "SpiceBot_StartupMonologue") -@sopel.module.event('2001') +@sopel.module.event(botevents.BOT_CHANNELS) @sopel.module.rule('.*') def bot_startup_monologue_channels(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -46,10 +47,10 @@ def bot_startup_monologue_channels(bot, trigger): 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, 2010, "SpiceBot_StartupMonologue") + bot_events_trigger(bot, botevents.BOT_STARTUPMONOLOGUE_CHANNELS, "SpiceBot_StartupMonologue") -@sopel.module.event('1004') +@sopel.module.event(botevents.BOT_LOADED) @sopel.module.rule('.*') def bot_startup_monologue_display(bot, trigger): bot_events_recieved(bot, trigger.event) @@ -63,4 +64,5 @@ def bot_startup_monologue_display(bot, trigger): bot.osd(bot.memory['SpiceBot_StartupMonologue'], bot.channels.keys(), 'ACTION') - bot_events_trigger(bot, 2005, "SpiceBot_StartupMonologue") + 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_osd/__init__.py b/sopel_modules/SpiceBot_osd/__init__.py index 105158a..7bd3142 100644 --- a/sopel_modules/SpiceBot_osd/__init__.py +++ b/sopel_modules/SpiceBot_osd/__init__.py @@ -37,17 +37,23 @@ def setup(bot): # Inject OSD bot_logging(bot, 'SpiceBot_OSD', "Implanting OSD function into bot") bot.osd = SopelOSD.osd - sopel.bot.SopelWrapper.osd = SopelOSD.SopelWrapper.osd + sopel.bot.SopelWrapper.osd = SopelWrapperOSD.osd tools.get_available_message_bytes = ToolsOSD.get_available_message_bytes tools.get_sendable_message_list = ToolsOSD.get_sendable_message_list tools.get_message_recipientgroups = ToolsOSD.get_message_recipientgroups # overwrite default bot messaging bot_logging(bot, 'SpiceBot_OSD', "Overwrite Default Sopel messaging commands") - sopel.bot.SopelWrapper.say = SopelOSD.SopelWrapper.say - sopel.bot.SopelWrapper.action = SopelOSD.SopelWrapper.action - sopel.bot.SopelWrapper.notice = SopelOSD.SopelWrapper.notice - sopel.bot.SopelWrapper.reply = SopelOSD.SopelWrapper.reply + bot.osd = SopelOSD.osd + bot.say = SopelOSD.say + bot.action = SopelOSD.action + bot.notice = SopelOSD.notice + bot.reply = SopelOSD.reply + bot.msg = SopelOSD.msg + sopel.bot.SopelWrapper.say = SopelWrapperOSD.say + sopel.bot.SopelWrapper.action = SopelWrapperOSD.action + sopel.bot.SopelWrapper.notice = SopelWrapperOSD.notice + sopel.bot.SopelWrapper.reply = SopelWrapperOSD.reply # verify config settings for server bot_logging(bot, 'SpiceBot_OSD', "Checking for config settings") @@ -181,17 +187,21 @@ class ToolsOSD: messages_list[-1] = messages_list[-1] + message_padding + message else: text_list = [] - while len(message.encode('utf-8')) > max_length: + while len(message.encode('utf-8')) > max_length and not message.isspace(): last_space = message.rfind(' ', 0, max_length) if last_space == -1: # No last space, just split where it is possible - text_list.append(message[:max_length]) + splitappend = message[:max_length] + if not splitappend.isspace(): + text_list.append(splitappend) message = message[max_length:] else: # Split at the last best space found - text_list.append(message[:last_space]) + splitappend = message[:last_space] + if not splitappend.isspace(): + text_list.append(splitappend) message = message[last_space:] - if len(message.encode('utf-8')): + if len(message.encode('utf-8')) and not message.isspace(): text_list.append(message) messages_list.extend(text_list) @@ -318,39 +328,92 @@ class SopelOSD: finally: self.sending.release() - class SopelWrapper(object): + def say(self, text, recipient, max_messages=1): + """Send ``text`` as a PRIVMSG to ``recipient``. + In the context of a triggered callable, the ``recipient`` defaults to + the channel (or nickname, if a private message) from which the message + was received. + """ + self.osd(text, recipient, 'PRIVMSG', max_messages) - def osd(self, messages, recipients=None, text_method='PRIVMSG', max_messages=-1): - if recipients is None: - recipients = self._trigger.sender - self._bot.osd(self, messages, recipients, text_method, max_messages) + def notice(self, text, dest, max_messages=1): + """Send an IRC NOTICE to a user or a channel. - def say(self, message, destination=None, max_messages=1): - if destination is None: - destination = self._trigger.sender - self._bot.osd(self, message, destination, 'PRIVMSG', 1) - # self._bot.say(message, destination, max_messages) + Within the context of a triggered callable, ``dest`` will default to + the channel (or nickname, if a private message), in which the trigger + happened. + """ + self.osd(text, dest, 'NOTICE', max_messages) - def action(self, 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 action(self, text, dest, max_messages=1): + """Send ``text`` as a CTCP ACTION PRIVMSG to ``dest``. - def notice(self, message, destination=None, max_messages=1): - if destination is None: - destination = self._trigger.sender + The same loop detection and length restrictions apply as with + :func:`say`, though automatic message splitting is not available. + + Within the context of a triggered callable, ``dest`` will default to + the channel (or nickname, if a private message), in which the trigger + happened. + """ + self.osd(text, dest, 'ACTION', max_messages) + + def reply(self, text, dest, reply_to, notice=False, max_messages=1): + """Prepend ``reply_to`` to ``text``, and send as a PRIVMSG to ``dest``. + + If ``notice`` is ``True``, send a NOTICE rather than a PRIVMSG. + + The same loop detection and length restrictions apply as with + :func:`say`, though automatic message splitting is not available. + + Within the context of a triggered callable, ``reply_to`` will default to + the nickname of the user who triggered the call, and ``dest`` to the + channel (or nickname, if a private message), in which the trigger + happened. + """ + text = '%s: %s' % (reply_to, text) + if notice: + self.osd(text, dest, 'NOTICE', max_messages) + else: + self.osd(text, dest, 'PRIVMSG', max_messages) + + def msg(self, recipient, text, max_messages=1): + # Deprecated, but way too much of a pain to remove. + self.osd(text, recipient, 'PRIVMSG', max_messages) + + +class SopelWrapperOSD(object): + + def osd(self, messages, recipients=None, text_method='PRIVMSG', max_messages=-1): + if recipients is None: + recipients = self._trigger.sender + self._bot.osd(self, messages, recipients, text_method, max_messages) + + def say(self, message, destination=None, max_messages=1): + if destination is None: + destination = self._trigger.sender + self._bot.osd(self, message, destination, 'PRIVMSG', 1) + # 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: + destination = self._trigger.sender + if reply_to is None: + reply_to = self._trigger.nick + message = '%s: %s' % (reply_to, message) + if notice: self._bot.osd(self, message, destination, 'NOTICE', 1) - # 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: - destination = self._trigger.sender - if reply_to is None: - reply_to = self._trigger.nick - message = '%s: %s' % (reply_to, message) - if notice: - self._bot.osd(self, message, destination, 'NOTICE', 1) - else: - self._bot.osd(self, message, destination, 'PRIVMSG', 1) - # self._bot.reply(message, destination, reply_to, notice, max_messages) + else: + self._bot.osd(self, message, destination, 'PRIVMSG', 1) + # self._bot.reply(message, destination, reply_to, notice, max_messages)