Ejemplo n.º 1
0
    def test_lazy_loaded_attributes(self, mock_loader, mock_valid_directory):
        config = Config()

        assert hasattr(config.templates, 'content'), 'Config.templates must ' \
            'be of type Templates'
        assert hasattr(config.filters, 'score_allowed'), 'Config.filters must' \
            ' be of type PostConstraintSet'
Ejemplo n.º 2
0
def process_admin_command(self, author, subject, body, message_id):
    """
    This task is the basis for all other admin commands. It does not farm it out
    to another task per command, rather it runs it in the existing task.

    Steps:
    - Check for permissions
    - Retrieve associated function as a callable
    - Call said function with the commands (author, body, svc)
    - Send the response from the function as a reply back to the invoking
      message.
    """
    send_bot_message = signature('tor_worker.role_moderator.tasks.'
                                 'send_bot_message')

    # It only makes sense to have this be scoped to /r/ToR
    config = Config.subreddit('TranscribersOfReddit')
    command_name = subject.lower()[1:]  # Lowercase and remove the initial '!'

    if not config.commands.allows(command_name).by_user(author):
        log.warning(f'DENIED: {author} is not allowed to call {command_name}')
        # TODO: Send to slack
        return

    log.info(f'{author} called {command_name} with args {repr(body)}')

    func = config.commands.func(command_name)
    response = func(author=author, body=body, svc=self)

    log.debug(f'Responding to {command_name} with {repr(body)} -> '
              f'{repr(response)}.')

    send_bot_message.delay(body=_(response), message_id=message_id)
Ejemplo n.º 3
0
    def test_init_by_factory(self, mock_loader, mock_valid_directory):
        config = Config.subreddit('foo')

        mock_valid_directory.assert_not_called()
        assert config.env in ['development', 'testing', 'production']
        assert config.name == 'foo'
        assert str(config) == '/r/foo configuration'
Ejemplo n.º 4
0
    def test_default_init(self, mock_loader, mock_valid_directory):
        config = Config()

        mock_valid_directory.assert_called()
        assert config.env in ['development', 'testing', 'production']
        assert config.name == '[default]'
        assert str(config) == 'Default configuration'
        assert config.gifs.no
        assert config.gifs.thumbs_up
        assert 'me_irl' in config.subreddits
Ejemplo n.º 5
0
def post_to_tor(self, sub, title, link, domain, post_id, media_link=None):
    """
    Posts a transcription to the /r/ToR front page

    Params:
        sub - Subreddit name that this comes from
        title - The original title of the post from the other subreddit
        link - The link to the original post from the other subreddit
        domain - The domain of the original post's linked content
        media_link - The link to the media in need of transcription
    """
    if not media_link:
        log.warn(f'Attempting to post content with no media link. '
                 f'({sub}: [{domain}] {repr(title)})')
        return

    # If youtube transcript is found, skip posting it to /r/ToR
    if has_youtube_captions(media_link):
        log.info(f'Found youtube captions for {media_link}... skipped.')
        self.redis.sadd('complete_post_ids', post_id)
        self.redis.incr('total_posted', amount=1)
        self.redis.incr('total_new', amount=1)

        return

    update_post_flair = signature('tor_worker.role_moderator.tasks.'
                                  'update_post_flair')

    config = Config.subreddit(sub)
    title = textwrap.shorten(title, width=250, placeholder='...')

    post_type = config.templates.url_type(domain)
    post_template = config.templates.content(domain)
    footer = config.templates.footer

    submission = self.reddit.subreddit('TranscribersOfReddit').submit(
        title=f'{sub} | {post_type.title()} | "{title}"',
        url=link,
    )

    update_post_flair.delay(submission.id, 'Unclaimed')

    # Add completed post to tracker
    self.redis.sadd('complete_post_ids', post_id)
    self.redis.incr('total_posted', amount=1)
    self.redis.incr('total_new', amount=1)

    # TODO: OCR job for this comment
    reply = bot_msg['intro_comment'].format(
        post_type=post_type,
        formatting=post_template,
        footer=footer,
        message_url=message_link(subject='General Questions'),
    )
    post_comment(repliable=submission, body=reply)
Ejemplo n.º 6
0
    def test_user_is_allowed(self, mock_json, mock_valid_dir):
        self.command._func_base = __name__
        config = Config()
        assert config.globals.is_moderator('tor_mod')
        assert not config.globals.is_moderator('me')

        assert self.command.allows('ping').by_user('me'),\
            'User "me" is not allowed to use the command "update"'
        assert self.command.allows('ping').by_user('tor_mod'),\
            'User "tor_mod" is not allowed to use the command "update"'

        assert self.command.func('ping') == noop_commands.ping
        self.command.func('ping')('', '', '')  # Test method arity
Ejemplo n.º 7
0
    def test_not_authorized(self, mock_json, mock_valid_dir):
        self.command._func_base = __name__
        config = Config()
        assert not config.globals.is_moderator('me')
        assert config.globals.is_moderator('tor_mod')

        assert not self.command.allows('reload').by_user('me'),\
            'User "me" is allowed to use the command "reload"'
        assert self.command.allows('reload').by_user('tor_mod'),\
            'User "tor_mod" is not allowed to use the command "reload"'

        assert self.command.func('reload') == noop_commands.reload
        self.command.func('reload')('', '', '')  # Test method arity
Ejemplo n.º 8
0
    def test_no_such_command(self, mock_json, mock_valid_dir):
        config = Config()
        assert config.globals.is_moderator('tor_mod')
        assert not config.globals.is_moderator('me')

        assert not self.command.allows('somerandomcommand').by_user('me'),\
            'User "me" is allowed to use the command "somerandomcommand"'
        assert not self.command.allows('somerandomcommand').by_user('tor_mod'),\
            'User "tor_mod" is allowed to use the command "somerandomcommand"'

        assert self.command.func('somerandomcommand') != \
            noop_commands.somerandomcommand

        with pytest.raises(NotImplementedError):  # Test undefined behavior
            # Test method arity
            self.command.func('somerandomcommand')('', '', '')
Ejemplo n.º 9
0
def process_blacklist(author: str, arg: str, svc: Any) -> str:
    """
    Essentially shadow-banning a user, as far as the bots are concerned.

    author  -> The user doing the banning
    arg     -> The username in which to ban
    svc     -> Any object that has:
                 - a redis connection at `self.redis`
                 - a requests object at `self.http`
    """
    users = arg.splitlines()
    config = Config.subreddit('TranscribersOfReddit')
    failed = {
        # "username": "******"
    }
    succeeded = []

    for user in users:
        if config.globals.is_moderator(user):
            failed[user] = 'is a moderator'

        elif svc.http.get(f'https://reddit.com/u/{user}.json')\
                .status_code == 404:
            failed[user] = 'is not a valid username on Reddit'

        elif svc.redis.sadd('blacklist', user):
            succeeded.append(user)

        else:
            failed[user] = 'is already blacklisted'

    out = f'Blacklist: ' \
        f'{len(failed.keys())} failed, ' \
        f'{len(succeeded)} succeeded\n'

    for user, reason in failed.items():
        out += f'\n- **{user}** {reason}'

    return out
Ejemplo n.º 10
0
    def test_init_with_base_path(self, mock_valid_directory):
        config = Config(base_path='/fizz/buzz')

        mock_valid_directory.assert_called()
        assert config._base == '/fizz/buzz'
Ejemplo n.º 11
0
    def test_init_with_settings(self, mock_valid_directory):
        config = Config(_settings={'fizz': 'buzz'})

        mock_valid_directory.assert_not_called()
        assert config._settings.get('fizz') == 'buzz'