コード例 #1
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #2
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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()
コード例 #3
0
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.')
コード例 #4
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #5
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #6
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #7
0
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
コード例 #8
0
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))
コード例 #9
0
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))
コード例 #10
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #11
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #12
0
    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)
コード例 #13
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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))
コード例 #14
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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))
コード例 #15
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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))
コード例 #16
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #17
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #18
0
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)
コード例 #19
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)
コード例 #20
0
def write(msg, server):
    filename = cdir + to_filename(server) + '_corpus.txt'
    with open(filename, 'a') as f:
        f.write(msg + '\n')
コード例 #21
0
ファイル: quotebot.py プロジェクト: andreybarsky/nevermore
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)