def process_messages(): """Processes the bot's messages looking for invites/commands.""" global r stop_time = int(cfg_file.get('reddit', 'last_message')) owner_username = cfg_file.get('reddit', 'owner_username') new_last_message = None update_srs = set() invite_srs = set() sleep_after = False logging.debug('Checking messages') try: for message in r.get_inbox(): if int(message.created_utc) <= stop_time: break if message.was_comment: continue if not new_last_message: new_last_message = int(message.created_utc) # if it's a subreddit invite if (not message.author and message.subject.startswith('invitation to moderate /r/')): invite_srs.add(message.subreddit.display_name.lower()) elif message.body.strip().lower() == 'update': # handle if they put in something like '/r/' in the subject if '/' in message.subject: sr_name = message.subject[message.subject.rindex('/')+1:] else: sr_name = message.subject if (sr_name.lower(), message.author.name) in update_srs: continue try: subreddit = r.get_subreddit(sr_name) if (message.author.name == owner_username or message.author in subreddit.get_moderators()): update_srs.add((sr_name.lower(), message.author.name)) else: send_error_message(message.author, sr_name, 'You do not moderate /r/{0}'.format(sr_name)) except HTTPError as e: send_error_message(message.author, sr_name, 'Unable to access /r/{0}'.format(sr_name)) elif (message.subject.strip().lower() == 'sleep' and message.author.name == owner_username): sleep_after = True # accept subreddit invites for subreddit in invite_srs: try: # workaround for praw clearing mod sub list on accept mod_subs = r.user._mod_subs r.user._mod_subs = mod_subs r.user._mod_subs[subreddit] = r.get_subreddit(subreddit) logging.info('Accepted mod invite in /r/{0}' .format(subreddit)) except praw.errors.InvalidInvite: pass # do requested updates from wiki pages updated_srs = [] for subreddit, sender in update_srs: if update_from_wiki(r.get_subreddit(subreddit), r.get_redditor(sender)): updated_srs.append(subreddit) logging.info('Updated from wiki in /r/{0}'.format(subreddit)) else: logging.info('Error updating from wiki in /r/{0}' .format(subreddit)) if sleep_after: logging.info('Sleeping for 10 seconds') sleep(10) logging.info('Sleep ended, resuming') except Exception as e: logging.error('ERROR: {0}'.format(e)) raise finally: # update cfg with new last_message value if new_last_message: cfg_file.set('reddit', 'last_message', str(new_last_message)) cfg_file.write(open(path_to_cfg, 'w')) return updated_srs
def process_messages(): """Processes the bot's messages looking for invites/commands.""" global r stop_time = int(cfg_file.get('reddit', 'last_message')) owner_username = cfg_file.get('reddit', 'owner_username') new_last_message = None update_srs = set() invite_srs = set() sleep_after = False logging.debug('Checking messages') try: for message in r.get_inbox(): if int(message.created_utc) <= stop_time: break if message.was_comment: continue if not new_last_message: new_last_message = int(message.created_utc) # if it's a subreddit invite if (not message.author and message.subject.startswith('invitation to moderate /r/')): invite_srs.add(message.subreddit.display_name.lower()) elif message.body.strip().lower() == 'update': # handle if they put in something like '/r/' in the subject if '/' in message.subject: sr_name = message.subject[message.subject.rindex('/') + 1:] else: sr_name = message.subject if (sr_name.lower(), message.author.name) in update_srs: continue try: subreddit = r.get_subreddit(sr_name) if (message.author.name == owner_username or message.author in subreddit.get_moderators()): update_srs.add((sr_name.lower(), message.author.name)) else: send_error_message( message.author, sr_name, 'You do not moderate /r/{0}'.format(sr_name)) except HTTPError as e: send_error_message( message.author, sr_name, 'Unable to access /r/{0}'.format(sr_name)) elif (message.subject.strip().lower() == 'sleep' and message.author.name == owner_username): sleep_after = True # accept subreddit invites for subreddit in invite_srs: try: # workaround for praw clearing mod sub list on accept mod_subs = r.user._mod_subs r.accept_moderator_invite(subreddit) r.user._mod_subs = mod_subs r.user._mod_subs[subreddit] = r.get_subreddit(subreddit) logging.info('Accepted mod invite in /r/{0}'.format(subreddit)) except praw.errors.InvalidInvite: pass # do requested updates from wiki pages updated_srs = [] for subreddit, sender in update_srs: if update_from_wiki(r.get_subreddit(subreddit), r.get_redditor(sender)): updated_srs.append(subreddit) logging.info('Updated from wiki in /r/{0}'.format(subreddit)) else: logging.info( 'Error updating from wiki in /r/{0}'.format(subreddit)) if sleep_after: logging.info('Sleeping for 10 seconds') sleep(10) logging.info('Sleep ended, resuming') except Exception as e: logging.error('ERROR: {0}'.format(e)) raise finally: # update cfg with new last_message value if new_last_message: cfg_file.set('reddit', 'last_message', str(new_last_message)) cfg_file.write(open(path_to_cfg, 'w')) return updated_srs
def process_messages(): """Processes the bot's messages looking for invites/commands.""" global r stop_time = int(cfg_file.get('reddit', 'last_message')) new_last_message = None changes_made = False logging.debug('Checking messages') try: for message in r.get_inbox(): if int(message.created_utc) <= stop_time: break if message.was_comment: continue if not new_last_message: new_last_message = int(message.created_utc) # if it's a subreddit invite if (not message.author and message.subject.startswith('invitation to moderate /r/')): try: subreddit = message.subreddit # workaround for praw clearing mod sub list on accept mod_subs = r.user._mod_subs # r.accept_moderator_invite(subreddit) r.user._mod_subs = mod_subs r.user._mod_subs[subreddit.display_name.lower()] = subreddit logging.info('Accepted mod invite in /r/{0}' .format(message.subreddit.display_name)) except praw.errors.InvalidInvite: pass elif message.body.strip().lower() == 'update': # handle if they put in something like '/r/' in the subject if '/' in message.subject: sr_name = message.subject[message.subject.rindex('/')+1:] else: sr_name = message.subject try: subreddit = r.get_subreddit(sr_name) if message.author in subreddit.get_moderators(): logging.info('Updating from wiki in /r/{0}' .format(sr_name)) update_from_wiki(subreddit, message.author) changes_made = True else: send_error_message(message.author, sr_name, 'You are not a moderator of that subreddit.') except HTTPError as e: if e.response.status_code == 404: send_error_message(message.author, sr_name, "The message's subject was not a valid subreddit") else: raise except Exception as e: logging.error('ERROR: {0}'.format(e)) raise finally: # update cfg with new last_message value if new_last_message: cfg_file.set('reddit', 'last_message', str(new_last_message)) cfg_file.write(open(path_to_cfg, 'w')) return changes_made
def process_messages(sr_dict, settings_dict): """Processes the bot's messages looking for invites/commands.""" global r stop_time = int(cfg_file.get('reddit', 'last_message')) owner_username = cfg_file.get('reddit', 'owner_username') new_last_message = None update_srs = set() invite_srs = set() sleep_after = False logging.debug('Checking messages') try: for message in r.get_inbox(): logging.debug("Reading message from {0}".format(message.author)) # use exceptions to send error message reply to user try: if int(message.created_utc) <= stop_time: logging.debug(" Message too old") break if message.was_comment: logging.debug(" Message was comment") continue # don't get stuck in conversation loops with other bots if message.author.name.lower() in ['reddit', 'ban_timer', 'mod_mailer', 'f7u12_hampton', 'botwatchman']: continue if not new_last_message: new_last_message = int(message.created_utc) # if it's a subreddit invite if (message.subreddit and message.subject.startswith('invitation to moderate /r/')): message.mark_as_read() raise UserspaceError("/u/ban_timer is currently in closed beta. Message the mods of /r/ban_timer for access.") try: subreddit = message.subreddit.display_name.lower() # workaround for praw clearing mod sub list on accept mod_subs = r.user._mod_subs r.accept_moderator_invite(subreddit) r.user._mod_subs = mod_subs r.user._mod_subs[subreddit] = r.get_subreddit(subreddit) logging.info('Accepted mod invite in /r/{0}' .format(subreddit)) except praw.errors.InvalidInvite: pass # if it's a control message elif '/' in message.subject: logging.debug(" Control Message") sr_name = message.subject[message.subject.rindex('/')+1:].lower() logging.debug(" /r/{0}".format(sr_name)) if sr_name in sr_dict: sr = sr_dict[sr_name] else: logging.debug(" unknown subreddit /r/{0}".format(sr_name)) message.mark_as_read() raise UserspaceError("/r/{0} is not registered with /u/ban_timer. " "Please invite /u/ban_timer to moderate /r/{0} " "with at least the `access` permission.".format(subreddit)) if (message.author in sr.get_moderators() or message.author.name == owner_username): pass else: logging.debug(" unauthorized user /u/{0}".format(message.author.name)) message.mark_as_read() raise UserspaceError("You do not moderate /r/{0}".format(sr_name)) if message.body.strip().lower() == 'update': if (message.author.name == owner_username or message.author in sr.get_moderators()): logging.debug(" update message") update_srs.add((sr_name.lower(), message.author.name)) else: logging.debug(" ban message") # add or remove a ban args = message.body.strip().split("\n") args = filter(lambda arg: arg.strip() != '', args) user = args[1] # for mod in permissions: # print mod.permissions if args[0].lower() == 'ban': duration = args[2].lower() if 2 < len(args) else None duration = duration if duration != 'forever' else None note = args[3] if 3 < len(args) else None logging.debug(" Banning /u/{0}".format(user)) ban = Ban(sr_name, user, message.author.name, duration, note) sr.add_ban(ban.user, note="<{0}> {1} | /u/ban_timer for /u/{2}".format(ban.duration, ban.note, ban.banned_by)) # sr.add_ban(ban.user) session.add(ban) message.mark_as_read() raise UserspaceReply("Successfully banned /u/{0} from /r/{1} for {2}.".format(user, sr_name, duration)) elif args[0].lower() == 'unban': logging.debug(" Unbanning /u/{0}".format(user)) ban = session.query(Ban).filter(Ban.user==user, Ban.subreddit==sr_name).one() sr.remove_ban(ban.user) session.delete(ban) message.mark_as_read() raise UserspaceReply("Successfully unbanned /u/{0} from /r/{1}".format(user, sr_name)) else: message.reply('Unrecognized command syntax. Please check the command syntax documentation.') elif (message.subject.strip().lower() == 'sleep' and message.author.name == owner_username): logging.debug(" Sleep Message") sleep_after = True message.mark_as_read() else: logging.debug(" Unknown Message") except UserspaceReply as e: message.reply("{0}".format(e)) except UserspaceError as e: message.reply("Error: {0}".format(e)) # do requested updates from wiki pages updated_srs = {} for subreddit, sender in update_srs: new_settings = update_from_wiki(r.get_subreddit(subreddit), r.get_redditor(sender)) if new_settings: updated_srs[subreddit] = new_settings logging.info('Updated from wiki in /r/{0}'.format(subreddit)) else: logging.info('Error updating from wiki in /r/{0}' .format(subreddit)) if sleep_after: logging.info('Sleeping for 10 seconds') sleep(10) logging.info('Sleep ended, resuming') except Exception as e: logging.error('ERROR: {0}'.format(e)) raise finally: # update cfg with new last_message value if new_last_message: cfg_file.set('reddit', 'last_message', str(new_last_message)) cfg_file.write(open(path_to_cfg, 'w')) # push bans to the database session.commit() return updated_srs