async def remember(ctx, *args): key = args[0].lower() print(f'Remembering {key}') tag = ctx.message.content.split('.remember ' + key + ' ')[1] if key[0] == '.': # in case someone types the dot for the tag key = tag[1:] serv = to_filename(str(ctx.message.guild)) if serv not in bot.cmds: # load the xml: bot.cmds[serv] = mm.MemBank(serv) # check if the new cmd isn't an existing command: if key in list(bot.commands.keys()): print('invalid, that command already exists!') return outcome = bot.cmds[serv].remember(key, tag) requester = get_name(ctx.message.author, to_filename(str(ctx.message.guild))) acknowledgements = [ "you got it, {}.", "sure thing, {}.", "ok, {}.", "will do, {}.", "I will, {}.", "whatever you want, {}.", "if you say so, {}." ] msg = (random.choice(acknowledgements).format(requester)) if outcome is not None: msg += '\n' + outcome # tell them what we forgot # await bot.say(msg) await ctx.send(msg)
async def loadmarkov(ctx, servername): serv = to_filename(servername) print('Loading corpus from %s' % serv) bot.markovchains[serv], bot.markovchains2[serv] = cm.server_chain(serv) print('Chain1: %s units long' % len(bot.markovchains[serv])) print('Chain2: %s units long' % len(bot.markovchains2[serv])) bot.corpus_last_read = time.time()
async def tag(ctx, user: str, *tag: str): """<name> <tag>: Tag someone as something.""" print('user: %s' % user) print('tag: %s' % str(tag)) # detect multi word usernames: if '|' in tag: user2, tag = (' '.join(tag)).split(' | ') print("user2: %s\ntag: %s" % (user2, tag)) user = user + ' ' + user2 else: tag = ' '.join(tag) # extract string from 1-tuple serv = to_filename(str(ctx.message.server)) print('server name: %s' % serv) tags = tm.TagBank(serv) ret = tags.addtag(user, tag) tags.to_xml() if ret is not None: # tagbank tells us there are no tags await bot.say(ret) else: await bot.say('Tag added.')
async def markov_in(ctx): serv = to_filename(str(ctx.message.guild)) if serv not in bot.markovchains or time.time() - bot.corpus_last_read > ( 60 * 60): print('Loading corpus from %s' % serv) bot.markovchains[serv], bot.markovchains2[serv] = cm.server_chain(serv) print('Chain1: %s units long' % len(bot.markovchains[serv])) print('Chain2: %s units long' % len(bot.markovchains2[serv])) bot.corpus_last_read = time.time() seed = ['*in'] print("trying to make a markov chain, but with 'in'") valid = False attempts = 0 while not valid and attempts < 30: msg = cm.generate_message2(bot.markovchains[serv], bot.markovchains2[serv], seed=seed) if 'voice*' in msg: valid = True else: attempts += 1 print('made a 2nd order markov chain with in:\n%s' % msg) if msg is not None: # await bot.say(msg) await ctx.send(msg)
async def markov(ctx, *seed: str): serv = to_filename(str(ctx.message.guild)) print('server name: %s' % serv) if len(ctx.message.mentions) > 0: print('mention detected') mention = ctx.message.mentions[0] name = get_name(ctx.message.mentions[0]) if len(seed) == 1: # we've been asked to make a markov from just a mention, so just convert it to string: seed = [name] # if we haven't loaded the chain for this server, or if we haven't loaded one in a while: if serv not in bot.markovchains or time.time() - bot.corpus_last_read > ( 60 * 60 * 8): # not loaded in last 8 hours print('Loading corpus from %s' % serv) bot.markovchains[serv], bot.markovchains2[serv] = cm.server_chain(serv) print('Chain1: %s units long' % len(bot.markovchains[serv])) print('Chain2: %s units long' % len(bot.markovchains2[serv])) bot.corpus_last_read = time.time() if seed == (): seed = ['END'] else: seed = [x.lower() for x in seed] # lowercase the seed print('trying to make a markov chain...') msg = cm.generate_message2(bot.markovchains[serv], bot.markovchains2[serv], seed=seed) if msg is not None: # await bot.say(msg) await ctx.send(msg)
async def is_tag(ctx, user: str, *tag_question: str): """<name> <tag>: Is this person something?.""" serv = to_filename(str(ctx.message.guild)) #user = '******'.join(user) print('user parsed as: %s' % user) if len(ctx.message.mentions) > 0: print('mention detected') mention = ctx.message.mentions[0] name = get_name(ctx.message.mentions[0]) print('name parsed as: %s' % name) else: name = user print('name parsed as: %s' % name) tag_question = ' '.join(tag_question) tags = tm.TagBank(serv) tagstring = tags.gettags(name) taglist = tagstring.split(', ') if tag_question in taglist: msg = 'yes' else: msg = 'no' await ctx.send(msg)
def server_chain(server, max_lines=300000 ): # create transitional probability matrix for server log filename = cdir + to_filename(server) + '_corpus.txt' with open(filename, encoding='latin-1') as f: corpus = f.read().lower() #remove uninteresting lines: lines = corpus.split('\n') # only load the most recent fragment of corpus if it's very large: if len(lines) > max_lines: lines = lines[-max_lines:] newlines = [] for x in lines: if x != '' and x[0] != '!' and x[0] != '.': newlines.append(x) corpus = ' END '.join(newlines) splitted = re.findall(r"[\S']+|[.,!?;]", corpus) server_chain = build_chain(splitted) server_chain2 = build_chain2(splitted) return server_chain, server_chain2
async def tags(ctx, *user: str): """<name>: Show someone's tags.""" serv = to_filename(str(ctx.message.server)) user = '******'.join(user) tags = tm.TagBank(serv) tagstring = tags.gettags(user) await bot.say("%s: %s" % (user, tagstring))
async def tagged(ctx, *tag: str): """<tag>: Show everyone who is tagged as this.""" serv = to_filename(str(ctx.message.server)) print(tag) tag = ' '.join(tag) tags = tm.TagBank(serv) userstring = tags.gettagged(tag) await bot.say("%s: %s" % (tag, userstring))
async def womble(ctx): serv = to_filename(str(ctx.message.guild)) if serv not in bot.cmds: bot.cmds[serv] = mm.MemBank(serv) #print(bot.cmds[serv].memories) memories = [x for x in bot.cmds[serv].memories.keys()] msg = ', '.join(memories) # await bot.say(msg) await ctx.send(msg)
async def forget(ctx, key): key = key.lower() print(f'Forgetting {key}') serv = to_filename(str(ctx.message.guild)) if serv not in bot.cmds: # load the xml: bot.cmds[serv] = mm.MemBank(serv) msg = bot.cmds[serv].forget(key) # await bot.say(msg) await ctx.send(msg)
def __init__(self, server): "Contains stored commands from users" self.server = server self.memories = {} if platform.system() == 'Windows': mdir = 'cmds\\' else: mdir = 'cmds/' self.filename = mdir + to_filename(self.server) + '.xml' if os.path.isfile(self.filename): print('Importing cmds xml...') self.from_xml(self.filename)
async def request(ctx, *words): requester = get_name(ctx.message.author, to_filename(str(ctx.message.guild))) real_name = get_name(ctx.message.author, None) filename = 'feature_requests.txt' msg = ctx.message.content with open(filename, 'a') as f: f.write("%s: %s\n" % (real_name, msg)) acknowledgements = [ "I'll keep that in mind, {}.", "good idea, {}.", "that's a terrible idea, {}.", "I'll think about it, {}.", "interesting thought, {}.", "I like the sound of that, {}.", "why would you want that, {}." ] await ctx.send(random.choice(acknowledgements).format(requester))
async def tags(ctx, *user: str): """<name>: Show someone's tags.""" serv = to_filename(str(ctx.message.guild)) user = '******'.join(user) print('user parsed as: %s' % user) if len(ctx.message.mentions) > 0: print('mention detected') mention = ctx.message.mentions[0] name = get_name(ctx.message.mentions[0]) print('name parsed as: %s' % name) else: name = user print('name parsed as: %s' % name) tags = tm.TagBank(serv) tagstring = tags.gettags(name) await ctx.send("%s: %s" % (name, tagstring))
async def tag(ctx, user: str, *tag: str): """<name> <tag>: Tag someone as something.""" print('user: %s' % user) print('tag: %s' % str(tag)) # detect multi word usernames: if '|' in tag: user2, tag = (' '.join(tag)).split(' | ') print("user2: %s\ntag: %s" % (user2, tag)) user = user + ' ' + user2 elif len(ctx.message.mentions) > 0: print('mention detected') mention = ctx.message.mentions[0] user = get_name(ctx.message.mentions[0]) tag = ' '.join(tag) # extract string from 1-tuple else: tag = ' '.join(tag) # extract string from 1-tuple serv = to_filename(str(ctx.message.guild)) print('server name: %s' % serv) tags = tm.TagBank(serv) # check for self taggers: if user.lower() == get_name(ctx.message.author, serv=None).lower(): msg = random.choice(bot.shames) tags = tm.TagBank(serv) ret = tags.addtag(user, 'self tagger') tags.to_xml() await ctx.send(msg) else: ret = tags.addtag(user, tag) tags.to_xml() if ret is not None: # tagbank tells us there are no tags await ctx.send(ret) else: tagstring = tags.gettags(user) await ctx.send("%s: %s" % (user, tagstring))
async def servmarkov(ctx, servername): serv = to_filename(servername) seed = ['END'] if serv not in bot.markovchains or time.time() - bot.corpus_last_read > ( 60 * 60): print('Loading corpus from %s' % serv) bot.markovchains[serv], bot.markovchains2[serv] = cm.server_chain(serv) print('Chain1: %s units long' % len(bot.markovchains[serv])) print('Chain2: %s units long' % len(bot.markovchains2[serv])) bot.corpus_last_read = time.time() else: print('Corpus is freshly loaded!') print('making a markov chain from server corpus: %s and seed: %s' % (serv, str(seed))) msg = cm.generate_message2(bot.markovchains[serv], bot.markovchains2[serv], seed=seed) print('made a 2nd order markov chain:\n%s' % msg) if msg is not None: await ctx.send(msg)
async def on_command_error(ctx, error): # this is a MASSIVE hack but it is how we allow users to set new commands dynamically if isinstance(error, commands.CommandNotFound): # recall from cmds: serv = to_filename(str(ctx.message.guild)) if serv not in bot.cmds: bot.cmds[serv] = mm.MemBank(serv) cmd = ctx.message.content[1:].lower() if cmd in bot.cmds[serv].memories: print('I remember this one:') print(bot.cmds[serv].recall(cmd)) recall = bot.cmds[serv].recall(cmd) # await ctx.send(recall) await ctx.message.channel.send(recall) # await bot.send_message(ctx.message.channel, f'{recall}') else: print('nobody has set that command!') else: print('===bot error:\n%s' % error)
async def q(ctx, arg1: str, *words: str): """add <name> <quote>: Adds a quote to someone. <name> [<idx>]: Retrieves a quote from someone, optionally indexed by quote number.""" serv = to_filename(str(ctx.message.server)) print('server name: %s' % serv) quotes = qm.QuoteBank(serv) if arg1 == 'add': # add a quote user = words[0] if '|' in words: # detect multi-word usernames user, restwords = (' '.join(words)).split(' | ') fullmsg = ctx.message.content # have to parse the full message to preserve newlines msg = fullmsg.split('| ')[1] # separate out the | else: fullmsg = ctx.message.content # have to parse the full message to preserve newlines msg = fullmsg.split(user + ' ')[1] # separate out the .q add quote = qparse(msg, user) print('Adding quote:\n%s::%s' % (user, quote)) quotes.add(user, quote) quotes.to_xml() await bot.say('Quote added.') else: # say a quote if arg1 == 'all': # grab a quote irrespective of user q = quotes.allquote() else: # grab a random quote from the named user user = arg1 if '|' in words: # detect multi line usernames user, words = (' '.join(words)).split(' | ') if len( words ) > 0: # we've been asked for an index, or a multi line username, or both if is_number(words[-1]): # there is an index idx = int(words[-1]) # retrieve index words = words[:-1] if len(words ) > 0: # are we dealing with a multi word username? user = "******" % (user, ' '.join(words) ) # complete the username #print("user: %s" % user) #print("words: %s" % words) q = quotes.get(user, idx) # multi word username with index else: # no index, just a multi word username on its own user = "******" % (user, ' '.join(words)) #print("user: %s" % user) #print("words: %s" % words) q = quotes.get(user) # multi word username without index else: # get a random quote q = quotes.get(user) await bot.say(q)
async def on_message(message): msg = None # we do not want the bot to reply to itself if message.author != bot.user: cmd = message.content.lower() serv = to_filename(str(message.guild)) if cmd.lower() == 'same' or cmd.lower() == 'same.': bot.sames += 1 else: bot.sames = 0 if bot.sames >= 2: time.sleep(1) bot.sames = 0 msg = 'same.' # respond to thanks, ignores the timer: elif 'ty bot' in cmd or 'thanks bot' in cmd or 'thanks nevermore' in cmd or 'ty nevermore' in cmd or 'thx bot' in cmd or 'thx nevermore' in cmd: requester = get_name(message.author, to_filename(str(message.guild))) responses = [ "you're welcome, {}", "ur welcome, {}", "no problem, {}", "any time, {}", "my pleasure, {}" ] msg = (random.choice(responses).format(requester)) # general banter with timer: elif time.time() - bot.last_reply > 2: # 60 sec cooldown # responds to praise or blame: if 'bad bot' in cmd: msg = ':(' elif 'good bot' in cmd: msg = ':)' # responds to greetings: elif cmd in [ 'hello bot', 'hi bot', 'hello nevermore', 'hi nevermore' ]: name = message.author.nick if name is None: name = get_name(message.author, serv) greeting = random.choice(['hi', 'hello']) msg = '%s %s' % (greeting, name) # make the 'very carefully' joke: elif 'how do' in cmd and 'feel' not in cmd and len( cmd ) < 100: # we want "how do", but not "how do i/you feel" chance = 0.15 roll = random.uniform(0, 1) if roll < chance: time.sleep(3) # for comedic effect msg = 'very carefully.' # make fun of your wife: elif 'my wife' in cmd: msg = 'My Wife' # make the 'much like your posting' joke: elif 'so bad' in cmd or 'very bad' in cmd or 'really bad' in cmd or 'insanely bad' in cmd or 'incredibly bad' in cmd or 'unbelievably bad' in cmd: print('I smell something bad.') print('the server is: %s' % serv) if serv == 'very_official_discord_server' or serv == 'bot_testing_server': # this is a dom goons injoke print("so I'm considering making the joke") if 'very bad' in cmd or 'so bad' in cmd or 'really bad' in cmd: chance = 0.25 else: chance = 0.5 roll = random.uniform(0, 1) print('The roll is: %s' % roll) if roll < chance: time.sleep(5) # for comedic effect msg = 'much like your posting' # correct anime spelling: elif 'anime' in cmd: chance = 0.35 roll = random.uniform(0, 1) if roll < chance: msg = "I think you mean animé." # detect mentions (but does not currently do anything): elif len(message.mentions) > 0: print('mention detected') mention = message.mentions[0] name = get_name(message.mentions[0]) if name == 'nevermore': # someone is addressing us directly! print("someone's talking about me") # do something here else: # respond to 69: pattern = r"\b6 ?9\b" r = re.compile(pattern) if r.search(cmd) or 'sixty nine' in cmd: print(cmd + '?\nnice') chance = 0.25 roll = random.uniform(0, 1) if roll < chance: time.sleep(5) # for comedic effect msg = 'nice.' else: # a random chance to spit out a markov chain chance = MARKOV_PROC roll = random.uniform(0, 1) print('Random markov roll: %.2f' % roll) if roll < chance and cmd[ 0] != '.': # don't do this for bot commands # if we haven't loaded the chain for this server, or if we haven't loaded one in a while: if serv not in bot.markovchains or time.time( ) - bot.corpus_last_read > (60 * 60): print('Loading corpus from %s' % serv) bot.markovchains[serv], bot.markovchains2[ serv] = cm.server_chain(serv) print('The result chain is %s units long' % len(bot.markovchains[serv])) bot.corpus_last_read = time.time() msg = cm.generate_message2(bot.markovchains[serv], bot.markovchains2[serv], seed=['END']) if msg is not None: bot.last_reply = time.time() # await bot.send_message(message.channel, msg) await message.channel.send(msg) # record raw messages to corpus: cm.write(cmd, serv) await bot.process_commands(message)
def write(msg, server): filename = cdir + to_filename(server) + '_corpus.txt' with open(filename, 'a') as f: f.write(msg + '\n')
async def q(ctx, arg1: str = 'all', *words: str): """add <name> <quote>: Adds a quote to someone. <name> [<idx>]: Retrieves a quote from someone, optionally indexed by quote number.""" serv = to_filename(str(ctx.message.guild)) print('server name: %s' % serv) quotes = qm.QuoteBank(serv) if arg1 == 'add': # add a quote user = words[0] if '|' in words: # detect multi-word usernames user, restwords = (' '.join(words)).split(' | ') fullmsg = ctx.message.content # have to parse the full message to preserve newlines msg = fullmsg.split('| ')[1] # separate out the | elif len(ctx.message.mentions) > 0: print('mention detected') mention = ctx.message.mentions[0] user = get_name(ctx.message.mentions[0]) fullmsg = ctx.message.content print('fullmsg: %s' % fullmsg) id = "<@%s>" % ctx.message.mentions[0].id msg = fullmsg.split('.q add ' + id + ' ')[1] print('msg: %s' % msg) else: fullmsg = ctx.message.content # have to parse the full message to preserve newlines msg = fullmsg.split('.q add ' + user + ' ')[1] # separate out the .q add quote = qparse(msg, user) print('Adding quote:\n%s::%s' % (user, quote)) # check for self quoting: if user.lower() == get_name(ctx.message.author, serv=None).lower(): msg = random.choice(bot.shames) tags = tm.TagBank(serv) ret = tags.addtag(user, 'self quoter') tags.to_xml() # await bot.say(msg) await ctx.send(msg) else: quotes.add(user, quote) #quotes.to_xml() await ctx.send('Quote added.') else: # say a quote if arg1 == 'all': # grab a quote irrespective of user q = quotes.allquote() elif is_number(arg1): # get an allquote with index q = quotes.allquote(int(arg1)) else: # grab a random quote from the named user user = arg1 if '|' in words: # detect multi line usernames user, words = (' '.join(words)).split(' | ') elif len(ctx.message.mentions) > 0: # detect mentions print('mention detected') mention = ctx.message.mentions[0] user = get_name(ctx.message.mentions[0] ) # keep words the same; the mention is arg1 if len( words ) > 0: # we've been asked for an index, or a multi line username, or both if is_number(words[-1]): # there is an index idx = int(words[-1]) # retrieve index words = words[:-1] if len(words ) > 0: # are we dealing with a multi word username? user = "******" % (user, ' '.join(words) ) # complete the username q = quotes.get(user, idx) # multi word username with index else: # no index, just a multi word username on its own user = "******" % (user, ' '.join(words)) q = quotes.get(user) # multi word username without index else: # get a random quote q = quotes.get(user) await ctx.send(q)