Merge pull request #35 from deathbybandaid/development

Development
This commit is contained in:
Deathbybandaid 2019-05-09 13:32:05 -04:00 committed by GitHub
commit 1206c12fa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 619 additions and 130 deletions

View File

@ -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

View File

@ -13,4 +13,5 @@ channels = #spicebot
prefix = \.|!
homedir = /home/sopel/.sopel/
db_filename = /home/sopel/.sopel/SpiceBot.db
pid_dir = /run/sopel
extra =

View File

@ -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

View File

@ -1,3 +1,4 @@
spicemanip>=0.1.6
gitpython
pygit2
fake-useragent

View File

@ -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

View File

@ -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'

View File

@ -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):

View File

@ -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':

View File

@ -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()

View File

@ -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')

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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 + "!!!")

View File

@ -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')

View File

@ -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'

View File

@ -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())

View File

@ -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):

View File

@ -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.")

View File

@ -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'

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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.")

View File

@ -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)