Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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