def getStrength(house, status, requester): reply = '' if houseIsValid(house) and statusIsValid(status): # get total house strength (status-independent) house_strength = students.count({'house': house}) # get modal house strength (status-dependent) and build reply if status in ['present', 'absent']: status_strength = students.count({ 'house': house, 'status': status }) reply += 'Strength for \'%s\' in \'%s\': %d/%d' % ( status, house, status_strength, house_strength) else: reply += 'Total strength for \'%s\' house is %d' % (house, house_strength) else: # catch shitty parameters logger.info('%s: /strength query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house or status. See \'/help strength\'' logger.info('%s: Returning strength for \'%s\' house' % (whoIs(requester), house)) return reply
def add(house, name, requester): if houseIsValid(house): # check for duplicate name if students.find( {'name': name, 'house': house }).count() != 0: logger.warn('%s: /add failed due to duplicate entry' % (whoIs(requester))) return 'There is already someone with that name and house in the database. /add failed.' timestamp = str(datetime.datetime.now()) logger.info('%s: Adding \'%s\' from \'%s\'' % (whoIs(requester), name, house)) student = { 'name': name, 'type': 'freshman', 'color': house, 'house': [house, 'all'], 'status': 'present', 'statuslog': ['Initial Registration @ ' + makeTimestamp()], 'diet': 'NIL', 'medical': 'NIL', 'addedby': whoIs(requester) } students.insert_one(student) logger.info('%s: Added \'%s\' to \'%s\' house' % (whoIs(requester), name, house)) return 'Successfully added \'%s\' of \'%s\' house into database.' % (name, house) logger.info('%s: /add query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house name. See \'/help add\''
def find(house, pattern, verbose, requester): reply = '' if houseIsValid(house): # query for database cursor results = students.find( {'name': { '$regex': '.*' + pattern + '.*'}, 'house': house } ) # sort results results.sort( [ ('color', -1), ('name', 1) ] ) # what info to send back (determined by verbose flag) if verbose is True: details = ['name', 'house', 'status', 'diet', 'medical', 'addedby'] else: details = ['name', 'house', 'status'] # build the reply reply += 'Finding any names containing \'%s\' for \'%s\'\n\n' % (pattern, house) reply += enumerator(results, details) else: # catch shitty parameters logger.info('%s: /find query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house. See \'/help find\'' logger.info('%s: Returning find query for pattern \'%s\' for \'%s\'' % (whoIs(requester), pattern, house)) return reply
def find(house, pattern, verbose, requester): reply = '' if houseIsValid(house): # query for database cursor results = students.find({ 'name': { '$regex': '.*' + pattern + '.*' }, 'house': house }) # sort results results.sort([('color', -1), ('name', 1)]) # what info to send back (determined by verbose flag) if verbose is True: details = ['name', 'house', 'status', 'diet', 'medical', 'addedby'] else: details = ['name', 'house', 'status'] # build the reply reply += 'Finding any names containing \'%s\' for \'%s\'\n\n' % ( pattern, house) reply += enumerator(results, details) else: # catch shitty parameters logger.info('%s: /find query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house. See \'/help find\'' logger.info('%s: Returning find query for pattern \'%s\' for \'%s\'' % (whoIs(requester), pattern, house)) return reply
def add(house, name, requester): if houseIsValid(house): # check for duplicate name if students.find({'name': name, 'house': house}).count() != 0: logger.warn('%s: /add failed due to duplicate entry' % (whoIs(requester))) return 'There is already someone with that name and house in the database. /add failed.' timestamp = str(datetime.datetime.now()) logger.info('%s: Adding \'%s\' from \'%s\'' % (whoIs(requester), name, house)) student = { 'name': name, 'type': 'freshman', 'color': house, 'house': [house, 'all'], 'status': 'present', 'statuslog': ['Initial Registration @ ' + makeTimestamp()], 'diet': 'NIL', 'medical': 'NIL', 'addedby': whoIs(requester) } students.insert_one(student) logger.info('%s: Added \'%s\' to \'%s\' house' % (whoIs(requester), name, house)) return 'Successfully added \'%s\' of \'%s\' house into database.' % ( name, house) logger.info('%s: /add query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house name. See \'/help add\''
def find(cg, pattern, requester): reply = '' if cgIsValid(cg): # query for database cursor results = cgls.find({ 'name': { '$regex': '.*' + pattern + '.*' }, 'cg': cg }) # sort results results.sort([('name', 1)]) details = ['name', 'chatID'] # build the reply reply += 'Finding any names containing \'%s\' for \'%s\'\n\n' % ( pattern, cg) reply += enumerator(results, details) else: # catch shitty parameters logger.info('%s: /find query failed (invalid parameters)' % whoIs(requester)) return 'Invalid cg. See \'/help find\'' logger.info('%s: Returning find query for pattern \'%s\' for \'%s\'' % (whoIs(requester), pattern, cg)) return reply
def on_chat_message(self, message): content_type, chat_type, chat_id = telepot.glance(message) command = message['text'] logger.info('Received \'%s\' from %s' % (command, authorized.whoIs(chat_id))) # for '/start' if command == '/start': self.sendMessage( chat_id, 'Hi! I\'m AndreaBot. I help Andrea and other FOP comm members disseminate information. Your name is \'%s\'.' % authorized.whoIs(chat_id)) # /help [<command>] elif command == '/help': self.sendMessage(chat_id, helper.getNaiveHelp()) elif command.startswith('/help'): keyword = re.match('\s*/help\s+([a-z]+)\s*', command).group(1) self.sendMessage(chat_id, helper.getHelp(keyword)) # /who elif command == '/who': self.sendMessage(chat_id, authorized.enumerateListeners()) # /yell elif command.startswith('/yell'): yell(self, command, chat_id) # /whisper elif command.startswith('/whisper'): whisper(self, command, False, chat_id) # /log elif command == '/log': self.sendMessage(chat_id, getLog(5)) # /vlog <size> elif command.startswith('/vlog'): return_size = re.match('\s*/vlog\s+(\d+)', command).group(1) self.sendMessage(chat_id, getLog(int(return_size))) # /time elif command == '/time': self.sendMessage(chat_id, getTime()) elif command.startswith('/name'): name = re.match('\s*/name\s+(.+)', command).group(1) logger.info('/name: %s is \'%s\'' % (chat_id, name)) self.sendMessage(authorized.address_book.get('Darren'), '%s is %s' % (chat_id, name)) self.sendMessage(chat_id, 'Thanks! You will be added shortly.') # when nothing works else: self.sendMessage(chat_id, 'Invalid command. Try /help') return
def updater(house, name, field, content, requester): reply = 'Updating \'%s\' for \'%s\' in \'%s\' house.\n\n' % (field, name, house) if houseIsValid(house): # check if result was found if students.find_one({'name': name, 'house': house}) == None: # no results reply += 'Could not find \'%s\' from \'%s\' house.' % (name, house) else: # got results if fieldIsValid(field) and field != 'house': logger.info( '%s: Updating \'%s\' for \'%s\' in \'%s\' with: \'%s\'' % (whoIs(requester), field, name, house, content)) students.update_one({ 'name': name, 'house': house }, {'$set': { field: content }}) # perform update reply += 'Successfully updated \'%s\' field for \'%s\' in \'%s\' with: \'%s\'' % ( field, name, house, content) else: reply += 'Invalid field.' return reply
def updater(cg, name, field, content, requester): reply = 'Updating \'%s\' for \'%s\' in \'%s\' cg.\n\n' % (field, name, cg) if cgIsValid(cg): # check if result was found if cgls.find({'name': name, 'cg': cg}) == None: # no results reply += 'Could not find \'%s\' from \'%s\' cg.' % (name, cg) else: # got results if fieldIsValid(field) and field != 'cg': logger.info( '%s: Updating \'%s\' for \'%s\' in \'%s\' with: \'%s\'' % (whoIs(requester), field, name, cg, content)) cgls.update_one({ 'name': name, 'cg': cg }, {'$set': { field: content }}) # perform update reply += 'Successfully updated \'%s\' field for \'%s\' in \'%s\' with: \'%s\'' % ( field, name, cg, content) else: reply += 'Invalid field.' return reply
def updateAttendanceLog(house, name, isIn, requester): if houseIsValid(house): if isIn == True: entry = 'In @ %s' % makeTimestamp() else: entry = 'Out @ %s' % makeTimestamp() students.update_one( {'name': name, 'house': house}, { '$push': {'statuslog': entry} } ) logger.info('%s: Appended status log entry to \'%s\' from \'%s\'' % (whoIs(requester), name.title(), house.title()))
def getEnumerate(house, requester): if houseIsValid(house): # cover the all case and single house case if house == 'all': houses = ['black', 'blue', 'green', 'orange', 'purple', 'red'] else: houses = [house] reply = '' for target_house in houses: reply += '=====================\n' reply += target_house.upper() + '\n\n' for status in ['present', 'absent']: # query for database cursor results = students.find({ 'house': target_house, 'status': status }) # sort results results.sort([('color', 1), ('name', 1)]) reply += status.title() + '\n' # catch empty house/mode query if results.count() == 0: reply += 'No records found.\n' else: # build the reply message i = 1 for person in results: reply += '%d. %-15s' % (i, person['name'].title()) i += 1 if (i + 1) % 2 == 0: reply += '\n' reply += '\n' else: # catch invalid parameters logger.info('%s: /enum query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house or status. See \'/help enumerate\'' logger.info('%s: Returning enumeration for \'%s\' in \'%s\'' % (whoIs(requester), status, house)) return reply
def getEnumerate(cg, requester): if cgIsValid(cg): # cover the all case and single cg case if cg == 'all': cgs = authorized.cg_list else: cgs = [cg] reply = '' for target_cg in cgs: reply += '=====================\n' reply += target_cg.upper() + '\n\n' # query for database cursor results = cgls.find({'cg': target_cg}) # sort results results.sort([('name', 1)]) #reply += status.title() + '\n' # catch empty cg/mode query if results.count() == 0: reply += 'No records found.\n' else: # build the reply message i = 1 for person in results: reply += '%d. %-15s' % (i, person['name'].title()) i += 1 if (i + 1) % 2 == 0: reply += '\n' reply += '\n' else: # catch invalid parameters logger.info('%s: /enum query failed (invalid parameters)' % whoIs(requester)) return 'Invalid cg or status. See \'/help enumerate\'' #logger.info('%s: Returning enumeration for \'%s\' in \'%s\'' % (whoIs(requester), status, cg)) logger.info('%s: Returning enumeration for \'%s\'' % (whoIs(requester), cg)) return reply
def getStrength(house, status, requester): reply = '' if houseIsValid(house) and statusIsValid(status): # get total house strength (status-independent) house_strength = students.count( {'house': house} ) # get modal house strength (status-dependent) and build reply if status in ['present', 'absent']: status_strength = students.count( {'house': house, 'status': status} ) reply += 'Strength for \'%s\' in \'%s\': %d/%d' % (status, house, status_strength, house_strength) else: reply += 'Total strength for \'%s\' house is %d' % (house, house_strength) else: # catch shitty parameters logger.info('%s: /strength query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house or status. See \'/help strength\'' logger.info('%s: Returning strength for \'%s\' house' % (whoIs(requester), house)) return reply
def getEnumerate(house, requester): if houseIsValid(house): # cover the all case and single house case if house == 'all': houses = ['black', 'blue', 'green', 'orange', 'purple', 'red'] else: houses = [house] reply = '' for target_house in houses: reply += '=====================\n' reply += target_house.upper() + '\n\n' for status in ['present','absent']: # query for database cursor results = students.find( {'house': target_house, 'status': status} ) # sort results results.sort( [ ('color', 1), ('name', 1) ] ) reply += status.title() + '\n' # catch empty house/mode query if results.count() == 0: reply += 'No records found.\n' else: # build the reply message i = 1 for person in results: reply += '%d. %-15s' % (i, person['name'].title()) i += 1 if (i+1)%2 == 0: reply += '\n' reply += '\n' else: # catch invalid parameters logger.info('%s: /enum query failed (invalid parameters)' % whoIs(requester)) return 'Invalid house or status. See \'/help enumerate\'' logger.info('%s: Returning enumeration for \'%s\' in \'%s\'' % (whoIs(requester), status, house)) return reply
def remove(house, name, requester): reply = 'Removed \'%s\' of \'%s\' house from database.' % (name, house) # perform remove if students.find({'name': name, 'house': house}).count() == 0: return 'No such record found.' elif students.find({'name': name, 'house': house}).count() == 1: students.remove({'name': name, 'house': house}, 1) logger.info(whoIs(requester) + ': ' + reply) return reply return 'Multiple records with the same name and house found. Contact Darren for removal.'
def remove(house, name, requester): reply = 'Removed \'%s\' of \'%s\' house from database.' % (name, house) # perform remove if students.find( {'name': name, 'house': house }).count() == 0: return 'No such record found.' elif students.find( {'name': name, 'house': house }).count() == 1: students.remove( {'name': name, 'house': house}, 1 ) logger.info(whoIs(requester) + ': ' + reply) return reply return 'Multiple records with the same name and house found. Contact Darren for removal.'
def remove(cg, name, requester): reply = 'Removed \'%s\' of \'%s\' cg from database.' % (name, cg) name = name.title() cg = cg.lower() # perform remove if cgls.find({'name': name, 'cg': cg}).count() == 0: return 'No such record found.' elif cgls.find({'name': name, 'cg': cg}).count() >= 1: cgls.delete_one({'name': name, 'cg': cg}) logger.info(whoIs(requester) + ': ' + reply) return reply return 'Multiple records with the same name and cg found. Contact Justin for removal.'
def updateAttendanceLog(house, name, isIn, requester): if houseIsValid(house): if isIn == True: entry = 'In @ %s' % makeTimestamp() else: entry = 'Out @ %s' % makeTimestamp() students.update_one({ 'name': name, 'house': house }, {'$push': { 'statuslog': entry }}) logger.info('%s: Appended status log entry to \'%s\' from \'%s\'' % (whoIs(requester), name.title(), house.title()))
def whisper(bot, message, needAcknowledgement, requester_id): # deny unauthorized yeller if requester_id not in authorized.getMailingList() or requester_id < 0: logger.warn('Attempted unauthorized use of /whisper by %s' % authorized.whoIs(requester_id)) bot.sendMessage(requester_id, 'Sorry! You can\'t use this function. Contact Darren @ohdearren if this is a mistake.') return # deny empty whisper if re.match('^\s*/whisper\s*$', message) != None: logger.warn('%s: /whisper denied; no message or groups!' % authorized.whoIs(requester_id)) bot.sendMessage(requester_id, 'I need a message and group list to whisper! Whisper not carried out.') return matches = re.match('\s*/whisper\s+([a-zA-Z+]+)\s+(.+)', message) groups = matches.group(1).lower() broadcast = matches.group(2) group_list = groupArg2List(groups) timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%I:%M%p, %d %B %Y') if authorized.groupIsValid(group_list): broadcast = re.sub('^\s*/whisper\s*[a-zA-Z+]+', '', message) broadcast += '\n\nSent by %s via whisper to:\n' % (authorized.whoIs(requester_id)) broadcast += ', '.join(group_list) + '\n' bot.sendMessage(requester_id, 'Message is propagating now to: %s' % ', '.join(group_list)) # log in database announcement_log = { 'message': broadcast, 'to': '+'.join(group_list), 'by': authorized.whoIs(requester_id), 'timestamp': timestamp, } announcements.insert_one(announcement_log) logger.info('Added whisper by %s to database.' % authorized.whoIs(requester_id)) # propagate message for recipient in authorized.getGroups(group_list): bot.sendMessage(recipient, broadcast) logger.info('%s: Whisper propagated to %s (\'%s ...\')' % (authorized.whoIs(requester_id), authorized.whoIs(recipient), broadcast[:60])) # echo to sender bot.sendMessage(requester_id, 'MESSAGE ECHO\n\n' + broadcast) # inform darren bot.sendMessage(authorized.address_book.get('Darren'), 'Whisper sent by %s to group \'%s\'' % (authorized.whoIs(requester_id), groups)) else: # bad group parameters bot.sendMessage(requester_id, 'One of your groups is not valid. Check /who for the group names.') logger.warn('%s: /whisper denied; invalid group' % authorized.whoIs(requester_id)) return
def yell(bot, message, requester_id): # deny unauthorized yeller if requester_id not in authorized.getMailingList() or requester_id < 0: logger.warn('Attempted unauthorized use of /yell by %s' % authorized.whoIs(requester_id)) bot.sendMessage( requester_id, 'Sorry! You can\'t use this function. Contact Darren @ohdearren if this is a mistake.' ) return # deny empty yell if re.match('^\s*/yell\s*$', message) != None: logger.warn('%s: /yell denied; no message' % authorized.whoIs(requester_id)) bot.sendMessage(requester_id, 'I need a message to yell! Yell not carried out.') return # strip the command word broadcast = re.sub('^/yell\s+', '', message) # append byline broadcast += '\n\nSent by %s via yell\n' % (authorized.whoIs(requester_id)) # add the announcement to the database timestamp = datetime.datetime.fromtimestamp( time.time()).strftime('%I:%M%p, %d %B %Y') announcement_log = { 'message': broadcast, 'to': 'all', 'by': authorized.whoIs(requester_id), 'timestamp': timestamp, } announcements.insert_one(announcement_log) logger.info('Added yell by %s to database.' % authorized.whoIs(requester_id)) # talk to the requester bot.sendMessage(requester_id, 'Message is propagating now all listeners.') for recipient in authorized.getMailingList(): bot.sendMessage(recipient, broadcast) logger.info('%s: Yell propagated to %s (\'%s ...\')' % (authorized.whoIs(requester_id), authorized.whoIs(recipient), broadcast[:60])) return
def on_chat_message(self, message): content_type, chat_type, chat_id = telepot.glance(message) command = message['text'] logger.info('Received \'%s\' from %s' % (command, authorized.whoIs(chat_id))) # for '/start' if command == '/start': self.sendMessage(chat_id, 'Hi! I\'m AndreaBot. I help Andrea and other FOP comm members disseminate information. Your name is \'%s\'.' % authorized.whoIs(chat_id)) # /help [<command>] elif command == '/help': self.sendMessage(chat_id, helper.getNaiveHelp()) elif command.startswith('/help'): keyword = re.match('\s*/help\s+([a-z]+)\s*', command).group(1) self.sendMessage(chat_id, helper.getHelp(keyword)) # /who elif command == '/who': self.sendMessage(chat_id, authorized.enumerateListeners()) # /yell elif command.startswith('/yell'): yell(self, command, chat_id) # /whisper elif command.startswith('/whisper'): whisper(self, command, False, chat_id) # /log elif command == '/log': self.sendMessage(chat_id, getLog(5)) # /vlog <size> elif command.startswith('/vlog'): return_size = re.match('\s*/vlog\s+(\d+)', command).group(1) self.sendMessage(chat_id, getLog(int(return_size))) # /time elif command == '/time': self.sendMessage(chat_id, getTime()) elif command.startswith('/name'): name = re.match('\s*/name\s+(.+)', command).group(1) logger.info('/name: %s is \'%s\'' % (chat_id, name)) self.sendMessage(authorized.address_book.get('Darren'), '%s is %s' % (chat_id, name)) self.sendMessage(chat_id, 'Thanks! You will be added shortly.') # when nothing works else: self.sendMessage(chat_id, 'Invalid command. Try /help') return
def yell(bot, message, requester_id): # deny unauthorized yeller if requester_id not in authorized.getMailingList() or requester_id < 0: logger.warn('Attempted unauthorized use of /yell by %s' % authorized.whoIs(requester_id)) bot.sendMessage(requester_id, 'Sorry! You can\'t use this function. Contact Darren @ohdearren if this is a mistake.') return # deny empty yell if re.match('^\s*/yell\s*$', message) != None: logger.warn('%s: /yell denied; no message' % authorized.whoIs(requester_id)) bot.sendMessage(requester_id, 'I need a message to yell! Yell not carried out.') return # strip the command word broadcast = re.sub('^/yell\s+', '', message) # append byline broadcast += '\n\nSent by %s via yell\n' % (authorized.whoIs(requester_id)) # add the announcement to the database timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%I:%M%p, %d %B %Y') announcement_log = { 'message': broadcast, 'to': 'all', 'by': authorized.whoIs(requester_id), 'timestamp': timestamp, } announcements.insert_one(announcement_log) logger.info('Added yell by %s to database.' % authorized.whoIs(requester_id)) # talk to the requester bot.sendMessage(requester_id, 'Message is propagating now all listeners.') for recipient in authorized.getMailingList(): bot.sendMessage(recipient, broadcast) logger.info('%s: Yell propagated to %s (\'%s ...\')' % (authorized.whoIs(requester_id), authorized.whoIs(recipient), broadcast[:60])) return
def whisper(bot, message, needAcknowledgement, requester_id): # deny unauthorized yeller if requester_id not in authorized.getMailingList() or requester_id < 0: logger.warn('Attempted unauthorized use of /whisper by %s' % authorized.whoIs(requester_id)) bot.sendMessage( requester_id, 'Sorry! You can\'t use this function. Contact Darren @ohdearren if this is a mistake.' ) return # deny empty whisper if re.match('^\s*/whisper\s*$', message) != None: logger.warn('%s: /whisper denied; no message or groups!' % authorized.whoIs(requester_id)) bot.sendMessage( requester_id, 'I need a message and group list to whisper! Whisper not carried out.' ) return matches = re.match('\s*/whisper\s+([a-zA-Z+]+)\s+(.+)', message) groups = matches.group(1).lower() broadcast = matches.group(2) group_list = groupArg2List(groups) timestamp = datetime.datetime.fromtimestamp( time.time()).strftime('%I:%M%p, %d %B %Y') if authorized.groupIsValid(group_list): broadcast = re.sub('^\s*/whisper\s*[a-zA-Z+]+', '', message) broadcast += '\n\nSent by %s via whisper to:\n' % ( authorized.whoIs(requester_id)) broadcast += ', '.join(group_list) + '\n' bot.sendMessage( requester_id, 'Message is propagating now to: %s' % ', '.join(group_list)) # log in database announcement_log = { 'message': broadcast, 'to': '+'.join(group_list), 'by': authorized.whoIs(requester_id), 'timestamp': timestamp, } announcements.insert_one(announcement_log) logger.info('Added whisper by %s to database.' % authorized.whoIs(requester_id)) # propagate message for recipient in authorized.getGroups(group_list): bot.sendMessage(recipient, broadcast) logger.info('%s: Whisper propagated to %s (\'%s ...\')' % (authorized.whoIs(requester_id), authorized.whoIs(recipient), broadcast[:60])) # echo to sender bot.sendMessage(requester_id, 'MESSAGE ECHO\n\n' + broadcast) # inform darren bot.sendMessage( authorized.address_book.get('Darren'), 'Whisper sent by %s to group \'%s\'' % (authorized.whoIs(requester_id), groups)) else: # bad group parameters bot.sendMessage( requester_id, 'One of your groups is not valid. Check /who for the group names.') logger.warn('%s: /whisper denied; invalid group' % authorized.whoIs(requester_id)) return
def updater(house, name, field, content, requester): reply = 'Updating \'%s\' for \'%s\' in \'%s\' house.\n\n' % (field, name, house) if houseIsValid(house): # check if result was found if students.find_one( {'name': name, 'house':house} ) == None: # no results reply += 'Could not find \'%s\' from \'%s\' house.' % (name, house) else: # got results if fieldIsValid(field) and field != 'house': logger.info('%s: Updating \'%s\' for \'%s\' in \'%s\' with: \'%s\'' % (whoIs(requester), field, name, house, content)) students.update_one( {'name': name, 'house': house}, { '$set': { field: content } } ) # perform update reply += 'Successfully updated \'%s\' field for \'%s\' in \'%s\' with: \'%s\'' % (field, name, house, content) else: reply += 'Invalid field.' return reply
def removeById(chatID): logger.info('%s (%s) left.' % (whoIs(chatID), chatID)) return cgls.delete_one({'chatID': str(chatID)})