Merge pull request #76 from deathbybandaid/development

Development
This commit is contained in:
Deathbybandaid 2019-06-28 14:29:18 -04:00 committed by GitHub
commit 7d6b208e78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
490 changed files with 7513 additions and 95 deletions

2
.gitignore vendored
View File

@ -54,4 +54,4 @@ coverage.xml
docs/_build/
# PyBuilder
target/
#target/

View File

@ -7,3 +7,4 @@ recursive-include tests *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
recursive-include sopel_modules/SpiceBot_Configs/* *
recursive-include sopel_modules/SpiceBot_Text/*

View File

@ -3,3 +3,5 @@ gitpython
pygit2
fake-useragent
google-api-python-client
num2words
word2number

View File

@ -104,7 +104,7 @@ class BotCommands():
return self.dict['disabled'][disabletype]["users"]
elif botchannels.check_channel_bot(target, True):
if not len(list(self.dict['disabled'][disabletype]["channels"])):
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_disabled') or {}
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_' + disabletype + 'disabled') or {}
return self.dict['disabled'][disabletype]["channels"]
else:
raise Exception(str(target.lower()) + " appears to not be a valid user/channel")
@ -128,14 +128,14 @@ class BotCommands():
}
if botdb.check_nick_id(target):
if not len(list(self.dict['disabled'][disabletype]["users"])):
self.dict['disabled'][disabletype]["users"] = botdb.get_nick_value(target, 'commands_disabled') or {}
self.dict['disabled'][disabletype]["users"] = botdb.get_nick_value(target, 'commands_' + disabletype + 'disabled') or {}
self.dict['disabled'][disabletype]["users"][command] = {"reason": reason, "timestamp": timestamp, "disabledby": bywhom}
botdb.set_nick_value(target, 'commands_disabled', self.dict['disabled'][disabletype]["users"])
botdb.set_nick_value(target, 'commands_' + disabletype + 'disabled', self.dict['disabled'][disabletype]["users"])
elif botchannels.check_channel_bot(target, True):
if not len(list(self.dict['disabled'][disabletype]["channels"])):
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_disabled') or {}
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_' + disabletype + 'disabled') or {}
self.dict['disabled'][disabletype]["channels"][command] = {"reason": reason, "timestamp": timestamp, "disabledby": bywhom}
botdb.set_channel_value(target, 'commands_disabled', self.dict['disabled'][disabletype]["channels"])
botdb.set_channel_value(target, 'commands_' + disabletype + 'disabled', self.dict['disabled'][disabletype]["channels"])
else:
raise Exception(str(target.lower()) + " appears to not be a valid user/channel")
@ -147,16 +147,16 @@ class BotCommands():
}
if botdb.check_nick_id(target):
if not len(list(self.dict['disabled'][disabletype]["users"])):
self.dict['disabled'][disabletype]["users"] = botdb.get_nick_value(target, 'commands_disabled') or {}
self.dict['disabled'][disabletype]["users"] = botdb.get_nick_value(target, 'commands_' + disabletype + 'disabled') or {}
if command in list(self.dict['disabled'][disabletype]["users"].keys()):
del self.dict['disabled'][disabletype]["users"][command]
botdb.set_nick_value(target, 'commands_disabled', self.dict['disabled'][disabletype]["users"])
botdb.set_nick_value(target, 'commands_' + disabletype + 'disabled', self.dict['disabled'][disabletype]["users"])
elif botchannels.check_channel_bot(target, True):
if not len(list(self.dict['disabled'][disabletype]["channels"])):
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_disabled') or {}
self.dict['disabled'][disabletype]["channels"] = botdb.get_channel_value(target, 'commands_' + disabletype + 'disabled') or {}
if command in list(self.dict['disabled'][disabletype]["channels"].keys()):
del self.dict['disabled'][disabletype]["channels"][command]
botdb.set_channel_value(target, 'commands_disabled', self.dict['disabled'][disabletype]["channels"])
botdb.set_channel_value(target, 'commands_' + disabletype + 'disabled', self.dict['disabled'][disabletype]["channels"])
else:
raise Exception(str(target.lower()) + " appears to not be a valid user/channel")

View File

@ -11,12 +11,14 @@ from sopel.db import SopelDB, _deserialize
from .Config import config as botconfig
from sqlalchemy import Column, String, ForeignKey, Integer, Text
from sqlalchemy.engine.url import URL
from sqlalchemy import create_engine, Column, String, ForeignKey, Integer, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import SQLAlchemyError
import json
import threading
import os
BASE = declarative_base()
@ -531,6 +533,48 @@ class BotDatabase():
def __init__(self):
db_type = botconfig.core.db_type
if db_type == 'sqlite':
path = botconfig.core.db_filename
config_dir, config_file = os.path.split(botconfig.filename)
config_name, _ = os.path.splitext(config_file)
if path is None:
path = os.path.join(config_dir, config_name + '.db')
path = os.path.expanduser(path)
if not os.path.isabs(path):
path = os.path.normpath(os.path.join(config_dir, path))
SopelDB.filename = path
SopelDB.url = 'sqlite:///%s' % path
# Otherwise, handle all other database engines
else:
if db_type == 'mysql':
drivername = botconfig.core.db_driver or 'mysql'
elif db_type == 'postgres':
drivername = botconfig.core.db_driver or 'postgresql'
elif db_type == 'oracle':
drivername = botconfig.core.db_driver or 'oracle'
elif db_type == 'mssql':
drivername = botconfig.core.db_driver or 'mssql+pymssql'
elif db_type == 'firebird':
drivername = botconfig.core.db_driver or 'firebird+fdb'
elif db_type == 'sybase':
drivername = botconfig.core.db_driver or 'sybase+pysybase'
else:
raise Exception('Unknown db_type')
db_user = botconfig.core.db_user
db_pass = botconfig.core.db_pass
db_host = botconfig.core.db_host
db_port = botconfig.core.db_port # Optional
db_name = botconfig.core.db_name # Optional, depending on DB
SopelDB.url = URL(drivername=drivername, username=db_user, password=db_pass,
host=db_host, port=db_port, database=db_name, query={'charset': 'utf8'})
SopelDB.engine = create_engine(SopelDB.url, encoding='utf-8')
SopelDB.nick_id_lock = threading.Lock()
sopel.db.NickIDs = NickIDs

View File

@ -11,10 +11,8 @@ from sopel.config.types import StaticSection, ListAttribute
from .Config import config as botconfig
from .Read import read as botread
from .Commands import commands as botcommands
from .Database import db as botdb
# import requests
from fake_useragent import UserAgent
# import urllib
import os
import copy
@ -27,10 +25,8 @@ class BotDictCommands():
def __init__(self):
self.setup_dictcoms()
self.header = {'User-Agent': str(UserAgent().chrome)}
self.valid_com_types = ['simple']
self.valid_com_types_old = [
'simple', 'fillintheblank', 'targetplusreason',
self.valid_com_types = [
'simple', 'fillintheblank', 'target', 'targetplusreason',
'sayings', "readfromfile", "readfromurl",
"ascii_art", "gif", "translate", "responses",
"feeds", "search"
@ -129,9 +125,6 @@ class BotDictCommands():
else:
dict_from_file[mustbe]["type"] = "simple"
return dict_from_file
"""
# each usecase needs to know if it can be updated. Default is false
if "updates_enabled" not in list(dict_from_file[mustbe].keys()):
dict_from_file[mustbe]["updates_enabled"] = False
@ -180,9 +173,9 @@ class BotDictCommands():
if not isinstance(dict_from_file[mustbe]["response_fail"], list):
dict_from_file[mustbe]["response_fail"] = [dict_from_file[mustbe]["response_fail"]]
# if dict_from_file[mustbe]["updates_enabled"]:
# adjust_nick_array(bot, str(bot.nick), 'long', 'sayings', maincom + "_" + str(mustbe), dict_from_file[mustbe]["responses"], 'startup')
# dict_from_file[mustbe]["responses"] = get_nick_value(bot, str(bot.nick), 'long', 'sayings', maincom + "_" + str(mustbe)) or []
if dict_from_file[mustbe]["updates_enabled"]:
self.adjust_nick_array(str(botconfig.nick), 'sayings', maincom + "_" + str(mustbe), dict_from_file[mustbe]["responses"], 'startup')
dict_from_file[mustbe]["responses"] = botdb.get_plugin_value("dictcom", maincom + "_" + str(mustbe)) or []
# each usecase needs a response
if "responses" not in list(dict_from_file[mustbe].keys()):
@ -190,20 +183,17 @@ class BotDictCommands():
# verify responses are in list form
if not isinstance(dict_from_file[mustbe]["responses"], list):
# TODO read text files
# if dict_from_file[mustbe]["responses"] in bot.memory["botdict"]["tempvals"]['txt_files'].keys():
# dict_from_file[mustbe]["responses"] = bot.memory["botdict"]["tempvals"]['txt_files'][dict_from_file[mustbe]["responses"]]
if str(dict_from_file[mustbe]["responses"]).startswith(tuple(["https://", "http://"])):
try:
page = requests.get(dict_from_file[mustbe]["responses"], headers=self.header)
except Exception as e:
page = e
page = None
if page and not str(page.status_code).startswith(tuple(["4", "5"])):
htmlfile = urllib.request.urlopen(dict_from_file[mustbe]["responses"])
lines = htmlfile.read().splitlines()
dict_from_file[mustbe]["responses"] = lines
# text files
if dict_from_file[mustbe]["responses"] in list(botread.dict["text"].keys()):
dict_from_file[mustbe]["responses"] = botread.dict["text"][dict_from_file[mustbe]["responses"]]["lines"]
if str(dict_from_file[mustbe]["responses"]).startswith(tuple(["https://", "http://"])):
botread.webpage_to_list(dict_from_file[mustbe]["responses"])
# TODO assign dict value, but don't load until needed
# TODO use botdb to store an offline version
if dict_from_file[mustbe]["responses"] in list(botread.dict["webpage"].keys()):
dict_from_file[mustbe]["responses"] = botread.dict["webpage"][dict_from_file[mustbe]["responses"]]["lines"]
else:
dict_from_file[mustbe]["responses"] = [dict_from_file[mustbe]["responses"]]
@ -273,7 +263,34 @@ class BotDictCommands():
dict_from_file[mustbe]["privs"] = []
return dict_from_file
"""
def adjust_nick_array(self, nick, sortingkey, usekey, values, direction):
if not isinstance(values, list):
values = [values]
oldvalues = botdb.get_nick_value(nick, usekey, sortingkey) or []
# startup entries
if direction == 'startup':
if oldvalues == []:
direction == 'add'
else:
return
# adjust
for value in values:
if direction == 'add':
if value not in oldvalues:
oldvalues.append(value)
elif direction == 'startup':
if value not in oldvalues:
oldvalues.append(value)
elif direction in ['del', 'remove']:
if value in oldvalues:
oldvalues.remove(value)
botdb.set_nick_value(nick, usekey, oldvalues, sortingkey)
def setup_dictcoms(self):
botconfig.define_section("SpiceBot_DictComs", SpiceBot_DictComs_MainSection, validate=False)

View File

@ -134,7 +134,7 @@ def prerun_query(t_command_type='module', t_command_subtype=None):
# messagelog ID
argsdict_default["log_id"] = botmessagelog.messagelog_assign()
argsdict_default["realcom"] = "query_command"
argsdict_default["realcom"] = "query"
argsdict_default["comtext"] = "'" + bot.nick + " query'"
argsdict_default["realcomtext"] = "'" + bot.nick + " query'"
@ -143,28 +143,19 @@ def prerun_query(t_command_type='module', t_command_subtype=None):
argsdict_default["dict"] = botcommands.get_command_dict("query", 'nickname')
# split into && groupings
and_split = trigger_and_split(trigger_args)
# Create dict listings for trigger.sb
argsdict_list = trigger_argsdict_list(argsdict_default, and_split)
argsdict = trigger_argsdict_single(argsdict_default, trigger_args)
# Run the function for all splits
botmessagelog.messagelog_start(bot, trigger, argsdict_default["log_id"])
runcount = 0
for argsdict in argsdict_list:
runcount += 1
trigger.sb = copy.deepcopy(argsdict)
trigger.sb["runcount"] = runcount
trigger.sb = copy.deepcopy(argsdict)
trigger.sb["args"], trigger.sb["hyphen_arg"] = trigger_hyphen_args(trigger.sb["args"])
if not trigger.sb["hyphen_arg"]:
# check if anything prohibits the nick from running the command
if trigger_runstatus(bot, trigger):
function(bot, trigger, *args, **kwargs)
else:
trigger_hyphen_arg_handler(bot, trigger)
trigger.sb["runcount"] = 1
# check if anything prohibits the nick from running the command
if trigger_runstatus_query(bot, trigger):
function(bot, trigger, *args, **kwargs)
botmessagelog.messagelog_exit(bot, argsdict_default["log_id"])
return internal_prerun
@ -198,9 +189,12 @@ def trigger_argsdict_list(argsdict_default, and_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":
if len(argsdict_part["args"]) and (argsdict_part["args"][0] == "-a" or argsdict_part["args"][-1] == "-a"):
argsdict_part["adminswitch"] = True
argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list')
if argsdict_part["args"][0] == "-a":
argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list')
elif argsdict_part["args"][-1] == "-a":
del argsdict_part["args"][-1]
else:
argsdict_part["adminswitch"] = False
prerun_split.append(argsdict_part)
@ -210,14 +204,68 @@ def trigger_argsdict_list(argsdict_default, and_split):
def trigger_argsdict_single(argsdict_default, trigger_args_part):
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":
if len(argsdict_part["args"]) and (argsdict_part["args"][0] == "-a" or argsdict_part["args"][-1] == "-a"):
argsdict_part["adminswitch"] = True
argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list')
if argsdict_part["args"][0] == "-a":
argsdict_part["args"] = spicemanip.main(argsdict_part["args"], '2+', 'list')
elif argsdict_part["args"][-1] == "-a":
del argsdict_part["args"][-1]
else:
argsdict_part["adminswitch"] = False
return argsdict_part
def trigger_runstatus_query(bot, trigger):
# 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:
botmessagelog.messagelog_error(trigger.sb["log_id"], "The admin switch (-a) is for use by authorized nicks ONLY.")
return False
# don't run commands that are disabled in channels
if not trigger.is_privmsg:
channel_disabled_list = botcommands.get_commands_disabled(str(trigger.sender), "fully")
if "nickname_query" in list(channel_disabled_list.keys()):
return False
# don't run commands that are disabled for specific users
nick_disabled_list = botcommands.get_commands_disabled(str(trigger.nick), "fully")
if "nickname_query" in list(nick_disabled_list.keys()):
return False
# don't run commands that are disabled in channels
if not trigger.is_privmsg:
channel_disabled_list = botcommands.get_commands_disabled(str(trigger.sender), "fully")
if "nickname_query" in list(channel_disabled_list.keys()):
reason = channel_disabled_list["nickname_query"]["reason"]
timestamp = channel_disabled_list["nickname_query"]["timestamp"]
bywhom = channel_disabled_list["nickname_query"]["disabledby"]
message = "The " + str(trigger.sb["comtext"]) + " command was disabled by " + bywhom + " for " + str(trigger.sender) + " at " + str(timestamp) + " for the following reason: " + str(reason)
return trigger_cant_run(bot, trigger, message)
# don't run commands that are disabled for specific users
nick_disabled_list = botcommands.get_commands_disabled(str(trigger.nick), "fully")
if "nickname_query" in list(nick_disabled_list.keys()):
bywhom = nick_disabled_list["nickname_query"]["disabledby"]
if bywhom != trigger.nick:
reason = nick_disabled_list["nickname_query"]["reason"]
timestamp = nick_disabled_list["nickname_query"]["timestamp"]
message = "The " + str(trigger.sb["comtext"]) + " command was disabled by " + bywhom + " for " + str(trigger.sender) + " at " + str(timestamp) + " for the following reason: " + str(reason)
return trigger_cant_run(bot, trigger, message)
else:
botcommands.unset_command_disabled(trigger.sb["realcomref"], trigger.nick, "fully")
botmessagelog.messagelog(trigger.sb["log_id"], trigger.sb["comtext"] + " is now enabled for " + str(trigger.nick))
return True
def trigger_runstatus(bot, trigger):
# Bots can't run commands

View File

@ -6,6 +6,9 @@ import sopel_modules
import os
import codecs
import requests
import urllib
from fake_useragent import UserAgent
from .Logs import logs
from .Config import config as botconfig
@ -14,7 +17,46 @@ from .Config import config as botconfig
class BotRead():
def __init__(self):
self.dict = dict()
self.header = {'User-Agent': str(UserAgent().chrome)}
self.dict = {
"text": {},
"webpage": {},
}
self.load_txt_files()
def load_txt_files(self):
dir_to_scan = []
for plugin_dir in set(sopel_modules.__path__):
textdir = os.path.join(plugin_dir, "SpiceBot_Text")
if os.path.exists(textdir) and os.path.isdir(textdir):
if len(os.listdir(textdir)) > 0:
dir_to_scan.append(textdir)
# iterate over files within
for directory in dir_to_scan:
for txtfile in os.listdir(directory):
text_file_list = []
text_file = open(os.path.join(directory, txtfile), 'r')
lines = text_file.readlines()
for line in lines:
text_file_list.append(line)
text_file.close()
self.dict["text"][txtfile] = {
"lines": text_file_list
}
def webpage_to_list(self, url):
try:
page = requests.get(url, headers=self.header)
except Exception as e:
page = e
page = None
if page and not str(page.status_code).startswith(tuple(["4", "5"])):
htmlfile = urllib.request.urlopen(url)
lines = htmlfile.read().splitlines()
self.dict["webpage"][url] = {
"lines": lines
}
def get_config_dirs(self, config_dir_name):
dir_to_scan = []

View File

@ -0,0 +1,195 @@
# coding=utf8
from __future__ import unicode_literals, absolute_import, division, print_function
import spicemanip
import re
from num2words import num2words
class Translate():
def __init__(self):
self.dict = {}
def bot_translate_process(self, totranslate, translationtypes):
# just in case
if not isinstance(translationtypes, list):
translationtypes = [translationtypes]
for translationtype in translationtypes:
if translationtype == "hyphen":
totranslate = spicemanip.main(totranslate, 0).replace(' ', '-')
elif translationtype == "underscore":
totranslate = spicemanip.main(totranslate, 0).replace(' ', '_')
elif translationtype == "ermahgerd":
totranslate = self.trernslert(totranslate)
elif translationtype == "obscure":
totranslate = self.text_obscure(totranslate)
elif translationtype == "piglatin":
totranslate = self.text_piglatin(totranslate)
elif translationtype == "binaryinvert":
totranslate = self.text_binary_swap(totranslate)
elif translationtype == "onetozero":
totranslate = self.text_one_to_zero_swap(totranslate)
elif translationtype == "upper":
totranslate = spicemanip.main(totranslate, 0).upper()
elif translationtype == "lower":
totranslate = spicemanip.main(totranslate, 0).lower()
return totranslate
def text_obscure(self, words):
amountofletters = len(words)
mystring = "*" * amountofletters
return mystring
def text_piglatin(self, words):
if not isinstance(words, list):
words = [words]
rebuildarray = []
for word in words:
word = word.lower()
first = word[:1]
if first in ['a', 'e', 'i', 'o', 'u']:
new_word = word + 'ay'
else:
new_word = word[1:] + first + 'ay'
rebuildarray.append(new_word)
words = spicemanip.main(rebuildarray, 0)
return words
def trernslert(self, werds):
terkerns = werds.split()
er = ''
for terk in terkerns:
if terk.endswith(','):
terk = re.sub(r"[,]+", '', terk)
cermmer = 'true'
else:
cermmer = 'false'
if terk.startswith('('):
terk = re.sub(r"[(]+", '', terk)
lerftperernthersers = 'true'
else:
lerftperernthersers = 'false'
if terk.endswith(')'):
terk = re.sub(r"[)]+", '', terk)
rerghtperernthersers = 'true'
else:
rerghtperernthersers = 'false'
if terk.endswith('%'):
terk = re.sub(r"[%]+", '', terk)
percernt = 'true'
else:
percernt = 'false'
werd = self.ermergerd(terk)
if lerftperernthersers == 'true':
werd = str('(' + werd)
if percernt == 'true':
werd = str(werd + ' PERCERNT')
if rerghtperernthersers == 'true':
werd = str(werd + ')')
if cermmer == 'true':
werd = str(werd + ',')
cermmer
er = er + ' ' + werd
return er
def ermergerd(self, w):
w = w.strip().lower()
derctshernerer = {'me': 'meh', 'you': 'u', 'are': 'er', "you're": "yer", "i'm": "erm", "i've": "erv", "my": "mah", "the": "da", "omg": "ermahgerd"}
if w in derctshernerer:
return derctshernerer[w].upper()
else:
w = re.sub(r"[\.,/;:!@#$%^&*\?)(]+", '', w)
if w[0].isdigit():
w = num2words(int(w))
w = re.sub(r"tion", "shun", w)
pat = r"[aeiouy]+"
er = re.sub(pat, "er", w)
if w.startswith('y'):
er = 'y' + re.sub(pat, "er", w[1:])
if w.endswith('e') and not w.endswith('ee') and len(w) > 3:
er = re.sub(pat, "er", w[:-1])
if w.endswith('ing'):
er = re.sub(pat, "er", w[:-3]) + 'in'
er = er[0] + er[1:].replace('y', 'er')
er = er.replace('rr', 'r')
return er.upper()
def text_one_to_zero_swap(self, words):
if not words or words == []:
return "No input provided"
if not isinstance(words, list):
words = [words]
words = spicemanip.main(words, 0).split(" ")
outputarray = []
for word in words:
if not self.isitbinary(word):
word = self.text_binary_swap(word)
word = str(word).replace('1', '2')
word = str(word).replace('0', '1')
word = str(word).replace('2', '0')
outputarray.append(str(word))
outputarray = spicemanip.main(outputarray, 0)
return outputarray
def text_binary_swap(self, words):
if not words or words == []:
return "No input provided"
if not isinstance(words, list):
words = [words]
words = spicemanip.main(words, 0).split(" ")
outputarray = []
for word in words:
if self.isitbinary(word):
word = self.bits2string(word) or 'error'
else:
word = self.string2bits(word) or 1
word = spicemanip.main(word, 0)
outputarray.append(str(word))
outputarray = spicemanip.main(outputarray, 0)
return outputarray
def unicode_string_cleanup(string):
for r in (("\u2013", "-"), ("\u2019", "'"), ("\u2026", "...")):
string = string.replace(*r)
return string
def isitbinary(self, string):
p = set(string)
s = {'0', '1'}
if s == p or p == {'0'} or p == {'1'}:
return True
else:
return False
def string2bits(self, s=''):
return [bin(ord(x))[2:].zfill(8) for x in s]
def bits2string(self, b=None):
return ''.join(chr(int(b[i*8:i*8+8], 2)) for i in range(len(b)//8))
translate = Translate()

View File

@ -5,7 +5,9 @@ from __future__ import unicode_literals, absolute_import, division, print_functi
from sopel.tools import Identifier
from .Database import db as botdb
from .Tools import is_number
from .Tools import is_number, inlist, similar, array_arrangesort
import spicemanip
# TODO timestamp for new .seen
@ -45,9 +47,15 @@ class BotUsers():
nick_id = self.whois_ident(nickinput)
return nick_id
def whois_ident(self, nick):
def whois_ident(self, nick, usercreate=True):
nick = Identifier(nick)
nick_id = botdb.db.get_nick_id(nick, create=True)
try:
nick_id = botdb.db.get_nick_id(nick, create=usercreate)
except Exception as e:
nick_id = e
nick_id = None
if usercreate:
self.add_to_all(nick, nick_id)
return int(nick_id)
def save_user_db(self):
@ -84,8 +92,8 @@ class BotUsers():
# set current nick
self.dict["current"][nick_id]["nick"] = user
# add joined channel to nick list
if channel not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(channel)
if str(channel).lower() not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(str(channel).lower())
# mark user as online
if nick_id not in self.dict["online"]:
self.dict["online"].append(int(nick_id))
@ -104,8 +112,8 @@ class BotUsers():
# set current nick
self.dict["current"][nick_id]["nick"] = user
# add joined channel to nick list
if trigger.sender not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(trigger.sender)
if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower())
# mark user as online
if nick_id not in self.dict["online"]:
self.dict["online"].append(int(nick_id))
@ -121,8 +129,8 @@ class BotUsers():
# set current nick
self.dict["current"][nick_id]["nick"] = trigger.nick
# add joined channel to nick list
if trigger.sender not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(trigger.sender)
if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower())
# mark user as online
if nick_id not in self.dict["online"]:
self.dict["online"].append(int(nick_id))
@ -139,8 +147,8 @@ class BotUsers():
# Verify nick is in the all list
self.add_to_current(trigger.nick, nick_id)
# empty nicks channel list
if trigger.sender in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(trigger.sender)
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower())
self.dict["current"][nick_id]["channels"] = []
# mark user as offline
if nick_id in self.dict["online"]:
@ -151,8 +159,8 @@ class BotUsers():
def part(self, bot, trigger):
if trigger.nick == bot.nick:
for nick_id in list(self.dict["current"].keys()):
if trigger.sender in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(trigger.sender)
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower())
# mark offline
if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]:
self.dict["online"].remove(nick_id)
@ -166,8 +174,8 @@ class BotUsers():
# Verify nick is in the all list
self.add_to_current(trigger.nick, nick_id)
# remove channel from nick list
if trigger.sender in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(trigger.sender)
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower())
# mark offline
if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]:
self.dict["online"].remove(nick_id)
@ -178,8 +186,8 @@ class BotUsers():
targetnick = Identifier(str(trigger.args[1]))
if targetnick == bot.nick:
for nick_id in list(self.dict["current"].keys()):
if trigger.sender in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(trigger.sender)
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower())
# mark offline
if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]:
self.dict["online"].remove(nick_id)
@ -193,8 +201,8 @@ class BotUsers():
# Verify nick is in the all list
self.add_to_current(targetnick, nick_id)
# remove channel from nick list
if trigger.sender in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(trigger.sender)
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].remove(str(trigger.sender).lower())
# mark offline
if not len(self.dict["current"][nick_id]["channels"]) and nick_id in self.dict["online"]:
self.dict["online"].remove(nick_id)
@ -217,8 +225,8 @@ class BotUsers():
# set current nick
self.dict["current"][nick_id]["nick"] = newnick
# add joined channel to nick list
if trigger.sender not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(trigger.sender)
if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]:
self.dict["current"][nick_id]["channels"].append(str(trigger.sender).lower())
# mark user as online
if nick_id not in self.dict["online"]:
self.dict["online"].append(int(nick_id))
@ -228,12 +236,107 @@ class BotUsers():
def mode(self, bot, trigger):
return
def targetcheck(self):
def targetcheck(self, target):
return True
# idk whois
if not botdb.check_nick_id(posstarget):
if not botdb.check_nick_id(target):
return
def nick_actual(self, nick, altlist=None):
nick_id = self.whois_ident(nick)
nick_actual = self.ID(nick_id)
return nick_actual
def target_online(self, nick, nick_id=None):
if not nick_id:
nick_id = self.ID(nick)
if nick_id in self.dict["online"]:
return True
else:
return False
def target_check(self, bot, trigger, target, targetbypass):
targetgood = {"targetgood": True, "error": "None", "reason": None}
if not isinstance(targetbypass, list):
targetbypass = [targetbypass]
if "notarget" not in targetbypass:
if not target or target == '':
return {"targetgood": False, "error": "No target Given.", "reason": "notarget"}
# Optional don't allow self-target
if "self" not in targetbypass:
if inlist(target, trigger.nick):
return {"targetgood": False, "error": "This command does not allow you to target yourself.", "reason": "self"}
# cannot target bots
if "bot" not in targetbypass:
if inlist(target, bot.nick):
return {"targetgood": False, "error": "I am a bot and cannot be targeted.", "reason": "bot"}
if "bots" not in targetbypass:
if inlist(target, bot.nick):
return {"targetgood": False, "error": self.nick_actual(target) + " is a bot and cannot be targeted.", "reason": "bots"}
# Not a valid user
if "unknown" not in targetbypass:
if not botdb.check_nick_id(target):
sim_user, sim_num = [], []
for nick_id in list(self.dict["all"].keys()):
nick_list = self.dict["all"][nick_id]
for nick in nick_list:
similarlevel = similar(str(target).lower(), nick.lower())
if similarlevel >= .75:
sim_user.append(nick)
sim_num.append(similarlevel)
if sim_user != [] and sim_num != []:
sim_num, sim_user = array_arrangesort(bot, sim_num, sim_user)
closestmatch = spicemanip.main(sim_user, 'reverse', "list")
listnumb, relist = 1, []
for item in closestmatch:
if listnumb <= 3:
relist.append(str(item))
listnumb += 1
closestmatches = spicemanip.main(relist, "andlist")
targetgooderror = "It looks like you're trying to target someone! Did you mean: " + str(closestmatches) + "?"
else:
targetgooderror = "I am not sure who that is."
return {"targetgood": False, "error": targetgooderror, "reason": "unknown"}
nick_id = self.whois_ident(target, usercreate=False)
# User offline
if "offline" not in targetbypass:
if not self.target_online(target, nick_id):
return {"targetgood": False, "error": "It looks like " + self.nick_actual(target) + " is offline right now!", "reason": "offline"}
# Private Message
if "privmsg" not in targetbypass:
if trigger.is_privmsg and not inlist(target, trigger.nick):
return {"targetgood": False, "error": "Leave " + self.nick_actual(target) + " out of this private conversation!", "reason": "privmsg"}
# not in the same channel
if "diffchannel" not in targetbypass:
if not trigger.is_privmsg and self.target_online(target, nick_id):
if str(trigger.sender).lower() not in self.dict["current"][nick_id]["channels"]:
return {"targetgood": False, "error": "It looks like " + self.nick_actual(target) + " is online right now, but in a different channel.", "reason": "diffchannel"}
return targetgood
def random_valid_target(self, bot, trigger, outputtype):
validtargs = []
if trigger.is_privmsg:
validtargs.extend([str(bot.nick), trigger.nick])
else:
for nick_id in self.dict["online"]:
if str(trigger.sender).lower() in self.dict["current"][nick_id]["channels"]:
nick = self.dict["all"][nick_id][0]
validtargs.append(nick)
if outputtype == 'list':
return validtargs
elif outputtype == 'random':
return spicemanip.main(validtargs, 'random')
users = BotUsers()

View File

@ -29,6 +29,7 @@ from .Sherlock import *
from .Reddit import *
from .DictComs import *
from .Read import *
from .Translate import *
from .configure import *

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ( 〇□〇) '],
},
}

View File

@ -0,0 +1,28 @@
{
"?default": {
"type": "simple",
"responses": [
[
"_________$$____________",
"________$__$___________",
"________$__$___________",
"_______$$__$$__________",
"______$__$__$_$$_$$____",
"______$__$__$__$$__$___",
"_$$$__$__$__$__$$__$___",
"$___$$_______________$_",
"$____$$_______________$",
"_$____________________$",
"__$___________________$",
"___$_________________$_",
"____$_______________$__",
"_____$_____________$___",
"______$___________$____",
"_______$$$$$$$$$$$_____",
],
],
},
}

View File

@ -0,0 +1,7 @@
{
"validcoms": ['confused', 'wat'],
"?default": {
"type": "simple",
"responses": [' (●__●)??? '],
},
}

View File

@ -0,0 +1,16 @@
{
"?default": {
"type": "simple",
"responses": [
[
" (",
" __________ )\\",
" / /\______{,}",
" \_________\/",
],
],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ⊙_ʘ '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ( p′︵‵。) '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ᕕ( ᐛ )ᕗ '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ლ(´ڡ`ლ) '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' (●♡∀♡) '],
},
}

View File

@ -0,0 +1,7 @@
{
"validcoms": ['rage', 'anger'],
"?default": {
"type": "simple",
"responses": [' щ(ಠ益ಠщ) '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [" ¯\_(ツ)_/¯ "],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' (-﹏-。) '],
},
}

View File

@ -0,0 +1,7 @@
{
"validcoms": ['success', 'winner'],
"?default": {
"type": "simple",
"responses": [' ٩( ᐛ )و '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' (((( ;°Д°)))) '],
},
}

View File

@ -0,0 +1,7 @@
{
"validcoms": ['tableflip', 'flip', 'tflip'],
"?default": {
"type": "simple",
"responses": [' (╯°□°)╯︵ ┻━┻ '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ┬┬ ノ( ゜-゜ノ) '],
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "simple",
"responses": [' ( ゚д゚) '],
},
}

View File

@ -0,0 +1,7 @@
{
"validcoms": ['sword', 'link', 'zelda'],
"?default": {
"type": "simple",
"responses": ["It's dangerous to go alone take this 0==|======>"],
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['atwebby', 'actualtechwebby'],
"?default": {
"type": "feeds",
"responses": "actualtechwebby",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['comptiawebby'],
"?default": {
"type": "feeds",
"responses": "comptiawebby",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['dilbert'],
"?default": {
"type": "feeds",
"responses": "dilbert",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,22 @@
{
"validcoms": ['github', 'repo'],
"?default": {
"type": "simple",
"responses": ['You have two choices. master or dev'],
},
"master": {
"type": "feeds",
"responses": "githubrepomaster",
"selection_allowed": False,
},
("dev", "development"): {
"type": "feeds",
"responses": "githubrepodev",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['packt'],
"?default": {
"type": "feeds",
"responses": "packt",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['gcal', 'spicebotcal', 'spicecal'],
"?default": {
"type": "feeds",
"responses": "spicebotcalendar",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['spicewebby', 'spiceworkswebby'],
"?default": {
"type": "feeds",
"responses": "spiceworkswebby",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['stardate'],
"?default": {
"type": "feeds",
"responses": "stardates",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['onion', 'theonion'],
"?default": {
"type": "feeds",
"responses": "theonion",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['truthinit'],
"?default": {
"type": "feeds",
"responses": "truthinit",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['twitlive'],
"?default": {
"type": "feeds",
"responses": "twitlive",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['xkcd'],
"?default": {
"type": "feeds",
"responses": "xkcd",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['zits'],
"?default": {
"type": "feeds",
"responses": "zits",
"selection_allowed": False,
},
}

View File

@ -0,0 +1,10 @@
{
"validcoms": ['notsaying', 'aliens'],
"?default": {
"type": "fillintheblank",
"blank_phrasehandle": ["a", "an"],
"responses": ["I'm not saying it was $blank, but it was $blank!"],
"blank_backup": "aliens",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['ants', 'ant'],
"?default": {
"type": "fillintheblank",
"responses": ["Do you want $blank cause that's how you get $blank!"],
"blank_backup": 'ants',
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$instigator approves $blank"],
"blank_backup": 'that',
},
}

View File

@ -0,0 +1,10 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$instigator introduces a backdoor into $blank system"],
"response_fail": [
"$instigator introduces a backdoor into my system... Ohhh... It tickles.",
],
},
}

View File

@ -0,0 +1,9 @@
{
"validcoms": ['backup', 'backups'],
"?default": {
"type": "fillintheblank",
"responses": ["$blank? weee dun neeeed no steenkin $blank!!"],
"blank_backup": "backups"
},
}

View File

@ -0,0 +1,6 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["If you $blank, you're gonna have a bad time"],
},
}

View File

@ -0,0 +1,9 @@
{
"validcoms": ['beach'],
"?default": {
"type": "fillintheblank",
"responses": ["$instigator wants to start a ransomware company on the beach because of $blank!"],
"blank_backup": "money",
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["We're gonna need a bigger $blank!"],
"blank_backup": 'boat',
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['boop', 'r2d2'],
"?default": {
"type": "fillintheblank",
"responses": ["$botnick boops $instigator softly because $input!"],
"response_fail": "$botnick boops $instigator softly!",
},
}

View File

@ -0,0 +1,20 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["let me call my buddy and get him down here... he's an expert on $blank"],
"response_fail": [
"What is your buddy good at?",
],
},
"not": {
"type": "simple",
"responses": [
[
"I'm not your friend, buddy",
"I'm not your buddy, pal",
"I'm not your pal, guy",
"I'm not your guy, friend ",
]
],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['catch', 'first'],
"?default": {
"type": "fillintheblank",
"responses": ["The first $blank of the day!"],
"blank_backup": 'catch',
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['chump', 'chumps'],
"?default": {
"type": "fillintheblank",
"responses": ["$blanks are for chumps!!!!"],
},
}

View File

@ -0,0 +1,9 @@
{
"validcoms": ['cdh', 'colddeadhands'],
"?default": {
"type": "fillintheblank",
"responses": ["You can have my $blank, when you pry it from my cold dead hands!!"],
"blank_backup": 'gun',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Needs Moar $blank!!"],
"blank_backup": 'cowbell',
},
}

View File

@ -0,0 +1,6 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$blank, $blank everywhere!"],
},
}

View File

@ -0,0 +1,9 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["For the record: $blank"],
"blank_backup": "it was not my fault",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['grind', 'gears', 'grinds', 'gears'],
"?default": {
"type": "fillintheblank",
"responses": ["You know what grinds my gears?? $blank"],
"blank_required": False,
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["YOU CAN'T HANDLE THE $blank"],
"blank_backup": 'truth',
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['got', 'milk'],
"?default": {
"type": "fillintheblank",
"responses": ["Got $blank?"],
"blank_backup": 'milk',
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["If you could $blank,,, That'd be great."],
"blank_backup": 'come in on Saturday',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Stop trying to make $blank happen. It's not going to happen!"],
"blank_backup": "stuff",
},
}

View File

@ -0,0 +1,18 @@
{
"validcoms": ['hashbrown', 'hb'],
"?default": {
"type": "fillintheblank",
"responses": ["hashbrown $blank"],
"blank_backup": 'fail',
},
"fwp": {
"type": "fillintheblank",
"responses": ["hashbrown $blank"],
"blank_backup": 'firstworldproblems',
},
"ym": {
"type": "fillintheblank",
"responses": ["hashbrown $blank"],
"blank_backup": 'yo momma',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Too much $blank is bad for your health."],
"blank_backup": '$instigator',
},
}

View File

@ -0,0 +1,18 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["mmmmmmm $blank"],
"blank_backup": 'donuts',
},
('good', 'g'): {
"type": "simple",
"responses": ["WooHoo!"],
},
('bad', 'b', 'bad?', 'good?'): {
"type": "simple",
"responses": ["D'ooooh!"],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['ich', 'icanhaz'],
"?default": {
"type": "fillintheblank",
"responses": ["I can haz $blank??"],
"blank_backup": 'stuff',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["I Can't Even $blank"],
"blank_backup": '...',
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["I don't always $blank, but when I do, I drink Dos Equis."],
"blank_backup": 'drink beer',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$blank IS HAAAAARD!!!"],
"blank_backup": 'stuff',
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$blank??? is THAT what the kids are calling it these days?"],
},
}

View File

@ -0,0 +1,6 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Am I the only one around here who $blank???"],
},
}

View File

@ -0,0 +1,10 @@
{
"validcoms": ['let', 'letit', 'letitgo'],
"?default": {
"type": "fillintheblank",
"responses": ["Let it $blank, let it $blank; Can't hold it back anymore; Let it $blank, let it $blank; Turn away and slam the door; I don't care what they're going to say; Let the storm rage on; The cold never bothered me anyway; Let it $blank, let it $blank; Can't hold it back anymore; Let it $blank, let it $blank; Turn away and slam the door"],
"blank_backup": "go",
# "blank_phrasehandle": ["a", "an"],
},
}

View File

@ -0,0 +1,9 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["I like $blank!"],
"blank_backup": "$replyvariation",
"replyvariation": ["porn", "turtles", "trains"],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['mf', 'motherfuckers'],
"?default": {
"type": "fillintheblank",
"responses": ["Y'all motherfuckers need $blank!"],
"blank_backup": 'Surak',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$instigator thinks it's starting to get a little misty up in $blank"],
"blank_backup": 'this biznatch',
},
}

View File

@ -0,0 +1,6 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["What if I told you $blank"],
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Fine! I'll build my own $blank, with blackjack and hookers. In fact, forget the $blank and the blackjack. Ahh, screw the whole thing!"],
"blank_backup": "lunar lander",
},
}

View File

@ -0,0 +1,10 @@
{
"validcoms": ['never'],
"?default": {
"type": "fillintheblank",
"blank_phrasehandle": ["a", "an"],
"responses": ["they say there's never a $blank around when you need them"],
"blank_backup": "cop",
},
}

View File

@ -0,0 +1,9 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Really ?? We dont have a $blank yet??"],
"blank_backup": "new",
},
}

View File

@ -0,0 +1,14 @@
{
"?default": {
"type": "fillintheblank",
"blank_phrasehandle": ["for"],
"responses": ["Ain't nobody got time $blank!"],
"blank_backup": "dat",
},
"full": {
"type": "fillintheblank",
"blank_phrasehandle": ["for"],
"responses": ["Well I woke up to get me a cold pop and then I thought somebody was barbequing. I said oh lord Jesus it's a fire. Then I ran out, I didn't grab no shoes or nothin' Jesus, I ran for my life. And then the smoke got me, I got bronchitis ain't nobody got time $blank!"],
"blank_backup": "dat",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['old'],
"?default": {
"type": "fillintheblank",
"responses": ["Sorry dude, I'm way too fucking old right now for $blank!!"],
"blank_backup": 'that shit',
},
}

View File

@ -0,0 +1,9 @@
{
"?default": {
"type": "fillintheblank",
"blank_phrasehandle": ["a", "an"],
"responses": ["You get $blank! And You get $blank! Everyone gets $blank!"],
"blank_backup": "car",
},
}

View File

@ -0,0 +1,11 @@
{
"validcoms": ['pepperidgefarms', 'pf'],
"?default": {
"type": "fillintheblank",
"responses": ["Pepperidge Farms remembers $blank"],
"response_fail": [
"You're so old Pepperidge Farms doesn't even remember that.",
],
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["How can you have any $blank if you don't eat your meat!?!"],
"blank_backup": 'anything good',
},
}

View File

@ -0,0 +1,7 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["Piping to bash is dangerous, this pipe only accessible to $blank"],
"blank_backup": "Mario",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['props','prop'],
"?default": {
"type": "fillintheblank",
"responses": ["I'll give you props for doing that $blank!"],
"blank_required": False,
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["The reason I gathered you all here today is... $blank!"],
"blank_required": False,
},
}

View File

@ -0,0 +1,9 @@
{
"validcoms": ['rrr', 'reducereuserecycle'],
"?default": {
"type": "fillintheblank",
"responses": ["Reduce, Reuse, Recycle $blank"],
"blank_backup": 'everything',
},
}

View File

@ -0,0 +1,11 @@
{
"?default": {
"type": "fillintheblank",
"prefixtext": "<secret_bot_code> ",
"suffixtext": " </secret_bot_code>",
"responses": ["$blank"],
"translations": ["underscore"],
"blank_backup": 'whisper_whisper_whisper',
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['simply', 'lotr'],
"?default": {
"type": "fillintheblank",
"responses": ["One does not simply $blank"],
"blank_backup": 'walk into mordor',
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["NO $blank FOR YOU!"],
"blank_backup": 'soup',
"translations": ["upper"],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['steenkin', 'dontneed'],
"?default": {
"type": "fillintheblank",
"responses": ["$blank? weee dun neeeed no steenkin $blank!!"],
},
}

View File

@ -0,0 +1,10 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["$instigator struggles with $blank"],
"response_fail": [
"You don't know me! You don't know my struggles!",
],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['suckers', 'sucker'],
"?default": {
"type": "fillintheblank",
"responses": ["$blanks are for suckers!!!!"],
},
}

View File

@ -0,0 +1,8 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["sudo $blank"],
"blank_backup": 'Go make me a sandwich',
},
}

View File

@ -0,0 +1,10 @@
{
"?default": {
"type": "fillintheblank",
"responses": ["to be honest; $blank"],
"response_fail": [
"Lets be honest...",
],
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['tr', 'thatsracist'],
"?default": {
"type": "fillintheblank",
"responses": ["That's Racist against $blank!"],
"response_fail": "That's Racist!™",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['ts', 'thatssexist'],
"?default": {
"type": "fillintheblank",
"responses": ["That's sexist against $blank! (you misogynistic prick!)"],
"response_fail": "That's Sexist!™ (you misogynistic prick!)",
},
}

View File

@ -0,0 +1,8 @@
{
"validcoms": ['thc', 'doobie', 'pot'],
"?default": {
"type": "fillintheblank",
"responses": ["Sorry dude, I'm way too fucking high right now for $blank!!"],
"blank_backup": 'that shit',
},
}

Some files were not shown because too many files have changed in this diff Show More