mirror of
https://github.com/SpiceBot/SpiceBot.git
synced 2026-11-13 06:59:53 -05:00
commit
af391dbc26
@ -7,3 +7,4 @@ recursive-include tests *
|
|||||||
recursive-exclude * __pycache__
|
recursive-exclude * __pycache__
|
||||||
recursive-exclude * *.py[co]
|
recursive-exclude * *.py[co]
|
||||||
recursive-include sopel_modules/SpiceBot_GifSearch/gifapi *
|
recursive-include sopel_modules/SpiceBot_GifSearch/gifapi *
|
||||||
|
recursive-include sopel_modules/SpiceBot_Configs/aiml *
|
||||||
|
|||||||
243
sopel_modules/SpiceBot/AI.py
Normal file
243
sopel_modules/SpiceBot/AI.py
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot AI system. Based On Chatty cathy
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sopel.tools import Identifier
|
||||||
|
from sopel.config.types import StaticSection, ListAttribute, ValidatedAttribute
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import aiml
|
||||||
|
|
||||||
|
from .Database import db as botdb
|
||||||
|
from .Config import config as botconfig
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_AI_MainSection(StaticSection):
|
||||||
|
extra = ListAttribute('extra')
|
||||||
|
gender = ValidatedAttribute('gender', default='female')
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_AI():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.setup_ai()
|
||||||
|
self.braindirs = []
|
||||||
|
self.dict = {
|
||||||
|
"patterncounts": 0,
|
||||||
|
"filecounts": 0,
|
||||||
|
"sessioncache": {},
|
||||||
|
"files": {}
|
||||||
|
}
|
||||||
|
# Load AIML kernel
|
||||||
|
self.aiml_kernel = aiml.Kernel()
|
||||||
|
|
||||||
|
# aiml parser
|
||||||
|
self.aiml_parser = aiml.AimlParser.create_parser()
|
||||||
|
|
||||||
|
# Don't warn for no matches
|
||||||
|
self.aiml_kernel._verboseMode = False
|
||||||
|
|
||||||
|
# Learn responses
|
||||||
|
self.load_saved_brain()
|
||||||
|
self.load_brain()
|
||||||
|
|
||||||
|
# Load bot values
|
||||||
|
self.load_bot_values()
|
||||||
|
|
||||||
|
def setup_ai(self):
|
||||||
|
botconfig.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False)
|
||||||
|
botconfig.config.aibrain = os.path.join(botconfig.homedir, botconfig.config.core.basename + '.aibrain.brn')
|
||||||
|
|
||||||
|
def load_saved_brain(self):
|
||||||
|
if os.path.isfile(botconfig.config.aibrain):
|
||||||
|
self.aiml_kernel.bootstrap(brainFile=botconfig.config.aibrain)
|
||||||
|
self.save_brain()
|
||||||
|
|
||||||
|
def load_brain(self):
|
||||||
|
import sopel_modules
|
||||||
|
braindirs = []
|
||||||
|
for plugin_dir in set(sopel_modules.__path__):
|
||||||
|
configsdir = os.path.join(plugin_dir, "SpiceBot_Configs")
|
||||||
|
aimldir = os.path.join(configsdir, "aiml")
|
||||||
|
braindirs.append(aimldir)
|
||||||
|
|
||||||
|
if len(botconfig.SpiceBot_AI.extra):
|
||||||
|
for extrabraindir in botconfig.SpiceBot_AI.extra:
|
||||||
|
braindirs.append(extrabraindir)
|
||||||
|
|
||||||
|
# learn directories
|
||||||
|
self.learn(braindirs)
|
||||||
|
self.save_brain()
|
||||||
|
|
||||||
|
def load_bot_values(self):
|
||||||
|
|
||||||
|
current_bot_db = botdb.get_bot_value('botai') or None
|
||||||
|
if current_bot_db:
|
||||||
|
for predicate in current_bot_db.keys():
|
||||||
|
predval = current_bot_db[predicate]
|
||||||
|
self.aiml_kernel.setBotPredicate(predicate, predval)
|
||||||
|
|
||||||
|
# sopel nick
|
||||||
|
self.aiml_kernel.setBotPredicate("nick", botconfig.nick)
|
||||||
|
|
||||||
|
# gender
|
||||||
|
self.aiml_kernel.setBotPredicate("gender", botconfig.SpiceBot_AI.gender.lower())
|
||||||
|
if botconfig.SpiceBot_AI.gender.lower() not in ["male", "female"]:
|
||||||
|
self.aiml_kernel.setBotPredicate("gendertype", "item")
|
||||||
|
else:
|
||||||
|
self.aiml_kernel.setBotPredicate("gendertype", botconfig.SpiceBot_AI.gender.lower())
|
||||||
|
|
||||||
|
def learn(self, braindirs):
|
||||||
|
for braindir in braindirs:
|
||||||
|
if braindir not in self.braindirs:
|
||||||
|
self.braindirs.append(braindir)
|
||||||
|
|
||||||
|
# Count matches
|
||||||
|
for pathname in os.listdir(braindir):
|
||||||
|
self.dict["filecounts"] += 1
|
||||||
|
aimlfile = os.path.join(braindir, pathname)
|
||||||
|
data = open(aimlfile).read()
|
||||||
|
count = data.count('pattern')
|
||||||
|
count = count / 2
|
||||||
|
self.dict["patterncounts"] += int(count)
|
||||||
|
|
||||||
|
tempbrain = tempfile.mkstemp()[1]
|
||||||
|
with open(tempbrain, 'w') as fileo:
|
||||||
|
fileo.write(
|
||||||
|
"<aiml version='1.0.1' encoding='UTF-8'>"
|
||||||
|
" <!-- std-startup.xml -->\n"
|
||||||
|
" <category>\n"
|
||||||
|
" <pattern>LOAD AIML B</pattern>\n"
|
||||||
|
" <template>\n"
|
||||||
|
" <learn>{}</learn>\n"
|
||||||
|
" </template>\n"
|
||||||
|
" </category>\n"
|
||||||
|
"</aiml>".format(os.path.join(braindir, "*.aiml"))
|
||||||
|
)
|
||||||
|
self.aiml_kernel.learn(tempbrain)
|
||||||
|
self.aiml_kernel.respond("LOAD AIML B")
|
||||||
|
|
||||||
|
def on_message(self, bot, trigger, message):
|
||||||
|
|
||||||
|
nick = Identifier(trigger.nick)
|
||||||
|
nick_id = botdb.get_nick_id(nick, create=True)
|
||||||
|
self.check_user_import(nick, nick_id)
|
||||||
|
|
||||||
|
message = self.bot_message_precipher(bot, trigger, message)
|
||||||
|
aiml_response = self.aiml_kernel.respond(message, nick_id)
|
||||||
|
if aiml_response:
|
||||||
|
aiml_response = self.bot_message_decipher(bot, trigger, aiml_response)
|
||||||
|
|
||||||
|
self.save_nick_session(nick, nick_id)
|
||||||
|
self.save_brain()
|
||||||
|
|
||||||
|
return aiml_response
|
||||||
|
|
||||||
|
def bot_message_precipher(self, bot, trigger, message):
|
||||||
|
|
||||||
|
# uppercase input
|
||||||
|
message = message.upper()
|
||||||
|
|
||||||
|
# punctuation
|
||||||
|
puct_dict = {"!": "exclamationmark", ".": "period", "?": "questionmark", ",": "comma"}
|
||||||
|
for puctuation in puct_dict.keys():
|
||||||
|
message = message.replace(puctuation, puct_dict[puctuation])
|
||||||
|
|
||||||
|
# bot items
|
||||||
|
for botitem in ["nick"]:
|
||||||
|
message = message.replace(str(eval("bot." + botitem)).upper(), str("bot" + botitem).upper())
|
||||||
|
|
||||||
|
for triggeritem in ["nick", "sender"]:
|
||||||
|
message = message.replace(str(eval("trigger." + triggeritem)).upper(), str("trigger" + triggeritem).upper())
|
||||||
|
|
||||||
|
return message
|
||||||
|
|
||||||
|
def bot_message_decipher(self, bot, trigger, aiml_response):
|
||||||
|
|
||||||
|
# bot items
|
||||||
|
for botitem in ["nick"]:
|
||||||
|
aiml_response = aiml_response.replace("bot" + botitem, str(eval("bot." + botitem)))
|
||||||
|
|
||||||
|
# trigger items
|
||||||
|
for triggeritem in ["nick", "sender"]:
|
||||||
|
aiml_response = aiml_response.replace("trigger" + triggeritem, str(eval("trigger." + triggeritem)))
|
||||||
|
|
||||||
|
# pronouns
|
||||||
|
botgendertype = self.aiml_kernel.getBotPredicate("gendertype")
|
||||||
|
pronounsdict = {
|
||||||
|
"male": {
|
||||||
|
"main": "he",
|
||||||
|
"possess": "his",
|
||||||
|
"self": "himself",
|
||||||
|
},
|
||||||
|
"female": {
|
||||||
|
"main": "her",
|
||||||
|
"possess": "hers",
|
||||||
|
"self": "herself",
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
"main": "it",
|
||||||
|
"possess": "its",
|
||||||
|
"self": "itself",
|
||||||
|
},
|
||||||
|
"point": {
|
||||||
|
"main": "you",
|
||||||
|
"possess": "yours",
|
||||||
|
"self": "yourself",
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"main": "them",
|
||||||
|
"possess": "theirs",
|
||||||
|
"self": "themselves",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for pronounitem in pronounsdict[botgendertype].keys():
|
||||||
|
aiml_response = aiml_response.replace("BOTPRONOUN" + pronounitem, pronounsdict[botgendertype][pronounitem])
|
||||||
|
triggergendertype = self.getPredicate("gender", trigger.nick)
|
||||||
|
if not triggergendertype or triggergendertype == "":
|
||||||
|
triggergendertype = "point"
|
||||||
|
for pronounitem in pronounsdict[triggergendertype].keys():
|
||||||
|
aiml_response = aiml_response.replace("TRIGGERPRONOUN" + pronounitem, pronounsdict[triggergendertype][pronounitem])
|
||||||
|
|
||||||
|
aiml_response = "\x0315" + aiml_response + "\x03"
|
||||||
|
|
||||||
|
return aiml_response
|
||||||
|
|
||||||
|
def getPredicate(self, predicate, nick, nick_id=None):
|
||||||
|
if not nick_id:
|
||||||
|
nick = Identifier(nick)
|
||||||
|
nick_id = botdb.get_nick_id(nick, create=True)
|
||||||
|
self.aiml_kernel.getPredicate(predicate, nick_id)
|
||||||
|
|
||||||
|
def check_user_import(self, nick, nick_id=None):
|
||||||
|
if not nick_id:
|
||||||
|
nick = Identifier(nick)
|
||||||
|
nick_id = botdb.get_nick_id(nick, create=True)
|
||||||
|
if nick_id not in self.dict["sessioncache"].keys():
|
||||||
|
self.dict["sessioncache"][nick_id] = botdb.get_nick_value(nick, 'botai') or {}
|
||||||
|
for predicate in self.dict["sessioncache"][nick_id].keys():
|
||||||
|
predval = self.dict["sessioncache"][nick_id][predicate]
|
||||||
|
self.aiml_kernel.setPredicate(predicate, predval, nick_id)
|
||||||
|
|
||||||
|
# defaults
|
||||||
|
if "nick" not in self.dict["sessioncache"][nick_id].keys():
|
||||||
|
self.dict["sessioncache"][nick_id]["nick"] = nick
|
||||||
|
self.aiml_kernel.setPredicate("nick", nick, nick_id)
|
||||||
|
|
||||||
|
def save_nick_session(self, nick, nick_id=None):
|
||||||
|
if not nick_id:
|
||||||
|
nick = Identifier(nick)
|
||||||
|
nick_id = botdb.get_nick_id(nick, create=True)
|
||||||
|
sessionData = self.aiml_kernel.getSessionData(nick_id)
|
||||||
|
botdb.set_nick_value(nick, 'botai', sessionData)
|
||||||
|
|
||||||
|
def save_brain(self):
|
||||||
|
self.aiml_kernel.saveBrain(botconfig.config.aibrain)
|
||||||
|
botsessiondata = self.aiml_kernel._botPredicates
|
||||||
|
botdb.set_bot_value('botai', botsessiondata)
|
||||||
|
|
||||||
|
|
||||||
|
botai = SpiceBot_AI()
|
||||||
@ -1,23 +1,39 @@
|
|||||||
# coding=utf8
|
# coding=utf8
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
"""
|
"""
|
||||||
This is the SpiceBot Logs system.
|
This is the SpiceBot Channels system.
|
||||||
|
|
||||||
This Class stores logs in an easy to access manner
|
|
||||||
"""
|
"""
|
||||||
import sopel
|
import sopel
|
||||||
|
from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from .Config import config as botconfig
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_Channels_MainSection(StaticSection):
|
||||||
|
announcenew = ValidatedAttribute('announcenew', default=False)
|
||||||
|
joinall = ValidatedAttribute('joinall', default=False)
|
||||||
|
operadmin = ValidatedAttribute('operadmin', default=False)
|
||||||
|
chanignore = ListAttribute('chanignore')
|
||||||
|
|
||||||
|
|
||||||
class BotChannels():
|
class BotChannels():
|
||||||
"""This Logs all channels known to the server"""
|
"""This Logs all channels known to the server"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.setup_channels()
|
||||||
|
|
||||||
|
self.lock = threading.Lock()
|
||||||
self.channel_lock = False
|
self.channel_lock = False
|
||||||
self.SpiceBot_Channels = {
|
self.dict = {
|
||||||
"list": {},
|
"list": {},
|
||||||
"InitialProcess": False
|
"InitialProcess": False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setup_channels(self):
|
||||||
|
botconfig.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False)
|
||||||
|
|
||||||
def channel_list_request(self, bot):
|
def channel_list_request(self, bot):
|
||||||
bot.write(['LIST'])
|
bot.write(['LIST'])
|
||||||
|
|
||||||
@ -25,16 +41,20 @@ class BotChannels():
|
|||||||
self.channel_lock = True
|
self.channel_lock = True
|
||||||
|
|
||||||
def channel_list_recieve_input(self, trigger):
|
def channel_list_recieve_input(self, trigger):
|
||||||
|
self.lock.acquire()
|
||||||
channel, _, topic = trigger.args[1:]
|
channel, _, topic = trigger.args[1:]
|
||||||
if channel.lower() not in self.SpiceBot_Channels['list'].keys():
|
if channel.lower() not in self.dict['list'].keys():
|
||||||
self.SpiceBot_Channels['list'][channel.lower()] = dict()
|
self.dict['list'][channel.lower()] = dict()
|
||||||
self.SpiceBot_Channels['list'][channel.lower()]['name'] = channel
|
self.dict['list'][channel.lower()]['name'] = channel
|
||||||
self.SpiceBot_Channels['list'][channel.lower()]['topic'] = self.topic_compile(topic)
|
self.dict['list'][channel.lower()]['topic'] = self.topic_compile(topic)
|
||||||
self.channel_lock = True
|
self.channel_lock = True
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
def channel_list_recieve_finish(self):
|
def channel_list_recieve_finish(self):
|
||||||
if not self.SpiceBot_Channels['InitialProcess']:
|
self.lock.acquire()
|
||||||
self.SpiceBot_Channels['InitialProcess'] = True
|
if not self.dict['InitialProcess']:
|
||||||
|
self.dict['InitialProcess'] = True
|
||||||
|
self.lock.release()
|
||||||
self.channel_lock = False
|
self.channel_lock = False
|
||||||
|
|
||||||
def topic_compile(self, topic):
|
def topic_compile(self, topic):
|
||||||
@ -50,28 +70,30 @@ class BotChannels():
|
|||||||
for channel in bot.channels.keys():
|
for channel in bot.channels.keys():
|
||||||
if len(bot.channels[channel].privileges.keys()) == 1 and channel not in ignorepartlist and channel.startswith("#"):
|
if len(bot.channels[channel].privileges.keys()) == 1 and channel not in ignorepartlist and channel.startswith("#"):
|
||||||
bot.part(channel, "Leaving Empty Channel")
|
bot.part(channel, "Leaving Empty Channel")
|
||||||
if channel.lower() in botchannels.SpiceBot_Channels['list']:
|
if channel.lower() in self.dict['list']:
|
||||||
del botchannels.SpiceBot_Channels['list'][channel.lower()]
|
self.lock.acquire()
|
||||||
|
del self.dict['list'][channel.lower()]
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
def join_all_channels(self, bot):
|
def join_all_channels(self, bot):
|
||||||
if bot.config.SpiceBot_Channels.joinall:
|
if botconfig.SpiceBot_Channels.joinall:
|
||||||
for channel in botchannels.SpiceBot_Channels['list'].keys():
|
for channel in self.dict['list'].keys():
|
||||||
if channel.startswith("#"):
|
if channel.startswith("#"):
|
||||||
if channel not in bot.channels.keys() and channel not in bot.config.SpiceBot_Channels.chanignore:
|
if channel not in bot.channels.keys() and channel not in botconfig.SpiceBot_Channels.chanignore:
|
||||||
bot.write(('JOIN', bot.nick, botchannels.SpiceBot_Channels['list'][channel]['name']))
|
bot.write(('JOIN', bot.nick, self.dict['list'][channel]['name']))
|
||||||
if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin:
|
if channel not in bot.channels.keys() and botconfig.SpiceBot_Channels.operadmin:
|
||||||
bot.write(('SAJOIN', bot.nick, botchannels.SpiceBot_Channels['list'][channel]['name']))
|
bot.write(('SAJOIN', bot.nick, self.dict['list'][channel]['name']))
|
||||||
|
|
||||||
def chanadmin_all_channels(self, bot):
|
def chanadmin_all_channels(self, bot):
|
||||||
# Chan ADMIN +a
|
# Chan ADMIN +a
|
||||||
for channel in bot.channels.keys():
|
for channel in bot.channels.keys():
|
||||||
if channel.startswith("#"):
|
if channel.startswith("#"):
|
||||||
if channel not in bot.config.SpiceBot_Channels.chanignore:
|
if channel not in botconfig.SpiceBot_Channels.chanignore:
|
||||||
if bot.config.SpiceBot_Channels.operadmin:
|
if botconfig.SpiceBot_Channels.operadmin:
|
||||||
if not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN:
|
if not bot.channels[channel].privileges[bot.nick] < sopel.module.ADMIN:
|
||||||
bot.write(('SAMODE', channel, "+a", bot.nick))
|
bot.write(('SAMODE', channel, "+a", bot.nick))
|
||||||
else:
|
else:
|
||||||
bot.part(channel)
|
bot.part(channel)
|
||||||
|
|
||||||
|
|
||||||
botchannels = BotChannels()
|
channels = BotChannels()
|
||||||
|
|||||||
259
sopel_modules/SpiceBot/Commands.py
Normal file
259
sopel_modules/SpiceBot/Commands.py
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Commands system.
|
||||||
|
|
||||||
|
This Class stores commands in an easy to access manner
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sopel
|
||||||
|
from sopel.config.types import StaticSection, ValidatedAttribute
|
||||||
|
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
from .Logs import logs
|
||||||
|
from .Config import config as botconfig
|
||||||
|
from .Database import db as botdb
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_Commands_MainSection(StaticSection):
|
||||||
|
query_prefix = ValidatedAttribute('query_prefix', default="?")
|
||||||
|
|
||||||
|
|
||||||
|
class BotCommands():
|
||||||
|
"""This Logs all commands known to the bot"""
|
||||||
|
def __init__(self):
|
||||||
|
self.setup_commands()
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.dict = {
|
||||||
|
"counts": 0,
|
||||||
|
'nickrules': [],
|
||||||
|
'nickaiml': [],
|
||||||
|
"commands": {
|
||||||
|
'module': {},
|
||||||
|
'nickname': {},
|
||||||
|
'rule': {}
|
||||||
|
},
|
||||||
|
'disabled': {}
|
||||||
|
}
|
||||||
|
self.module_files_parse()
|
||||||
|
self.nickrules()
|
||||||
|
for comtype in ['module', 'nickname', 'rule']:
|
||||||
|
logs.log('SpiceBot_Commands', "Found " + str(len(self.dict['commands'][comtype].keys())) + " " + comtype + " commands.", True)
|
||||||
|
|
||||||
|
def setup_commands(self):
|
||||||
|
botconfig.define_section("SpiceBot_Commands", SpiceBot_Commands_MainSection, validate=False)
|
||||||
|
botconfig.core.query_list = str(botconfig.SpiceBot_Commands.query_prefix).replace("\\", '').split("|")
|
||||||
|
botconfig.core.prefix_list.extend(botconfig.SpiceBot_Commands.query_prefix)
|
||||||
|
|
||||||
|
def nickrules(self):
|
||||||
|
for command in self.dict['commands']['rule'].keys():
|
||||||
|
if command.startswith("$nickname"):
|
||||||
|
command = command.split("$nickname")[-1]
|
||||||
|
if command not in self.dict['nickrules']:
|
||||||
|
self.dict['nickrules'].append(command)
|
||||||
|
|
||||||
|
def find_command_type(self, command):
|
||||||
|
for commandstype in self.dict['commands'].keys():
|
||||||
|
if commandstype not in ['rule']:
|
||||||
|
for com in self.dict['commands'][commandstype].keys():
|
||||||
|
if com.lower() == command.lower():
|
||||||
|
return commandstype
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_commands_disabled(self, channel):
|
||||||
|
if not len(list(self.dict['disabled'])):
|
||||||
|
self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {}
|
||||||
|
return self.dict['disabled']
|
||||||
|
|
||||||
|
def check_commands_disabled(self, command, channel):
|
||||||
|
if command in self.get_commands_disabled(channel).keys():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_realcom(self, command, trigger_command_type):
|
||||||
|
realcom = command
|
||||||
|
|
||||||
|
if trigger_command_type not in self.dict['commands'].keys():
|
||||||
|
return realcom
|
||||||
|
|
||||||
|
if command not in self.dict['commands'][trigger_command_type].keys():
|
||||||
|
return realcom
|
||||||
|
|
||||||
|
if "aliasfor" in self.dict['commands'][trigger_command_type][command].keys():
|
||||||
|
realcom = self.dict['commands'][trigger_command_type][command]
|
||||||
|
|
||||||
|
return realcom
|
||||||
|
|
||||||
|
def set_command_disabled(self, command, channel, timestamp, reason, bywhom):
|
||||||
|
if not len(list(self.dict['disabled'])):
|
||||||
|
self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {}
|
||||||
|
self.dict['disabled'][command] = {"reason": reason, "timestamp": timestamp, "disabledby": bywhom}
|
||||||
|
botdb.set_channel_value(channel, 'commands_disabled', self.dict['disabled'])
|
||||||
|
|
||||||
|
def unset_command_disabled(self, command, channel):
|
||||||
|
if not len(list(self.dict['disabled'])):
|
||||||
|
self.dict['disabled'] = botdb.get_channel_value(channel, 'commands_disabled') or {}
|
||||||
|
if command in self.dict['disabled'].keys():
|
||||||
|
del self.dict['disabled'][command]
|
||||||
|
botdb.set_channel_value(channel, 'commands_disabled', self.dict['disabled'])
|
||||||
|
|
||||||
|
def register(self, command_dict):
|
||||||
|
|
||||||
|
self.lock.acquire()
|
||||||
|
|
||||||
|
command_type = command_dict["comtype"]
|
||||||
|
validcoms = command_dict["validcoms"]
|
||||||
|
|
||||||
|
if not isinstance(validcoms, list):
|
||||||
|
validcoms = [validcoms]
|
||||||
|
|
||||||
|
if command_type not in self.dict['commands'].keys():
|
||||||
|
self.dict['commands'][command_type] = dict()
|
||||||
|
|
||||||
|
dict_from_file = dict()
|
||||||
|
|
||||||
|
# default command to filename
|
||||||
|
if "validcoms" not in dict_from_file.keys():
|
||||||
|
dict_from_file["validcoms"] = 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 = []
|
||||||
|
|
||||||
|
self.dict['commands'][command_type][maincom] = dict_from_file
|
||||||
|
for comalias in comaliases:
|
||||||
|
if comalias not in self.dict['commands'][command_type].keys():
|
||||||
|
self.dict['commands'][command_type][comalias] = {"aliasfor": maincom}
|
||||||
|
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
|
def module_directory_list(self):
|
||||||
|
filepathlisting = []
|
||||||
|
|
||||||
|
# main Modules directory
|
||||||
|
main_dir = os.path.dirname(os.path.abspath(sopel.__file__))
|
||||||
|
modules_dir = os.path.join(main_dir, 'modules')
|
||||||
|
filepathlisting.append(modules_dir)
|
||||||
|
|
||||||
|
# Home Directory
|
||||||
|
home_modules_dir = os.path.join(botconfig.homedir, 'modules')
|
||||||
|
if os.path.isdir(home_modules_dir):
|
||||||
|
filepathlisting.append(home_modules_dir)
|
||||||
|
|
||||||
|
# pypi installed
|
||||||
|
try:
|
||||||
|
import sopel_modules
|
||||||
|
for plugin_dir in set(sopel_modules.__path__):
|
||||||
|
for pathname in os.listdir(plugin_dir):
|
||||||
|
pypi_modules_dir = os.path.join(plugin_dir, pathname)
|
||||||
|
filepathlisting.append(pypi_modules_dir)
|
||||||
|
except Exception as e:
|
||||||
|
logs.log('SpiceBOT_COMMANDS', "sopel_modules not loaded :" + str(e))
|
||||||
|
|
||||||
|
# Extra directories
|
||||||
|
for directory in botconfig.extra:
|
||||||
|
filepathlisting.append(directory)
|
||||||
|
|
||||||
|
return filepathlisting
|
||||||
|
|
||||||
|
def module_files_list(self):
|
||||||
|
filepathlisting = self.module_directory_list()
|
||||||
|
|
||||||
|
filepathlist = []
|
||||||
|
|
||||||
|
for directory in filepathlisting:
|
||||||
|
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('_')):
|
||||||
|
if pathname not in ["SpiceBot_dummycommand.py"]:
|
||||||
|
filepathlist.append(str(path))
|
||||||
|
|
||||||
|
# CoreTasks
|
||||||
|
main_dir = os.path.dirname(os.path.abspath(sopel.__file__))
|
||||||
|
ct_path = os.path.join(main_dir, 'coretasks.py')
|
||||||
|
filepathlist.append(ct_path)
|
||||||
|
|
||||||
|
return filepathlist
|
||||||
|
|
||||||
|
def module_files_parse(self):
|
||||||
|
filepathlist = self.module_files_list()
|
||||||
|
|
||||||
|
for modulefile in filepathlist:
|
||||||
|
|
||||||
|
module_file_lines = []
|
||||||
|
module_file = open(modulefile, 'r')
|
||||||
|
lines = module_file.readlines()
|
||||||
|
for line in lines:
|
||||||
|
module_file_lines.append(line)
|
||||||
|
module_file.close()
|
||||||
|
|
||||||
|
detected_lines = []
|
||||||
|
for line in module_file_lines:
|
||||||
|
|
||||||
|
if str(line).startswith("@"):
|
||||||
|
line = str(line)[1:]
|
||||||
|
|
||||||
|
if str(line).startswith(tuple(["commands", "module.commands", "sopel.module.commands"])):
|
||||||
|
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"])):
|
||||||
|
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"])):
|
||||||
|
line = str(line).split("rule")[-1]
|
||||||
|
line = "rule" + line
|
||||||
|
else:
|
||||||
|
line = None
|
||||||
|
|
||||||
|
if line:
|
||||||
|
detected_lines.append(line)
|
||||||
|
|
||||||
|
if len(detected_lines):
|
||||||
|
|
||||||
|
filelinelist = []
|
||||||
|
currentsuccesslines = 0
|
||||||
|
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]
|
||||||
|
for regexcom in ["(.*)", '^\?(.*)']:
|
||||||
|
if regexcom in validcoms:
|
||||||
|
while regexcom in validcoms:
|
||||||
|
validcoms.remove(regexcom)
|
||||||
|
|
||||||
|
if len(validcoms):
|
||||||
|
validcomdict = {"comtype": comtype, "validcoms": validcoms}
|
||||||
|
filelinelist.append(validcomdict)
|
||||||
|
currentsuccesslines += 1
|
||||||
|
|
||||||
|
if currentsuccesslines:
|
||||||
|
self.dict['counts'] += 1
|
||||||
|
|
||||||
|
if len(filelinelist):
|
||||||
|
for atlinefound in filelinelist:
|
||||||
|
self.register(atlinefound)
|
||||||
|
|
||||||
|
|
||||||
|
commands = BotCommands()
|
||||||
57
sopel_modules/SpiceBot/Config.py
Normal file
57
sopel_modules/SpiceBot/Config.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""A way to read the bot's config without bot"""
|
||||||
|
|
||||||
|
from sopel.cli.run import build_parser, get_configuration
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
|
||||||
|
class BotConfig():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.dict = {}
|
||||||
|
# Load config
|
||||||
|
parser = build_parser()
|
||||||
|
if not len(sys.argv[1:]):
|
||||||
|
argv = ['legacy']
|
||||||
|
else:
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
opts = parser.parse_args(argv)
|
||||||
|
self.config = get_configuration(opts)
|
||||||
|
|
||||||
|
self.setup_config()
|
||||||
|
|
||||||
|
# load as dict
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(self.config.filename)
|
||||||
|
for each_section in config.sections():
|
||||||
|
if each_section.lower() not in self.dict.keys():
|
||||||
|
self.dict[each_section.lower()] = dict()
|
||||||
|
for (each_key, each_val) in config.items(each_section):
|
||||||
|
if each_key.lower() not in self.dict[each_section.lower()].keys():
|
||||||
|
self.dict[each_section.lower()][each_key.lower()] = each_val
|
||||||
|
|
||||||
|
def setup_config(self):
|
||||||
|
self.config.core.basename = os.path.basename(self.config.filename).rsplit('.', 1)[0]
|
||||||
|
self.config.core.prefix_list = str(self.config.core.prefix).replace("\\", '').split("|")
|
||||||
|
|
||||||
|
def define_section(self, name, cls_, validate=True):
|
||||||
|
return self.config.define_section(name, cls_, validate)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
''' will only get called for undefined attributes '''
|
||||||
|
"""We will try to find a core value, or return None"""
|
||||||
|
if hasattr(self.config.core, name):
|
||||||
|
return eval("self.config.core." + name)
|
||||||
|
elif name.lower() in self.dict["core"].keys():
|
||||||
|
return self.dict["core"][str(name).lower()]
|
||||||
|
elif hasattr(self.config, name):
|
||||||
|
return eval("self.config." + name)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
config = BotConfig()
|
||||||
595
sopel_modules/SpiceBot/Database.py
Normal file
595
sopel_modules/SpiceBot/Database.py
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Database
|
||||||
|
"""
|
||||||
|
|
||||||
|
# sopel imports
|
||||||
|
from sopel.tools import Identifier
|
||||||
|
import sopel.db
|
||||||
|
from sopel.db import SopelDB, _deserialize
|
||||||
|
|
||||||
|
from .Config import config as botconfig
|
||||||
|
|
||||||
|
from sqlalchemy import Column, String, ForeignKey, Integer, Text
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
BASE = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
class NickIDs(BASE):
|
||||||
|
"""
|
||||||
|
NickIDs SQLAlchemy Class
|
||||||
|
"""
|
||||||
|
__tablename__ = 'nick_ids'
|
||||||
|
nick_id = Column(Integer, primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Nicknames(BASE):
|
||||||
|
"""
|
||||||
|
Nicknames SQLAlchemy Class
|
||||||
|
"""
|
||||||
|
__tablename__ = 'nicknames'
|
||||||
|
nick_id = Column(Integer, ForeignKey('nick_ids.nick_id'), primary_key=True)
|
||||||
|
slug = Column(String(255), primary_key=True)
|
||||||
|
canonical = Column(String(255))
|
||||||
|
|
||||||
|
|
||||||
|
class NickValues(BASE):
|
||||||
|
"""
|
||||||
|
NickValues SQLAlchemy Class
|
||||||
|
"""
|
||||||
|
__tablename__ = 'spice_nick_values'
|
||||||
|
nick_id = Column(Integer, ForeignKey('nick_ids.nick_id'), primary_key=True)
|
||||||
|
namespace = Column(String(255), primary_key=True)
|
||||||
|
key = Column(String(255), primary_key=True)
|
||||||
|
value = Column(Text())
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelValues(BASE):
|
||||||
|
"""
|
||||||
|
ChannelValues SQLAlchemy Class
|
||||||
|
"""
|
||||||
|
__tablename__ = 'spice_channel_values'
|
||||||
|
channel = Column(String(255), primary_key=True)
|
||||||
|
namespace = Column(String(255), primary_key=True)
|
||||||
|
key = Column(String(255), primary_key=True)
|
||||||
|
value = Column(Text())
|
||||||
|
|
||||||
|
|
||||||
|
class PluginValues(BASE):
|
||||||
|
"""
|
||||||
|
PluginValues SQLAlchemy Class
|
||||||
|
"""
|
||||||
|
__tablename__ = 'spice_plugin_values'
|
||||||
|
plugin = Column(String(255), primary_key=True)
|
||||||
|
namespace = Column(String(255), primary_key=True)
|
||||||
|
key = Column(String(255), primary_key=True)
|
||||||
|
value = Column(Text())
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceDB(object):
|
||||||
|
|
||||||
|
# NICK FUNCTIONS
|
||||||
|
|
||||||
|
def set_nick_value(self, nick, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the nick."""
|
||||||
|
nick = Identifier(nick)
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
nick_id = self.get_nick_id(nick)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(NickValues) \
|
||||||
|
.filter(NickValues.nick_id == nick_id) \
|
||||||
|
.filter(NickValues.namespace == namespace)\
|
||||||
|
.filter(NickValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# NickValue exists, update
|
||||||
|
if result:
|
||||||
|
result.value = value
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=value)
|
||||||
|
session.add(new_nickvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def get_nick_value(self, nick, key, namespace='default'):
|
||||||
|
"""Retrieves the value for a given key associated with a nick."""
|
||||||
|
nick = Identifier(nick)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(NickValues) \
|
||||||
|
.filter(Nicknames.nick_id == NickValues.nick_id) \
|
||||||
|
.filter(Nicknames.slug == nick.lower()) \
|
||||||
|
.filter(NickValues.namespace == namespace)\
|
||||||
|
.filter(NickValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
if result is not None:
|
||||||
|
result = result.value
|
||||||
|
return _deserialize(result)
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def delete_nick_value(self, nick, key, namespace='default'):
|
||||||
|
"""Deletes the value for a given key to be associated with the nick."""
|
||||||
|
nick = Identifier(nick)
|
||||||
|
nick_id = self.get_nick_id(nick)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(NickValues) \
|
||||||
|
.filter(NickValues.nick_id == nick_id) \
|
||||||
|
.filter(NickValues.namespace == namespace)\
|
||||||
|
.filter(NickValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# NickValue exists, delete
|
||||||
|
if result:
|
||||||
|
session.delete(result)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_nick_value(self, nick, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the nick."""
|
||||||
|
nick = Identifier(nick)
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
nick_id = self.get_nick_id(nick)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(NickValues) \
|
||||||
|
.filter(NickValues.nick_id == nick_id) \
|
||||||
|
.filter(NickValues.namespace == namespace)\
|
||||||
|
.filter(NickValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# NickValue exists, update
|
||||||
|
if result:
|
||||||
|
result.value = float(result.value) + float(value)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=float(value))
|
||||||
|
session.add(new_nickvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_nick_list(self, nick, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the nick."""
|
||||||
|
nick = Identifier(nick)
|
||||||
|
if not isinstance(entries, list):
|
||||||
|
entries = [entries]
|
||||||
|
entries = json.dumps(entries, ensure_ascii=False)
|
||||||
|
nick_id = self.get_nick_id(nick)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(NickValues) \
|
||||||
|
.filter(NickValues.nick_id == nick_id) \
|
||||||
|
.filter(NickValues.namespace == namespace)\
|
||||||
|
.filter(NickValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# NickValue exists, update
|
||||||
|
if result:
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in result.value:
|
||||||
|
result.value.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in result.value:
|
||||||
|
result.value.remove(entry)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
values = []
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in values:
|
||||||
|
values.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in values:
|
||||||
|
values.remove(entry)
|
||||||
|
new_nickvalue = NickValues(nick_id=nick_id, namespace=namespace, key=key, value=values)
|
||||||
|
session.add(new_nickvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
# CHANNEL FUNCTIONS
|
||||||
|
|
||||||
|
def set_channel_value(self, channel, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the channel."""
|
||||||
|
channel = Identifier(channel).lower()
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(ChannelValues) \
|
||||||
|
.filter(ChannelValues.channel == channel)\
|
||||||
|
.filter(ChannelValues.namespace == namespace)\
|
||||||
|
.filter(ChannelValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, update
|
||||||
|
if result:
|
||||||
|
result.value = value
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=value)
|
||||||
|
session.add(new_channelvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def get_channel_value(self, channel, key, namespace='default'):
|
||||||
|
"""Retrieves the value for a given key associated with a channel."""
|
||||||
|
channel = Identifier(channel).lower()
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(ChannelValues) \
|
||||||
|
.filter(ChannelValues.channel == channel)\
|
||||||
|
.filter(ChannelValues.namespace == namespace)\
|
||||||
|
.filter(ChannelValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
if result is not None:
|
||||||
|
result = result.value
|
||||||
|
return _deserialize(result)
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def delete_channel_value(self, channel, key, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the channel."""
|
||||||
|
channel = Identifier(channel).lower()
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(ChannelValues) \
|
||||||
|
.filter(ChannelValues.channel == channel)\
|
||||||
|
.filter(ChannelValues.namespace == namespace)\
|
||||||
|
.filter(ChannelValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, delete
|
||||||
|
if result:
|
||||||
|
session.delete(result)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_channel_value(self, channel, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the channel."""
|
||||||
|
channel = Identifier(channel).lower()
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(ChannelValues) \
|
||||||
|
.filter(ChannelValues.channel == channel)\
|
||||||
|
.filter(ChannelValues.namespace == namespace)\
|
||||||
|
.filter(ChannelValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, update
|
||||||
|
if result:
|
||||||
|
result.value = float(result.value) + float(value)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=float(value))
|
||||||
|
session.add(new_channelvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_channel_list(self, channel, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the channel."""
|
||||||
|
channel = Identifier(channel).lower()
|
||||||
|
if not isinstance(entries, list):
|
||||||
|
entries = [entries]
|
||||||
|
entries = json.dumps(entries, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(ChannelValues) \
|
||||||
|
.filter(ChannelValues.channel == channel)\
|
||||||
|
.filter(ChannelValues.namespace == namespace)\
|
||||||
|
.filter(ChannelValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, update
|
||||||
|
if result:
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in result.value:
|
||||||
|
result.value.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in result.value:
|
||||||
|
result.value.remove(entry)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
values = []
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in values:
|
||||||
|
values.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in values:
|
||||||
|
values.remove(entry)
|
||||||
|
new_channelvalue = ChannelValues(channel=channel, namespace=namespace, key=key, value=values)
|
||||||
|
session.add(new_channelvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
# PLUGIN FUNCTIONS
|
||||||
|
|
||||||
|
def set_plugin_value(self, plugin, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the plugin."""
|
||||||
|
plugin = Identifier(plugin).lower()
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(PluginValues) \
|
||||||
|
.filter(PluginValues.plugin == plugin)\
|
||||||
|
.filter(PluginValues.namespace == namespace)\
|
||||||
|
.filter(PluginValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# PluginValues exists, update
|
||||||
|
if result:
|
||||||
|
result.value = value
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=value)
|
||||||
|
session.add(new_pluginvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def get_plugin_value(self, plugin, key, namespace='default'):
|
||||||
|
"""Retrieves the value for a given key associated with a plugin."""
|
||||||
|
plugin = Identifier(plugin).lower()
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(PluginValues) \
|
||||||
|
.filter(PluginValues.plugin == plugin)\
|
||||||
|
.filter(PluginValues.namespace == namespace)\
|
||||||
|
.filter(PluginValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
if result is not None:
|
||||||
|
result = result.value
|
||||||
|
return _deserialize(result)
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def delete_plugin_value(self, plugin, key, namespace='default'):
|
||||||
|
"""Deletes the value for a given key to be associated with the plugin."""
|
||||||
|
plugin = Identifier(plugin).lower()
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(PluginValues) \
|
||||||
|
.filter(PluginValues.plugin == plugin)\
|
||||||
|
.filter(PluginValues.namespace == namespace)\
|
||||||
|
.filter(PluginValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# PluginValues exists, delete
|
||||||
|
if result:
|
||||||
|
session.delete(result)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_plugin_value(self, plugin, key, value, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the plugin."""
|
||||||
|
plugin = Identifier(plugin).lower()
|
||||||
|
value = json.dumps(value, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(PluginValues) \
|
||||||
|
.filter(PluginValues.plugin == plugin)\
|
||||||
|
.filter(PluginValues.namespace == namespace)\
|
||||||
|
.filter(PluginValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, update
|
||||||
|
if result:
|
||||||
|
result.value = float(result.value) + float(value)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=float(value))
|
||||||
|
session.add(new_pluginvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def adjust_plugin_list(self, plugin, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
"""Sets the value for a given key to be associated with the plugin."""
|
||||||
|
plugin = Identifier(plugin).lower()
|
||||||
|
if not isinstance(entries, list):
|
||||||
|
entries = [entries]
|
||||||
|
entries = json.dumps(entries, ensure_ascii=False)
|
||||||
|
session = self.ssession()
|
||||||
|
try:
|
||||||
|
result = session.query(PluginValues) \
|
||||||
|
.filter(PluginValues.plugin == plugin)\
|
||||||
|
.filter(PluginValues.namespace == namespace)\
|
||||||
|
.filter(PluginValues.key == key) \
|
||||||
|
.one_or_none()
|
||||||
|
# ChannelValue exists, update
|
||||||
|
if result:
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in result.value:
|
||||||
|
result.value.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in result.value:
|
||||||
|
result.value.remove(entry)
|
||||||
|
session.commit()
|
||||||
|
# DNE - Insert
|
||||||
|
else:
|
||||||
|
values = []
|
||||||
|
if adjustmentdirection == 'add':
|
||||||
|
for entry in entries:
|
||||||
|
if entry not in values:
|
||||||
|
values.append(entry)
|
||||||
|
elif adjustmentdirection == 'del':
|
||||||
|
for entry in entries:
|
||||||
|
while entry in values:
|
||||||
|
values.remove(entry)
|
||||||
|
new_pluginvalue = PluginValues(plugin=plugin, namespace=namespace, key=key, value=values)
|
||||||
|
session.add(new_pluginvalue)
|
||||||
|
session.commit()
|
||||||
|
except SQLAlchemyError:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
|
||||||
|
class BotDatabase():
|
||||||
|
"""A thread safe database cache"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
sopel.db.NickValues = NickValues
|
||||||
|
SopelDB.get_nick_value = SpiceDB.get_nick_value
|
||||||
|
SopelDB.set_nick_value = SpiceDB.set_nick_value
|
||||||
|
SopelDB.delete_nick_value = SpiceDB.delete_nick_value
|
||||||
|
SopelDB.adjust_nick_value = SpiceDB.adjust_nick_value
|
||||||
|
SopelDB.adjust_nick_list = SpiceDB.adjust_nick_list
|
||||||
|
|
||||||
|
sopel.db.ChannelValues = ChannelValues
|
||||||
|
SopelDB.get_channel_value = SpiceDB.get_channel_value
|
||||||
|
SopelDB.set_channel_value = SpiceDB.set_channel_value
|
||||||
|
SopelDB.delete_channel_value = SpiceDB.delete_channel_value
|
||||||
|
SopelDB.adjust_channel_value = SpiceDB.adjust_channel_value
|
||||||
|
SopelDB.adjust_channel_list = SpiceDB.adjust_channel_list
|
||||||
|
|
||||||
|
sopel.db.PluginValues = PluginValues
|
||||||
|
SopelDB.get_plugin_value = SpiceDB.get_plugin_value
|
||||||
|
SopelDB.set_plugin_value = SpiceDB.set_plugin_value
|
||||||
|
SopelDB.delete_plugin_value = SpiceDB.delete_plugin_value
|
||||||
|
SopelDB.adjust_plugin_value = SpiceDB.adjust_plugin_value
|
||||||
|
SopelDB.adjust_plugin_list = SpiceDB.adjust_plugin_list
|
||||||
|
|
||||||
|
self.db = SopelDB(botconfig.config)
|
||||||
|
BASE.metadata.create_all(self.db.engine)
|
||||||
|
|
||||||
|
"""Nick"""
|
||||||
|
|
||||||
|
def get_nick_id(self, nick, create=True):
|
||||||
|
return self.db.get_nick_id(nick, create)
|
||||||
|
|
||||||
|
def get_nick_value(self, nick, key, namespace='default'):
|
||||||
|
return self.db.get_nick_value(nick, key, namespace)
|
||||||
|
|
||||||
|
def set_nick_value(self, nick, key, value, namespace='default'):
|
||||||
|
return self.db.set_nick_value(nick, key, value, namespace)
|
||||||
|
|
||||||
|
def delete_nick_value(self, nick, key, namespace='default'):
|
||||||
|
return self.db.delete_nick_value(nick, key, namespace)
|
||||||
|
|
||||||
|
def adjust_nick_value(self, nick, key, value, namespace='default'):
|
||||||
|
return self.db.adjust_nick_value(nick, key, value, namespace)
|
||||||
|
|
||||||
|
def adjust_nick_list(self, nick, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
return self.db.adjust_nick_list(nick, key, entries, adjustmentdirection, namespace)
|
||||||
|
|
||||||
|
"""Bot"""
|
||||||
|
|
||||||
|
def get_bot_value(self, key, namespace='default'):
|
||||||
|
return self.db.get_nick_value(botconfig.nick, key, namespace)
|
||||||
|
|
||||||
|
def set_bot_value(self, key, value, namespace='default'):
|
||||||
|
return self.db.set_nick_value(botconfig.nick, key, value, namespace)
|
||||||
|
|
||||||
|
def delete_bot_value(self, key, namespace='default'):
|
||||||
|
return self.db.delete_nick_value(botconfig.nick, key, namespace)
|
||||||
|
|
||||||
|
def adjust_bot_value(self, key, value, namespace='default'):
|
||||||
|
return self.db.adjust_nick_value(botconfig.nick, key, value, namespace)
|
||||||
|
|
||||||
|
def adjust_bot_list(self, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
return self.db.adjust_nick_list(botconfig.nick, key, entries, adjustmentdirection, namespace)
|
||||||
|
|
||||||
|
"""Channels"""
|
||||||
|
|
||||||
|
def get_channel_value(self, channel, key, namespace='default'):
|
||||||
|
return self.db.get_channel_value(channel, key, namespace)
|
||||||
|
|
||||||
|
def set_channel_value(self, channel, key, value, namespace='default'):
|
||||||
|
return self.db.set_channel_value(channel, key, value, namespace)
|
||||||
|
|
||||||
|
def delete_channel_value(self, channel, key, namespace='default'):
|
||||||
|
return self.db.delete_channel_value(channel, key, namespace)
|
||||||
|
|
||||||
|
def adjust_channel_value(self, channel, key, value, namespace='default'):
|
||||||
|
return self.db.adjust_channel_value(channel, key, value, namespace)
|
||||||
|
|
||||||
|
def adjust_channel_list(self, nick, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
return self.db.adjust_channel_list(nick, key, entries, adjustmentdirection, namespace)
|
||||||
|
|
||||||
|
"""Plugins"""
|
||||||
|
|
||||||
|
def get_plugin_value(self, plugin, key, namespace='default'):
|
||||||
|
return self.db.get_plugin_value(plugin, key, namespace)
|
||||||
|
|
||||||
|
def set_plugin_value(self, plugin, key, value, namespace='default'):
|
||||||
|
return self.db.set_plugin_value(plugin, key, value, namespace)
|
||||||
|
|
||||||
|
def delete_plugin_value(self, plugin, key, namespace='default'):
|
||||||
|
return self.db.delete_plugin_value(plugin, key, namespace)
|
||||||
|
|
||||||
|
def adjust_plugin_value(self, plugin, key, value, namespace='default'):
|
||||||
|
return self.db.adjust_plugin_value(plugin, key, value, namespace)
|
||||||
|
|
||||||
|
def adjust_plugin_list(self, nick, key, entries, adjustmentdirection, namespace='default'):
|
||||||
|
return self.db.adjust_plugin_list(nick, key, entries, adjustmentdirection, namespace)
|
||||||
|
|
||||||
|
|
||||||
|
db = BotDatabase()
|
||||||
@ -7,9 +7,16 @@ We utilize the Sopel code for event numbers and
|
|||||||
self-trigger the bot into performing actions
|
self-trigger the bot into performing actions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import sopel
|
import sopel
|
||||||
import functools
|
import functools
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from .Logs import logs
|
||||||
|
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# full_message = ':{} PRIVMSG {} :{}'.format(hostmask, sender, msg)
|
||||||
|
|
||||||
|
|
||||||
class BotEvents(object):
|
class BotEvents(object):
|
||||||
@ -17,7 +24,7 @@ class BotEvents(object):
|
|||||||
|
|
||||||
Events will be assigned a 4-digit number above 1000.
|
Events will be assigned a 4-digit number above 1000.
|
||||||
|
|
||||||
This allows you to do, ``@module.event(botevents.BOT_WELCOME)````
|
This allows you to do, ``@module.event(events.BOT_WELCOME)````
|
||||||
|
|
||||||
Triggers handled by this module will be processed immediately.
|
Triggers handled by this module will be processed immediately.
|
||||||
Others will be placed into a queue.
|
Others will be placed into a queue.
|
||||||
@ -26,15 +33,17 @@ class BotEvents(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.lock = threading.Lock()
|
||||||
self.RPL_WELCOME = '001' # This is a defined IRC event
|
self.RPL_WELCOME = '001' # This is a defined IRC event
|
||||||
|
self.BOT_UPTIME = time.time()
|
||||||
self.BOT_WELCOME = '1001'
|
self.BOT_WELCOME = '1001'
|
||||||
self.BOT_READY = '1002'
|
self.BOT_READY = '1002'
|
||||||
self.BOT_CONNECTED = '1003'
|
self.BOT_CONNECTED = '1003'
|
||||||
self.BOT_LOADED = '1004'
|
self.BOT_LOADED = '1004'
|
||||||
self.BOT_RECONNECTED = '1005'
|
self.BOT_RECONNECTED = '1005'
|
||||||
self.defaultevents = [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED, self.BOT_LOADED, self.BOT_RECONNECTED]
|
self.defaultevents = [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED, self.BOT_LOADED, self.BOT_RECONNECTED]
|
||||||
self.SpiceBot_Events = {
|
self.dict = {
|
||||||
"assigned_IDs": {1000: "Default", 1001: "BOT_WELCOME", 1002: "BOT_READY", 1003: "BOT_CONNECTED", 1004: "BOT_LOADED", 1005: "BOT_RECONNECTED"},
|
"assigned_IDs": {1000: "BOT_UPTIME", 1001: "BOT_WELCOME", 1002: "BOT_READY", 1003: "BOT_CONNECTED", 1004: "BOT_LOADED", 1005: "BOT_RECONNECTED"},
|
||||||
"triggers_recieved": {},
|
"triggers_recieved": {},
|
||||||
"trigger_queue": [],
|
"trigger_queue": [],
|
||||||
"startup_required": [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED],
|
"startup_required": [self.BOT_WELCOME, self.BOT_READY, self.BOT_CONNECTED],
|
||||||
@ -43,9 +52,11 @@ class BotEvents(object):
|
|||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
''' will only get called for undefined attributes '''
|
''' will only get called for undefined attributes '''
|
||||||
eventnumber = max(list(self.SpiceBot_Events["assigned_IDs"].keys())) + 1
|
self.lock.acquire()
|
||||||
self.SpiceBot_Events["assigned_IDs"][eventnumber] = str(name)
|
eventnumber = max(list(self.dict["assigned_IDs"].keys())) + 1
|
||||||
|
self.dict["assigned_IDs"][eventnumber] = str(name)
|
||||||
setattr(self, name, str(eventnumber))
|
setattr(self, name, str(eventnumber))
|
||||||
|
self.lock.release()
|
||||||
return str(eventnumber)
|
return str(eventnumber)
|
||||||
|
|
||||||
def trigger(self, bot, number, message="SpiceBot_Events"):
|
def trigger(self, bot, number, message="SpiceBot_Events"):
|
||||||
@ -53,7 +64,7 @@ class BotEvents(object):
|
|||||||
if number in self.defaultevents:
|
if number in self.defaultevents:
|
||||||
self.dispatch(bot, pretriggerdict)
|
self.dispatch(bot, pretriggerdict)
|
||||||
else:
|
else:
|
||||||
self.SpiceBot_Events["trigger_queue"].append(pretriggerdict)
|
self.dict["trigger_queue"].append(pretriggerdict)
|
||||||
|
|
||||||
def dispatch(self, bot, pretriggerdict):
|
def dispatch(self, bot, pretriggerdict):
|
||||||
number = pretriggerdict["number"]
|
number = pretriggerdict["number"]
|
||||||
@ -66,43 +77,51 @@ class BotEvents(object):
|
|||||||
self.recieved({"number": number, "message": message})
|
self.recieved({"number": number, "message": message})
|
||||||
|
|
||||||
def recieved(self, trigger):
|
def recieved(self, trigger):
|
||||||
|
self.lock.acquire()
|
||||||
|
|
||||||
if isinstance(trigger, dict):
|
if isinstance(trigger, dict):
|
||||||
eventnumber = str(trigger["number"])
|
eventnumber = str(trigger["number"])
|
||||||
message = str(trigger["message"])
|
message = str(trigger["message"])
|
||||||
else:
|
else:
|
||||||
eventnumber = str(trigger.event)
|
eventnumber = str(trigger.event)
|
||||||
message = trigger.args[1]
|
message = trigger.args[1]
|
||||||
if eventnumber not in self.SpiceBot_Events["triggers_recieved"]:
|
logs.log('SpiceBot_Events', str(eventnumber) + " " + str(message))
|
||||||
self.SpiceBot_Events["triggers_recieved"][eventnumber] = []
|
if eventnumber not in self.dict["triggers_recieved"]:
|
||||||
self.SpiceBot_Events["triggers_recieved"][eventnumber].append(message)
|
self.dict["triggers_recieved"][eventnumber] = []
|
||||||
|
self.dict["triggers_recieved"][eventnumber].append(message)
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
def check(self, checklist):
|
def check(self, checklist):
|
||||||
if not isinstance(checklist, list):
|
if not isinstance(checklist, list):
|
||||||
checklist = [str(checklist)]
|
checklist = [str(checklist)]
|
||||||
for number in checklist:
|
for number in checklist:
|
||||||
if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys():
|
if str(number) not in self.dict["triggers_recieved"].keys():
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def startup_add(self, startlist):
|
def startup_add(self, startlist):
|
||||||
|
self.lock.acquire()
|
||||||
if not isinstance(startlist, list):
|
if not isinstance(startlist, list):
|
||||||
startlist = [str(startlist)]
|
startlist = [str(startlist)]
|
||||||
self.SpiceBot_Events["startup_required"].extend(startlist)
|
for eventitem in startlist:
|
||||||
|
if eventitem not in self.dict["startup_required"]:
|
||||||
|
self.dict["startup_required"].append(eventitem)
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
def startup_check(self):
|
def startup_check(self):
|
||||||
for number in self.SpiceBot_Events["startup_required"]:
|
for number in self.dict["startup_required"]:
|
||||||
if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys():
|
if str(number) not in self.dict["triggers_recieved"].keys():
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def startup_debug(self):
|
def startup_debug(self):
|
||||||
not_done = []
|
not_done = []
|
||||||
for number in self.SpiceBot_Events["startup_required"]:
|
for number in self.dict["startup_required"]:
|
||||||
if str(number) not in self.SpiceBot_Events["triggers_recieved"].keys():
|
if str(number) not in self.dict["triggers_recieved"].keys():
|
||||||
not_done.append(int(number))
|
not_done.append(int(number))
|
||||||
reference_not_done = []
|
reference_not_done = []
|
||||||
for item in not_done:
|
for item in not_done:
|
||||||
reference_not_done.append(str(self.SpiceBot_Events["assigned_IDs"][item]))
|
reference_not_done.append(str(self.dict["assigned_IDs"][item]))
|
||||||
return reference_not_done
|
return reference_not_done
|
||||||
|
|
||||||
def check_ready(self, checklist):
|
def check_ready(self, checklist):
|
||||||
@ -126,4 +145,4 @@ class BotEvents(object):
|
|||||||
return actual_decorator
|
return actual_decorator
|
||||||
|
|
||||||
|
|
||||||
botevents = BotEvents()
|
events = BotEvents()
|
||||||
|
|||||||
37
sopel_modules/SpiceBot/Kick.py
Normal file
37
sopel_modules/SpiceBot/Kick.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Update system.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sopel.config.types import StaticSection, ValidatedAttribute
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_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
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
raise RuntimeError('Error: KICK requires a channel.')
|
||||||
|
else:
|
||||||
|
channel = self._trigger.sender
|
||||||
|
if nick is None:
|
||||||
|
raise RuntimeError('Error: KICK requires a nick.')
|
||||||
|
self._bot.kick(nick, channel, message)
|
||||||
@ -6,51 +6,74 @@ This is the SpiceBot Logs system.
|
|||||||
This Class stores logs in an easy to access manner
|
This Class stores logs in an easy to access manner
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import threading
|
||||||
import sopel
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
|
from .Config import config as botconfig
|
||||||
|
|
||||||
class botlogs():
|
|
||||||
|
# TODO timestamps
|
||||||
|
|
||||||
|
class BotLogs():
|
||||||
"""This Is a contained source of log information"""
|
"""This Is a contained source of log information"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.SpiceBot_Logs = {
|
self.setup_logs()
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.dict = {
|
||||||
"list": {"Sopel_systemd": [], "Sopel_stdio": []},
|
"list": {"Sopel_systemd": [], "Sopel_stdio": []},
|
||||||
"queue": []
|
"queue": []
|
||||||
}
|
}
|
||||||
self.sopel_config = {
|
|
||||||
"logging_channel": True
|
def setup_logs(self):
|
||||||
}
|
botconfig.core.logs_stdio = os.path.join(botconfig.core.logdir, 'stdio.log')
|
||||||
|
# botconfig.core.logs_stdio = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.stdio.log')
|
||||||
|
botconfig.core.logs_exceptions = os.path.join(botconfig.core.logdir, 'exceptions.log')
|
||||||
|
# botconfig.core.logs_exceptions = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.exceptions.log')
|
||||||
|
botconfig.core.logs_raw = os.path.join(botconfig.core.logdir, 'raw.log')
|
||||||
|
# botconfig.core.logs_raw = os.path.os.path.join(botconfig.core.logdir, botconfig.basename + '.raw.log')
|
||||||
|
|
||||||
|
def botstderr(self, logmessage):
|
||||||
|
sys.stderr.write(logmessage)
|
||||||
|
|
||||||
def log(self, logtype, logentry, stdio=False):
|
def log(self, logtype, logentry, stdio=False):
|
||||||
|
|
||||||
|
self.lock.acquire()
|
||||||
|
|
||||||
logtitle = "[" + logtype + "]"
|
logtitle = "[" + logtype + "]"
|
||||||
logmessage = logtitle + " " + logentry
|
logmessage = logtitle + " " + logentry
|
||||||
|
|
||||||
if self.sopel_config["logging_channel"]:
|
if botconfig.logging_channel:
|
||||||
self.SpiceBot_Logs["queue"].append(logmessage)
|
self.dict["queue"].append(logmessage)
|
||||||
|
|
||||||
if stdio:
|
if stdio:
|
||||||
sopel.tools.stderr(logmessage)
|
self.botstderr(logmessage)
|
||||||
|
|
||||||
if logtype not in self.SpiceBot_Logs["list"].keys():
|
if logtype not in self.dict["list"].keys():
|
||||||
self.SpiceBot_Logs["list"][logtype] = []
|
self.dict["list"][logtype] = []
|
||||||
self.SpiceBot_Logs["list"][logtype].append(logentry)
|
self.dict["list"][logtype].append(logentry)
|
||||||
|
|
||||||
def get_logs(self):
|
self.lock.release()
|
||||||
return []
|
|
||||||
|
|
||||||
def stdio_logs_fetch(self, bot):
|
def get_logs(self, logtype):
|
||||||
|
if logtype == "Sopel_systemd":
|
||||||
|
logindex = self.systemd_logs_fetch()
|
||||||
|
elif logtype == "Sopel_stdio":
|
||||||
|
logindex = self.stdio_logs_fetch()
|
||||||
|
else:
|
||||||
|
logindex = self.dict["list"][logtype]
|
||||||
|
return logindex
|
||||||
|
|
||||||
|
def stdio_logs_fetch(self):
|
||||||
|
|
||||||
stdio_ignore = []
|
stdio_ignore = []
|
||||||
for logtype in botlogs.SpiceBot_Logs["list"].keys():
|
for logtype in self.dict["list"].keys():
|
||||||
stdio_ignore.append("[" + logtype + "]")
|
stdio_ignore.append("[" + logtype + "]")
|
||||||
|
|
||||||
logfile = os.path.os.path.join(bot.config.core.logdir, 'stdio.log')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
log_file_lines = []
|
log_file_lines = []
|
||||||
log_file = open(logfile, 'r')
|
log_file = open(botconfig.logs_stdio, 'r')
|
||||||
lines = log_file.readlines()
|
lines = log_file.readlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
log_file_lines.append(line)
|
log_file_lines.append(line)
|
||||||
@ -80,8 +103,8 @@ class botlogs():
|
|||||||
|
|
||||||
return debuglines
|
return debuglines
|
||||||
|
|
||||||
def systemd_logs_fetch(self, bot):
|
def systemd_logs_fetch(self):
|
||||||
servicepid = self.get_running_pid(bot)
|
servicepid = self.get_running_pid()
|
||||||
debuglines = []
|
debuglines = []
|
||||||
for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'):
|
for line in os.popen(str("sudo journalctl _PID=" + str(servicepid))).read().split('\n'):
|
||||||
line = str(line).split(str(os.uname()[1] + " "))[-1]
|
line = str(line).split(str(os.uname()[1] + " "))[-1]
|
||||||
@ -92,15 +115,15 @@ class botlogs():
|
|||||||
debuglines.append(str(line))
|
debuglines.append(str(line))
|
||||||
return debuglines
|
return debuglines
|
||||||
|
|
||||||
def get_running_pid(self, bot):
|
def get_running_pid(self):
|
||||||
try:
|
try:
|
||||||
filename = "/run/sopel/sopel-" + str(bot.nick) + ".pid"
|
filename = "/run/sopel/sopel-" + str(botconfig.nick) + ".pid"
|
||||||
with open(filename, 'r') as pid_file:
|
with open(filename, 'r') as pid_file:
|
||||||
pidnum = int(pid_file.read())
|
pidnum = int(pid_file.read())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pidnum = e
|
pidnum = e
|
||||||
pidnum = str(os.popen("systemctl show " + str(bot.nick) + " --property=MainPID").read()).split("=")[-1]
|
pidnum = str(os.popen("systemctl show " + str(botconfig.nick) + " --property=MainPID").read()).split("=")[-1]
|
||||||
return pidnum
|
return pidnum
|
||||||
|
|
||||||
|
|
||||||
botlogs = botlogs()
|
logs = BotLogs()
|
||||||
|
|||||||
198
sopel_modules/SpiceBot/Prerun.py
Normal file
198
sopel_modules/SpiceBot/Prerun.py
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Prerun system.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sopel.tools import Identifier
|
||||||
|
|
||||||
|
import functools
|
||||||
|
import copy
|
||||||
|
import datetime
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
from .Tools import command_permissions_check
|
||||||
|
from .Commands import commands as botcommands
|
||||||
|
from .Database import db as botdb
|
||||||
|
|
||||||
|
|
||||||
|
class BotPrerun():
|
||||||
|
def __init__(self):
|
||||||
|
self.dict = {}
|
||||||
|
|
||||||
|
"""Command Splitting"""
|
||||||
|
|
||||||
|
def prerun(self, trigger_command_type='module'):
|
||||||
|
def actual_decorator(function):
|
||||||
|
|
||||||
|
@functools.wraps(function)
|
||||||
|
def internal_prerun(bot, trigger, *args, **kwargs):
|
||||||
|
|
||||||
|
# Primary command used for trigger, and a list of all words
|
||||||
|
trigger_args, trigger_command = self.trigger_args(trigger.args[1], trigger_command_type)
|
||||||
|
|
||||||
|
# Argsdict Defaults
|
||||||
|
argsdict_default = {}
|
||||||
|
argsdict_default["type"] = trigger_command_type
|
||||||
|
argsdict_default["com"] = trigger_command
|
||||||
|
|
||||||
|
realcom = botcommands.get_realcom(argsdict_default["com"], trigger_command_type)
|
||||||
|
argsdict_default["realcom"] = realcom
|
||||||
|
|
||||||
|
# split into && groupings
|
||||||
|
and_split = self.trigger_and_split(trigger_args)
|
||||||
|
|
||||||
|
# Create dict listings for trigger.sb
|
||||||
|
argsdict_list = self.trigger_argsdict_list(argsdict_default, and_split)
|
||||||
|
|
||||||
|
# Run the function for all splits
|
||||||
|
for argsdict in argsdict_list:
|
||||||
|
trigger.sb = copy.deepcopy(argsdict)
|
||||||
|
|
||||||
|
trigger.sb["args"], trigger.sb["hyphen_arg"] = self.trigger_hyphen_args(trigger.sb["args"])
|
||||||
|
if not trigger.sb["hyphen_arg"]:
|
||||||
|
# check if anything prohibits the nick from running the command
|
||||||
|
if self.trigger_runstatus(bot, trigger):
|
||||||
|
function(bot, trigger, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
self.trigger_hyphen_arg_handler(bot, trigger)
|
||||||
|
return
|
||||||
|
|
||||||
|
return internal_prerun
|
||||||
|
return actual_decorator
|
||||||
|
|
||||||
|
def trigger_args(self, triggerargs_one, trigger_command_type='module'):
|
||||||
|
trigger_args = spicemanip.main(triggerargs_one, 'create')
|
||||||
|
if trigger_command_type in ['nickname']:
|
||||||
|
trigger_command = spicemanip.main(trigger_args, 2).lower()
|
||||||
|
trigger_args = spicemanip.main(trigger_args, '3+', 'list')
|
||||||
|
else:
|
||||||
|
trigger_command = spicemanip.main(trigger_args, 1).lower()[1:]
|
||||||
|
trigger_args = spicemanip.main(trigger_args, '2+', 'list')
|
||||||
|
return trigger_args, trigger_command
|
||||||
|
|
||||||
|
def trigger_and_split(self, trigger_args):
|
||||||
|
trigger_args_list_split = spicemanip.main(trigger_args, "split_&&")
|
||||||
|
if not len(trigger_args_list_split):
|
||||||
|
trigger_args_list_split.append([])
|
||||||
|
return trigger_args_list_split
|
||||||
|
|
||||||
|
def trigger_argsdict_list(self, argsdict_default, and_split):
|
||||||
|
prerun_split = []
|
||||||
|
for trigger_args_part in and_split:
|
||||||
|
argsdict_part = copy.deepcopy(argsdict_default)
|
||||||
|
argsdict_part["args"] = spicemanip.main(trigger_args_part, 'create')
|
||||||
|
if len(argsdict_part["args"]) and argsdict_part["args"][0] == "-a":
|
||||||
|
argsdict_part["adminswitch"] = True
|
||||||
|
argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list')
|
||||||
|
else:
|
||||||
|
argsdict_part["adminswitch"] = False
|
||||||
|
prerun_split.append(argsdict_part)
|
||||||
|
return prerun_split
|
||||||
|
|
||||||
|
def trigger_runstatus(self, bot, trigger):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Bots can't run commands
|
||||||
|
if Identifier(trigger.nick) == bot.nick:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Allow permissions for enabling and disabling commands via hyphenargs
|
||||||
|
if trigger.sb["adminswitch"]:
|
||||||
|
if command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
bot.osd("The admin switch (-a) is for use by authorized nicks ONLY.", 'notice')
|
||||||
|
return False
|
||||||
|
|
||||||
|
# don't run commands that are disabled in channels
|
||||||
|
if not trigger.is_privmsg:
|
||||||
|
commandused = trigger.sb["realcom"]
|
||||||
|
disabled_list = botdb.get_channel_value(trigger.sender, 'commands_disabled') or {}
|
||||||
|
if commandused in disabled_list.keys():
|
||||||
|
reason = disabled_list[trigger.sb["realcom"]]["reason"]
|
||||||
|
timestamp = disabled_list[trigger.sb["realcom"]]["timestamp"]
|
||||||
|
bywhom = disabled_list[trigger.sb["realcom"]]["disabledby"]
|
||||||
|
message = "The " + str(trigger.sb["com"]) + " command was disabled by " + bywhom + " in " + str(trigger.sender) + " at " + str(timestamp) + " for the following reason: " + str(reason)
|
||||||
|
return self.trigger_cant_run(bot, trigger, message)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def trigger_cant_run(self, bot, trigger, message=None):
|
||||||
|
if message:
|
||||||
|
bot.osd(message, trigger.nick, 'notice')
|
||||||
|
if command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
bot.osd("You however are authorized to bypass this warning with the (-a) admin switch.", trigger.nick, 'notice')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def trigger_hyphen_args(self, trigger_args_part):
|
||||||
|
valid_hyphen_args = [
|
||||||
|
'check',
|
||||||
|
'enable', 'disable'
|
||||||
|
]
|
||||||
|
hyphen_args = []
|
||||||
|
trigger_args_unhyphend = []
|
||||||
|
for worditem in trigger_args_part:
|
||||||
|
if str(worditem).startswith("--") and worditem[2:] in valid_hyphen_args:
|
||||||
|
hyphen_args.append(worditem[2:])
|
||||||
|
else:
|
||||||
|
trigger_args_unhyphend.append(worditem)
|
||||||
|
if len(hyphen_args):
|
||||||
|
hyphenarg = hyphen_args[0]
|
||||||
|
else:
|
||||||
|
hyphenarg = None
|
||||||
|
return trigger_args_unhyphend, hyphenarg
|
||||||
|
|
||||||
|
def trigger_hyphen_arg_handler(self, bot, trigger):
|
||||||
|
|
||||||
|
# Commands that cannot run via privmsg
|
||||||
|
if trigger.sb["hyphen_arg"] in ['check']:
|
||||||
|
if trigger.sb["com"].lower() != trigger.sb["realcom"]:
|
||||||
|
bot.osd(trigger.sb["com"] + " is a valid alias command for " + trigger.sb["realcom"])
|
||||||
|
else:
|
||||||
|
bot.osd(trigger.sb["com"] + " is a valid command")
|
||||||
|
return
|
||||||
|
|
||||||
|
elif trigger.sb["hyphen_arg"] in ['enable']:
|
||||||
|
|
||||||
|
if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
bot.osd("I was unable to disable this command due to privilege issues.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.is_privmsg:
|
||||||
|
bot.osd("This command must be run in a channel you which to enable it in.", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not botcommands.check_commands_disabled(trigger.sb["realcom"], trigger.sender):
|
||||||
|
bot.osd(trigger.sb["com"] + " is already enabled in " + str(trigger.sender), trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
botcommands.unset_command_disabled(trigger.sb["realcom"], trigger.sender)
|
||||||
|
bot.osd(trigger.sb["com"] + " is now enabled in " + str(trigger.sender))
|
||||||
|
return
|
||||||
|
|
||||||
|
elif trigger.sb["hyphen_arg"] in ['disable']:
|
||||||
|
|
||||||
|
if not command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
bot.osd("I was unable to disable this command due to privilege issues.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.is_privmsg:
|
||||||
|
bot.osd("This command must be run in a channel you which to disable it in.", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
if botcommands.check_commands_disabled(trigger.sb["realcom"], trigger.sender):
|
||||||
|
bot.osd(trigger.sb["com"] + " is already disabled in " + str(trigger.sender), trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
trailingmessage = spicemanip.main(trigger.sb["args"], 0) or "No reason given."
|
||||||
|
timestamp = str(datetime.datetime.utcnow())
|
||||||
|
|
||||||
|
botcommands.set_command_disabled(trigger.sb["realcom"], trigger.sender, timestamp, trailingmessage, trigger.nick)
|
||||||
|
bot.osd(trigger.sb["com"] + " is now disabled in " + str(trigger.sender))
|
||||||
|
return
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
prerun = BotPrerun()
|
||||||
13
sopel_modules/SpiceBot/StartupMonologue.py
Normal file
13
sopel_modules/SpiceBot/StartupMonologue.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""StartupMonologue class"""
|
||||||
|
|
||||||
|
|
||||||
|
class BotMonologue():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.dict = {}
|
||||||
|
|
||||||
|
|
||||||
|
startupmonologue = BotMonologue()
|
||||||
@ -7,7 +7,6 @@ from __future__ import unicode_literals, absolute_import, print_function, divisi
|
|||||||
import sopel
|
import sopel
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import codecs
|
import codecs
|
||||||
@ -20,7 +19,8 @@ from pygit2 import clone_repository
|
|||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
from .Logs import logs
|
||||||
|
from .Config import config as botconfig
|
||||||
|
|
||||||
|
|
||||||
"""Variable References"""
|
"""Variable References"""
|
||||||
@ -39,27 +39,10 @@ github_dict = {
|
|||||||
"""Sopel Wrapping Tools"""
|
"""Sopel Wrapping Tools"""
|
||||||
|
|
||||||
|
|
||||||
def sopel_triggerargs(bot, trigger, command_type='module_command'):
|
def bot_privs(privtype):
|
||||||
triggerargs = []
|
|
||||||
|
|
||||||
if len(trigger.args) > 1:
|
|
||||||
triggerargs = spicemanip.main(trigger.args[1], 'create')
|
|
||||||
triggerargs = spicemanip.main(triggerargs, 'create')
|
|
||||||
|
|
||||||
if command_type in ['nickname_command']:
|
|
||||||
command = spicemanip.main(triggerargs, 2).lower()
|
|
||||||
triggerargs = spicemanip.main(triggerargs, '3+', 'list')
|
|
||||||
else:
|
|
||||||
command = spicemanip.main(triggerargs, 1).lower()[1:]
|
|
||||||
triggerargs = spicemanip.main(triggerargs, '2+', 'list')
|
|
||||||
|
|
||||||
return triggerargs, command
|
|
||||||
|
|
||||||
|
|
||||||
def bot_privs(bot, privtype):
|
|
||||||
if privtype == 'owners':
|
if privtype == 'owners':
|
||||||
privtype = 'owner'
|
privtype = 'owner'
|
||||||
botpriveval = eval("bot.config.core." + privtype)
|
botpriveval = eval("botconfig." + privtype)
|
||||||
if not isinstance(botpriveval, list):
|
if not isinstance(botpriveval, list):
|
||||||
botpriveval = [botpriveval]
|
botpriveval = [botpriveval]
|
||||||
return botpriveval
|
return botpriveval
|
||||||
@ -71,8 +54,8 @@ def command_permissions_check(bot, trigger, privslist):
|
|||||||
|
|
||||||
for botpriv in ["admins", "owner"]:
|
for botpriv in ["admins", "owner"]:
|
||||||
if botpriv in privslist:
|
if botpriv in privslist:
|
||||||
botpriveval = bot_privs(bot, botpriv)
|
botpriveval = bot_privs(botpriv)
|
||||||
if not inlist(bot, trigger.nick, botpriveval):
|
if not inlist(trigger.nick, botpriveval):
|
||||||
commandrunconsensus.append('False')
|
commandrunconsensus.append('False')
|
||||||
else:
|
else:
|
||||||
commandrunconsensus.append('True')
|
commandrunconsensus.append('True')
|
||||||
@ -81,7 +64,7 @@ def command_permissions_check(bot, trigger, privslist):
|
|||||||
for chanpriv in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']:
|
for chanpriv in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']:
|
||||||
if chanpriv in privslist:
|
if chanpriv in privslist:
|
||||||
chanpriveval = channel_privs(bot, trigger.sender, chanpriv)
|
chanpriveval = channel_privs(bot, trigger.sender, chanpriv)
|
||||||
if not inlist(bot, trigger.nick, chanpriveval):
|
if not inlist(trigger.nick, chanpriveval):
|
||||||
commandrunconsensus.append('False')
|
commandrunconsensus.append('False')
|
||||||
else:
|
else:
|
||||||
commandrunconsensus.append('True')
|
commandrunconsensus.append('True')
|
||||||
@ -135,7 +118,7 @@ def humanized_time(countdownseconds):
|
|||||||
"""Online Information Requests"""
|
"""Online Information Requests"""
|
||||||
|
|
||||||
|
|
||||||
def googlesearch(bot, searchterm, searchtype=None):
|
def googlesearch(searchterm, searchtype=None):
|
||||||
header = {'User-Agent': str(UserAgent().chrome)}
|
header = {'User-Agent': str(UserAgent().chrome)}
|
||||||
data = searchterm.replace(' ', '+')
|
data = searchterm.replace(' ', '+')
|
||||||
lookfor = data.replace(':', '%3A')
|
lookfor = data.replace(':', '%3A')
|
||||||
@ -157,7 +140,7 @@ def googlesearch(bot, searchterm, searchtype=None):
|
|||||||
"""List Manipulation Functions"""
|
"""List Manipulation Functions"""
|
||||||
|
|
||||||
|
|
||||||
def inlist(bot, searchterm, searchlist):
|
def inlist(searchterm, searchlist):
|
||||||
|
|
||||||
# verify we are searching a list
|
# verify we are searching a list
|
||||||
if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict):
|
if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict):
|
||||||
@ -178,7 +161,7 @@ def inlist(bot, searchterm, searchlist):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def inlist_match(bot, searchterm, searchlist):
|
def inlist_match(searchterm, searchlist):
|
||||||
# verify we are searching a list
|
# verify we are searching a list
|
||||||
if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict):
|
if isinstance(searchlist, collections.abc.KeysView) or isinstance(searchlist, dict):
|
||||||
searchlist = [x for x in searchlist]
|
searchlist = [x for x in searchlist]
|
||||||
@ -202,7 +185,7 @@ def similar(a, b):
|
|||||||
return SequenceMatcher(None, a, b).ratio()
|
return SequenceMatcher(None, a, b).ratio()
|
||||||
|
|
||||||
|
|
||||||
def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse'):
|
def similar_list(searchitem, searchlist, matchcount=1, searchorder='reverse'):
|
||||||
|
|
||||||
if sys.version_info.major >= 3:
|
if sys.version_info.major >= 3:
|
||||||
if isinstance(searchlist, abc.KeysView):
|
if isinstance(searchlist, abc.KeysView):
|
||||||
@ -231,7 +214,7 @@ def similar_list(bot, searchitem, searchlist, matchcount=1, searchorder='reverse
|
|||||||
return sim_listitems
|
return sim_listitems
|
||||||
|
|
||||||
|
|
||||||
def array_arrangesort(bot, sortbyarray, arrayb):
|
def array_arrangesort(sortbyarray, arrayb):
|
||||||
sortbyarray, arrayb = (list(x) for x in zip(*sorted(zip(sortbyarray, arrayb), key=itemgetter(0))))
|
sortbyarray, arrayb = (list(x) for x in zip(*sorted(zip(sortbyarray, arrayb), key=itemgetter(0))))
|
||||||
return sortbyarray, arrayb
|
return sortbyarray, arrayb
|
||||||
|
|
||||||
@ -246,12 +229,6 @@ def letters_in_string(text):
|
|||||||
"""Channel Functions"""
|
"""Channel Functions"""
|
||||||
|
|
||||||
|
|
||||||
def topic_compile(topic):
|
|
||||||
actual_topic = re.compile(r'^\[\+[a-zA-Z]+\] (.*)')
|
|
||||||
topic = re.sub(actual_topic, r'\1', topic)
|
|
||||||
return topic
|
|
||||||
|
|
||||||
|
|
||||||
def channel_privs(bot, channel, privtype):
|
def channel_privs(bot, channel, privtype):
|
||||||
privlist = []
|
privlist = []
|
||||||
for user in bot.channels[channel].privileges.keys():
|
for user in bot.channels[channel].privileges.keys():
|
||||||
@ -273,7 +250,7 @@ def channel_privs(bot, channel, privtype):
|
|||||||
"""Environment Functions"""
|
"""Environment Functions"""
|
||||||
|
|
||||||
|
|
||||||
def stock_modules_begone(bot):
|
def stock_modules_begone():
|
||||||
|
|
||||||
# Remove stock modules, if present
|
# Remove stock modules, if present
|
||||||
main_sopel_dir = os.path.dirname(os.path.abspath(sopel.__file__))
|
main_sopel_dir = os.path.dirname(os.path.abspath(sopel.__file__))
|
||||||
@ -297,7 +274,7 @@ def stock_modules_begone(bot):
|
|||||||
os.system("sudo mv " + path + " " + stockdir)
|
os.system("sudo mv " + path + " " + stockdir)
|
||||||
|
|
||||||
|
|
||||||
def spicebot_update(bot, deps=False):
|
def spicebot_update(deps=False):
|
||||||
|
|
||||||
if not os.path.exists("/tmp") or not os.path.isdir("/tmp"):
|
if not os.path.exists("/tmp") or not os.path.isdir("/tmp"):
|
||||||
os.system("sudo mkdir /tmp")
|
os.system("sudo mkdir /tmp")
|
||||||
@ -305,48 +282,48 @@ def spicebot_update(bot, deps=False):
|
|||||||
if not os.path.exists(clonepath) or not os.path.isdir(clonepath):
|
if not os.path.exists(clonepath) or not os.path.isdir(clonepath):
|
||||||
os.system(clonepath)
|
os.system(clonepath)
|
||||||
|
|
||||||
botlogs.log('SpiceBot_Update', "Cloning to " + clonepath, True)
|
logs.log('SpiceBot_Update', "Cloning to " + clonepath, True)
|
||||||
|
|
||||||
clone_repository(str(bot.config.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=bot.config.SpiceBot_Update.gitbranch)
|
clone_repository(str(botconfig.SpiceBot_Update.gitrepo + ".git"), clonepath, checkout_branch=botconfig.SpiceBot_Update.gitbranch)
|
||||||
|
|
||||||
pipcommand = "sudo pip3 install --upgrade"
|
pipcommand = "sudo pip3 install --upgrade"
|
||||||
if not deps:
|
if not deps:
|
||||||
pipcommand += " --no-deps"
|
pipcommand += " --no-deps"
|
||||||
pipcommand += " --force-reinstall"
|
pipcommand += " --force-reinstall"
|
||||||
# pipcommand += " git+" + str(bot.config.SpiceBot_Update.gitrepo) + "@" + str(bot.config.SpiceBot_Update.gitbranch)
|
# pipcommand += " git+" + str(botconfig.SpiceBot_Update.gitrepo) + "@" + str(botconfig.SpiceBot_Update.gitbranch)
|
||||||
pipcommand += " /tmp/SpiceBot/"
|
pipcommand += " /tmp/SpiceBot/"
|
||||||
|
|
||||||
botlogs.log('SpiceBot_Update', "Running `" + pipcommand + "`", True)
|
logs.log('SpiceBot_Update', "Running `" + pipcommand + "`", True)
|
||||||
# for line in os.popen(pipcommand).read().split('\n'):
|
# for line in os.popen(pipcommand).read().split('\n'):
|
||||||
# botlogs.log('SpiceBot_Update', " " + line)
|
# logs.log('SpiceBot_Update', " " + line)
|
||||||
os.system(pipcommand)
|
os.system(pipcommand)
|
||||||
|
|
||||||
botlogs.log('SpiceBot_Update', "Deleting " + clonepath, True)
|
logs.log('SpiceBot_Update', "Deleting " + clonepath, True)
|
||||||
|
|
||||||
os.system("sudo rm -r /tmp/SpiceBot")
|
os.system("sudo rm -r /tmp/SpiceBot")
|
||||||
|
|
||||||
stock_modules_begone(bot)
|
stock_modules_begone()
|
||||||
|
|
||||||
|
|
||||||
def spicebot_reload(bot, log_from='service_manip', quitmessage='Recieved QUIT'):
|
def spicebot_reload(bot, log_from='service_manip', quitmessage='Recieved QUIT'):
|
||||||
# service_manip(bot, bot.nick, 'restart', log_from)
|
# service_manip(bot.nick, 'restart', log_from)
|
||||||
bot.restart(quitmessage)
|
bot.restart(quitmessage)
|
||||||
|
|
||||||
|
|
||||||
def service_manip(bot, servicename, dowhat, log_from='service_manip'):
|
def service_manip(servicename, dowhat, log_from='service_manip'):
|
||||||
if str(dowhat) not in ["start", "stop", "restart"]:
|
if str(dowhat) not in ["start", "stop", "restart"]:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.")
|
logs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service.")
|
||||||
os.system("sudo service " + str(servicename) + " " + str(dowhat))
|
os.system("sudo service " + str(servicename) + " " + str(dowhat))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
botlogs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e))
|
logs.log(log_from, str(dowhat).title() + "ing " + str(servicename) + ".service Failed: " + str(e))
|
||||||
|
|
||||||
|
|
||||||
"""Config Reading Functions"""
|
"""Config Reading Functions"""
|
||||||
|
|
||||||
|
|
||||||
def read_directory_json_to_dict(bot, directories, configtypename="Config File", log_from='read_directory_json_to_dict'):
|
def read_directory_json_to_dict(directories, configtypename="Config File", log_from='read_directory_json_to_dict', logging=True):
|
||||||
|
|
||||||
if not isinstance(directories, list):
|
if not isinstance(directories, list):
|
||||||
directories = [directories]
|
directories = [directories]
|
||||||
@ -371,8 +348,8 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File",
|
|||||||
dict_from_file = eval(infread)
|
dict_from_file = eval(infread)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
filereadgood = False
|
filereadgood = False
|
||||||
if bot:
|
if logging:
|
||||||
botlogs.log(log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath))
|
logs.log(log_from, "Error loading %s: %s (%s)" % (configtypename, e, filepath))
|
||||||
dict_from_file = dict()
|
dict_from_file = dict()
|
||||||
# Close File
|
# Close File
|
||||||
inf.close()
|
inf.close()
|
||||||
@ -386,11 +363,11 @@ def read_directory_json_to_dict(bot, directories, configtypename="Config File",
|
|||||||
fileopenfail += 1
|
fileopenfail += 1
|
||||||
|
|
||||||
if filecount:
|
if filecount:
|
||||||
if bot:
|
if logging:
|
||||||
botlogs.log(log_from, 'Registered %d %s dict files,' % (filecount, configtypename))
|
logs.log(log_from, 'Registered %d %s dict files,' % (filecount, configtypename))
|
||||||
botlogs.log(log_from, '%d %s dict files failed to load' % (fileopenfail, configtypename), True)
|
logs.log(log_from, '%d %s dict files failed to load' % (fileopenfail, configtypename), True)
|
||||||
else:
|
else:
|
||||||
if bot:
|
if logging:
|
||||||
botlogs.log(log_from, "Warning: Couldn't load any %s dict files" % (configtypename))
|
logs.log(log_from, "Warning: Couldn't load any %s dict files" % (configtypename))
|
||||||
|
|
||||||
return configs_dict
|
return configs_dict
|
||||||
12
sopel_modules/SpiceBot/Update.py
Normal file
12
sopel_modules/SpiceBot/Update.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Update system.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sopel.config.types import StaticSection, ValidatedAttribute
|
||||||
|
|
||||||
|
|
||||||
|
class SpiceBot_Update_MainSection(StaticSection):
|
||||||
|
gitrepo = ValidatedAttribute('gitrepo', default="https://github.com/SpiceBot/SpiceBot")
|
||||||
|
gitbranch = ValidatedAttribute('gitbranch', default="master")
|
||||||
@ -6,9 +6,26 @@ These are the core SpiceBot Classes
|
|||||||
This module contains references only for other modules to utilize.
|
This module contains references only for other modules to utilize.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from .Config import *
|
||||||
from .Logs import *
|
from .Logs import *
|
||||||
|
from .Database import *
|
||||||
|
|
||||||
|
from .Update import *
|
||||||
|
from .osd import *
|
||||||
|
from .Kick import *
|
||||||
|
|
||||||
|
from .Tools import *
|
||||||
|
from .Prerun import *
|
||||||
|
from .Commands import *
|
||||||
from .Events import *
|
from .Events import *
|
||||||
|
from .StartupMonologue import *
|
||||||
from .Channels import *
|
from .Channels import *
|
||||||
|
from .AI import *
|
||||||
|
|
||||||
|
|
||||||
|
from .configure import *
|
||||||
|
from .setup import *
|
||||||
|
from .shutdown import *
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
__author__ = 'Sam Zick'
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
__email__ = 'sam@deathbybandaid.net'
|
||||||
|
|||||||
38
sopel_modules/SpiceBot/configure.py
Normal file
38
sopel_modules/SpiceBot/configure.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""Configuration for SpiceBot"""
|
||||||
|
|
||||||
|
from .Channels import SpiceBot_Channels_MainSection
|
||||||
|
from .AI import SpiceBot_AI_MainSection
|
||||||
|
from .Update import SpiceBot_Update_MainSection
|
||||||
|
from .Kick import SpiceBot_Kick
|
||||||
|
from .osd import SpiceBot_OSD
|
||||||
|
|
||||||
|
|
||||||
|
def configure(config):
|
||||||
|
|
||||||
|
config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False)
|
||||||
|
config.SpiceBot_OSD.configure_setting('notice', 'MAXTARG limit for NOTICE')
|
||||||
|
config.SpiceBot_OSD.configure_setting('privmsg', 'MAXTARG limit for PRIVMSG')
|
||||||
|
config.SpiceBot_OSD.configure_setting('flood_burst_lines', 'How many messages can be sent in burst mode.')
|
||||||
|
config.SpiceBot_OSD.configure_setting('flood_empty_wait', 'How long to wait between sending messages when not in burst mode, in seconds.')
|
||||||
|
config.SpiceBot_OSD.configure_setting('flood_refill_rate', 'How quickly burst mode recovers, in messages per second.')
|
||||||
|
config.SpiceBot_OSD.configure_setting('flood_throttle', 'Whether messages will be throttled if too many are sent in a short time.')
|
||||||
|
config.SpiceBot_OSD.configure_setting('flood_dots', "Whether repeated messages will be replaced with '...', then dropped.")
|
||||||
|
|
||||||
|
config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False)
|
||||||
|
config.SpiceBot_Channels.configure_setting('announcenew', 'SpiceBot_Channels Announce New Channels')
|
||||||
|
config.SpiceBot_Channels.configure_setting('joinall', 'SpiceBot_Channels JOIN New Channels')
|
||||||
|
config.SpiceBot_Channels.configure_setting('operadmin', 'SpiceBot_Channels OPER ADMIN MODE')
|
||||||
|
config.SpiceBot_Channels.configure_setting('chanignore', 'SpiceBot_Channels Ignore JOIN for channels')
|
||||||
|
|
||||||
|
config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False)
|
||||||
|
config.SpiceBot_Update.configure_setting('gitrepo', 'SpiceBot_Update git repo to install')
|
||||||
|
config.SpiceBot_Update.configure_setting('gitbranch', 'SpiceBot_Update git branch to install')
|
||||||
|
|
||||||
|
config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False)
|
||||||
|
config.SpiceBot_Kick.configure_setting('kick', 'MAXTARG limit for KICK')
|
||||||
|
|
||||||
|
config.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False)
|
||||||
|
config.SpiceBot_AI.configure_setting('extra', 'extra aiml directories to import matches from')
|
||||||
|
config.SpiceBot_AI.configure_setting('gender', 'bot gender')
|
||||||
@ -1,94 +1,18 @@
|
|||||||
# coding=utf8
|
# coding=utf8
|
||||||
"""Sopel OSD
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
Sopel OSD is a "niche" method of displaying text in a Sopel bot
|
This is the SpiceBot OSD system.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylama:ignore=W0611
|
from sopel import tools
|
||||||
|
|
||||||
|
|
||||||
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.tools import Identifier
|
||||||
from sopel.config.types import StaticSection, ValidatedAttribute
|
from sopel.config.types import StaticSection, ValidatedAttribute
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from collections import abc
|
from collections import abc
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.2'
|
|
||||||
|
|
||||||
|
|
||||||
def configure(config):
|
|
||||||
config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False)
|
|
||||||
config.SpiceBot_OSD.configure_setting('notice', 'MAXTARG limit for NOTICE')
|
|
||||||
config.SpiceBot_OSD.configure_setting('privmsg', 'MAXTARG limit for PRIVMSG')
|
|
||||||
config.SpiceBot_OSD.configure_setting('flood_burst_lines', 'How many messages can be sent in burst mode.')
|
|
||||||
config.SpiceBot_OSD.configure_setting('flood_empty_wait', 'How long to wait between sending messages when not in burst mode, in seconds.')
|
|
||||||
config.SpiceBot_OSD.configure_setting('flood_refill_rate', 'How quickly burst mode recovers, in messages per second.')
|
|
||||||
config.SpiceBot_OSD.configure_setting('flood_dots', 'Display dots instead of spam.')
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
|
|
||||||
# Inject OSD
|
|
||||||
botlogs.log('SpiceBot_OSD', "Implanting OSD function into bot")
|
|
||||||
bot.osd = SopelOSD.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
|
|
||||||
botlogs.log('SpiceBot_OSD', "Overwrite Default Sopel messaging commands")
|
|
||||||
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
|
|
||||||
botlogs.log('SpiceBot_OSD', "Checking for config settings")
|
|
||||||
bot.config.define_section("SpiceBot_OSD", SpiceBot_OSD, 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 ['NOTICE', 'PRIVMSG']:
|
|
||||||
try:
|
|
||||||
value = str(setting).split(':')[1] or None
|
|
||||||
except IndexError:
|
|
||||||
value = None
|
|
||||||
if value:
|
|
||||||
if settingname.upper() == 'NOTICE':
|
|
||||||
bot.config.SpiceBot_OSD.notice = int(value)
|
|
||||||
elif settingname.upper() == 'PRIVMSG':
|
|
||||||
bot.config.SpiceBot_OSD.privmsg = int(value)
|
|
||||||
|
|
||||||
|
|
||||||
class SpiceBot_OSD(StaticSection):
|
class SpiceBot_OSD(StaticSection):
|
||||||
|
|
||||||
"""MAXTARG"""
|
"""MAXTARG"""
|
||||||
@ -104,8 +28,11 @@ class SpiceBot_OSD(StaticSection):
|
|||||||
flood_refill_rate = ValidatedAttribute('flood_refill_rate', int, default=1)
|
flood_refill_rate = ValidatedAttribute('flood_refill_rate', int, default=1)
|
||||||
"""How quickly burst mode recovers, in messages per second."""
|
"""How quickly burst mode recovers, in messages per second."""
|
||||||
|
|
||||||
flood_dots = ValidatedAttribute('flood_dots', default=True)
|
flood_throttle = ValidatedAttribute('flood_throttle', bool, default=True)
|
||||||
"""Display dots instead of spam."""
|
"""Whether messages will be throttled if too many are sent in a short time."""
|
||||||
|
|
||||||
|
flood_dots = ValidatedAttribute('flood_dots', bool, default=True)
|
||||||
|
"""Whether repeated messages will be replaced with '...', then dropped."""
|
||||||
|
|
||||||
|
|
||||||
class ToolsOSD:
|
class ToolsOSD:
|
||||||
@ -261,6 +188,9 @@ class SopelOSD:
|
|||||||
will default to ``1``.
|
will default to ``1``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not hasattr(self, 'osdstack'):
|
||||||
|
self.osdstack = {}
|
||||||
|
|
||||||
text_method = text_method.upper()
|
text_method = text_method.upper()
|
||||||
if text_method == 'SAY' or text_method not in ['NOTICE', 'ACTION']:
|
if text_method == 'SAY' or text_method not in ['NOTICE', 'ACTION']:
|
||||||
text_method = 'PRIVMSG'
|
text_method = 'PRIVMSG'
|
||||||
@ -279,7 +209,7 @@ class SopelOSD:
|
|||||||
|
|
||||||
recipient_id = Identifier(recipientgroup)
|
recipient_id = Identifier(recipientgroup)
|
||||||
|
|
||||||
recipient_stack = self.stack.setdefault(recipient_id, {
|
recipient_stack = self.osdstack.setdefault(recipient_id, {
|
||||||
'messages': [],
|
'messages': [],
|
||||||
'flood_left': self.config.SpiceBot_OSD.flood_burst_lines,
|
'flood_left': self.config.SpiceBot_OSD.flood_burst_lines,
|
||||||
'dots': 0,
|
'dots': 0,
|
||||||
@ -303,7 +233,7 @@ class SopelOSD:
|
|||||||
penalty = float(max(0, len(text) - 50)) / 70
|
penalty = float(max(0, len(text) - 50)) / 70
|
||||||
# Never wait more than 2 seconds
|
# Never wait more than 2 seconds
|
||||||
wait = min(self.config.SpiceBot_OSD.flood_empty_wait + penalty, 2)
|
wait = min(self.config.SpiceBot_OSD.flood_empty_wait + penalty, 2)
|
||||||
if elapsed < wait:
|
if elapsed < wait and self.config.SpiceBot_OSD.flood_throttle:
|
||||||
time.sleep(wait - elapsed)
|
time.sleep(wait - elapsed)
|
||||||
|
|
||||||
# Loop detection
|
# Loop detection
|
||||||
@ -339,61 +269,6 @@ class SopelOSD:
|
|||||||
finally:
|
finally:
|
||||||
self.sending.release()
|
self.sending.release()
|
||||||
|
|
||||||
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 notice(self, text, dest, max_messages=1):
|
|
||||||
"""Send an IRC NOTICE to a user or a channel.
|
|
||||||
|
|
||||||
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, text, dest, max_messages=1):
|
|
||||||
"""Send ``text`` as a CTCP ACTION PRIVMSG to ``dest``.
|
|
||||||
|
|
||||||
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:: 6.0
|
|
||||||
Use :meth:`say` instead. Will be removed in Sopel 8.
|
|
||||||
"""
|
|
||||||
self.osd(text, recipient, 'PRIVMSG', max_messages)
|
|
||||||
|
|
||||||
|
|
||||||
class SopelWrapperOSD(object):
|
class SopelWrapperOSD(object):
|
||||||
|
|
||||||
@ -401,29 +276,3 @@ class SopelWrapperOSD(object):
|
|||||||
if recipients is None:
|
if recipients is None:
|
||||||
recipients = self._trigger.sender
|
recipients = self._trigger.sender
|
||||||
self._bot.osd(self, messages, recipients, text_method, max_messages)
|
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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
131
sopel_modules/SpiceBot/setup.py
Normal file
131
sopel_modules/SpiceBot/setup.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""Setup for SpiceBot"""
|
||||||
|
|
||||||
|
import sopel.bot
|
||||||
|
from sopel import tools
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from .Config import config as botconfig
|
||||||
|
from .Logs import logs
|
||||||
|
from .Events import events
|
||||||
|
|
||||||
|
from .Channels import SpiceBot_Channels_MainSection
|
||||||
|
from .Commands import SpiceBot_Commands_MainSection
|
||||||
|
from .Update import SpiceBot_Update_MainSection
|
||||||
|
from .osd import SopelWrapperOSD, ToolsOSD, SopelOSD, SpiceBot_OSD
|
||||||
|
from .Kick import SopelWrapperKICK, SopelKICK, SpiceBot_Kick
|
||||||
|
from .AI import SpiceBot_AI_MainSection
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
|
||||||
|
# basic config settings
|
||||||
|
setup_config(bot)
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
setup_logs(bot)
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
setup_commands(bot)
|
||||||
|
|
||||||
|
# OSD
|
||||||
|
setup_osd(bot)
|
||||||
|
|
||||||
|
# kick
|
||||||
|
setup_kick(bot)
|
||||||
|
|
||||||
|
# update
|
||||||
|
setup_update(bot)
|
||||||
|
|
||||||
|
# channels
|
||||||
|
setup_channels(bot)
|
||||||
|
|
||||||
|
# AI
|
||||||
|
setup_ai(bot)
|
||||||
|
|
||||||
|
# startupmonologue
|
||||||
|
setup_startupmonologue(bot)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_config(bot):
|
||||||
|
logs.log('SpiceBot_Config', "Setting Up Configuration")
|
||||||
|
bot.config.core.basename = os.path.basename(bot.config.filename).rsplit('.', 1)[0]
|
||||||
|
bot.config.core.prefix_list = str(bot.config.core.prefix).replace("\\", '').split("|")
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logs(bot):
|
||||||
|
logs.log('SpiceBot_Logs', "Starting Setup Procedure")
|
||||||
|
events.startup_add([events.BOT_LOGS])
|
||||||
|
bot.config.core.logs_stdio = os.path.join(bot.config.core.logdir, 'stdio.log')
|
||||||
|
# bot.config.core.logs_stdio = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.stdio.log')
|
||||||
|
bot.config.core.logs_exceptions = os.path.join(bot.config.core.logdir, 'exceptions.log')
|
||||||
|
# bot.config.core.logs_exceptions = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.exceptions.log')
|
||||||
|
bot.config.core.logs_raw = os.path.join(bot.config.core.logdir, 'raw.log')
|
||||||
|
# bot.config.core.logs_raw = os.path.os.path.join(bot.config.core.logdir, bot.config.core.basename + '.raw.log')
|
||||||
|
events.trigger(bot, events.BOT_LOGS, "SpiceBot_Logs")
|
||||||
|
|
||||||
|
|
||||||
|
def setup_commands(bot):
|
||||||
|
logs.log('SpiceBot_Commands', "Setting Up Configuration")
|
||||||
|
events.startup_add([events.BOT_COMMANDS])
|
||||||
|
bot.config.define_section("SpiceBot_Commands", SpiceBot_Commands_MainSection, validate=False)
|
||||||
|
bot.config.core.query_list = str(bot.config.SpiceBot_Commands.query_prefix).replace("\\", '').split("|")
|
||||||
|
bot.config.core.prefix_list.extend(bot.config.SpiceBot_Commands.query_prefix)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_startupmonologue(bot):
|
||||||
|
logs.log('SpiceBot_StartupMonologue', "Initial Setup processing")
|
||||||
|
events.startup_add([
|
||||||
|
events.BOT_STARTUPMONOLOGUE_CONNECTED,
|
||||||
|
events.BOT_STARTUPMONOLOGUE_CHANNELS,
|
||||||
|
events.BOT_STARTUPMONOLOGUE_COMMANDS,
|
||||||
|
events.BOT_STARTUPMONOLOGUE_AI,
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def setup_channels(bot):
|
||||||
|
logs.log('SpiceBot_Channels', "Setting Up Configuration")
|
||||||
|
events.startup_add([events.BOT_CHANNELS])
|
||||||
|
bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_update(bot):
|
||||||
|
logs.log('SpiceBot_Update', "Initial Setup processing")
|
||||||
|
bot.config.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False)
|
||||||
|
botconfig.define_section("SpiceBot_Update", SpiceBot_Update_MainSection, validate=False)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_ai(bot):
|
||||||
|
logs.log('SpiceBot_AI', "Setting Up Configuration")
|
||||||
|
bot.config.define_section("SpiceBot_AI", SpiceBot_AI_MainSection, validate=False)
|
||||||
|
bot.config.aibrain = os.path.join(bot.config.homedir, bot.config.core.basename + '.aibrain.brn')
|
||||||
|
events.startup_add([events.BOT_AI])
|
||||||
|
|
||||||
|
|
||||||
|
def setup_osd(bot):
|
||||||
|
# Inject OSD
|
||||||
|
logs.log('SpiceBot_OSD', "Implanting OSD function into bot")
|
||||||
|
bot.osd = SopelOSD.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
|
||||||
|
|
||||||
|
# verify config settings for server
|
||||||
|
logs.log('SpiceBot_OSD', "Checking for config settings")
|
||||||
|
bot.config.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False)
|
||||||
|
botconfig.define_section("SpiceBot_OSD", SpiceBot_OSD, validate=False)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_kick(bot):
|
||||||
|
# Inject KICK
|
||||||
|
logs.log('SpiceBot_Kick', "Implanting Kick function into bot")
|
||||||
|
bot.kick = SopelKICK.kick
|
||||||
|
sopel.bot.SopelWrapper.kick = SopelWrapperKICK.kick
|
||||||
|
|
||||||
|
# verify config settings for server
|
||||||
|
logs.log('SpiceBot_Kick', "Checking for config settings")
|
||||||
|
bot.config.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False)
|
||||||
|
botconfig.define_section("SpiceBot_Kick", SpiceBot_Kick, validate=False)
|
||||||
10
sopel_modules/SpiceBot/shutdown.py
Normal file
10
sopel_modules/SpiceBot/shutdown.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""shutdown for SpiceBot"""
|
||||||
|
|
||||||
|
from .AI import botai
|
||||||
|
|
||||||
|
|
||||||
|
def shutdown(bot):
|
||||||
|
|
||||||
|
botai.save_brain()
|
||||||
@ -6,80 +6,38 @@ import sopel.module
|
|||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, googlesearch, bot_privs, inlist, inlist_match, similar_list
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY])
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOADED, SpiceBot.events.BOT_COMMANDS])
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('(.*)')
|
@sopel.module.nickname_commands('(.*)')
|
||||||
def bot_command_nick(bot, trigger):
|
def bot_command_nick(bot, trigger):
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command')
|
if not trigger.sb['com']:
|
||||||
|
|
||||||
if not triggercommand:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if triggercommand[0] == "?":
|
if trigger.sb['com'][0] == "?":
|
||||||
return
|
return
|
||||||
|
|
||||||
if triggercommand in bot.memory['SpiceBot_CommandsQuery']['commands']["nickname"].keys():
|
if trigger.sb['com'] in SpiceBot.commands.dict['commands']["nickname"].keys():
|
||||||
return
|
return
|
||||||
triggerargs.insert(0, triggercommand)
|
trigger.sb['args'].insert(0, trigger.sb['com'])
|
||||||
|
|
||||||
fulltrigger = spicemanip.main(triggerargs, 0).lower()
|
fulltrigger = spicemanip.main(trigger.sb['args'], 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"):
|
# if fulltrigger.lower().startswith("what time is it"):
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
# elif fulltrigger.lower().startswith(tuple(["have you seen"])):
|
# elif fulltrigger.lower().startswith(tuple(["have you seen"])):
|
||||||
# posstarget = spicemanip.main(triggerargs, 4) or 0
|
# posstarget = spicemanip.main(trigger.sb['args'], 4) or 0
|
||||||
# message = seen_search(bot, botcom, posstarget)
|
# message = seen_search(bot, botcom, posstarget)
|
||||||
# bot.osd(message)
|
# bot.osd(message)
|
||||||
# return
|
# return
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
elif fulltrigger.lower().startswith(tuple(["make me a", "beam me a"])):
|
if fulltrigger.lower().startswith(tuple(["make me a", "beam me a"])):
|
||||||
makemea = spicemanip.main(triggerargs, "4+") or None
|
makemea = spicemanip.main(trigger.sb['args'], "4+") or None
|
||||||
if makemea:
|
if makemea:
|
||||||
bot.osd("beams " + trigger.nick + " a " + makemea, trigger.sender, 'action')
|
bot.osd("beams " + trigger.nick + " a " + makemea, trigger.sender, 'action')
|
||||||
else:
|
else:
|
||||||
@ -87,7 +45,7 @@ def bot_command_nick(bot, trigger):
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif fulltrigger.lower().startswith("beam me to"):
|
elif fulltrigger.lower().startswith("beam me to"):
|
||||||
location = spicemanip.main(triggerargs, "4+") or None
|
location = spicemanip.main(trigger.sb['args'], "4+") or None
|
||||||
if location:
|
if location:
|
||||||
bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to " + location, 'action')
|
bot.osd("locks onto " + trigger.nick + "s coordinates and transports them to " + location, 'action')
|
||||||
else:
|
else:
|
||||||
@ -101,7 +59,7 @@ def bot_command_nick(bot, trigger):
|
|||||||
elif fulltrigger.lower().endswith(tuple(["order 66"])):
|
elif fulltrigger.lower().endswith(tuple(["order 66"])):
|
||||||
|
|
||||||
if fulltrigger.lower() == "execute order 66":
|
if fulltrigger.lower() == "execute order 66":
|
||||||
if inlist(bot, trigger.nick, bot_privs(bot, 'owners')):
|
if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('owners')):
|
||||||
if trigger.is_privmsg:
|
if trigger.is_privmsg:
|
||||||
jedi = None
|
jedi = None
|
||||||
else:
|
else:
|
||||||
@ -119,7 +77,7 @@ def bot_command_nick(bot, trigger):
|
|||||||
bot.osd("I'm sure I don't know what you're talking about.")
|
bot.osd("I'm sure I don't know what you're talking about.")
|
||||||
|
|
||||||
elif fulltrigger.lower() == "explain order 66":
|
elif fulltrigger.lower() == "explain order 66":
|
||||||
if inlist(bot, trigger.nick, bot_privs(bot, 'owners')):
|
if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('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.")
|
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:
|
else:
|
||||||
bot.osd("I'm afraid I cannot tell you that, sir.")
|
bot.osd("I'm afraid I cannot tell you that, sir.")
|
||||||
@ -128,39 +86,27 @@ def bot_command_nick(bot, trigger):
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif fulltrigger.lower() == "initiate clean slate protocol":
|
elif fulltrigger.lower() == "initiate clean slate protocol":
|
||||||
if inlist(bot, trigger.nick, bot_privs(bot, 'admins')):
|
if SpiceBot.inlist(trigger.nick, SpiceBot.bot_privs('admins')):
|
||||||
bot.osd("sends a destruct command to the network of bots.", 'action')
|
bot.osd("sends a destruct command to the network of bots.", 'action')
|
||||||
else:
|
else:
|
||||||
bot.osd("I'm afraid you do not have the authority to make that call, " + trigger.nick + ".")
|
bot.osd("I'm afraid you do not have the authority to make that call, " + trigger.nick + ".")
|
||||||
return
|
return
|
||||||
|
|
||||||
elif fulltrigger.lower().startswith("can you see"):
|
elif fulltrigger.lower().startswith("can you see"):
|
||||||
target = spicemanip.main(triggerargs, "4+") or None
|
target = spicemanip.main(trigger.sb['args'], "4+") or None
|
||||||
if not target:
|
if not target:
|
||||||
bot.osd(trigger.nick + ", I can see clearly.")
|
bot.osd(trigger.nick + ", I can see clearly.")
|
||||||
return
|
return
|
||||||
if target in [trigger.nick, 'me']:
|
if target in [trigger.nick, 'me']:
|
||||||
bot.osd(trigger.nick + ", I can see you.")
|
bot.osd(trigger.nick + ", I can see you.")
|
||||||
else:
|
else:
|
||||||
if inlist(bot, trigger.nick, bot.users):
|
if SpiceBot.inlist(trigger.nick, bot.users):
|
||||||
bot.osd(trigger.nick + ", yes. I can see " + inlist_match(bot, target, bot.users) + " right now!")
|
bot.osd(trigger.nick + ", yes. I can see " + SpiceBot.inlist_match(target, bot.users) + " right now!")
|
||||||
else:
|
else:
|
||||||
bot.osd(trigger.nick + ", no. I cannot see " + inlist_match(bot, target, bot.users) + " right now!")
|
bot.osd(trigger.nick + ", no. I cannot see " + SpiceBot.inlist_match(target, bot.users) + " right now!")
|
||||||
# if bot_check_inlist(bot, target, bot.memory["botdict"]["users"].keys()):
|
# if bot_check_inlist(target, bot.memory["botdict"]["users"].keys()):
|
||||||
# bot.osd(trigger.nick + ", I can't see " + inlist_match(bot, target, bot.users) + " at the moment.")
|
# bot.osd(trigger.nick + ", I can't see " + inlist_match(target, bot.users) + " at the moment.")
|
||||||
# else:
|
# else:
|
||||||
# bot.osd("I have never seen " + str(target) + ".")
|
# bot.osd("I have never seen " + str(target) + ".")
|
||||||
# TODO
|
# TODO
|
||||||
return
|
return
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@ -1,19 +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)(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)
|
|
||||||
@ -1,19 +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)
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.nickname_commands('hello', 'hi', 'hey')
|
|
||||||
def bot_command_hello_b(bot, trigger):
|
|
||||||
bot_command_hello(bot, trigger)
|
|
||||||
@ -1,10 +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!")
|
|
||||||
@ -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)(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)
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@ -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)(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)
|
|
||||||
@ -1,18 +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)(really),? $nickname\?')
|
|
||||||
def bot_command_really(bot, trigger):
|
|
||||||
really = spicemanip.main(["Yes, really.", "Really really"], "random")
|
|
||||||
bot.reply(really)
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.rule('$nickname really\?')
|
|
||||||
def bot_command_really_b(bot, trigger):
|
|
||||||
bot_command_really(bot, trigger)
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@ -1,13 +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)(welcome back),? $nickname\?')
|
|
||||||
def bot_command_really(bot, trigger):
|
|
||||||
reply = spicemanip.main(['Thank you', 'thanks'], "random")
|
|
||||||
bot.reply(reply)
|
|
||||||
88
sopel_modules/SpiceBot_AI/AI_aiml.py
Normal file
88
sopel_modules/SpiceBot_AI/AI_aiml.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.rule('(.*)')
|
||||||
|
def bot_command_rule(bot, trigger):
|
||||||
|
|
||||||
|
# TODO add config limits
|
||||||
|
# but still allow in privmsg
|
||||||
|
|
||||||
|
if trigger.nick == bot.nick:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not len(trigger.args):
|
||||||
|
return
|
||||||
|
|
||||||
|
message = trigger.args[1]
|
||||||
|
|
||||||
|
# ignore text coming from a valid prefix
|
||||||
|
if str(message).startswith(tuple(bot.config.core.prefix_list)):
|
||||||
|
trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'module')
|
||||||
|
# patch for people typing "...", maybe other stuff, but this verifies that there is still a command here
|
||||||
|
if trigger_command.startswith("."):
|
||||||
|
return
|
||||||
|
commands_list = []
|
||||||
|
for commandstype in SpiceBot.commands.dict['commands'].keys():
|
||||||
|
if commandstype not in ['rule', 'nickname']:
|
||||||
|
for com in SpiceBot.commands.dict['commands'][commandstype].keys():
|
||||||
|
if com not in commands_list:
|
||||||
|
commands_list.append(com)
|
||||||
|
if trigger_command not in commands_list:
|
||||||
|
if not SpiceBot.letters_in_string(trigger_command):
|
||||||
|
return
|
||||||
|
invalid_display = ["I don't seem to have a command for " + str(trigger_command) + "!"]
|
||||||
|
# invalid_display.append("If you have a suggestion for this command, you can run .feature ." + str(trigger_command))
|
||||||
|
# invalid_display.append("ADD DESCRIPTION HERE!")
|
||||||
|
bot.osd(invalid_display, trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
if str(message).lower().startswith(str(bot.nick).lower()):
|
||||||
|
command_type = 'nickname'
|
||||||
|
trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'nickname')
|
||||||
|
fulltrigger = spicemanip.main(trigger_args, 0)
|
||||||
|
if str(trigger_command).startswith("?"):
|
||||||
|
return
|
||||||
|
if fulltrigger in SpiceBot.commands.dict['nickrules']:
|
||||||
|
return
|
||||||
|
if trigger_command in SpiceBot.commands.dict['commands']["nickname"].keys():
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
command_type = 'module'
|
||||||
|
trigger_args, trigger_command = SpiceBot.prerun.trigger_args(message, 'module')
|
||||||
|
fulltrigger = spicemanip.main(trigger_args, 0)
|
||||||
|
|
||||||
|
returnmessage = SpiceBot.botai.on_message(bot, trigger, message)
|
||||||
|
if returnmessage:
|
||||||
|
bot.osd(str(returnmessage))
|
||||||
|
else:
|
||||||
|
if command_type == 'nickname':
|
||||||
|
|
||||||
|
if trigger_args[0].lower() in ["what", "where"] and trigger_args[0].lower() in ["is", "are"]:
|
||||||
|
searchterm = spicemanip.main(trigger_args, "3+") or None
|
||||||
|
if searchterm:
|
||||||
|
if trigger_args[0].lower() == "where":
|
||||||
|
searchreturn = SpiceBot.googlesearch(searchterm, 'maps')
|
||||||
|
else:
|
||||||
|
searchreturn = SpiceBot.googlesearch(searchterm)
|
||||||
|
if not searchreturn:
|
||||||
|
bot.osd('I cannot find anything about that')
|
||||||
|
else:
|
||||||
|
bot.osd(str(searchreturn))
|
||||||
|
return
|
||||||
|
|
||||||
|
closestmatches = SpiceBot.similar_list(trigger_command, SpiceBot.commands.dict['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
|
||||||
@ -2,16 +2,7 @@
|
|||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
from .AI import *
|
from .AI import *
|
||||||
from .AI_Hello import *
|
from .AI_aiml 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 *
|
|
||||||
from .AI_Really import *
|
|
||||||
from .AI_Welcomeback import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
__author__ = 'Sam Zick'
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
__email__ = 'sam@deathbybandaid.net'
|
||||||
|
|||||||
@ -6,24 +6,25 @@ import sopel.module
|
|||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, bot_privs
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('owners', 'owner')
|
@sopel.module.nickname_commands('owners', 'owner')
|
||||||
def bot_command_owners(bot, trigger):
|
def bot_command_owners(bot, trigger):
|
||||||
bot_command_process(bot, trigger)
|
bot_command_process(bot, trigger)
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.nickname_commands('admins')
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
|
@sopel.module.nickname_commands('admins', 'admin')
|
||||||
def bot_command_admins(bot, trigger):
|
def bot_command_admins(bot, trigger):
|
||||||
bot_command_process(bot, trigger)
|
bot_command_process(bot, trigger)
|
||||||
|
|
||||||
|
|
||||||
def bot_command_process(bot, trigger):
|
def bot_command_process(bot, trigger):
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command')
|
|
||||||
|
|
||||||
if triggercommand == 'owner':
|
if not trigger.sb['com'].endswith("s"):
|
||||||
triggercommand = 'owners'
|
trigger.sb['com'] = str(trigger.sb['com'] + "s")
|
||||||
|
|
||||||
privlist = spicemanip.main(bot_privs(bot, triggercommand), 'andlist')
|
privlist = spicemanip.main(SpiceBot.bot_privs(trigger.sb['com']), 'andlist')
|
||||||
bot.osd(str(bot.nick) + " " + triggercommand + ": " + privlist)
|
bot.osd(str(bot.nick) + " " + trigger.sb['com'] + ": " + privlist)
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
"""Event Parsing from IRC
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
from .Channels_Command import *
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# coding=utf-8
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
# sopel imports
|
|
||||||
import sopel.module
|
|
||||||
from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
from sopel_modules.SpiceBot.Channels import botchannels
|
|
||||||
|
|
||||||
import spicemanip
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
class SpiceBot_Channels_MainSection(StaticSection):
|
|
||||||
announcenew = ValidatedAttribute('announcenew', default=False)
|
|
||||||
joinall = ValidatedAttribute('joinall', default=False)
|
|
||||||
operadmin = ValidatedAttribute('operadmin', default=False)
|
|
||||||
chanignore = ListAttribute('chanignore')
|
|
||||||
|
|
||||||
|
|
||||||
def configure(config):
|
|
||||||
config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False)
|
|
||||||
config.SpiceBot_Channels.configure_setting('announcenew', 'SpiceBot_Channels Announce New Channels')
|
|
||||||
config.SpiceBot_Channels.configure_setting('joinall', 'SpiceBot_Channels JOIN New Channels')
|
|
||||||
config.SpiceBot_Channels.configure_setting('operadmin', 'SpiceBot_Channels OPER ADMIN MODE')
|
|
||||||
config.SpiceBot_Channels.configure_setting('chanignore', 'SpiceBot_Channels Ignore JOIN for channels')
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
botlogs.log('SpiceBot_Channels', "Starting setup procedure")
|
|
||||||
botevents.startup_add([botevents.BOT_CHANNELS])
|
|
||||||
bot.config.define_section("SpiceBot_Channels", SpiceBot_Channels_MainSection, validate=False)
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.RPL_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def unkickable_bot(bot, trigger):
|
|
||||||
if bot.config.SpiceBot_Channels.operadmin:
|
|
||||||
bot.write(('SAMODE', bot.nick, '+q'))
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.RPL_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def request_channels_list_initial(bot, trigger):
|
|
||||||
|
|
||||||
botchannels.bot_part_empty(bot)
|
|
||||||
|
|
||||||
botlogs.log('SpiceBot_Channels', "Sending Request for all server channels")
|
|
||||||
botchannels.channel_list_request(bot)
|
|
||||||
|
|
||||||
starttime = time.time()
|
|
||||||
|
|
||||||
# wait 60 seconds for initial population of information
|
|
||||||
while not botchannels.SpiceBot_Channels['InitialProcess']:
|
|
||||||
if time.time() - starttime >= 60:
|
|
||||||
botlogs.log('SpiceBot_Channels', "Initial Channel list populating Timed Out")
|
|
||||||
botchannels.SpiceBot_Channels['InitialProcess'] = True
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
foundchannelcount = len(botchannels.SpiceBot_Channels['list'].keys())
|
|
||||||
botlogs.log('SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.")
|
|
||||||
|
|
||||||
botchannels.join_all_channels(bot)
|
|
||||||
botchannels.chanadmin_all_channels(bot)
|
|
||||||
|
|
||||||
if "*" in botchannels.SpiceBot_Channels['list'].keys():
|
|
||||||
del botchannels.SpiceBot_Channels['list']["*"]
|
|
||||||
|
|
||||||
botchannels.bot_part_empty(bot)
|
|
||||||
botevents.trigger(bot, botevents.BOT_CHANNELS, "SpiceBot_Channels")
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event('321')
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def watch_chanlist_start(bot, trigger):
|
|
||||||
botchannels.channel_list_recieve_start()
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event('322')
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def watch_chanlist_populate(bot, trigger):
|
|
||||||
botchannels.channel_list_recieve_input(trigger)
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event('323')
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def watch_chanlist_complete(bot, trigger):
|
|
||||||
botchannels.channel_list_recieve_finish()
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_CHANNELS)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def trigger_channel_list_recurring(bot, trigger):
|
|
||||||
while True:
|
|
||||||
time.sleep(1800)
|
|
||||||
botchannels.bot_part_empty(bot)
|
|
||||||
|
|
||||||
oldlist = list(botchannels.SpiceBot_Channels['list'].keys())
|
|
||||||
botchannels.channel_list_request(bot)
|
|
||||||
|
|
||||||
while botchannels.channel_lock:
|
|
||||||
pass
|
|
||||||
|
|
||||||
newlist = [item.lower() for item in oldlist if item.lower() not in list(botchannels.SpiceBot_Channels['list'].keys())]
|
|
||||||
if "*" in newlist:
|
|
||||||
newlist.remove("*")
|
|
||||||
if len(newlist) and bot.config.SpiceBot_Channels.announcenew:
|
|
||||||
bot.osd(["The Following channel(s) are new:", spicemanip.main(newlist, 'andlist')], bot.channels.keys())
|
|
||||||
|
|
||||||
botchannels.join_all_channels(bot)
|
|
||||||
|
|
||||||
botchannels.chanadmin_all_channels(bot)
|
|
||||||
|
|
||||||
if "*" in botchannels.SpiceBot_Channels['list'].keys():
|
|
||||||
del botchannels.SpiceBot_Channels['list']["*"]
|
|
||||||
botchannels.bot_part_empty(bot)
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
"""Event Parsing from IRC
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
from .Channels_Parsing import *
|
|
||||||
@ -1,213 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
import spicemanip
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
botlogs.log('SpiceBot_CommandsQuery', "Starting setup procedure")
|
|
||||||
botevents.startup_add([botevents.BOT_COMMANDSQUERY])
|
|
||||||
|
|
||||||
if 'SpiceBot_CommandsQuery' not in bot.memory:
|
|
||||||
bot.memory['SpiceBot_CommandsQuery'] = {"counts": 0, "commands": {}, "nickrules": []}
|
|
||||||
|
|
||||||
for comtype in ['module', 'nickname', 'rule']:
|
|
||||||
if comtype not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys():
|
|
||||||
bot.memory['SpiceBot_CommandsQuery']['commands'][comtype] = dict()
|
|
||||||
|
|
||||||
filepathlisting = []
|
|
||||||
|
|
||||||
# main Modules directory
|
|
||||||
main_dir = os.path.dirname(os.path.abspath(sopel.__file__))
|
|
||||||
modules_dir = os.path.join(main_dir, 'modules')
|
|
||||||
filepathlisting.append(modules_dir)
|
|
||||||
|
|
||||||
# Home Directory
|
|
||||||
home_modules_dir = os.path.join(bot.config.homedir, 'modules')
|
|
||||||
if os.path.isdir(home_modules_dir):
|
|
||||||
filepathlisting.append(home_modules_dir)
|
|
||||||
|
|
||||||
# pypi installed
|
|
||||||
try:
|
|
||||||
import sopel_modules
|
|
||||||
for plugin_dir in set(sopel_modules.__path__):
|
|
||||||
for pathname in os.listdir(plugin_dir):
|
|
||||||
pypi_modules_dir = os.path.join(plugin_dir, pathname)
|
|
||||||
filepathlisting.append(pypi_modules_dir)
|
|
||||||
except Exception as e:
|
|
||||||
botlogs.log('SpiceBot_CommandsQuery', "sopel_modules not loaded :" + str(e))
|
|
||||||
|
|
||||||
# Extra directories
|
|
||||||
filepathlist = []
|
|
||||||
for directory in bot.config.core.extra:
|
|
||||||
filepathlisting.append(directory)
|
|
||||||
|
|
||||||
for directory in filepathlisting:
|
|
||||||
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('_')):
|
|
||||||
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()
|
|
||||||
for line in lines:
|
|
||||||
module_file_lines.append(line)
|
|
||||||
module_file.close()
|
|
||||||
|
|
||||||
dict_from_file = dict()
|
|
||||||
|
|
||||||
detected_lines = []
|
|
||||||
for line in module_file_lines:
|
|
||||||
|
|
||||||
if str(line).startswith("@"):
|
|
||||||
line = str(line)[1:]
|
|
||||||
|
|
||||||
if str(line).startswith(tuple(["commands", "module.commands", "sopel.module.commands"])):
|
|
||||||
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"])):
|
|
||||||
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"])):
|
|
||||||
line = str(line).split("rule")[-1]
|
|
||||||
line = "rule" + line
|
|
||||||
else:
|
|
||||||
line = None
|
|
||||||
|
|
||||||
if line:
|
|
||||||
detected_lines.append(line)
|
|
||||||
|
|
||||||
if len(detected_lines):
|
|
||||||
|
|
||||||
filelinelist = []
|
|
||||||
currentsuccesslines = 0
|
|
||||||
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]
|
|
||||||
for regexcom in ["(.*)", '^\?(.*)']:
|
|
||||||
if regexcom in validcoms:
|
|
||||||
while regexcom in validcoms:
|
|
||||||
validcoms.remove(regexcom)
|
|
||||||
|
|
||||||
if len(validcoms):
|
|
||||||
validcomdict = {"comtype": comtype, "validcoms": validcoms}
|
|
||||||
filelinelist.append(validcomdict)
|
|
||||||
currentsuccesslines += 1
|
|
||||||
|
|
||||||
if currentsuccesslines:
|
|
||||||
bot.memory['SpiceBot_CommandsQuery']['counts'] += 1
|
|
||||||
|
|
||||||
if len(filelinelist):
|
|
||||||
for atlinefound in filelinelist:
|
|
||||||
|
|
||||||
dict_from_file = dict()
|
|
||||||
|
|
||||||
comtype = atlinefound["comtype"]
|
|
||||||
validcoms = atlinefound["validcoms"]
|
|
||||||
|
|
||||||
# default command to filename
|
|
||||||
if "validcoms" not in dict_from_file.keys():
|
|
||||||
dict_from_file["validcoms"] = 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 = []
|
|
||||||
|
|
||||||
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']:
|
|
||||||
botlogs.log('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)
|
|
||||||
|
|
||||||
botevents.trigger(bot, botevents.BOT_COMMANDSQUERY, "SpiceBot_CommandsQuery")
|
|
||||||
|
|
||||||
|
|
||||||
def shutdown(bot):
|
|
||||||
if "SpiceBot_CommandsQuery" in bot.memory:
|
|
||||||
del bot.memory["SpiceBot_CommandsQuery"]
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_LOADED)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_complete(bot, trigger):
|
|
||||||
|
|
||||||
for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys():
|
|
||||||
if comtype not in ['module', 'nickname', 'rule']:
|
|
||||||
botlogs.log('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": 0, "commands": {}, "nickrules": []}
|
|
||||||
|
|
||||||
if not isinstance(validcoms, list):
|
|
||||||
validcoms = [validcoms]
|
|
||||||
|
|
||||||
if command_type not in bot.memory['SpiceBot_CommandsQuery']['commands'].keys():
|
|
||||||
bot.memory['SpiceBot_CommandsQuery']['commands'][command_type] = dict()
|
|
||||||
bot.memory['SpiceBot_CommandsQuery']['counts'] += 1
|
|
||||||
|
|
||||||
dict_from_file = dict()
|
|
||||||
|
|
||||||
# default command to filename
|
|
||||||
if "validcoms" not in dict_from_file.keys():
|
|
||||||
dict_from_file["validcoms"] = validcoms
|
|
||||||
|
|
||||||
if not aliasfor:
|
|
||||||
|
|
||||||
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'][command_type][maincom] = dict_from_file
|
|
||||||
else:
|
|
||||||
comaliases = validcoms
|
|
||||||
|
|
||||||
for comalias in comaliases:
|
|
||||||
if comalias not in bot.memory['SpiceBot_CommandsQuery']['commands'][command_type].keys():
|
|
||||||
bot.memory['SpiceBot_CommandsQuery']['commands'][command_type][comalias] = {"aliasfor": aliasfor}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string
|
|
||||||
|
|
||||||
|
|
||||||
import spicemanip
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_COMMANDSQUERY])
|
|
||||||
@sopel.module.nickname_commands('(.*)')
|
|
||||||
def query_detection_nick(bot, trigger):
|
|
||||||
|
|
||||||
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)
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, similar_list, letters_in_string
|
|
||||||
|
|
||||||
|
|
||||||
import spicemanip
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_COMMANDSQUERY])
|
|
||||||
@sopel.module.rule('^\?(.*)')
|
|
||||||
def query_detection(bot, trigger):
|
|
||||||
|
|
||||||
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():
|
|
||||||
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]
|
|
||||||
|
|
||||||
if triggercommand[:-1] == "+":
|
|
||||||
|
|
||||||
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 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 = 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(triggercommand) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick)
|
|
||||||
return
|
|
||||||
|
|
||||||
if triggercommand[:-1] == "?":
|
|
||||||
|
|
||||||
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 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)
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
# coding=utf8
|
|
||||||
"""Sopel Commands Query
|
|
||||||
|
|
||||||
Sopel Commands Query responds to ? to display commands matching patterns
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
from .CommandsQuery import *
|
|
||||||
from .QueryCommand import *
|
|
||||||
from .NickQueryCommand import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.1'
|
|
||||||
18
sopel_modules/SpiceBot_Configs/aiml/dog.aiml
Normal file
18
sopel_modules/SpiceBot_Configs/aiml/dog.aiml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>MY DOGS NAME IS *</pattern>
|
||||||
|
<template>
|
||||||
|
That is interesting that you have a dog named <set name="dog"><star/></set>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
<category>
|
||||||
|
<pattern>WHAT IS MY DOGS NAME</pattern>
|
||||||
|
<template>
|
||||||
|
Your dog's name is <get name="dog"/>.
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
</aiml>
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICKexclamationmark</pattern>
|
||||||
|
<template>triggernick!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICKquestionmark</pattern>
|
||||||
|
<template>I'm here, triggernick</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>That's my name, don't wear it out!</li>
|
||||||
|
<li>Need something, triggernick?</li>
|
||||||
|
<li>What's going on, triggernick?</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
16
sopel_modules/SpiceBot_Configs/aiml/nickname_gender.aiml
Normal file
16
sopel_modules/SpiceBot_Configs/aiml/nickname_gender.aiml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK GENDER</pattern>
|
||||||
|
<template>If societal genders are binary, my gender is <bot name="gender"/></template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK WHAT IS YOUR GENDER</pattern>
|
||||||
|
<template>If societal genders are binary, my gender is <bot name="gender"/></template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
</aiml>
|
||||||
134
sopel_modules/SpiceBot_Configs/aiml/nickname_goodbye.aiml
Normal file
134
sopel_modules/SpiceBot_Configs/aiml/nickname_goodbye.aiml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK BYE</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK GOODBYE</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK seeya</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK cya</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK ttyl</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BYE BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>GOODBYE BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>seeya BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>cya BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>ttyl BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>bye, triggernick</li>
|
||||||
|
<li>goodbye, triggernick</li>
|
||||||
|
<li>seeya, triggernick</li>
|
||||||
|
<li>cya, triggernick</li>
|
||||||
|
<li>ttyl, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
70
sopel_modules/SpiceBot_Configs/aiml/nickname_hello.aiml
Normal file
70
sopel_modules/SpiceBot_Configs/aiml/nickname_hello.aiml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK hi</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK hello</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK hey</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>hi BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>hello BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>hey BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK fuck you</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK fuck off</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK screw you</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>fuck you BOTNICK</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>fuck off BOTNICK</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>screw you BOTNICK</pattern>
|
||||||
|
<template>Watch your mouth, triggernick, or I'll tell your mother!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
38
sopel_modules/SpiceBot_Configs/aiml/nickname_lazy.aiml
Normal file
38
sopel_modules/SpiceBot_Configs/aiml/nickname_lazy.aiml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK IS LAZY</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>LAZY BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>DAMNIT BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>hi, triggernick</li>
|
||||||
|
<li>hello, triggernick</li>
|
||||||
|
<li>hey, triggernick</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
44
sopel_modules/SpiceBot_Configs/aiml/nickname_love.aiml
Normal file
44
sopel_modules/SpiceBot_Configs/aiml/nickname_love.aiml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK I love you</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK loveya</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK I love you</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK I like you</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>I love you BOTNICK</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>loveya BOTNICK</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>I love BOTNICK</pattern>
|
||||||
|
<template>triggernick, I love you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>I like BOTNICK</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
9
sopel_modules/SpiceBot_Configs/aiml/nickname_ping.aiml
Normal file
9
sopel_modules/SpiceBot_Configs/aiml/nickname_ping.aiml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK PING</pattern>
|
||||||
|
<template>pong</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
9
sopel_modules/SpiceBot_Configs/aiml/nickname_praise.aiml
Normal file
9
sopel_modules/SpiceBot_Configs/aiml/nickname_praise.aiml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK IS COOL</pattern>
|
||||||
|
<template>Thanks!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
25
sopel_modules/SpiceBot_Configs/aiml/nickname_really.aiml
Normal file
25
sopel_modules/SpiceBot_Configs/aiml/nickname_really.aiml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK really</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>triggernick, Yes, really.</li>
|
||||||
|
<li>triggernick, Really really</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>really BOTNICK</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>triggernick, Yes, really.</li>
|
||||||
|
<li>triggernick, Really really</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
</aiml>
|
||||||
34
sopel_modules/SpiceBot_Configs/aiml/nickname_thanks.aiml
Normal file
34
sopel_modules/SpiceBot_Configs/aiml/nickname_thanks.aiml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>thank you BOTNICK</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK thank you</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>thanks BOTNICK</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK thanks</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>thankya BOTNICK</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK thankya</pattern>
|
||||||
|
<template>triggernick, I like you too.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK welcome back</pattern>
|
||||||
|
<template>Thanks!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>welcome back BOTNICK</pattern>
|
||||||
|
<template>Thanks!</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
9
sopel_modules/SpiceBot_Configs/aiml/nickname_whatis.aiml
Normal file
9
sopel_modules/SpiceBot_Configs/aiml/nickname_whatis.aiml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK what is</pattern>
|
||||||
|
<template>Do you think this is Jeopardy?</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
29
sopel_modules/SpiceBot_Configs/aiml/nickname_whereis.aiml
Normal file
29
sopel_modules/SpiceBot_Configs/aiml/nickname_whereis.aiml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aiml version="1.0">
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK where is waldo</pattern>
|
||||||
|
<template>He is hiding for a reason?</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK where is wally</pattern>
|
||||||
|
<template>He is hiding for a reason?</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK where is carmen sandiego</pattern>
|
||||||
|
<template>
|
||||||
|
<random>
|
||||||
|
<li>Currently she is located at ACME Headquarters</li>
|
||||||
|
<li>Currently she is located at Villains' International League of Evil</li>
|
||||||
|
</random>
|
||||||
|
</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category>
|
||||||
|
<pattern>BOTNICK where is</pattern>
|
||||||
|
<template>Not sure what you want me to look for.</template>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
</aiml>
|
||||||
@ -1,28 +1,26 @@
|
|||||||
# coding=utf-8
|
# coding=utf8
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
import sopel.module
|
This is the SpiceBot Channels system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot.Channels import botchannels
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, inlist, channel_privs
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_LOADED])
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOADED])
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('channels', 'channel')
|
@sopel.module.nickname_commands('channels', 'channel')
|
||||||
def nickname_comand_channels(bot, trigger):
|
def nickname_comand_channels(bot, trigger):
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command')
|
if not len(trigger.sb['args']):
|
||||||
|
|
||||||
if not len(triggerargs):
|
|
||||||
commandused = 'list'
|
commandused = 'list'
|
||||||
else:
|
else:
|
||||||
commandused = spicemanip.main(triggerargs, 1).lower()
|
commandused = spicemanip.main(trigger.sb['args'], 1).lower()
|
||||||
|
|
||||||
triggerargs = spicemanip.main(triggerargs, '2+', 'list')
|
trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list')
|
||||||
|
|
||||||
if commandused == 'list':
|
if commandused == 'list':
|
||||||
chanlist = spicemanip.main(bot.channels.keys(), 'andlist')
|
chanlist = spicemanip.main(bot.channels.keys(), 'andlist')
|
||||||
@ -31,14 +29,14 @@ def nickname_comand_channels(bot, trigger):
|
|||||||
|
|
||||||
elif commandused == 'total':
|
elif commandused == 'total':
|
||||||
botcount = len(bot.channels.keys())
|
botcount = len(bot.channels.keys())
|
||||||
servercount = len(botchannels.SpiceBot_Channels['list'].keys())
|
servercount = len(SpiceBot.channels.dict['list'].keys())
|
||||||
bot.osd("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.")
|
bot.osd("I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server.")
|
||||||
return
|
return
|
||||||
|
|
||||||
elif commandused == 'random':
|
elif commandused == 'random':
|
||||||
channel = spicemanip.main(botchannels.SpiceBot_Channels['list'], 'random')
|
channel = spicemanip.main(SpiceBot.channels.dict['list'], 'random')
|
||||||
topic = botchannels.SpiceBot_Channels['list'][channel]['topic']
|
topic = SpiceBot.channels.dict['list'][channel]['topic']
|
||||||
msg = ["Random channel for you: {}.".format(botchannels.SpiceBot_Channels['list'][channel]['name'])]
|
msg = ["Random channel for you: {}.".format(SpiceBot.channels.dict['list'][channel]['name'])]
|
||||||
if topic and not topic.isspace():
|
if topic and not topic.isspace():
|
||||||
msg.append("The topic is: {}".format(topic))
|
msg.append("The topic is: {}".format(topic))
|
||||||
else:
|
else:
|
||||||
@ -50,47 +48,47 @@ def nickname_comand_channels(bot, trigger):
|
|||||||
if not trigger.admin:
|
if not trigger.admin:
|
||||||
bot.osd("You do not have permission to update the channel listing.")
|
bot.osd("You do not have permission to update the channel listing.")
|
||||||
return
|
return
|
||||||
botchannels.bot_part_empty(bot)
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
botchannels.channel_list_request(bot)
|
SpiceBot.channels.channel_list_request(bot)
|
||||||
bot.osd(["[SpiceBot_Channels]", "I am now updating the channel listing for this server."])
|
bot.osd(["[SpiceBot_Channels]", "I am now updating the channel listing for this server."])
|
||||||
while botchannels.channel_lock:
|
while SpiceBot.channels.channel_lock:
|
||||||
pass
|
pass
|
||||||
botchannels.join_all_channels(bot)
|
SpiceBot.channels.join_all_channels(bot)
|
||||||
foundchannelcount = len(botchannels.SpiceBot_Channels['list'].keys())
|
foundchannelcount = len(SpiceBot.channels.dict['list'].keys())
|
||||||
bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.")
|
bot.osd("[SpiceBot_Channels]", "Channel listing finished!", str(foundchannelcount) + " channel(s) found.")
|
||||||
botchannels.bot_part_empty(bot)
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
return
|
return
|
||||||
|
|
||||||
elif commandused == 'topic':
|
elif commandused == 'topic':
|
||||||
if not len(triggerargs):
|
if not len(trigger.sb['args']):
|
||||||
bot.osd("Channel name input missing.")
|
bot.osd("Channel name input missing.")
|
||||||
return
|
return
|
||||||
channel = spicemanip.main(triggerargs, 1)
|
channel = spicemanip.main(trigger.sb['args'], 1)
|
||||||
if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()):
|
if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()):
|
||||||
bot.osd("Channel name {} not valid.".format(channel))
|
bot.osd("Channel name {} not valid.".format(channel))
|
||||||
return
|
return
|
||||||
topic = botchannels.SpiceBot_Channels['list'][channel.lower()]['topic']
|
topic = SpiceBot.channels.dict['list'][channel.lower()]['topic']
|
||||||
channel = botchannels.SpiceBot_Channels['list'][channel.lower()]['name']
|
channel = SpiceBot.channels.dict['list'][channel.lower()]['name']
|
||||||
bot.osd("Topic for {}: {}".format(channel, topic))
|
bot.osd("Topic for {}: {}".format(channel, topic))
|
||||||
return
|
return
|
||||||
|
|
||||||
if commandused.upper() in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']:
|
if commandused.upper() in ['OP', 'HOP', 'VOICE', 'OWNER', 'ADMIN']:
|
||||||
if not len(triggerargs):
|
if not len(trigger.sb['args']):
|
||||||
if trigger.is_privmsg:
|
if trigger.is_privmsg:
|
||||||
bot.osd("Channel name required.")
|
bot.osd("Channel name required.")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
channel = trigger.sender
|
channel = trigger.sender
|
||||||
else:
|
else:
|
||||||
channel = spicemanip.main(triggerargs, 1)
|
channel = spicemanip.main(trigger.sb['args'], 1)
|
||||||
if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()):
|
if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()):
|
||||||
bot.osd("Channel name {} not valid.".format(channel))
|
bot.osd("Channel name {} not valid.".format(channel))
|
||||||
return
|
return
|
||||||
if not inlist(bot, channel.lower(), bot.channels.keys()):
|
if not SpiceBot.inlist(channel.lower(), bot.channels.keys()):
|
||||||
bot.osd("I need to be in {} to see nick privileges.".format(channel))
|
bot.osd("I need to be in {} to see nick privileges.".format(channel))
|
||||||
return
|
return
|
||||||
|
|
||||||
privlist = channel_privs(bot, channel, commandused.upper())
|
privlist = SpiceBot.channel_privs(bot, channel, commandused.upper())
|
||||||
dispmsg = []
|
dispmsg = []
|
||||||
if not len(privlist):
|
if not len(privlist):
|
||||||
dispmsg.append("There are no Channel " + commandused.upper() + "s for " + str(channel))
|
dispmsg.append("There are no Channel " + commandused.upper() + "s for " + str(channel))
|
||||||
@ -102,11 +100,11 @@ def nickname_comand_channels(bot, trigger):
|
|||||||
|
|
||||||
# Users List
|
# Users List
|
||||||
if commandused == 'users':
|
if commandused == 'users':
|
||||||
channel = spicemanip.main(triggerargs, 1)
|
channel = spicemanip.main(trigger.sb['args'], 1)
|
||||||
if not inlist(bot, channel.lower(), botchannels.SpiceBot_Channels['list'].keys()):
|
if not SpiceBot.inlist(channel.lower(), SpiceBot.channels.dict['list'].keys()):
|
||||||
bot.osd("Channel name {} not valid.".format(channel))
|
bot.osd("Channel name {} not valid.".format(channel))
|
||||||
return
|
return
|
||||||
if not inlist(bot, channel.lower(), bot.channels.keys()):
|
if not SpiceBot.inlist(channel.lower(), bot.channels.keys()):
|
||||||
bot.osd("I need to be in {} to see user list.".format(channel))
|
bot.osd("I need to be in {} to see user list.".format(channel))
|
||||||
return
|
return
|
||||||
dispmsg = []
|
dispmsg = []
|
||||||
175
sopel_modules/SpiceBot_Core_Commands/Commands.py
Normal file
175
sopel_modules/SpiceBot_Core_Commands/Commands.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Commands system.
|
||||||
|
|
||||||
|
This Class stores commands in an easy to access manner
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS])
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
|
@sopel.module.nickname_commands('commands', 'command')
|
||||||
|
def nickname_comand_channels(bot, trigger):
|
||||||
|
|
||||||
|
if not len(trigger.sb['args']):
|
||||||
|
commandused = 'list'
|
||||||
|
else:
|
||||||
|
commandused = spicemanip.main(trigger.sb['args'], 1).lower()
|
||||||
|
|
||||||
|
commands_list = []
|
||||||
|
for commandstype in SpiceBot.commands.dict['commands'].keys():
|
||||||
|
if commandstype not in ['rule']:
|
||||||
|
for com in SpiceBot.commands.dict['commands'][commandstype].keys():
|
||||||
|
if com not in commands_list:
|
||||||
|
if commandstype in ['nickname']:
|
||||||
|
commands_list.append(bot.nick + " " + com)
|
||||||
|
else:
|
||||||
|
commands_list.append(com)
|
||||||
|
|
||||||
|
if commandused == 'list':
|
||||||
|
bot.osd(spicemanip.main(commands_list, 'andlist'), trigger.nick, 'NOTICE')
|
||||||
|
return
|
||||||
|
|
||||||
|
elif commandused == 'total':
|
||||||
|
bot.osd("I have " + str(len(commands_list)) + " commands available.")
|
||||||
|
return
|
||||||
|
|
||||||
|
elif commandused == 'random':
|
||||||
|
bot.osd(["Here's a random command for you:", + spicemanip.main(commands_list, 'random')])
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS])
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
|
@sopel.module.nickname_commands('(.*)')
|
||||||
|
def query_detection_nick(bot, trigger):
|
||||||
|
|
||||||
|
# command issued, check if valid
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not trigger.sb['com'][0] == "?":
|
||||||
|
return
|
||||||
|
trigger.sb['com'] = trigger.sb['com'][1:]
|
||||||
|
|
||||||
|
if not SpiceBot.letters_in_string(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
commands_list = dict()
|
||||||
|
for com in SpiceBot.commands.dict['commands']['nickname'].keys():
|
||||||
|
if com not in commands_list.keys():
|
||||||
|
commands_list[com] = SpiceBot.commands.dict['commands']['nickname'][com]
|
||||||
|
|
||||||
|
if trigger.sb['com'].endswith("+"):
|
||||||
|
|
||||||
|
trigger.sb['com'] = trigger.sb['com'][:-1]
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.sb['com'].lower() not in list(commands_list.keys()):
|
||||||
|
dispmsg = ["Cannot find any alias " + bot.nick + " commands: No valid commands match " + str(trigger.sb['com']) + "."]
|
||||||
|
closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse')
|
||||||
|
if len(closestmatches):
|
||||||
|
dispmsg.append("The following " + bot.nick + " commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".")
|
||||||
|
bot.osd(dispmsg, trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
realcom = trigger.sb['com']
|
||||||
|
if "aliasfor" in commands_list[trigger.sb['com']].keys():
|
||||||
|
realcom = commands_list[trigger.sb['com']]["aliasfor"]
|
||||||
|
validcomlist = commands_list[realcom]["validcoms"]
|
||||||
|
bot.osd("The following " + bot.nick + " commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.sb['com'].endswith("?"):
|
||||||
|
|
||||||
|
trigger.sb['com'] = trigger.sb['com'][:-1]
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse')
|
||||||
|
if not len(closestmatches):
|
||||||
|
bot.osd("Cannot find any similar " + bot.nick + " commands for " + str(trigger.sb['com']) + ".", trigger.nick, 'notice')
|
||||||
|
else:
|
||||||
|
bot.osd("The following " + bot.nick + " commands may match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
commandlist = []
|
||||||
|
for command in list(commands_list.keys()):
|
||||||
|
if command.lower().startswith(str(trigger.sb['com']).lower()):
|
||||||
|
commandlist.append(command)
|
||||||
|
|
||||||
|
if not len(commandlist):
|
||||||
|
bot.osd("No " + bot.nick + " commands start with " + str(trigger.sb['com']) + ".", trigger.nick, 'notice')
|
||||||
|
else:
|
||||||
|
bot.osd("The following " + bot.nick + " commands start with " + str(trigger.sb['com']) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_COMMANDS])
|
||||||
|
@SpiceBot.prerun.prerun('query')
|
||||||
|
@sopel.module.rule('^\?(.*)')
|
||||||
|
def query_detection(bot, trigger):
|
||||||
|
|
||||||
|
# command issued, check if valid
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not SpiceBot.letters_in_string(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
commands_list = dict()
|
||||||
|
for commandstype in SpiceBot.commands.dict['commands'].keys():
|
||||||
|
if commandstype not in ['rule', 'nickname']:
|
||||||
|
for com in SpiceBot.commands.dict['commands'][commandstype].keys():
|
||||||
|
if com not in commands_list.keys():
|
||||||
|
commands_list[com] = SpiceBot.commands.dict['commands'][commandstype][com]
|
||||||
|
|
||||||
|
if trigger.sb['com'][:-1] == "+":
|
||||||
|
|
||||||
|
trigger.sb['com'] = trigger.sb['com'][:-1]
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.sb['com'].lower() not in list(commands_list.keys()):
|
||||||
|
dispmsg = ["Cannot find any alias commands: No valid commands match " + str(trigger.sb['com']) + "."]
|
||||||
|
closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse')
|
||||||
|
if len(closestmatches):
|
||||||
|
dispmsg.append("The following commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".")
|
||||||
|
bot.osd(dispmsg, trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
realcom = trigger.sb['com']
|
||||||
|
if "aliasfor" in commands_list[trigger.sb['com']].keys():
|
||||||
|
realcom = commands_list[trigger.sb['com']]["aliasfor"]
|
||||||
|
validcomlist = commands_list[realcom]["validcoms"]
|
||||||
|
bot.osd("The following commands match " + str(trigger.sb['com']) + ": " + spicemanip.main(validcomlist, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
if trigger.sb['com'][:-1] == "?":
|
||||||
|
|
||||||
|
trigger.sb['com'] = trigger.sb['com'][:-1]
|
||||||
|
if not trigger.sb['com'] or not len(trigger.sb['com']):
|
||||||
|
return
|
||||||
|
|
||||||
|
closestmatches = SpiceBot.similar_list(trigger.sb['com'], list(commands_list.keys()), 10, 'reverse')
|
||||||
|
if not len(closestmatches):
|
||||||
|
bot.osd("Cannot find any similar commands for " + str(trigger.sb['com']) + ".", trigger.nick, 'notice')
|
||||||
|
else:
|
||||||
|
bot.osd("The following commands may match " + str(trigger.sb['com']) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
return
|
||||||
|
|
||||||
|
commandlist = []
|
||||||
|
for command in list(commands_list.keys()):
|
||||||
|
if command.lower().startswith(str(trigger.sb['com']).lower()):
|
||||||
|
commandlist.append(command)
|
||||||
|
|
||||||
|
if not len(commandlist):
|
||||||
|
bot.osd("No commands start with " + str(trigger.sb['com']) + ".", trigger.nick, 'notice')
|
||||||
|
else:
|
||||||
|
bot.osd("The following commands start with " + str(trigger.sb['com']) + ": " + spicemanip.main(commandlist, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
15
sopel_modules/SpiceBot_Core_Commands/Database.py
Normal file
15
sopel_modules/SpiceBot_Core_Commands/Database.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Database
|
||||||
|
"""
|
||||||
|
|
||||||
|
# sopel imports
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.nickname_commands('database')
|
||||||
|
def bot_command_database(bot, trigger):
|
||||||
|
bot.osd("Database is " + SpiceBot.config.db_type)
|
||||||
16
sopel_modules/SpiceBot_Core_Commands/Docs.py
Normal file
16
sopel_modules/SpiceBot_Core_Commands/Docs.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.nickname_commands('help', 'docs', 'wiki')
|
||||||
|
def bot_command_owners(bot, trigger):
|
||||||
|
bot.osd(["IRC Modules Repository",
|
||||||
|
str(SpiceBot.github_dict["url_main"] +
|
||||||
|
SpiceBot.github_dict["repo_owner"] + "/" +
|
||||||
|
SpiceBot.github_dict["repo_name"] +
|
||||||
|
SpiceBot.github_dict["url_path_wiki"])])
|
||||||
49
sopel_modules/SpiceBot_Core_Commands/Logs.py
Normal file
49
sopel_modules/SpiceBot_Core_Commands/Logs.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Logs System
|
||||||
|
"""
|
||||||
|
|
||||||
|
# sopel imports
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_LOGS])
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
|
@sopel.module.nickname_commands('logs', 'debug')
|
||||||
|
def bot_command_logs(bot, trigger):
|
||||||
|
|
||||||
|
if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
bot.osd("I was unable to process this Bot Nick command due to privilege issues.")
|
||||||
|
return
|
||||||
|
|
||||||
|
logtype = spicemanip.main(trigger.sb['args'], 1) or None
|
||||||
|
if not logtype:
|
||||||
|
bot.osd("Current valid log(s) include: " + spicemanip.main(SpiceBot.logs.dict["list"].keys(), 'andlist'), trigger.sender, 'action')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not SpiceBot.inlist(logtype, SpiceBot.logs.dict["list"].keys()):
|
||||||
|
closestmatches = SpiceBot.similar_list(logtype, SpiceBot.logs.dict["list"].keys(), 10, 'reverse')
|
||||||
|
if not len(closestmatches):
|
||||||
|
bot.osd("No valid logs match " + str(logtype) + ".", trigger.nick, 'notice')
|
||||||
|
else:
|
||||||
|
bot.osd("The following commands may match " + str(logtype) + ": " + spicemanip.main(closestmatches, 'andlist') + ".", trigger.nick, 'notice')
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
logtype = SpiceBot.inlist_match(logtype, SpiceBot.logs.dict["list"].keys())
|
||||||
|
|
||||||
|
logindex = SpiceBot.logs.get_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 logindex:
|
||||||
|
bot.osd(" " + str(line))
|
||||||
|
bot.osd(str(logtype) + " log(s) Complete.")
|
||||||
@ -6,20 +6,22 @@ import sopel.module
|
|||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Channels import botchannels
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist
|
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('action')
|
@sopel.module.nickname_commands('action')
|
||||||
def bot_command_action(bot, trigger):
|
def bot_command_action(bot, trigger):
|
||||||
bot_command_process(bot, trigger)
|
bot_command_process(bot, trigger)
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('notice')
|
@sopel.module.nickname_commands('notice')
|
||||||
def bot_command_notice(bot, trigger):
|
def bot_command_notice(bot, trigger):
|
||||||
bot_command_process(bot, trigger)
|
bot_command_process(bot, trigger)
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
@sopel.module.nickname_commands('privmsg', 'say', 'msg')
|
@sopel.module.nickname_commands('privmsg', 'say', 'msg')
|
||||||
def bot_command_privmsg(bot, trigger):
|
def bot_command_privmsg(bot, trigger):
|
||||||
bot_command_process(bot, trigger)
|
bot_command_process(bot, trigger)
|
||||||
@ -27,27 +29,25 @@ def bot_command_privmsg(bot, trigger):
|
|||||||
|
|
||||||
def bot_command_process(bot, trigger):
|
def bot_command_process(bot, trigger):
|
||||||
|
|
||||||
if not command_permissions_check(bot, trigger, ['admins', 'owner']):
|
if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner']):
|
||||||
bot.say("I was unable to process this Bot Nick command due to privilege issues.")
|
bot.osd("I was unable to process this Bot Nick command due to privilege issues.")
|
||||||
return
|
return
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command')
|
if trigger.sb['com'] in ['say', 'msg']:
|
||||||
|
trigger.sb['com'] = 'privmsg'
|
||||||
|
|
||||||
if triggercommand in ['say', 'msg']:
|
if not len(trigger.sb['args']):
|
||||||
triggercommand = 'privmsg'
|
bot.osd("You must specify a channel or nick.")
|
||||||
|
|
||||||
if not len(triggerargs):
|
|
||||||
bot.say("You must specify a channel or nick.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
target = spicemanip.main(triggerargs, 1)
|
target = spicemanip.main(trigger.sb['args'], 1)
|
||||||
if (target not in ['allchans', 'allnicks']
|
if (target not in ['allchans', 'allnicks']
|
||||||
and not inlist(bot, target.lower(), botchannels.SpiceBot_Channels['list'].keys())
|
and not SpiceBot.inlist(target.lower(), SpiceBot.channels.dict['list'].keys())
|
||||||
and not inlist(bot, target.lower(), bot.users)):
|
and not SpiceBot.inlist(target.lower(), bot.users)):
|
||||||
bot.osd("Channel/nick name {} not valid.".format(target))
|
bot.osd("Channel/nick name {} not valid.".format(target))
|
||||||
return
|
return
|
||||||
|
|
||||||
triggerargs = spicemanip.main(triggerargs, '2+', 'list')
|
trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list')
|
||||||
|
|
||||||
if target == 'allchans':
|
if target == 'allchans':
|
||||||
targetsendlist = bot.channels.keys()
|
targetsendlist = bot.channels.keys()
|
||||||
@ -56,9 +56,9 @@ def bot_command_process(bot, trigger):
|
|||||||
else:
|
else:
|
||||||
targetsendlist = [target]
|
targetsendlist = [target]
|
||||||
|
|
||||||
botmessage = spicemanip.main(triggerargs, 0)
|
botmessage = spicemanip.main(trigger.sb['args'], 0)
|
||||||
if not botmessage:
|
if not botmessage:
|
||||||
bot.say("You must specify a message to send.")
|
bot.osd("You must specify a message to send.")
|
||||||
return
|
return
|
||||||
|
|
||||||
bot.osd(botmessage, targetsendlist, triggercommand.upper())
|
bot.osd(botmessage, targetsendlist, trigger.sb['com'].upper())
|
||||||
55
sopel_modules/SpiceBot_Core_Commands/Runtime_Controls.py
Normal file
55
sopel_modules/SpiceBot_Core_Commands/Runtime_Controls.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.prerun.prerun('nickname')
|
||||||
|
@sopel.module.nickname_commands('update')
|
||||||
|
def nickname_comand_update(bot, trigger):
|
||||||
|
|
||||||
|
if not SpiceBot.command_permissions_check(bot, trigger, ['admins', 'owner', 'OP', 'ADMIN', 'OWNER']):
|
||||||
|
bot.osd("I was unable to process this Bot Nick command due to privilege issues.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not len(trigger.sb['args']):
|
||||||
|
commandused = 'nodeps'
|
||||||
|
else:
|
||||||
|
commandused = spicemanip.main(trigger.sb['args'], 1).lower()
|
||||||
|
|
||||||
|
if commandused not in ['deps', 'nodeps']:
|
||||||
|
bot.osd("Please specify deps or nodeps")
|
||||||
|
return
|
||||||
|
|
||||||
|
trigger.sb['args'] = spicemanip.main(trigger.sb['args'], '2+', 'list')
|
||||||
|
|
||||||
|
quitmessage = "Received command from " + trigger.nick + " to update from Github and restart"
|
||||||
|
SpiceBot.logs.log('SpiceBot_Update', quitmessage)
|
||||||
|
bot.osd(quitmessage, bot.channels.keys())
|
||||||
|
|
||||||
|
if commandused == 'nodeps':
|
||||||
|
SpiceBot.spicebot_update(False)
|
||||||
|
if commandused == 'deps':
|
||||||
|
SpiceBot.spicebot_update(True)
|
||||||
|
|
||||||
|
# service_manip(bot.nick, 'restart', 'SpiceBot_Update')
|
||||||
|
SpiceBot.spicebot_reload(bot, 'SpiceBot_Update', quitmessage)
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.nickname_commands('restart')
|
||||||
|
def nickname_comand_restart(bot, trigger):
|
||||||
|
|
||||||
|
if not trigger.admin:
|
||||||
|
bot.osd("You are not authorized to perform this function.")
|
||||||
|
|
||||||
|
quitmessage = "Received command from " + trigger.nick + " to restart. Be Back Soon!"
|
||||||
|
SpiceBot.logs.log('SpiceBot_Restart', quitmessage)
|
||||||
|
bot.osd(quitmessage, bot.channels.keys())
|
||||||
|
|
||||||
|
# service_manip(bot.nick, 'restart', 'SpiceBot_Restart')
|
||||||
|
SpiceBot.spicebot_reload(bot, 'SpiceBot_Restart', quitmessage)
|
||||||
15
sopel_modules/SpiceBot_Core_Commands/Uptime.py
Normal file
15
sopel_modules/SpiceBot_Core_Commands/Uptime.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.nickname_commands('uptime')
|
||||||
|
def bot_command_srewyou(bot, trigger):
|
||||||
|
timesince = str(SpiceBot.humanized_time(time.time() - SpiceBot.events.BOT_UPTIME)) + " ago."
|
||||||
|
bot.osd("I have been running since " + timesince)
|
||||||
20
sopel_modules/SpiceBot_Core_Commands/__init__.py
Normal file
20
sopel_modules/SpiceBot_Core_Commands/__init__.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
These are the core SpiceBot Classes
|
||||||
|
|
||||||
|
This module contains references only for other modules to utilize.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .Commands import *
|
||||||
|
from .Channels import *
|
||||||
|
from .Database import *
|
||||||
|
from .Uptime import *
|
||||||
|
from .Logs import *
|
||||||
|
from .Runtime_Controls import *
|
||||||
|
from .Messaging import *
|
||||||
|
from .Docs import *
|
||||||
|
|
||||||
|
__author__ = 'Sam Zick'
|
||||||
|
__email__ = 'sam@deathbybandaid.net'
|
||||||
|
__version__ = '0.1.1'
|
||||||
17
sopel_modules/SpiceBot_Core_Processing/AI.py
Normal file
17
sopel_modules/SpiceBot_Core_Processing/AI.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot AI system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_READY)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_complete_ai(bot, trigger):
|
||||||
|
|
||||||
|
SpiceBot.logs.log('SpiceBot_Commands', "Found " + str(SpiceBot.botai.dict['patterncounts']) + " AI pattern Matches.", True)
|
||||||
|
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_AI, "SpiceBot_AI")
|
||||||
97
sopel_modules/SpiceBot_Core_Processing/Channels.py
Normal file
97
sopel_modules/SpiceBot_Core_Processing/Channels.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Channels system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.RPL_WELCOME)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def unkickable_bot(bot, trigger):
|
||||||
|
if SpiceBot.config.SpiceBot_Channels.operadmin:
|
||||||
|
bot.write(('SAMODE', bot.nick, '+q'))
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.RPL_WELCOME)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def request_channels_list_initial(bot, trigger):
|
||||||
|
|
||||||
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
|
|
||||||
|
SpiceBot.logs.log('SpiceBot_Channels', "Sending Request for all server channels")
|
||||||
|
SpiceBot.channels.channel_list_request(bot)
|
||||||
|
|
||||||
|
starttime = time.time()
|
||||||
|
|
||||||
|
# wait 60 seconds for initial population of information
|
||||||
|
while not SpiceBot.channels.dict['InitialProcess']:
|
||||||
|
if time.time() - starttime >= 60:
|
||||||
|
SpiceBot.logs.log('SpiceBot_Channels', "Initial Channel list populating Timed Out")
|
||||||
|
SpiceBot.channels.dict['InitialProcess'] = True
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
foundchannelcount = len(SpiceBot.channels.dict['list'].keys())
|
||||||
|
SpiceBot.logs.log('SpiceBot_Channels', "Channel listing finished! " + str(foundchannelcount) + " channel(s) found.")
|
||||||
|
|
||||||
|
SpiceBot.channels.join_all_channels(bot)
|
||||||
|
SpiceBot.channels.chanadmin_all_channels(bot)
|
||||||
|
|
||||||
|
if "*" in SpiceBot.channels.dict['list'].keys():
|
||||||
|
del SpiceBot.channels.dict['list']["*"]
|
||||||
|
|
||||||
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_CHANNELS, "SpiceBot_Channels")
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event('321')
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def watch_chanlist_start(bot, trigger):
|
||||||
|
SpiceBot.channels.channel_list_recieve_start()
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event('322')
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def watch_chanlist_populate(bot, trigger):
|
||||||
|
SpiceBot.channels.channel_list_recieve_input(trigger)
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event('323')
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def watch_chanlist_complete(bot, trigger):
|
||||||
|
SpiceBot.channels.channel_list_recieve_finish()
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_CHANNELS)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def trigger_channel_list_recurring(bot, trigger):
|
||||||
|
while True:
|
||||||
|
time.sleep(1800)
|
||||||
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
|
|
||||||
|
oldlist = list(SpiceBot.channels.dict['list'].keys())
|
||||||
|
SpiceBot.channels.channel_list_request(bot)
|
||||||
|
|
||||||
|
while SpiceBot.channels.channel_lock:
|
||||||
|
pass
|
||||||
|
|
||||||
|
newlist = [item.lower() for item in oldlist if item.lower() not in list(SpiceBot.channels.dict['list'].keys())]
|
||||||
|
if "*" in newlist:
|
||||||
|
newlist.remove("*")
|
||||||
|
if len(newlist) and SpiceBot.config.SpiceBot_Channels.announcenew:
|
||||||
|
bot.osd(["The Following channel(s) are new:", spicemanip.main(newlist, 'andlist')], bot.channels.keys())
|
||||||
|
|
||||||
|
SpiceBot.channels.join_all_channels(bot)
|
||||||
|
|
||||||
|
SpiceBot.channels.chanadmin_all_channels(bot)
|
||||||
|
|
||||||
|
if "*" in SpiceBot.channels.dict['list'].keys():
|
||||||
|
del SpiceBot.channels.dict['list']["*"]
|
||||||
|
SpiceBot.channels.bot_part_empty(bot)
|
||||||
54
sopel_modules/SpiceBot_Core_Processing/Events.py
Normal file
54
sopel_modules/SpiceBot_Core_Processing/Events.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Events system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_WELCOME, SpiceBot.events.BOT_READY, SpiceBot.events.BOT_CONNECTED, SpiceBot.events.BOT_LOADED)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_complete(bot, trigger):
|
||||||
|
"""This is here simply to log to stderr that this was recieved."""
|
||||||
|
SpiceBot.logs.log('SpiceBot_Events', trigger.args[1], True)
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.RPL_WELCOME)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_connected(bot, trigger):
|
||||||
|
|
||||||
|
# Handling for connection count
|
||||||
|
SpiceBot.events.dict["RPL_WELCOME_Count"] += 1
|
||||||
|
if SpiceBot.events.dict["RPL_WELCOME_Count"] > 1:
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_RECONNECTED, "Bot ReConnected to IRC")
|
||||||
|
else:
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_WELCOME, "Welcome to the SpiceBot Events System")
|
||||||
|
|
||||||
|
"""For items tossed in a queue, this will trigger them accordingly"""
|
||||||
|
while True:
|
||||||
|
if len(SpiceBot.events.dict["trigger_queue"]):
|
||||||
|
pretriggerdict = SpiceBot.events.dict["trigger_queue"][0]
|
||||||
|
SpiceBot.events.dispatch(bot, pretriggerdict)
|
||||||
|
del SpiceBot.events.dict["trigger_queue"][0]
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_WELCOME)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_start(bot, trigger):
|
||||||
|
"""This stage is redundant, but shows the system is working."""
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_READY, "Ready To Process module setup procedures")
|
||||||
|
|
||||||
|
"""Here, we wait until we are in at least one channel"""
|
||||||
|
while not len(bot.channels.keys()) > 0:
|
||||||
|
pass
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_CONNECTED, "Bot Connected to IRC")
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.startup_check_ready()
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_READY)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_startup_complete(bot, trigger):
|
||||||
|
"""All events registered as required for startup have completed"""
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_LOADED, "All registered modules setup procedures have completed")
|
||||||
28
sopel_modules/SpiceBot_Core_Processing/Kick.py
Normal file
28
sopel_modules/SpiceBot_Core_Processing/Kick.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot OSD system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event('005')
|
||||||
|
@sopel.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.SpiceBot_Kick.kick = int(value)
|
||||||
27
sopel_modules/SpiceBot_Core_Processing/Logs.py
Normal file
27
sopel_modules/SpiceBot_Core_Processing/Logs.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Logs system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.RPL_WELCOME)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def join_log_channel(bot, trigger):
|
||||||
|
|
||||||
|
if SpiceBot.config.logging_channel:
|
||||||
|
channel = bot.config.core.logging_channel
|
||||||
|
if channel not in bot.channels.keys():
|
||||||
|
bot.write(('JOIN', bot.nick, channel))
|
||||||
|
if channel not in bot.channels.keys() and bot.config.SpiceBot_Channels.operadmin:
|
||||||
|
bot.write(('SAJOIN', bot.nick, channel))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if len(SpiceBot.logs.dict["queue"]):
|
||||||
|
bot.osd(str(SpiceBot.logs.dict["queue"][0]), channel)
|
||||||
|
del SpiceBot.logs.dict["queue"][0]
|
||||||
|
else:
|
||||||
|
SpiceBot.logs.dict["queue"] = []
|
||||||
19
sopel_modules/SpiceBot_Core_Processing/Modules.py
Normal file
19
sopel_modules/SpiceBot_Core_Processing/Modules.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot Modules system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_READY)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_events_complete_modules(bot, trigger):
|
||||||
|
|
||||||
|
for comtype in SpiceBot.commands.dict['commands'].keys():
|
||||||
|
if comtype not in ['module', 'nickname', 'rule']:
|
||||||
|
SpiceBot.logs.log('SpiceBot_Commands', "Found " + str(len(SpiceBot.commands.dict['commands'][comtype].keys())) + " " + comtype + " commands.", True)
|
||||||
|
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_COMMANDS, "SpiceBot_Commands")
|
||||||
93
sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py
Normal file
93
sopel_modules/SpiceBot_Core_Processing/StartupMonologue.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot StartupMonologue system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_CONNECTED)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_start(bot, trigger):
|
||||||
|
# Startup
|
||||||
|
SpiceBot.logs.log('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')
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_CONNECTED, "SpiceBot_StartupMonologue")
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_CHANNELS)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_channels(bot, trigger):
|
||||||
|
botcount = len(bot.channels.keys())
|
||||||
|
servercount = len(SpiceBot.channels.dict['list'].keys())
|
||||||
|
displayval = "I am in " + str(botcount) + " of " + str(servercount) + " channel(s) available on this server."
|
||||||
|
SpiceBot.startupmonologue.dict["channels"] = displayval
|
||||||
|
SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval)
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_CHANNELS, "SpiceBot_StartupMonologue")
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_COMMANDS)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_commands(bot, trigger):
|
||||||
|
availablecomsnum, availablecomsfiles = 0, 0
|
||||||
|
for commandstype in SpiceBot.commands.dict['commands'].keys():
|
||||||
|
availablecomsnum += len(SpiceBot.commands.dict['commands'][commandstype].keys())
|
||||||
|
availablecomsfiles += SpiceBot.commands.dict['counts']
|
||||||
|
displayval = "There are " + str(availablecomsnum) + " commands available in " + str(availablecomsfiles) + " files."
|
||||||
|
SpiceBot.startupmonologue.dict["commands"] = displayval
|
||||||
|
SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval)
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_COMMANDS, "SpiceBot_StartupMonologue")
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_AI)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_ai(bot, trigger):
|
||||||
|
availablecomsnum = SpiceBot.botai.dict['patterncounts']
|
||||||
|
availablecomsfiles = SpiceBot.botai.dict['filecounts']
|
||||||
|
displayval = "There are " + str(availablecomsnum) + " AI pattern matches available in " + str(availablecomsfiles) + " files."
|
||||||
|
SpiceBot.startupmonologue.dict["ai"] = displayval
|
||||||
|
SpiceBot.logs.log('SpiceBot_StartupMonologue', displayval)
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE_AI, "SpiceBot_StartupMonologue")
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_LOADED)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_display(bot, trigger):
|
||||||
|
dispmsg = [" startup complete"]
|
||||||
|
for messagekey in SpiceBot.startupmonologue.dict.keys():
|
||||||
|
dispmsg.append(SpiceBot.startupmonologue.dict[messagekey])
|
||||||
|
if SpiceBot.events.dict["RPL_WELCOME_Count"] == 1:
|
||||||
|
timesince = SpiceBot.humanized_time(time.time() - SpiceBot.events.BOT_UPTIME)
|
||||||
|
if timesince == "just now":
|
||||||
|
timesince = "1 second"
|
||||||
|
dispmsg.append("Startup took " + timesince)
|
||||||
|
# Announce to chan, then handle some closing stuff
|
||||||
|
SpiceBot.logs.log('SpiceBot_StartupMonologue', bot.nick + " startup complete")
|
||||||
|
bot.osd(dispmsg, bot.channels.keys(), 'ACTION')
|
||||||
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_STARTUPMONOLOGUE, "SpiceBot_StartupMonologue")
|
||||||
|
SpiceBot.logs.log('SpiceBot_StartupMonologue', "Startup Monologue has been issued to all channels.", True)
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event(SpiceBot.events.BOT_STARTUPMONOLOGUE)
|
||||||
|
@sopel.module.rule('.*')
|
||||||
|
def bot_startup_monologue_errors(bot, trigger):
|
||||||
|
|
||||||
|
debuglines = SpiceBot.logs.stdio_logs_fetch()
|
||||||
|
|
||||||
|
searchphrasefound = []
|
||||||
|
for line in debuglines:
|
||||||
|
if str(line).endswith("failed to load") and not str(line).startswith("0"):
|
||||||
|
searchphrasefound.append(line)
|
||||||
|
|
||||||
|
if len(searchphrasefound):
|
||||||
|
for foundphase in searchphrasefound:
|
||||||
|
SpiceBot.logs.log('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:
|
||||||
|
SpiceBot.logs.log('SpiceBot_Logs', "No issues found at bot startup!", True)
|
||||||
21
sopel_modules/SpiceBot_Core_Processing/__init__.py
Normal file
21
sopel_modules/SpiceBot_Core_Processing/__init__.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
These are the core SpiceBot Classes
|
||||||
|
|
||||||
|
This module contains references only for other modules to utilize.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .Channels import *
|
||||||
|
from .Events import *
|
||||||
|
from .Modules import *
|
||||||
|
from .AI import *
|
||||||
|
from .osd import *
|
||||||
|
from .StartupMonologue import *
|
||||||
|
from .Logs import *
|
||||||
|
from .Kick import *
|
||||||
|
|
||||||
|
|
||||||
|
__author__ = 'Sam Zick'
|
||||||
|
__email__ = 'sam@deathbybandaid.net'
|
||||||
|
__version__ = '0.1.1'
|
||||||
31
sopel_modules/SpiceBot_Core_Processing/osd.py
Normal file
31
sopel_modules/SpiceBot_Core_Processing/osd.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# coding=utf8
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
"""
|
||||||
|
This is the SpiceBot OSD system.
|
||||||
|
"""
|
||||||
|
import sopel
|
||||||
|
|
||||||
|
|
||||||
|
@sopel.module.event('005')
|
||||||
|
@sopel.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 ['NOTICE', 'PRIVMSG']:
|
||||||
|
try:
|
||||||
|
value = str(setting).split(':')[1] or None
|
||||||
|
except IndexError:
|
||||||
|
value = None
|
||||||
|
if value:
|
||||||
|
if settingname.upper() == 'NOTICE':
|
||||||
|
bot.config.SpiceBot_OSD.notice = int(value)
|
||||||
|
elif settingname.upper() == 'PRIVMSG':
|
||||||
|
bot.config.SpiceBot_OSD.privmsg = int(value)
|
||||||
@ -1,120 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# coding=utf-8
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
# sopel imports
|
|
||||||
import sopel.module
|
|
||||||
from sopel.tools import Identifier
|
|
||||||
from sopel.db import SopelDB, NickValues, ChannelValues
|
|
||||||
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
|
||||||
import json
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
pass
|
|
||||||
# Inject Database Functions
|
|
||||||
botlogs.log('SpiceBot_Databaseaddons', "Implanting Database functions into bot")
|
|
||||||
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:
|
|
||||||
|
|
||||||
"""Nicks"""
|
|
||||||
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
session.commit()
|
|
||||||
except SQLAlchemyError:
|
|
||||||
session.rollback()
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
def adjust_nick_value(self, nick, key, value):
|
|
||||||
"""Sets the value for a given key to be associated with the nick."""
|
|
||||||
nick = Identifier(nick)
|
|
||||||
value = json.dumps(value, ensure_ascii=False)
|
|
||||||
nick_id = self.get_nick_id(nick)
|
|
||||||
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 delete_channel_value(self, channel, key):
|
|
||||||
"""Sets the value for a given key to be associated with the channel."""
|
|
||||||
channel = Identifier(channel).lower()
|
|
||||||
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)
|
|
||||||
session.commit()
|
|
||||||
except SQLAlchemyError:
|
|
||||||
session.rollback()
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
def adjust_channel_value(self, channel, key, value):
|
|
||||||
"""Sets the value for a given key to be associated with the channel."""
|
|
||||||
channel = Identifier(channel).lower()
|
|
||||||
value = json.dumps(value, ensure_ascii=False)
|
|
||||||
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()
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
from .Databaseaddons import *
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# coding=utf-8
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
# sopel imports
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
botlogs.log('SpiceBot_DatabaseCache', "Setting up Database Cache")
|
|
||||||
if 'SpiceBot_DatabaseCache' not in bot.memory:
|
|
||||||
bot.memory['SpiceBot_DatabaseCache'] = dict()
|
|
||||||
|
|
||||||
|
|
||||||
def shutdown(bot):
|
|
||||||
if "SpiceBot_DatabaseCache" in bot.memory:
|
|
||||||
del bot.memory["SpiceBot_DatabaseCache"]
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
from .DatabaseCache import *
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# coding=utf-8
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
# sopel imports
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
|
|
||||||
"""Database Direct"""
|
|
||||||
|
|
||||||
|
|
||||||
# Get a value
|
|
||||||
def db_get_nick_value(bot, nick, key):
|
|
||||||
database_value = bot.db.get_nick_value(nick, key) or None
|
|
||||||
return database_value
|
|
||||||
|
|
||||||
|
|
||||||
# set a value
|
|
||||||
def db_set_nick_value(bot, nick, key, value):
|
|
||||||
bot.db.set_nick_value(nick, key, value)
|
|
||||||
|
|
||||||
|
|
||||||
# DELETE a value
|
|
||||||
def db_reset_value(bot, nick, key):
|
|
||||||
bot.db.reset_nick_value(nick, key)
|
|
||||||
|
|
||||||
|
|
||||||
# add or subtract from current value
|
|
||||||
def db_adjust_value(bot, nick, key, value):
|
|
||||||
bot.db.adjust_nick_value(nick, key, value)
|
|
||||||
|
|
||||||
|
|
||||||
# list stored in database, add or remove elements
|
|
||||||
def db_adjust_list(bot, nick, entries, key, adjustmentdirection):
|
|
||||||
if not isinstance(entries, list):
|
|
||||||
entries = [entries]
|
|
||||||
adjustlist = db_get_nick_value(bot, nick, key) or []
|
|
||||||
adjustlistnew = []
|
|
||||||
for x in adjustlist:
|
|
||||||
adjustlistnew.append(x)
|
|
||||||
db_reset_value(bot, nick, key)
|
|
||||||
adjustlist = []
|
|
||||||
if adjustmentdirection == 'add':
|
|
||||||
for y in entries:
|
|
||||||
if y not in adjustlistnew:
|
|
||||||
adjustlistnew.append(y)
|
|
||||||
elif adjustmentdirection == 'del':
|
|
||||||
for y in entries:
|
|
||||||
if y in adjustlistnew:
|
|
||||||
adjustlistnew.remove(y)
|
|
||||||
for x in adjustlistnew:
|
|
||||||
if x not in adjustlist:
|
|
||||||
adjustlist.append(x)
|
|
||||||
if not len(adjustlist):
|
|
||||||
db_reset_value(bot, nick, key)
|
|
||||||
else:
|
|
||||||
db_set_nick_value(bot, nick, key, adjustlist)
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
"""Useful miscellaneous tools and shortcuts for SpiceBot Sopel modules
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
||||||
|
|
||||||
from .DatabaseTools import *
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot_SBTools import github_dict
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.nickname_commands('help', 'docs', 'wiki')
|
|
||||||
def bot_command_owners(bot, trigger):
|
|
||||||
bot.osd(["IRC Modules Repository", str(github_dict["url_main"] + github_dict["repo_owner"] + "/" + github_dict["repo_name"] + github_dict["url_path_wiki"])])
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# coding=utf8
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
from .Docs import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.1'
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_Connected(bot, trigger):
|
|
||||||
"""Here, we wait until we are in at least one channel"""
|
|
||||||
while not len(bot.channels.keys()) > 0:
|
|
||||||
pass
|
|
||||||
botevents.trigger(bot, botevents.BOT_CONNECTED, "Bot Connected to IRC")
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.RPL_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_startup_welcome(bot, trigger):
|
|
||||||
botevents.SpiceBot_Events["RPL_WELCOME_Count"] += 1
|
|
||||||
if botevents.SpiceBot_Events["RPL_WELCOME_Count"] > 1:
|
|
||||||
botevents.trigger(bot, botevents.BOT_RECONNECTED, "Bot ReConnected to IRC")
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.startup_check_ready()
|
|
||||||
@sopel.module.event(botevents.BOT_READY)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_startup_complete(bot, trigger):
|
|
||||||
"""All events registered as required for startup have completed"""
|
|
||||||
botevents.trigger(bot, botevents.BOT_LOADED, "All registered modules setup procedures have completed")
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_WELCOME, botevents.BOT_READY, botevents.BOT_CONNECTED, botevents.BOT_LOADED)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_complete(bot, trigger):
|
|
||||||
"""This is here simply to log to stderr that this was recieved."""
|
|
||||||
botlogs.log('SpiceBot_Events', trigger.args[1], True)
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_connected(bot, trigger):
|
|
||||||
"""For items tossed in a queue, this will trigger them accordingly"""
|
|
||||||
while True:
|
|
||||||
if len(botevents.SpiceBot_Events["trigger_queue"]):
|
|
||||||
pretriggerdict = botevents.SpiceBot_Events["trigger_queue"][0]
|
|
||||||
botevents.dispatch(bot, pretriggerdict)
|
|
||||||
del botevents.SpiceBot_Events["trigger_queue"][0]
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.BOT_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_start(bot, trigger):
|
|
||||||
"""This stage is redundant, but shows the system is working."""
|
|
||||||
botevents.trigger(bot, botevents.BOT_READY, "Ready To Process module setup procedures")
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.event(botevents.RPL_WELCOME)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_startup_welcome(bot, trigger):
|
|
||||||
"""The Bot events system does not start until RPL_WELCOME 001 is recieved
|
|
||||||
from the server"""
|
|
||||||
if botevents.check(botevents.BOT_WELCOME):
|
|
||||||
return
|
|
||||||
botevents.trigger(bot, botevents.BOT_WELCOME, "Welcome to the SpiceBot Events System")
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
# coding=utf8
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
from .Welcome import *
|
|
||||||
from .Ready import *
|
|
||||||
from .Connected import *
|
|
||||||
from .Loaded import *
|
|
||||||
from .Queue import *
|
|
||||||
from .Logging import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.1'
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
|
|
||||||
@sopel.module.nickname_commands('gender')
|
|
||||||
def bot_command_gender(bot, trigger):
|
|
||||||
bot.osd("If societal genders are binary, my gender is female")
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# coding=utf8
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
from .Gender import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.1'
|
|
||||||
@ -8,24 +8,22 @@ import sopel.module
|
|||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_GIFSEARCH])
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH])
|
||||||
|
@SpiceBot.prerun.prerun('prefix')
|
||||||
@sopel.module.commands('(.*)')
|
@sopel.module.commands('(.*)')
|
||||||
def gifapi_triggers(bot, trigger):
|
def gifapi_triggers(bot, trigger):
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'prefix_command')
|
if trigger.sb['com'] not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys():
|
||||||
|
|
||||||
if triggercommand not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys():
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if not len(triggerargs):
|
if not len(trigger.sb['args']):
|
||||||
return bot.osd("Please present a query to search.")
|
return bot.osd("Please present a query to search.")
|
||||||
|
|
||||||
query = spicemanip.main(triggerargs, 0)
|
query = spicemanip.main(trigger.sb['args'], 0)
|
||||||
searchdict = {"query": query, "gifsearch": triggercommand}
|
searchdict = {"query": query, "gifsearch": trigger.sb['com']}
|
||||||
|
|
||||||
gifdict = getGif(bot, searchdict)
|
gifdict = getGif(bot, searchdict)
|
||||||
|
|
||||||
@ -6,21 +6,20 @@ from sopel import module
|
|||||||
|
|
||||||
from .gifsearch import getGif
|
from .gifsearch import getGif
|
||||||
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_GIFSEARCH])
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH])
|
||||||
|
@SpiceBot.prerun.prerun('prefix')
|
||||||
@module.commands('gif')
|
@module.commands('gif')
|
||||||
def gif_trigger(bot, trigger):
|
def gif_trigger(bot, trigger):
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger)
|
if not len(trigger.sb['args']):
|
||||||
if not len(triggerargs):
|
|
||||||
return bot.osd("Please present a query to search.")
|
return bot.osd("Please present a query to search.")
|
||||||
|
|
||||||
query = spicemanip.main(triggerargs, 0)
|
query = spicemanip.main(trigger.sb['args'], 0)
|
||||||
searchapis = bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys()
|
searchapis = bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys()
|
||||||
searchdict = {"query": query, "gifsearch": searchapis}
|
searchdict = {"query": query, "gifsearch": searchapis}
|
||||||
|
|
||||||
33
sopel_modules/SpiceBot_GifSearch/Gif_Search_Commands
Normal file
33
sopel_modules/SpiceBot_GifSearch/Gif_Search_Commands
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
|
from .gifsearch import getGif
|
||||||
|
|
||||||
|
import sopel.module
|
||||||
|
|
||||||
|
import spicemanip
|
||||||
|
|
||||||
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
|
|
||||||
|
|
||||||
|
@SpiceBot.events.check_ready([SpiceBot.events.BOT_GIFSEARCH])
|
||||||
|
@SpiceBot.prerun.prerun('prefix')
|
||||||
|
@sopel.module.commands('(.*)')
|
||||||
|
def gifapi_triggers(bot, trigger):
|
||||||
|
|
||||||
|
if trigger.sb['com'] not in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys():
|
||||||
|
return
|
||||||
|
|
||||||
|
if not len(trigger.sb['args']):
|
||||||
|
return bot.osd("Please present a query to search.")
|
||||||
|
|
||||||
|
query = spicemanip.main(trigger.sb['args'], 0)
|
||||||
|
searchdict = {"query": query, "gifsearch": trigger.sb['com']}
|
||||||
|
|
||||||
|
gifdict = getGif(bot, searchdict)
|
||||||
|
|
||||||
|
if gifdict["error"]:
|
||||||
|
bot.osd(gifdict["error"])
|
||||||
|
else:
|
||||||
|
bot.osd(str(gifdict['gifapi'].title() + " Result (" + str(query) + " #" + str(gifdict["returnnum"]) + "): " + str(gifdict["returnurl"])))
|
||||||
@ -5,8 +5,9 @@ Sopel Gif Search builds a convenient framework for searching for Gifs
|
|||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
from __future__ import unicode_literals, absolute_import, division, print_function
|
||||||
|
|
||||||
from .gif import *
|
from .Gif_Command import *
|
||||||
from .gifapi import *
|
from .Gif_API_Commands import *
|
||||||
|
# from .Gif_Search_Commands import *
|
||||||
from .gifsearch import *
|
from .gifsearch import *
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
__author__ = 'Sam Zick'
|
||||||
|
|||||||
@ -5,10 +5,7 @@ from __future__ import unicode_literals, absolute_import, division, print_functi
|
|||||||
import sopel.module
|
import sopel.module
|
||||||
from sopel.config.types import StaticSection, ValidatedAttribute
|
from sopel.config.types import StaticSection, ValidatedAttribute
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
import sopel_modules.SpiceBot as SpiceBot
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
from sopel_modules.SpiceBot_CommandsQuery.CommandsQuery import commandsquery_register
|
|
||||||
from sopel_modules.SpiceBot_SBTools import read_directory_json_to_dict
|
|
||||||
|
|
||||||
import spicemanip
|
import spicemanip
|
||||||
|
|
||||||
@ -32,7 +29,7 @@ class GifAPISection(StaticSection):
|
|||||||
def configure(config):
|
def configure(config):
|
||||||
moduledir = os.path.dirname(os.path.abspath(__file__))
|
moduledir = os.path.dirname(os.path.abspath(__file__))
|
||||||
api_dir = os.path.join(moduledir, 'gifapi')
|
api_dir = os.path.join(moduledir, 'gifapi')
|
||||||
valid_gif_api_dict = read_directory_json_to_dict(None, [api_dir], "Gif API", "SpiceBot_GifSearch")
|
valid_gif_api_dict = SpiceBot.read_directory_json_to_dict([api_dir], "Gif API", "SpiceBot_GifSearch", logging=True)
|
||||||
|
|
||||||
config.define_section("SopelGifSearch", GifAPIMainSection, validate=False)
|
config.define_section("SopelGifSearch", GifAPIMainSection, validate=False)
|
||||||
config.SopelGifSearch.configure_setting('extra', 'SpiceBot_GifSearch API Extra directory')
|
config.SopelGifSearch.configure_setting('extra', 'SpiceBot_GifSearch API Extra directory')
|
||||||
@ -45,8 +42,8 @@ def configure(config):
|
|||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
botlogs.log('SpiceBot_GifSearch', "Starting Setup Procedure")
|
SpiceBot.logs.log('SpiceBot_GifSearch', "Starting Setup Procedure")
|
||||||
botevents.startup_add([botevents.BOT_GIFSEARCH])
|
SpiceBot.events.startup_add([SpiceBot.events.BOT_GIFSEARCH])
|
||||||
|
|
||||||
if 'SpiceBot_GifSearch' not in bot.memory:
|
if 'SpiceBot_GifSearch' not in bot.memory:
|
||||||
bot.memory["SpiceBot_GifSearch"] = {"cache": {}, "badgiflinks": [], 'valid_gif_api_dict': {}}
|
bot.memory["SpiceBot_GifSearch"] = {"cache": {}, "badgiflinks": [], 'valid_gif_api_dict': {}}
|
||||||
@ -58,13 +55,15 @@ def setup(bot):
|
|||||||
dir_to_scan.append(api_dir)
|
dir_to_scan.append(api_dir)
|
||||||
|
|
||||||
bot.config.define_section("SopelGifSearch", GifAPIMainSection, validate=False)
|
bot.config.define_section("SopelGifSearch", GifAPIMainSection, validate=False)
|
||||||
|
SpiceBot.config.define_section("SopelGifSearch", GifAPIMainSection, validate=False)
|
||||||
if bot.config.SopelGifSearch.extra:
|
if bot.config.SopelGifSearch.extra:
|
||||||
dir_to_scan.append(bot.config.SopelGifSearch.extra)
|
dir_to_scan.append(bot.config.SopelGifSearch.extra)
|
||||||
|
|
||||||
valid_gif_api_dict = read_directory_json_to_dict(bot, dir_to_scan, "Gif API", "SpiceBot_GifSearch")
|
valid_gif_api_dict = SpiceBot.read_directory_json_to_dict(dir_to_scan, "Gif API", "SpiceBot_GifSearch", logging=True)
|
||||||
|
|
||||||
for gif_api in valid_gif_api_dict.keys():
|
for gif_api in valid_gif_api_dict.keys():
|
||||||
bot.config.define_section(gif_api, GifAPISection, validate=False)
|
bot.config.define_section(gif_api, GifAPISection, validate=False)
|
||||||
|
SpiceBot.config.define_section(gif_api, GifAPISection, validate=False)
|
||||||
apikey = eval("bot.config." + gif_api + ".apikey")
|
apikey = eval("bot.config." + gif_api + ".apikey")
|
||||||
if apikey:
|
if apikey:
|
||||||
valid_gif_api_dict[gif_api]["apikey"] = apikey
|
valid_gif_api_dict[gif_api]["apikey"] = apikey
|
||||||
@ -73,12 +72,17 @@ def setup(bot):
|
|||||||
bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'][gif_api] = valid_gif_api_dict[gif_api]
|
bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'][gif_api] = valid_gif_api_dict[gif_api]
|
||||||
|
|
||||||
for validgifapi in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys():
|
for validgifapi in bot.memory["SpiceBot_GifSearch"]['valid_gif_api_dict'].keys():
|
||||||
commandsquery_register(bot, "prefix", validgifapi)
|
command_dict = {
|
||||||
|
"comtype": "prefix",
|
||||||
|
"validcoms": validgifapi
|
||||||
|
}
|
||||||
|
SpiceBot.commands.dict['counts'] += 1
|
||||||
|
SpiceBot.commands.register(command_dict)
|
||||||
|
|
||||||
if validgifapi not in bot.memory["SpiceBot_GifSearch"]['cache'].keys():
|
if validgifapi not in bot.memory["SpiceBot_GifSearch"]['cache'].keys():
|
||||||
bot.memory["SpiceBot_GifSearch"]['cache'][validgifapi] = dict()
|
bot.memory["SpiceBot_GifSearch"]['cache'][validgifapi] = dict()
|
||||||
|
|
||||||
botevents.trigger(bot, botevents.BOT_GIFSEARCH, "SpiceBot_GifSearch")
|
SpiceBot.events.trigger(bot, SpiceBot.events.BOT_GIFSEARCH, "SpiceBot_GifSearch")
|
||||||
|
|
||||||
|
|
||||||
def shutdown(bot):
|
def shutdown(bot):
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
# 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 import botevents
|
|
||||||
|
|
||||||
|
|
||||||
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(botevents.BOT_LOADED)
|
|
||||||
@sopel.module.rule('.*')
|
|
||||||
def bot_events_complete(bot, trigger):
|
|
||||||
for comtype in bot.memory['SpiceBot_CommandsQuery']['commands'].keys():
|
|
||||||
bot.memory["SpiceBot_InvalidCommand"]["valid"].extend(bot.memory['SpiceBot_CommandsQuery']['commands'][comtype].keys())
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_LOADED, botevents.BOT_COMMANDSQUERY])
|
|
||||||
@sopel.module.commands('(.*)')
|
|
||||||
def InvalidCommand_triggers(bot, trigger):
|
|
||||||
return
|
|
||||||
|
|
||||||
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')
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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 .InvalidCommand import *
|
|
||||||
|
|
||||||
__author__ = 'Sam Zick'
|
|
||||||
__email__ = 'sam@deathbybandaid.net'
|
|
||||||
__version__ = '0.1.1'
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
# 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.config.types import StaticSection, ValidatedAttribute
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
|
|
||||||
|
|
||||||
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("SpiceBot_Kick", SpiceBot_Kick, validate=False)
|
|
||||||
config.SpiceBot_Kick.configure_setting('kick', 'MAXTARG limit for KICK')
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
|
||||||
|
|
||||||
# Inject KICK
|
|
||||||
botlogs.log('SpiceBot_Kick', "Implanting Kick function into bot")
|
|
||||||
bot.kick = SopelKICK.kick
|
|
||||||
sopel.bot.SopelWrapper.kick = SopelWrapperKICK.kick
|
|
||||||
|
|
||||||
# verify config settings for server
|
|
||||||
botlogs.log('SpiceBot_Kick', "Checking for config settings")
|
|
||||||
bot.config.define_section("SpiceBot_Kick", SpiceBot_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.SpiceBot_Kick.kick = int(value)
|
|
||||||
|
|
||||||
|
|
||||||
class SpiceBot_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
|
|
||||||
"""
|
|
||||||
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:
|
|
||||||
raise RuntimeError('Error: KICK requires a channel.')
|
|
||||||
else:
|
|
||||||
channel = self._trigger.sender
|
|
||||||
if nick is None:
|
|
||||||
raise RuntimeError('Error: KICK requires a nick.')
|
|
||||||
self._bot.kick(nick, channel, message)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,53 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
from __future__ import unicode_literals, absolute_import, division, print_function
|
|
||||||
|
|
||||||
import sopel.module
|
|
||||||
|
|
||||||
import spicemanip
|
|
||||||
|
|
||||||
from sopel_modules.SpiceBot.Logs import botlogs
|
|
||||||
from sopel_modules.SpiceBot.Events import botevents
|
|
||||||
from sopel_modules.SpiceBot_SBTools import sopel_triggerargs, command_permissions_check, inlist, inlist_match, similar_list
|
|
||||||
|
|
||||||
|
|
||||||
@botevents.check_ready([botevents.BOT_LOGS])
|
|
||||||
@sopel.module.nickname_commands('logs', 'debug')
|
|
||||||
def bot_command_logs(bot, trigger):
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
triggerargs, triggercommand = sopel_triggerargs(bot, trigger, 'nickname_command')
|
|
||||||
|
|
||||||
logtype = spicemanip.main(triggerargs, 1) or None
|
|
||||||
if not logtype:
|
|
||||||
bot.osd("Current valid log(s) include: " + spicemanip.main(botlogs.SpiceBot_Logs["list"].keys(), 'andlist'), trigger.sender, 'action')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not inlist(bot, logtype, botlogs.SpiceBot_Logs["list"].keys()):
|
|
||||||
closestmatches = similar_list(bot, logtype, botlogs.SpiceBot_Logs["list"].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, botlogs.SpiceBot_Logs["list"].keys())
|
|
||||||
|
|
||||||
if logtype == "Sopel_systemd":
|
|
||||||
logindex = botlogs.systemd_logs_fetch(bot)
|
|
||||||
elif logtype == "Sopel_stdio":
|
|
||||||
logindex = botlogs.stdio_logs_fetch(bot)
|
|
||||||
else:
|
|
||||||
logindex = botlogs.SpiceBot_Logs["list"][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 logindex:
|
|
||||||
bot.osd(" " + str(line))
|
|
||||||
bot.osd(str(logtype) + " log(s) Complete.")
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user