def list_own_nicks_cb(bot, message, *args, **kwargs): ''' List all your nicks and their id's. Nicks can be added using addnick, removed using rmnick. ''' sender = determine_sender(message) bot.cursor.execute('SELECT id,primary_nick FROM users WHERE jid = ?', (sender,)) result = bot.cursor.fetchone() if result is None: return 'Wie ben jij' userid = result[0] username = result[1] bot.cursor.execute('SELECT id,name FROM nicks WHERE jid = ?', (sender,)) results = bot.cursor.fetchall() if results is not None: reply = 'Nicknames for {} ({}/{}):'.format(username, sender, userid) for row in results: reply = reply + '\n' + '{} (id {})'.format(row[1], row[0]) else: reply = 'No nicknames known for number {} (internal id {})'.format( sender, userid) return reply
def update_lastseen_cb(bot, message, *args, **kwargs): ''' Updates the user's last seen time in the database. ''' author = determine_sender(message) currenttime = (datetime.datetime.now() - datetime.datetime(1970, 1, 1)).total_seconds() LOGGER.debug('Updating %s\'s last seen.', author) bot.cursor.execute('UPDATE users SET lastactive = ?, message = ? WHERE jid = ?', (currenttime, message.getBody().decode('utf-8'), author)) bot.conn.commit()
def restart_cb(bot, message, *args, **kwargs): ''' Restart the bot. ''' LOGGER.info('Restart message received from %s, content "%s"', message.getFrom(), message.getBody()) if not isadmin(bot, message): LOGGER.warning('Unauthorized shutdown attempt from %s', determine_sender(message)) return 'Not authorized.' bot.stop(True)
def update_lastseen_cb(bot, message, *args, **kwargs): ''' Updates the user's last seen time in the database. ''' author = determine_sender(message) currenttime = (datetime.datetime.now() - datetime.datetime(1970, 1, 1)).total_seconds() LOGGER.debug('Updating %s\'s last seen.', author) bot.cursor.execute( 'UPDATE users SET lastactive = ?, message = ? WHERE jid = ?', (currenttime, message.getBody().decode('utf-8'), author)) bot.conn.commit()
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
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
def mention_handler_cb(bot, message, *args, **kwargs): ''' Scans message text for @mentions and notifies user if appropriate. ''' mentioned_sent = [] for nick in MENTION_REGEX.findall(message.getBody()): LOGGER.debug('Nick detected: %s', nick) # Who sent the message? senderjid = determine_sender(message) LOGGER.debug('Resolving sender %s', senderjid) try: sendername = jid_to_nick(bot, senderjid) LOGGER.debug('Sendernick %s', sendername) except KeyError: sendername = senderjid LOGGER.debug('Could not find jid %s', senderjid) # Who was mentioned? try: targetjid = nick_to_jid(bot, nick) LOGGER.debug('Targetjid %s', targetjid) except KeyError as ex: # Some nick that is unknown, pass LOGGER.debug('Could not resolve nick %s', nick) LOGGER.debug('Exception %s', ex) continue if targetjid not in mentioned_sent: # Check timeout t_info = get_jid_timeout(bot, targetjid) currenttime = (datetime.datetime.now() - datetime.datetime(1970, 1, 1)).total_seconds() if currenttime < (t_info[1] + t_info[0]) and message.participant: # Do not send DM if recipient has not timed out yet continue # Send mention notification: [author]: [body] entity = TextMessageProtocolEntity('{}: {}'.format( sendername, message.getBody()), to=targetjid) bot.toLower(entity) LOGGER.debug('Sent mention with content %s to %s', message.getBody(), targetjid) mentioned_sent.append(targetjid) else: LOGGER.debug('Detected duplicate nick %s, skipping.', targetjid)
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'
def mention_handler_cb(bot, message, *args, **kwargs): ''' Scans message text for @mentions and notifies user if appropriate. ''' mentioned_sent = [] for nick in MENTION_REGEX.findall(message.getBody()): LOGGER.debug('Nick detected: %s', nick) # Who sent the message? senderjid = determine_sender(message) LOGGER.debug('Resolving sender %s', senderjid) try: sendername = jid_to_nick(bot, senderjid) LOGGER.debug('Sendernick %s', sendername) except KeyError: sendername = senderjid LOGGER.debug('Could not find jid %s', senderjid) # Who was mentioned? try: targetjid = nick_to_jid(bot, nick) LOGGER.debug('Targetjid %s', targetjid) except KeyError as ex: # Some nick that is unknown, pass LOGGER.debug('Could not resolve nick %s', nick) LOGGER.debug('Exception %s', ex) continue if targetjid not in mentioned_sent: # Check timeout t_info = get_jid_timeout(bot, targetjid) currenttime = (datetime.datetime.now() - datetime.datetime( 1970, 1, 1)).total_seconds() if currenttime < (t_info[1] + t_info[0]) and message.participant: # Do not send DM if recipient has not timed out yet continue # Send mention notification: [author]: [body] entity = TextMessageProtocolEntity('{}: {}'.format( sendername, message.getBody()), to=targetjid) bot.toLower(entity) LOGGER.debug('Sent mention with content %s to %s', message.getBody(), targetjid) mentioned_sent.append(targetjid) else: LOGGER.debug('Detected duplicate nick %s, skipping.', targetjid)
def isadmin(bot, message): ''' Determine whether or not a user can execute admin commands. A user can be marked as admin by either the database, or the config file. Config file overrides database. ''' sender = determine_sender(message) try: if bot.config['Admins'][sender]: return True except KeyError: pass bot.cursor.execute('SELECT admin FROM users WHERE jid = ?', (sender, )) result = bot.cursor.fetchone() if result: if result[0] == 1: return True return False return False
def isadmin(bot, message): ''' Determine whether or not a user can execute admin commands. A user can be marked as admin by either the database, or the config file. Config file overrides database. ''' sender = determine_sender(message) try: if bot.config['Admins'][sender]: return True except KeyError: pass bot.cursor.execute('SELECT admin FROM users WHERE jid = ?', (sender,)) result = bot.cursor.fetchone() if result: if result[0] == 1: return True return False return False
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)
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 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)
def list_own_nicks_cb(bot, message, *args, **kwargs): ''' List all your nicks and their id's. Nicks can be added using addnick, removed using rmnick. ''' sender = determine_sender(message) bot.cursor.execute('SELECT id,primary_nick FROM users WHERE jid = ?', (sender, )) result = bot.cursor.fetchone() if result is None: return 'Wie ben jij' userid = result[0] username = result[1] bot.cursor.execute('SELECT id,name FROM nicks WHERE jid = ?', (sender, )) results = bot.cursor.fetchall() if results is not None: reply = 'Nicknames for {} ({}/{}):'.format(username, sender, userid) for row in results: reply = reply + '\n' + '{} (id {})'.format(row[1], row[0]) else: reply = 'No nicknames known for number {} (internal id {})'.format( sender, userid) return reply