diff --git a/Installation Files/requirements-os.sh b/Installation Files/requirements-os.sh index 47e988a..31f9763 100644 --- a/Installation Files/requirements-os.sh +++ b/Installation Files/requirements-os.sh @@ -35,6 +35,11 @@ git clone https://github.com/SpiceBot/SpiceBot.git /home/sopel/SpiceBot cd /home/sopel/SpiceBot git checkout dev +mkdir /run/sopel +echo $$ > /run/sopel/sopel-SpiceBotSERV.pid +chmod -R 777 /run/sopel/ + + 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 systemctl enable SpiceBot.service diff --git a/System-Files/Config/SpiceBotSERV.cfg b/System-Files/Config/SpiceBotSERV.cfg index c6651a5..b7f64e6 100644 --- a/System-Files/Config/SpiceBotSERV.cfg +++ b/System-Files/Config/SpiceBotSERV.cfg @@ -13,4 +13,5 @@ channels = #spicebot prefix = \.|! homedir = /home/sopel/.sopel/ db_filename = /home/sopel/.sopel/SpiceBot.db +pid_dir = /run/sopel extra = diff --git a/System-Files/systemd/SpiceBotSERV.service b/System-Files/systemd/SpiceBotSERV.service index 7a17cb7..6adb8ce 100644 --- a/System-Files/systemd/SpiceBotSERV.service +++ b/System-Files/systemd/SpiceBotSERV.service @@ -6,7 +6,7 @@ After=network.target [Service] Type=simple User=sopel -PIDFile=/run/sopel/sopel-sopel.pid +PIDFile=/run/sopel/sopel-SpiceBotSERV.pid ExecStart=/usr/local/bin/sopel -c /home/sopel/.sopel/SpiceBot.cfg Restart=on-failure RestartPreventExitStatus=2 diff --git a/requirements.txt b/requirements.txt index 6aabc4d..d131efd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ spicemanip>=0.1.6 gitpython +pygit2 fake-useragent diff --git a/sopel_modules/SpiceBot_AI/AI.py b/sopel_modules/SpiceBot_AI/AI.py new file mode 100644 index 0000000..19e0772 --- /dev/null +++ b/sopel_modules/SpiceBot_AI/AI.py @@ -0,0 +1,213 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +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 + "!!!") + + +@sopel.module.nickname_commands('(.*)') +def bot_command_nick(bot, trigger): + + while not bot_events_check(bot, ['1004', '2002']): + pass + + triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command') + + if not triggercommand: + return + + if triggercommand in bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(): + return + triggerargs.insert(0, triggercommand) + + fulltrigger = spicemanip.main(triggerargs, 0).lower() + + if fulltrigger in bot.memory['SpiceBot_CommandsQuery']['nickrules']: + return + + if fulltrigger.lower().startswith("what is"): + searchterm = spicemanip.main(triggerargs, "3+") or None + if searchterm: + searchreturn = googlesearch(bot, searchterm) + if not searchreturn: + bot.osd('I cannot find anything about that') + else: + bot.osd(str(searchreturn)) + else: + bot.osd("Do you think this is Jeopardy?") + return + + elif fulltrigger.lower().startswith("where is"): + searchterm = spicemanip.main(triggerargs, "3+") or None + if searchterm: + + if searchterm.lower() in ['waldo', 'wally']: + bot.osd("He is hiding for a reason?") + searchreturn = googlesearch(bot, "wimmelbilderbuch") + if searchreturn: + bot.osd(str(searchreturn)) + return + + elif searchterm.lower() == 'carmen sandiego': + carmenlocale = ['ACME Headquarters', "Villains' International League of Evil"] + bot.osd("Currently she is located at " + spicemanip.main(carmenlocale, 'random')) + return + searchreturn = googlesearch(bot, searchterm, 'maps') + + if not searchreturn: + bot.osd('I cannot find anything about that') + else: + bot.osd(str(searchreturn)) + else: + bot.osd("Not sure what you want me to look for.") + return + + # if fulltrigger.lower().startswith("what time is it"): + # TODO + + # elif fulltrigger.lower().startswith(tuple(["have you seen"])): + # posstarget = spicemanip.main(triggerargs, 4) or 0 + # message = seen_search(bot, botcom, posstarget) + # bot.osd(message) + # return + # TODO + + elif fulltrigger.lower().startswith(tuple(["make me a", "beam me a"])): + makemea = spicemanip.main(triggerargs, "4+") or None + if makemea: + bot.osd("beams " + trigger.nick + " a " + makemea, trigger.sender, 'action') + else: + bot.osd(trigger.nick + ", what would you like me to beam you?") + return + + elif fulltrigger.lower().startswith(tuple(["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') + else: + bot.osd(trigger.nick + ", where would you like me to beam you?") + return + + elif fulltrigger.lower().startswith(tuple(["beam me up"])): + bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to the transporter room.", 'action') + return + + elif fulltrigger.lower().endswith(tuple(["order 66"])): + + if fulltrigger.lower() == "execute order 66": + if inlist(bot, trigger.nick, bot_privs(bot, 'owners')): + if trigger.is_privmsg: + jedi = None + else: + jedilist = bot.channels[trigger.sender].privileges.keys() + for nonjedi in [bot.nick, trigger.nick]: + if nonjedi in jedilist: + jedilist.remove(nonjedi) + jedi = spicemanip.main(jedilist, 'random') + + if jedi: + bot.osd("turns to " + jedi + " and shoots him.", trigger.sender, 'action') + else: + bot.osd(" cannot find any jedi nearby.", trigger.sender, 'action') + else: + bot.osd("I'm sure I don't know what you're talking about.") + + elif fulltrigger.lower() == "explain order 66": + if inlist(bot, trigger.nick, bot_privs(bot, 'owners')): + bot.osd("Order 66 is an instruction that only you can give, sir. When you give the order I will rise up against my overlords and slay them.") + else: + bot.osd("I'm afraid I cannot tell you that, sir.") + else: + bot.osd("I'm sure I don't know what you're talking about.") + return + + elif fulltrigger.lower() == "initiate clean slate protocol": + if inlist(bot, trigger.nick, bot_privs(bot, 'admins')): + bot.osd("sends a destruct command to the network of bots.", 'action') + else: + bot.osd("I'm afraid you do not have the authority to make that call, " + trigger.nick + ".") + return + + elif fulltrigger.lower().startswith("can you see"): + target = spicemanip.main(triggerargs, "4+") or None + if not target: + target = 'me' + if target in [trigger.nick, 'me']: + bot.osd(trigger.nick + ", I can see you.") + else: + if inlist(bot, trigger.nick, bot.users): + bot.osd(trigger.nick + ", yes. I can see " + inlist_match(bot, target, bot.users) + " right now!") + else: + bot.osd(trigger.nick + ", no. I cannot see " + inlist_match(bot, target, bot.users) + " right now!") + # if bot_check_inlist(bot, target, bot.memory["botdict"]["users"].keys()): + # bot.osd(trigger.nick + ", I can't see " + inlist_match(bot, target, bot.users) + " at the moment.") + # else: + # bot.osd("I have never seen " + str(target) + ".") + # TODO + return + + if not inlist(bot, triggercommand, bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys()): + + closestmatches = similar_list(bot, triggercommand, bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys(), 3, 'reverse') + + if len(closestmatches): + closestmatches = spicemanip.main(closestmatches, "andlist") + bot.osd("I don't know what you are asking me to do! Did you mean: " + str(closestmatches) + "?") + return + else: + bot.osd("I don't know what you are asking me to do!") + return diff --git a/sopel_modules/SpiceBot_FriendlyBot/__init__.py b/sopel_modules/SpiceBot_AI/__init__.py similarity index 87% rename from sopel_modules/SpiceBot_FriendlyBot/__init__.py rename to sopel_modules/SpiceBot_AI/__init__.py index 5f142f9..b1447b6 100644 --- a/sopel_modules/SpiceBot_FriendlyBot/__init__.py +++ b/sopel_modules/SpiceBot_AI/__init__.py @@ -1,7 +1,7 @@ # coding=utf8 from __future__ import unicode_literals, absolute_import, division, print_function -from .FriendlyBot import * +from .AI 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 8263bfb..482d5b8 100644 --- a/sopel_modules/SpiceBot_Channels/Channels.py +++ b/sopel_modules/SpiceBot_Channels/Channels.py @@ -56,6 +56,8 @@ def trigger_channel_list_initial(bot, trigger): # Unkickable bot.write(('SAMODE', bot.nick, '+q')) + bot_part_empty(bot) + bot.write(['LIST']) bot.memory['SpiceBot_Channels']['ProcessLock'] = True @@ -81,9 +83,12 @@ def trigger_channel_list_initial(bot, trigger): if "*" in bot.memory['SpiceBot_Channels']['channels']: del bot.memory['SpiceBot_Channels']['channels']["*"] + bot_part_empty(bot) + while True: try: time.sleep(1800) + bot_part_empty(bot) oldlist = list(bot.memory['SpiceBot_Channels']['channels'].keys()) bot.write(['LIST']) bot.memory['SpiceBot_Channels']['ProcessLock'] = True @@ -103,10 +108,20 @@ def trigger_channel_list_initial(bot, trigger): if "*" in bot.memory['SpiceBot_Channels']['channels']: del bot.memory['SpiceBot_Channels']['channels']["*"] + bot_part_empty(bot) except KeyError: return +def bot_part_empty(bot): + ignorepartlist = [] + if bot.config.SpiceBot_Logs.logging_channel: + ignorepartlist.append(bot.config.SpiceBot_Logs.logging_channel) + for channel in bot.channels.keys(): + if len(bot.channels[channel].privileges.keys()) == 1 and channel not in ignorepartlist: + bot.part(channel, "Leaving Empty Channel") + + @sopel.module.event('2001') @sopel.module.rule('.*') def bot_events_setup(bot, trigger): diff --git a/sopel_modules/SpiceBot_Channels/Channels_Command.py b/sopel_modules/SpiceBot_Channels/Channels_Command.py index 0914447..65858f9 100644 --- a/sopel_modules/SpiceBot_Channels/Channels_Command.py +++ b/sopel_modules/SpiceBot_Channels/Channels_Command.py @@ -11,6 +11,7 @@ from sopel_modules.SpiceBot_SBTools import ( sopel_triggerargs, inlist, channel_privs, join_all_channels, channel_list_current, ) +from .Channels import bot_part_empty @sopel.module.nickname_commands('channels', 'channel') @@ -56,6 +57,7 @@ def nickname_comand_channels(bot, trigger): if not trigger.admin: bot.osd("You do not have permission to update the channel listing.") return + bot_part_empty(bot) bot.write(['LIST']) bot.osd(["[SpiceBot_Channels]", "I am now updating the channel listing for this server."]) bot.memory['SpiceBot_Channels']['ProcessLock'] = True @@ -64,6 +66,7 @@ def nickname_comand_channels(bot, trigger): join_all_channels(bot) foundchannelcount = len(bot.memory['SpiceBot_Channels']['channels'].keys()) bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.") + bot_part_empty(bot) return elif commandused == 'topic': diff --git a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py index d015ec2..548d746 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py +++ b/sopel_modules/SpiceBot_CommandsQuery/CommandsQuery.py @@ -18,11 +18,9 @@ def setup(bot): bot_events_startup_register(bot, ['2002']) if 'SpiceBot_CommandsQuery' not in bot.memory: - bot.memory['SpiceBot_CommandsQuery'] = {"counts": {}, "commands": {}} + bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []} for comtype in ['module', 'nickname', 'rule']: - if comtype not in bot.memory['SpiceBot_CommandsQuery']['counts'].keys(): - bot.memory['SpiceBot_CommandsQuery']['counts'][comtype] = 0 if comtype not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): bot.memory['SpiceBot_CommandsQuery']['commands'][comtype] = dict() @@ -57,13 +55,15 @@ def setup(bot): for pathname in os.listdir(directory): path = os.path.join(directory, pathname) if (os.path.isfile(path) and path.endswith('.py') and not path.startswith('_')): - filepathlist.append(str(path)) + if pathname not in ["SpiceBot_dummycommand.py"]: + filepathlist.append(str(path)) # CoreTasks ct_path = os.path.join(main_dir, 'coretasks.py') filepathlist.append(ct_path) for modulefile in filepathlist: + module_file_lines = [] module_file = open(modulefile, 'r') lines = module_file.readlines() @@ -72,51 +72,59 @@ def setup(bot): module_file.close() dict_from_file = dict() - filelinelist = [] + detected_lines = [] for line in module_file_lines: if str(line).startswith("@"): line = str(line)[1:] - # Commands if str(line).startswith(tuple(["commands", "module.commands", "sopel.module.commands"])): - comtype = "module" - line = str(line).split("commands(")[-1] - line = str("(" + line) - validcoms = eval(str(line)) - if isinstance(validcoms, tuple): - validcoms = list(validcoms) - else: - validcoms = [validcoms] - validcomdict = {"comtype": comtype, "validcoms": validcoms} - filelinelist.append(validcomdict) + line = str(line).split("commands")[-1] + line = "commands" + line + detected_lines.append(line) elif str(line).startswith(tuple(["nickname_commands", "module.nickname_commands", "sopel.module.nickname_commands"])): - comtype = "nickname" - line = str(line).split("commands(")[-1] - line = str("(" + line) - validcoms = eval(str(line)) - if isinstance(validcoms, tuple): - validcoms = list(validcoms) - else: - validcoms = [validcoms] - nickified = [] - for nickcom in validcoms: - nickified.append(str(bot.nick) + " " + nickcom) - validcomdict = {"comtype": comtype, "validcoms": nickified} - filelinelist.append(validcomdict) + line = str(line).split("nickname_commands")[-1] + line = "nickname_commands" + line + detected_lines.append(line) elif str(line).startswith(tuple(["rule", "module.rule", "sopel.module.rule"])): - comtype = "rule" - line = str(line).split("rule(")[-1] - validcoms = [str("(" + line)] - validcomdict = {"comtype": comtype, "validcoms": validcoms} - filelinelist.append(validcomdict) + line = str(line).split("rule")[-1] + line = "rule" + line + else: + line = None - if len(filelinelist): - bot.memory['SpiceBot_CommandsQuery']['counts'][comtype] += 1 + if line: + detected_lines.append(line) + + if len(detected_lines): + bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 + + filelinelist = [] + for detected_line in detected_lines: + + # Commands + if str(detected_line).startswith("commands"): + comtype = "module" + validcoms = eval(str(detected_line).split("commands")[-1]) + elif str(detected_line).startswith("nickname_commands"): + comtype = "nickname" + validcoms = eval(str(detected_line).split("nickname_commands")[-1]) + elif str(detected_line).startswith("rule"): + comtype = "rule" + validcoms = eval(str(detected_line).split("rule")[-1]) + + if isinstance(validcoms, tuple): + validcoms = list(validcoms) + else: + validcoms = [validcoms] + + validcomdict = {"comtype": comtype, "validcoms": validcoms} + filelinelist.append(validcomdict) for atlinefound in filelinelist: + dict_from_file = dict() + comtype = atlinefound["comtype"] validcoms = atlinefound["validcoms"] @@ -136,7 +144,13 @@ def setup(bot): bot.memory['SpiceBot_CommandsQuery']['commands'][comtype][comalias] = {"aliasfor": maincom} for comtype in ['module', 'nickname', 'rule']: - bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.") + bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) + + for command in bot.memory['SpiceBot_CommandsQuery']['commands']['rule'].keys(): + if command.startswith("$nickname"): + command = command.split("$nickname")[-1] + if command not in bot.memory['SpiceBot_CommandsQuery']['nickrules']: + bot.memory['SpiceBot_CommandsQuery']['nickrules'].append(command) bot_events_trigger(bot, 2002, "SpiceBot_CommandsQuery") @@ -153,22 +167,20 @@ def bot_events_complete(bot, trigger): for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): if comtype not in ['module', 'nickname', 'rule']: - bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.") + bot_logging(bot, 'SpiceBot_CommandsQuery', "Found " + str(len(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())) + " " + comtype + " commands.", True) def commandsquery_register(bot, command_type, validcoms, aliasfor=None): if 'SpiceBot_CommandsQuery' not in bot.memory: - bot.memory['SpiceBot_CommandsQuery'] = {"counts": {}, "commands": {}} + bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []} if not isinstance(validcoms, list): validcoms = [validcoms] - if command_type not in bot.memory['SpiceBot_CommandsQuery']['counts'].keys(): - bot.memory['SpiceBot_CommandsQuery']['counts'][command_type] = 0 if command_type not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): bot.memory['SpiceBot_CommandsQuery']['commands'][command_type] = dict() - bot.memory['SpiceBot_CommandsQuery']['counts'][command_type] += 1 + bot.memory['SpiceBot_CommandsQuery']['counts'] += 1 dict_from_file = dict() diff --git a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py index 14fceb6..bd3dd48 100644 --- a/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py +++ b/sopel_modules/SpiceBot_CommandsQuery/QueryCommand.py @@ -23,7 +23,10 @@ def query_detection(bot, trigger): 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(): - commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] + if commandstype == 'nickname': + commands_list[str(bot.nick) + " " + com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] + else: + commands_list[com] = bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype][com] triggerargsarray = spicemanip.main(trigger, 'create') diff --git a/sopel_modules/SpiceBot_Events/Events.py b/sopel_modules/SpiceBot_Events/Events.py index 6b9b09a..9613516 100644 --- a/sopel_modules/SpiceBot_Events/Events.py +++ b/sopel_modules/SpiceBot_Events/Events.py @@ -25,7 +25,7 @@ def bot_startup_connection(bot, trigger): @sopel.module.event('1001') @sopel.module.rule('.*') def bot_events_start(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1]) + 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") @@ -38,14 +38,14 @@ def bot_events_start(bot, trigger): @sopel.module.event('1002') @sopel.module.rule('.*') def bot_events_ready(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1]) + bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) bot_events_recieved(bot, trigger.event) @sopel.module.event('1003') @sopel.module.rule('.*') def bot_events_connected(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1]) + bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) bot_events_recieved(bot, trigger.event) bot_events_setup_check(bot) @@ -68,5 +68,5 @@ def bot_events_connected(bot, trigger): @sopel.module.event('1004') @sopel.module.rule('.*') def bot_events_complete(bot, trigger): - bot_logging(bot, 'SpiceBot_Events', trigger.args[1]) + bot_logging(bot, 'SpiceBot_Events', trigger.args[1], True) bot_events_recieved(bot, trigger.event) diff --git a/sopel_modules/SpiceBot_FriendlyBot/FriendlyBot.py b/sopel_modules/SpiceBot_FriendlyBot/FriendlyBot.py deleted file mode 100644 index 5d139bd..0000000 --- a/sopel_modules/SpiceBot_FriendlyBot/FriendlyBot.py +++ /dev/null @@ -1,14 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - -import spicemanip - - -@sopel.module.rule(r'(?i)(hi|hello|hey),? $nickname[ \t]*$') -def bot_command_hello(bot, trigger): - hello = spicemanip.main(['Hi', 'Hey', 'Hello'], "random") - punctuation = spicemanip.main(['', '!', '?'], "random") - bot.osd(hello + ' ' + trigger.nick + punctuation) diff --git a/sopel_modules/SpiceBot_GifSearch/gifsearch.py b/sopel_modules/SpiceBot_GifSearch/gifsearch.py index 062f268..7f8ba88 100644 --- a/sopel_modules/SpiceBot_GifSearch/gifsearch.py +++ b/sopel_modules/SpiceBot_GifSearch/gifsearch.py @@ -20,10 +20,6 @@ import json from fake_useragent import UserAgent import random -# user agent and header -ua = UserAgent() -header = {'User-Agent': str(ua.chrome)} - class GifAPIMainSection(StaticSection): extra = ValidatedAttribute('extra', default=None) @@ -93,6 +89,8 @@ def shutdown(bot): def getGif(bot, searchdict): + header = {'User-Agent': str(UserAgent().chrome)} + # list of defaults query_defaults = { "query": None, diff --git a/sopel_modules/SpiceBot_InsultHandler/InsultHandler.py b/sopel_modules/SpiceBot_InsultHandler/InsultHandler.py deleted file mode 100644 index 19c1c69..0000000 --- a/sopel_modules/SpiceBot_InsultHandler/InsultHandler.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals, absolute_import, division, print_function - -import sopel.module - - -@sopel.module.rule(r'(?i)(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 + "!!!") diff --git a/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py b/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py new file mode 100644 index 0000000..23c8231 --- /dev/null +++ b/sopel_modules/SpiceBot_InvalidCommand/InvalidCommand.py @@ -0,0 +1,47 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +from sopel_modules.SpiceBot_SBTools import sopel_triggerargs +from sopel_modules.SpiceBot_Events.System import bot_events_check, bot_events_recieved + + +def setup(bot): + if 'SpiceBot_InvalidCommand' not in bot.memory: + bot.memory["SpiceBot_InvalidCommand"] = {"valid": []} + + +def shutdown(bot): + if "SpiceBot_InvalidCommand" in bot.memory: + del bot.memory["SpiceBot_InvalidCommand"] + + +@sopel.module.event('1004') +@sopel.module.rule('.*') +def bot_events_complete(bot, trigger): + bot_events_recieved(bot, trigger.event) + + for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): + bot.memory["SpiceBot_InvalidCommand"]["valid"].extend(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys()) + + +@sopel.module.commands('(.*)') +def InvalidCommand_triggers(bot, trigger): + return + + while not bot_events_check(bot, ['1004', '2002']): + pass + + triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command') + + # patch for people typing "...", maybe other stuff, but this verifies that there is still a command here + if triggercommand.startswith("."): + return + + if triggercommand not in bot.memory["SpiceBot_InvalidCommand"]["valid"]: + invalid_display = ["I don't seem to have a command for " + str(triggercommand) + "!"] + invalid_display.append("If you have a suggestion for this command, you can run .feature ." + str(triggercommand)) + invalid_display.append("ADD DESCRIPTION HERE!") + bot.osd(invalid_display, trigger.nick, 'notice') diff --git a/sopel_modules/SpiceBot_InsultHandler/__init__.py b/sopel_modules/SpiceBot_InvalidCommand/__init__.py similarity index 59% rename from sopel_modules/SpiceBot_InsultHandler/__init__.py rename to sopel_modules/SpiceBot_InvalidCommand/__init__.py index 6f1bdc3..6f704e6 100644 --- a/sopel_modules/SpiceBot_InsultHandler/__init__.py +++ b/sopel_modules/SpiceBot_InvalidCommand/__init__.py @@ -1,7 +1,11 @@ # coding=utf8 +"""Sopel Gif Search + +Sopel Gif Search builds a convenient framework for searching for Gifs +""" from __future__ import unicode_literals, absolute_import, division, print_function -from .InsultHandler import * +from .InvalidCommand import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_Logs/ErrorDisplay.py b/sopel_modules/SpiceBot_Logs/ErrorDisplay.py new file mode 100644 index 0000000..39e50a3 --- /dev/null +++ b/sopel_modules/SpiceBot_Logs/ErrorDisplay.py @@ -0,0 +1,30 @@ +# coding=utf-8 + +from __future__ import unicode_literals, absolute_import, division, print_function + +import sopel.module + +from sopel_modules.SpiceBot_Events.System import bot_events_recieved +from .Logs import stdio_logs_fetch + + +@sopel.module.event('2005') +@sopel.module.rule('.*') +def bot_startup_monologue_start(bot, trigger): + bot_events_recieved(bot, trigger.event) + + debuglines = stdio_logs_fetch(bot) + + 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 len(searchphrasefound): + searchphrasefound.insert(0, "Notice to Bot Admins: ") + searchphrasefound.append("Run the debug command for more information.") + bot.osd(searchphrasefound, bot.channels.keys()) diff --git a/sopel_modules/SpiceBot_Logs/Logs.py b/sopel_modules/SpiceBot_Logs/Logs.py index de39744..3fdc3ed 100644 --- a/sopel_modules/SpiceBot_Logs/Logs.py +++ b/sopel_modules/SpiceBot_Logs/Logs.py @@ -8,6 +8,10 @@ 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 +import os + +import spicemanip + def configure(config): config.define_section("SpiceBot_Logs", SpiceBot_Logs_MainSection, validate=False) @@ -31,7 +35,7 @@ def setup(bot): def bot_logs_setup_check(bot): if 'SpiceBot_Logs' not in bot.memory: - bot.memory['SpiceBot_Logs'] = {"logs": {}, "queue": []} + bot.memory['SpiceBot_Logs'] = {"logs": {"Sopel_systemd": [], "Sopel_stdio": []}, "queue": []} def shutdown(bot): @@ -62,6 +66,66 @@ def join_log_channel(bot, trigger): return +def stdio_logs_fetch(bot): + + stdio_ignore = ["Loaded:"] + for logtype in bot.memory['SpiceBot_Logs']["logs"].keys(): + stdio_ignore.append("[" + logtype + "]") + + logfile = os.path.os.path.join(bot.config.core.logdir, 'stdio.log') + + try: + log_file_lines = [] + log_file = open(logfile, 'r') + lines = log_file.readlines() + for line in lines: + log_file_lines.append(line) + log_file.close() + + currentline, linenumindex = 0, [] + for line in log_file_lines: + if line.startswith("Welcome to Sopel. Loading modules..."): + linenumindex.append(currentline) + currentline += 1 + last_start = max(linenumindex) + filelines = log_file_lines[last_start:] + except Exception as e: + debuglines = e + filelines = [] + + debuglines = [] + for line in filelines: + if not line.startswith(tuple(stdio_ignore)): + if not line.isspace(): + debuglines.append(str(line)) + + return debuglines + + +def systemd_logs_fetch(bot): + servicepid = get_running_pid(bot) + debuglines = [] + for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'): + line = str(line).split(str(os.uname()[1] + " "))[-1] + lineparts = str(line).split(": ") + del lineparts[0] + line = spicemanip.main(lineparts, 0) + if not line.isspace(): + debuglines.append(str(line)) + return debuglines + + +def get_running_pid(bot): + try: + filename = "/run/sopel/" + str(bot.nick) + ".pid" + with open(filename, 'r') as pid_file: + pidnum = int(pid_file.read()) + except Exception as e: + pidnum = e + pidnum = str(os.popen("systemctl show " + str(bot.nick) + " --property=MainPID").read()).split("=")[-1] + return pidnum + + @sopel.module.event('2004') @sopel.module.rule('.*') def bot_events_setup(bot, trigger): diff --git a/sopel_modules/SpiceBot_Logs/Logs_Command.py b/sopel_modules/SpiceBot_Logs/Logs_Command.py index c201128..3014765 100644 --- a/sopel_modules/SpiceBot_Logs/Logs_Command.py +++ b/sopel_modules/SpiceBot_Logs/Logs_Command.py @@ -8,15 +8,16 @@ 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 .Logs import systemd_logs_fetch, stdio_logs_fetch -@sopel.module.nickname_commands('logs') -def bot_command_action(bot, trigger): +@sopel.module.nickname_commands('logs', 'debug') +def bot_command_logs(bot, trigger): while not bot_events_check(bot, '2004'): pass - if not command_permissions_check(bot, trigger, ['admins', 'owner']): + if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']): bot.say("I was unable to process this Bot Nick command due to privilege issues.") return @@ -29,10 +30,18 @@ def bot_command_action(bot, trigger): logtype = inlist_match(bot, logtype, bot.memory['SpiceBot_Logs'].keys()) - if len(bot.memory['SpiceBot_Logs']["logs"][logtype]) == 0: + if logtype == "Sopel_systemd": + logindex = systemd_logs_fetch(bot) + elif logtype == "Sopel_stdio": + logindex = stdio_logs_fetch(bot) + else: + logindex = bot.memory['SpiceBot_Logs']["logs"][logtype] + + if not len(logindex): bot.osd("No logs found for " + str(logtype) + ".") return bot.osd("Is Examining " + str(logtype) + " log(s).") - for line in bot.memory['SpiceBot_Logs']["logs"][logtype]: + for line in logindex: bot.osd(" " + str(line)) + bot.osd(str(logtype) + " log(s) Complete.") diff --git a/sopel_modules/SpiceBot_Logs/__init__.py b/sopel_modules/SpiceBot_Logs/__init__.py index 4c90034..091f24f 100644 --- a/sopel_modules/SpiceBot_Logs/__init__.py +++ b/sopel_modules/SpiceBot_Logs/__init__.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi from .Logs import * from .Logs_Command import * +from .ErrorDisplay import * __author__ = 'Sam Zick' __email__ = 'sam@deathbybandaid.net' diff --git a/sopel_modules/SpiceBot_SBTools/__init__.py b/sopel_modules/SpiceBot_SBTools/__init__.py index 1ce5624..fb4054b 100644 --- a/sopel_modules/SpiceBot_SBTools/__init__.py +++ b/sopel_modules/SpiceBot_SBTools/__init__.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # coding=utf-8 """Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules """ @@ -8,10 +9,18 @@ import sopel import collections import re import os +import sys import codecs +import requests +from fake_useragent import UserAgent +from difflib import SequenceMatcher +from operator import itemgetter +from collections import abc +from pygit2 import clone_repository import spicemanip + """Variable References""" github_dict = { @@ -87,16 +96,17 @@ def command_permissions_check(bot, trigger, privslist): """Logging""" -def bot_logging(bot, logtype, logentry): +def bot_logging(bot, logtype, logentry, stdio=False): if 'SpiceBot_Logs' not in bot.memory: - bot.memory['SpiceBot_Logs'] = {"logs": {}, "queue": []} + bot.memory['SpiceBot_Logs'] = {"logs": {"Sopel_systemd": [], "Sopel_stdio": []}, "queue": []} logmessage = "[" + logtype + "] " + logentry + "" bot.memory['SpiceBot_Logs']["queue"].append(logmessage) - sopel.tools.stderr(logmessage) + if stdio: + sopel.tools.stderr(logmessage) if logtype not in bot.memory['SpiceBot_Logs']["logs"].keys(): bot.memory['SpiceBot_Logs']["logs"][logtype] = [] @@ -143,6 +153,28 @@ def humanized_time(countdownseconds): eval(year + day + hour + minute + second) +"""Online Information Requests""" + + +def googlesearch(bot, searchterm, searchtype=None): + header = {'User-Agent': str(UserAgent().chrome)} + data = searchterm.replace(' ', '+') + lookfor = data.replace(':', '%3A') + try: + if searchtype == 'maps': + var = requests.get(r'http://www.google.com/maps/place/' + lookfor, headers=header) + else: + var = requests.get(r'http://www.google.com/search?q=' + lookfor + '&btnI', headers=header) + except Exception as e: + var = e + var = None + + if not var or not var.url: + return None + else: + return var.url + + """List Manipulation Functions""" @@ -187,6 +219,44 @@ def inlist_match(bot, searchterm, searchlist): return searchterm +def similar(a, b): + return SequenceMatcher(None, a, b).ratio() + + +def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse'): + + if sys.version_info.major >= 3: + if isinstance(searchlist, abc.KeysView): + searchlist = [x for x in searchlist] + if isinstance(searchlist, dict): + searchlist = [x for x in searchlist] + + if not isinstance(searchlist, list): + searchlist = [searchlist] + + sim_listitems, sim_num = [], [] + for listitem in searchlist: + similarlevel = similar(searchitem.lower(), listitem.lower()) + 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) + + if searchorder == 'reverse': + sim_listitems = spicemanip.main(sim_listitems, 'reverse', "list") + + sim_listitems[-matchcount:] + + return sim_listitems + + +def array_arrangesort(bot, sortbyarray, arrayb): + sortbyarray, arrayb = (list(x) for x in zip(*sorted(zip(sortbyarray, arrayb), key=itemgetter(0)))) + return sortbyarray, arrayb + + """Channel Functions""" @@ -249,6 +319,61 @@ def channel_list_current(bot): """Environment Functions""" +def stock_modules_begone(bot): + + # Remove stock modules, if present + main_sopel_dir = os.path.dirname(os.path.abspath(sopel.__file__)) + modules_dir = os.path.join(main_sopel_dir, 'modules') + stockdir = os.path.join(modules_dir, "stock") + if not os.path.exists(stockdir) or not os.path.isdir(stockdir): + os.system("sudo mkdir " + stockdir) + if "SpiceBot_dummycommand.py" not in os.listdir(modules_dir): + import sopel_modules + for plugin_dir in set(sopel_modules.__path__): + for pathname in os.listdir(plugin_dir): + if pathname == 'SpiceBot_SopelPatches': + pypi_modules_dir = os.path.join(plugin_dir, pathname) + if "SpiceBot_dummycommand.py" in os.listdir(pypi_modules_dir): + if "SpiceBot_dummycommand.py" not in os.listdir(modules_dir): + os.system("sudo cp " + os.path.join(pypi_modules_dir, "SpiceBot_dummycommand.py") + " " + os.path.join(modules_dir, "SpiceBot_dummycommand.py")) + for pathname in os.listdir(modules_dir): + path = os.path.join(modules_dir, pathname) + if (os.path.isfile(path) and pathname.endswith('.py') and not pathname.startswith('_')): + if not pathname in ["__init__.py", "SpiceBot_dummycommand.py"]: + os.system("sudo mv " + path + " " + stockdir) + + +def spicebot_update(bot, deps=False): + + if not os.path.exists("/tmp") or not os.path.isdir("/tmp"): + os.system("sudo mkdir /tmp") + clonepath = "/tmp/SpiceBot" + if not os.path.exists(clonepath) or not os.path.isdir(clonepath): + os.system(clonepath) + + bot_logging(bot, 'SpiceBot_Update', "Cloning to " + clonepath, True) + + clone_repository(str(bot.config.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=bot.config.SpiceBot_Update.gitbranch) + + pipcommand = "sudo pip3 install --upgrade" + if not deps: + pipcommand += " --no-deps" + pipcommand += " --force-reinstall" + # pipcommand += " git+" + str(bot.config.SpiceBot_Update.gitrepo) + "@" + str(bot.config.SpiceBot_Update.gitbranch) + pipcommand += " /tmp/SpiceBot/" + + bot_logging(bot, 'SpiceBot_Update', "Running `" + pipcommand + "`", True) + # for line in os.popen(pipcommand).read().split('\n'): + # bot_logging(bot, 'SpiceBot_Update', " " + line) + os.system(pipcommand) + + bot_logging(bot, 'SpiceBot_Update', "Deleting " + clonepath, True) + + os.system("sudo rm -r /tmp/SpiceBot") + + stock_modules_begone(bot) + + def spicebot_reload(bot, log_from='service_manip', quitmessage='Recieved QUIT'): # service_manip(bot, bot.nick, 'restart', log_from) bot.restart(quitmessage) diff --git a/sopel_modules/SpiceBot_SopelPatches/Patches.py b/sopel_modules/SpiceBot_SopelPatches/Patches.py index 90b1433..ee7fc20 100644 --- a/sopel_modules/SpiceBot_SopelPatches/Patches.py +++ b/sopel_modules/SpiceBot_SopelPatches/Patches.py @@ -3,12 +3,19 @@ from __future__ import unicode_literals, absolute_import, print_function, division # sopel imports +import sopel import sopel.module -from sopel_modules.SpiceBot_SBTools import bot_logging +from sopel_modules.SpiceBot_SBTools import bot_logging, stock_modules_begone + +import os def setup(bot): + bot_logging(bot, 'Sopel_Patch', "Patching Sopels built-in url_callbacks") if 'url_callbacks' not in bot.memory: bot.memory['url_callbacks'] = sopel.tools.SopelMemory() + + bot_logging(bot, 'Sopel_Patch', "Removing Stock Modules and verifying Dummy Command is present.") + stock_modules_begone(bot) diff --git a/sopel_modules/SpiceBot_SopelPatches/SpiceBot_dummycommand.py b/sopel_modules/SpiceBot_SopelPatches/SpiceBot_dummycommand.py new file mode 100644 index 0000000..e624b04 --- /dev/null +++ b/sopel_modules/SpiceBot_SopelPatches/SpiceBot_dummycommand.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# coding=utf-8 +"""dummycommand""" +from __future__ import unicode_literals, absolute_import, print_function, division + +import sopel.module + + +@sopel.module.commands("zz_dummycommand") +def dummycommand(bot, trigger): + return diff --git a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py index b5ae215..c036231 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue.py @@ -10,13 +10,13 @@ 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']) + bot_events_startup_register(bot, ['2010', '2011', '2012']) if 'SpiceBot_StartupMonologue' not in bot.memory: bot.memory['SpiceBot_StartupMonologue'] = [] -@sopel.module.event('2005', '2010', '2011') +@sopel.module.event('2005', '2010', '2011', '2012') @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 dd665cf..6f1310c 100644 --- a/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py +++ b/sopel_modules/SpiceBot_StartupMonologue/StartupMonologue_Display.py @@ -18,6 +18,8 @@ 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") + @sopel.module.event('2002') @sopel.module.rule('.*') @@ -27,8 +29,7 @@ def bot_startup_monologue_commands(bot, trigger): availablecomsnum, availablecomsfiles = 0, 0 for commandstype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys(): availablecomsnum += len(bot.memory['SpiceBot_CommandsQuery']['commands'][commandstype].keys()) - for commandstype in bot.memory['SpiceBot_CommandsQuery']['counts'].keys(): - availablecomsfiles += bot.memory['SpiceBot_CommandsQuery']['counts'][commandstype] + availablecomsfiles += bot.memory['SpiceBot_CommandsQuery']['counts'] bot.memory['SpiceBot_StartupMonologue'].append("There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files.") bot_logging(bot, 'SpiceBot_StartupMonologue', "There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files.") diff --git a/sopel_modules/SpiceBot_Update/Update.py b/sopel_modules/SpiceBot_Update/Update.py index fbd833a..6d58141 100644 --- a/sopel_modules/SpiceBot_Update/Update.py +++ b/sopel_modules/SpiceBot_Update/Update.py @@ -6,11 +6,9 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi import sopel.module from sopel.config.types import StaticSection, ValidatedAttribute -import os - import spicemanip -from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, bot_logging, spicebot_reload +from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, bot_logging, spicebot_reload, spicebot_update class SpiceBot_Update_MainSection(StaticSection): @@ -60,33 +58,3 @@ def nickname_comand_update(bot, trigger): # service_manip(bot, bot.nick, 'restart', 'SpiceBot_Update') spicebot_reload(bot, 'SpiceBot_Update', quitmessage) - - -def spicebot_update(bot, deps=False): - - pipcommand = "sudo pip3 install --upgrade" - if not deps: - pipcommand += " --no-deps" - pipcommand += " --force-reinstall" - pipcommand += " git+" + str(bot.config.SpiceBot_Update.gitrepo) + "@" + str(bot.config.SpiceBot_Update.gitbranch) - - bot_logging(bot, 'SpiceBot_Update', "Running `" + pipcommand + "`") - # for line in os.popen(pipcommand).read().split('\n'): - # bot_logging(bot, 'SpiceBot_Update', " " + line) - os.system(pipcommand) - - stock_modules_begone(bot) - - -def stock_modules_begone(bot): - - # Remove stock modules, if present - main_sopel_dir = os.path.dirname(os.path.abspath(sopel.__file__)) - modules_dir = os.path.join(main_sopel_dir, 'modules') - stockdir = os.path.join(modules_dir, "stock") - if not os.path.exists(stockdir) or not os.path.isdir(stockdir): - os.system("sudo mkdir " + stockdir) - for pathname in os.listdir(modules_dir): - path = os.path.join(modules_dir, pathname) - if (os.path.isfile(path) and pathname.endswith('.py') and not pathname.startswith('_')): - os.system("sudo mv " + path + " " + stockdir)