Пример #1
0
def set_other_timeout_cb(bot, message, *args, **kwargs):
    '''
    Update the timeout of any user.

    Specify user by id or nick.
    '''
    if not isadmin(bot, message):
        return
    try:
        cmd = extract_query(message)
        cmdl = cmd.split()

        is_id = operator.methodcaller('isdigit')
        if is_id(cmdl[0]):
            id_ = int(cmdl[0])
        else:
            try:
                id_ = nick_to_id(bot, cmdl[0])
            except KeyError:
                return 'Unknown nick.'
        timeout = int(cmdl[1])
        bot.cursor.execute('UPDATE users SET timeout = ? WHERE id = ?',
                           (timeout, id_))
        bot.conn.commit()
        return 'Timeout for user {} updated to {}'.format(id_, timeout)
    except ValueError:
        return 'IT BROKE'
Пример #2
0
def wolfram_cb(bot, message, *args, **kwargs):
    '''
    (Attempt to) answer query using the WolframAlpha API.

    Results may not be interpreted as you'd expect, open link for explanation.
    '''
    if not CLIENT:
        return _('Not connected to WolframAlpha!')
    query = extract_query(message)
    LOGGER.debug('Query to WolframAlpha: %s', query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_TYPING, message.getFrom())
    bot.toLower(entity)
    result = CLIENT.query(query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_PAUSED, message.getFrom())
    bot.toLower(entity)
    restext = _('Result from WolframAlpha:\n')
    results = [
        p.text.encode('utf-8') for p in result.pods
        if p.title in ('Result', 'Value', 'Decimal approximation',
                       'Exact result')
    ]
    if not results:
        return _('No result.')
    restext += '\n'.join(results) + '\n'
    restext += 'Link: https://wolframalpha.com/input/?i={}'.format(
        urllib.quote(query).replace('%20', '+'))
    return restext
Пример #3
0
def list_other_nicks_cb(bot, message, *args, **kwargs):
    '''
    List all nicks of another user.

    Specify user by id or nick.
    '''
    cmd = extract_query(message)

    if IS_ID(cmd):
        bot.cursor.execute(
            'SELECT id,jid,lastactive,primary_nick FROM users WHERE id = ?',
            (cmd,))
    else:
        try:
            userjid = nick_to_jid(bot, cmd)
            bot.cursor.execute(
                'SELECT id,jid,lastactive,primary_nick FROM users WHERE jid = ?',
                (userjid,))
        except KeyError:
            return 'Unknown (nick)name'
    result = bot.cursor.fetchone()
    if not result:
        return 'Unknown ID' # nick resolution errors earlier
    reply = 'Nicks for {} ({}/{}):\n'.format(result[3], result[1], result[0])
    bot.cursor.execute('SELECT name FROM nicks WHERE jid = ?',
                       (result[1],))
    results = bot.cursor.fetchall()
    for row in results:
        reply = reply + row[0] + ' '
    return reply
Пример #4
0
def set_other_timeout_cb(bot, message, *args, **kwargs):
    '''
    Update the timeout of any user.

    Specify user by id or nick.
    '''
    if not isadmin(bot, message):
        return
    try:
        cmd = extract_query(message)
        cmdl = cmd.split()

        is_id = operator.methodcaller('isdigit')
        if is_id(cmdl[0]):
            id_ = int(cmdl[0])
        else:
            try:
                id_ = nick_to_id(bot, cmdl[0])
            except KeyError:
                return 'Unknown nick.'
        timeout = int(cmdl[1])
        bot.cursor.execute('UPDATE users SET timeout = ? WHERE id = ?',
                           (timeout, id_))
        bot.conn.commit()
        return 'Timeout for user {} updated to {}'.format(id_, timeout)
    except ValueError:
        return 'IT BROKE'
Пример #5
0
def list_other_nicks_cb(bot, message, *args, **kwargs):
    '''
    List all nicks of another user.

    Specify user by id or nick.
    '''
    cmd = extract_query(message)

    if IS_ID(cmd):
        bot.cursor.execute(
            'SELECT id,jid,lastactive,primary_nick FROM users WHERE id = ?',
            (cmd, ))
    else:
        try:
            userjid = nick_to_jid(bot, cmd)
            bot.cursor.execute(
                'SELECT id,jid,lastactive,primary_nick FROM users WHERE jid = ?',
                (userjid, ))
        except KeyError:
            return 'Unknown (nick)name'
    result = bot.cursor.fetchone()
    if not result:
        return 'Unknown ID'  # nick resolution errors earlier
    reply = 'Nicks for {} ({}/{}):\n'.format(result[3], result[1], result[0])
    bot.cursor.execute('SELECT name FROM nicks WHERE jid = ?', (result[1], ))
    results = bot.cursor.fetchall()
    for row in results:
        reply = reply + row[0] + ' '
    return reply
def wolfram_cb(bot, message, *args, **kwargs):
    '''
    (Attempt to) answer query using the WolframAlpha API.

    Results may not be interpreted as you'd expect, open link for explanation.
    '''
    if not CLIENT:
        return _('Not connected to WolframAlpha!')
    query = extract_query(message)
    LOGGER.debug('Query to WolframAlpha: %s', query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_TYPING, message.getFrom())
    bot.toLower(entity)
    result = CLIENT.query(query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_PAUSED, message.getFrom())
    bot.toLower(entity)
    restext = _('Result from WolframAlpha:\n')
    results = [p.text.encode('utf-8') for p in result.pods
               if p.title in ('Result', 'Value', 'Decimal approximation', 'Exact result')]
    if not results:
        return _('No result.')
    restext += '\n'.join(results) + '\n'
    restext += 'Link: https://wolframalpha.com/input/?i={}'.format(
        urllib.quote(query).replace('%20', '+'))
    return restext
Пример #7
0
def duckduckgo_cb(bot, message, *args, **kwargs):
    '''
    Answer query using DuckDuckGo.
    '''
    try:
        query = extract_query(message)
        return duckduckgo.get_zci(query)
    except ValueError:
        return 'Sorry, no results.'
    except AttributeError:
        return 'Sorry, no results.'
Пример #8
0
def help_cb(bot, message, *args, **kwargs):
    '''
    Give moral and spiritual guidance in using this bot.

    When you select one command, a longer text will be sent!
    '''
    cmd = extract_query(message)
    if not cmd:
        return HELP_OVERVIEW
    else:
        try:
            return pydoc.getdoc(COMMAND_DICT[cmd.upper()])
        except KeyError:
            return 'Sorry, that command is not known.'
Пример #9
0
def help_cb(bot, message, *args, **kwargs):
    '''
    Give moral and spiritual guidance in using this bot.

    When you select one command, a longer text will be sent!
    '''
    cmd = extract_query(message)
    if not cmd:
        return HELP_OVERVIEW
    else:
        try:
            return pydoc.getdoc(COMMAND_DICT[cmd.upper()])
        except KeyError:
            return 'Sorry, that command is not known.'
Пример #10
0
def set_own_timeout_cb(bot, message, *args, **kwargs):
    '''
    Update your mention timeout.

    Your timeout is the amount of time (in seconds) that has to elapse before you receive @mentions.
    A value of 0 means you receive all mentions.
    '''
    try:
        cmd = extract_query(message)
        timeout = int(cmd)
        bot.cursor.execute('UPDATE users SET timeout = ? WHERE jid = ?',
                           (timeout, determine_sender(message)))
        bot.conn.commit()
        return 'Ok'
    except ValueError:
        LOGGER.error('Timeout set failure: %s', cmd)
        return 'IT BROKE'
Пример #11
0
def set_own_timeout_cb(bot, message, *args, **kwargs):
    '''
    Update your mention timeout.

    Your timeout is the amount of time (in seconds) that has to elapse before you receive @mentions.
    A value of 0 means you receive all mentions.
    '''
    try:
        cmd = extract_query(message)
        timeout = int(cmd)
        bot.cursor.execute('UPDATE users SET timeout = ? WHERE jid = ?',
                           (timeout, determine_sender(message)))
        bot.conn.commit()
        return 'Ok'
    except ValueError:
        LOGGER.error('Timeout set failure: %s', cmd)
        return 'IT BROKE'
Пример #12
0
def diceroll_cb(bot, message, *args, **kwargs):
    '''
    Roll some dice!

    Usage: include a 'XdY' pattern somewhere in your message, optionally followed by a modifier.
    Examples:
     - roll 1d6 -> rolls one six-sided die
     - roll 2d10 + 5 -> rolls two ten-sided dice, adds up the result, and adds 5

    Supported operators are: +, -, /, *, % (modulo), ^ (power).
    '''
    query = extract_query(message)
    match = DICE_PATTERN.search(query)
    if match is None:
        return

    number = int(match.group('number'))
    sides = int(match.group('sides'))
    if sides < 0 or number < 0:
        return      # Maar hoe dan
    if number > 50 and message.participant:
        return      # Probably spam

    results = []
    for _ in xrange(number):
        results.append(random.randint(1, sides))
    result = ''
    for item in results:
        result = result + str(item)
        result = result + ' + '
    result = result.rstrip(' + ')
    som = sum(results)
    if len(results) > 1:
        result = result + ' = ' + str(som)
    if match.group(3) != None:
        try:
            modresult = DICE_MODIFIER_OPERATORS[match.group('operator')](
                som, int(match.group('modifier')))
            result = '{orig}, {som} {operator} {modifier} = {modresult}'.format(
                orig=result, som=som, operator=match.group('operator'),
                modifier=match.group('modifier'), modresult=modresult)
        except KeyError:
            pass  # unrecognized operator, skip modifier
    return result
Пример #13
0
def addreminder_cb(bot, message, *args, **kwargs):
    ''' (Hopefully) sends user a message at the given time '''
    body = extract_query(message)
    timespec = body.split()[0]
    try:
        trytime = dateutil.parser.parse(body,
                                        parserinfo=datefinder.BPI,
                                        fuzzy=True)
    except ValueError:
        trytime = datetime.datetime(
            1970, 1, 1)  # job is dropped if no other date is found
    delta = None
    if timespec in datefinder.DURATION_MARKERS or datefinder.STRICT_CLOCK_REGEX.match(
            timespec):
        try:
            delta = datetime.datetime.now() + datefinder.find_timedelta(body)
        except ValueError:
            delta = None
    elif timespec in datefinder.CLOCK_MARKERS:
        try:
            trytime = datefinder.find_first_time(body)
        except ValueError:
            LOGGER.error('Cannot find time in "%s"', body)
    if delta:
        deadline = delta
    else:
        deadline = trytime
    if deadline < datetime.datetime.now():
        LOGGER.error('Parsing %s failed, invalid deadline')
        return 'Sorry, limitations prevent parsing that kind of time.'
    LOGGER.debug('Parsed reminder command "%s"', body)
    LOGGER.info('Deadline %s from message "%s".', deadline, body)
    reply = 'Reminder set for {}.'.format(deadline)
    replymessage = TextMessageProtocolEntity(to=determine_sender(message),
                                             body=reply)
    bot.toLower(replymessage)
    bot.scheduler.add_job(rpc.remote_send,
                          'date', [body, determine_sender(message)],
                          run_date=deadline)
    return
Пример #14
0
def remove_own_nick_cb(bot, message, *args, **kwargs):
    '''
    Remove one of your nicks.

    Specify a nick by id (see mynicks) or the nick itself.
    '''
    cmd = extract_query(message)
    if IS_ID(cmd):
        bot.cursor.execute('SELECT id,name,jid FROM nicks WHERE id = ?',
                           (cmd, ))
    else:
        bot.cursor.execute('SELECT id,name,jid FROM nicks WHERE name = ?',
                           (cmd, ))
    result = bot.cursor.fetchone()
    if result is None:
        return 'Unknown nick'
    if result[2] != determine_sender(message):
        return 'That\'s not you'
    bot.cursor.execute('DELETE FROM nicks WHERE id = ?', (result[0], ))
    bot.conn.commit()
    LOGGER.info('Nick %s removed.', cmd)
    return 'Nick {} removed.'.format(cmd)
Пример #15
0
def add_own_nick_cb(bot, message, *args, **kwargs):
    '''
    Add a new nick to yourself.

    Nicknames can be removed using 'rmnick'.
    '''
    cmd = extract_query(message)
    cmdl = cmd.split()
    sender = determine_sender(message)
    newnick = cmdl[0].lower()
    if len(newnick) > 16:
        return 'Too long'
    if IS_ID(newnick):
        return 'Pls'
    try:
        LOGGER.info('Nick %s added to jid %s', newnick, sender)
        bot.cursor.execute('INSERT INTO nicks (name, jid) VALUES (?,?)',
                           (newnick, sender))
        bot.conn.commit()
        return 'Ok.'
    except sqlite3.IntegrityError:
        return 'Nick exists'
def anonsend_cb(bot, message, *args, **kwargs):
    ''' Send a mention under the group name and not the author's name '''
    if not message.participant:
        return

    try:
        groupname = jid_to_nick(bot, message.getFrom())
    except KeyError:
        return 'This group is not enrolled in the BrotherBother program, sorry'

    text = extract_query(message, 2)
    body = '{}: {}'.format(groupname, text)

    # Who was mentioned?
    nick = message.getBody().split()[2]
    try:
        recipient = nick_to_jid(bot, nick)
    except KeyError:
        return 'Unknown recipient!'

    entity = TextMessageProtocolEntity(body, to=recipient)
    bot.toLower(entity)
Пример #17
0
def add_own_nick_cb(bot, message, *args, **kwargs):
    '''
    Add a new nick to yourself.

    Nicknames can be removed using 'rmnick'.
    '''
    cmd = extract_query(message)
    cmdl = cmd.split()
    sender = determine_sender(message)
    newnick = cmdl[0].lower()
    if len(newnick) > 16:
        return 'Too long'
    if IS_ID(newnick):
        return 'Pls'
    try:
        LOGGER.info('Nick %s added to jid %s', newnick, sender)
        bot.cursor.execute('INSERT INTO nicks (name, jid) VALUES (?,?)',
                           (newnick, sender))
        bot.conn.commit()
        return 'Ok.'
    except sqlite3.IntegrityError:
        return 'Nick exists'
Пример #18
0
def addreminder_cb(bot, message, *args, **kwargs):
    ''' (Hopefully) sends user a message at the given time '''
    body = extract_query(message)
    timespec = body.split()[0]
    try:
        trytime = dateutil.parser.parse(body, parserinfo=datefinder.BPI, fuzzy=True)
    except ValueError:
        trytime = datetime.datetime(1970, 1, 1) # job is dropped if no other date is found
    delta = None
    if timespec in datefinder.DURATION_MARKERS or datefinder.STRICT_CLOCK_REGEX.match(timespec):
        try:
            delta = datetime.datetime.now() + datefinder.find_timedelta(body)
        except ValueError:
            delta = None
    elif timespec in datefinder.CLOCK_MARKERS:
        try:
            trytime = datefinder.find_first_time(body)
        except ValueError:
            LOGGER.error('Cannot find time in "%s"', body)
    if delta:
        deadline = delta
    else:
        deadline = trytime
    if deadline < datetime.datetime.now():
        LOGGER.error('Parsing %s failed, invalid deadline')
        return 'Sorry, limitations prevent parsing that kind of time.'
    LOGGER.debug('Parsed reminder command "%s"', body)
    LOGGER.info('Deadline %s from message "%s".',
                deadline, body)
    reply = 'Reminder set for {}.'.format(deadline)
    replymessage = TextMessageProtocolEntity(
        to=determine_sender(message), body=reply)
    bot.toLower(replymessage)
    bot.scheduler.add_job(
        rpc.remote_send, 'date',
        [body, determine_sender(message)],
        run_date=deadline)
    return
Пример #19
0
def register_user_cb(bot, message, *args, **kwargs):
    ''' Assign a primary nick to a user. '''
    if not isadmin(bot, message):
        return
    cmd = extract_query(message)
    try:
        cmdl = cmd.split()
        id_ = int(cmdl[0])
        name = cmdl[1]
        bot.cursor.execute('UPDATE users SET primary_nick = ? WHERE id = ?',
                           (name, id_))
        bot.conn.commit()
        LOGGER.info(bot.cursor.rowcount)
        LOGGER.info('User %s registered as %s.', id_, name)
        return 'Ok'
    except IndexError as ex:
        LOGGER.warning('Invalid message')
        LOGGER.warning(ex)
        return 'Malformed command'
    except sqlite3.IntegrityError as ex:
        LOGGER.error('Error during register')
        LOGGER.error(ex)
        return 'Error'
Пример #20
0
def remove_own_nick_cb(bot, message, *args, **kwargs):
    '''
    Remove one of your nicks.

    Specify a nick by id (see mynicks) or the nick itself.
    '''
    cmd = extract_query(message)
    if IS_ID(cmd):
        bot.cursor.execute('SELECT id,name,jid FROM nicks WHERE id = ?',
                           (cmd,))
    else:
        bot.cursor.execute('SELECT id,name,jid FROM nicks WHERE name = ?',
                           (cmd,))
    result = bot.cursor.fetchone()
    if result is None:
        return 'Unknown nick'
    if result[2] != determine_sender(message):
        return 'That\'s not you'
    bot.cursor.execute('DELETE FROM nicks WHERE id = ?',
                       (result[0],))
    bot.conn.commit()
    LOGGER.info('Nick %s removed.', cmd)
    return 'Nick {} removed.'.format(cmd)
Пример #21
0
def register_user_cb(bot, message, *args, **kwargs):
    ''' Assign a primary nick to a user. '''
    if not isadmin(bot, message):
        return
    cmd = extract_query(message)
    try:
        cmdl = cmd.split()
        id_ = int(cmdl[0])
        name = cmdl[1]
        bot.cursor.execute('UPDATE users SET primary_nick = ? WHERE id = ?',
                           (name, id_))
        bot.conn.commit()
        LOGGER.info(bot.cursor.rowcount)
        LOGGER.info('User %s registered as %s.', id_, name)
        return 'Ok'
    except IndexError as ex:
        LOGGER.warning('Invalid message')
        LOGGER.warning(ex)
        return 'Malformed command'
    except sqlite3.IntegrityError as ex:
        LOGGER.error('Error during register')
        LOGGER.error(ex)
        return 'Error'