Пример #1
0
def delete_post(username, post_id, reply_id=None):
    """Deletes posts.

    """
    # The default redirect is different for a post/reply deletion
    # Reply deletion keeps you on the page and post deletion takes you to feed
    if reply_id is not None:
        redirect_url = handle_next(
            request,
            url_for('posts.view_post', username=username, post_id=post_id))
    else:
        redirect_url = handle_next(request, url_for('users.feed'))

    user_id = get_uid(username)
    if not check_post(user_id, post_id, reply_id):
        return abort(404)

    if reply_id is not None:
        _post = get_post(reply_id)

        if _post['user_id'] != current_user['_id'] and \
                user_id != current_user['_id']:
            return abort(403)
    else:
        if user_id != current_user['_id']:
            return abort(403)

    if reply_id is not None:
        be_delete_post(reply_id)
        flash('Post has been deleted', 'success')
    else:
        be_delete_post(post_id)
        flash('Post has been deleted along with all replies', 'success')

    return redirect(redirect_url)
Пример #2
0
def delete_post(username, post_id, reply_id=None):
    """Deletes posts.

    """
    # The default redirect is different for a post/reply deletion
    # Reply deletion keeps you on the page and post deletion takes you to feed
    if reply_id is not None:
        redirect_url = handle_next(request, url_for('posts.view_post',
                                   username=username, post_id=post_id))
    else:
        redirect_url = handle_next(request, url_for('users.feed'))

    user_id = get_uid(username)
    if not check_post(user_id, post_id, reply_id):
        return abort(404)

    if reply_id is not None:
        _post = get_post(reply_id)

        if _post['user_id'] != current_user['_id'] and \
                user_id != current_user['_id']:
            return abort(403)
    else:
        if user_id != current_user['_id']:
            return abort(403)

    if reply_id is not None:
        be_delete_post(reply_id)
        flash('Post has been deleted', 'success')
    else:
        be_delete_post(post_id)
        flash('Post has been deleted along with all replies', 'success')

    return redirect(redirect_url)
Пример #3
0
def flag(username, post_id):
    """Flags a post so that moderators are aware of it.

    .. note: This is a requirement to enter the Apple app store.
    """
    # Ensure the default redirect is to the correct location.
    reply_id = get_post(post_id).get('reply_to')

    if reply_id is None:
        redirect_url = handle_next(request, url_for('posts.view_post',
                                   username=username, post_id=post_id))
    else:
        reply = get_post(reply_id)
        redirect_url = handle_next(request, url_for('posts.view_post',
                                   username=reply.get('username'),
                                   post_id=reply_id))

    user_id = get_uid(username)

    if not check_post(user_id, post_id):
        return abort(404)

    try:
        flag_post(current_user['_id'], post_id)
    except CantFlagOwn:
        flash('You can not flag on your own posts', 'error')
    except AlreadyFlagged:
        flash('You have already flagged this post', 'error')
    else:
        flash('You flagged the ' + ('comment' if reply_id else 'post'),
              'success')

    return redirect(redirect_url)
Пример #4
0
def remove_from_feed(post_id):
    """Removes ``post_id`` from current users feed."""
    redirect_url = handle_next(request, url_for('users.feed'))

    if be_rem_from_feed(post_id, current_user.get('_id')):  # pragma: no branch
        flash('Message has been removed from feed', 'success')

    return redirect(handle_next(request, redirect_url))
Пример #5
0
def remove_from_feed(post_id):
    """Removes ``post_id`` from current users feed."""
    redirect_url = handle_next(request, url_for('users.feed'))

    if be_rem_from_feed(post_id, current_user.get('_id')):  # pragma: no branch
        flash('Message has been removed from feed', 'success')

    return redirect(handle_next(request, redirect_url))
Пример #6
0
def post(username=None, post_id=None):
    """Enabled current_user to create a new post on Pjuu :)

    This view accepts GET and POST yet only acts on a POST. This is so that the
    Werkzeug router does not treat this like a profile lookup.

    """
    # Rather than just 404 if someone tries to GET this URL (which is default),
    # we will throw a 405.
    if request.method == 'GET':
        return abort(405)

    # Set the default redirect URLs depending on type of post it is
    if post_id is None:
        redirect_url = handle_next(request, url_for('users.profile',
                                   username=current_user['username']))
    else:
        redirect_url = handle_next(request, url_for('posts.view_post',
                                   username=username, post_id=post_id))

    # Stop muted users from creating posts
    if current_user.get('muted', False):
        flash('You have been silenced!', 'warning')
        return redirect(redirect_url)

    form = PostForm()
    if form.validate():
        # If there is an uploaded File pass it on else pass nothing
        if form.upload.data:
            # Pass the BytesIO stream to the backend.
            upload = form.upload.data.stream
        else:
            upload = None

        # Create the post
        if create_post(current_user['_id'], current_user['username'],
                       form.body.data, post_id, upload):
            # Inform the user we have created the post
            flash('Your post has been added', 'success')
        else:
            flash('There was an error creating your post',
                  'error')  # pragma: no cover
    else:
        # Will print out all errors that happen in a post form.
        # This is better than "There is an error in your post"
        for key, value in form.errors.iteritems():
            for error in value:
                flash(error, 'error')

    return redirect(redirect_url)
Пример #7
0
def signin():
    """
    Logs a user in.
    Will authenticate username/password, check account activation and
    if the user is banned or not before setting user_id in session.
    """
    form = SignInForm(request.form)
    if request.method == 'POST':
        # Handles the passing of the next argument to the login view
        redirect_url = handle_next(request, url_for('feed'))

        if form.validate():
            # Calls authenticate from backend.py
            uid = authenticate(form.username.data, form.password.data)
            if uid:
                # Ensure the user is active
                if not is_active(uid):
                    flash('Please activate your account<br />'
                          'Check your e-mail', 'information')
                # Ensure the user is not banned
                elif is_banned(uid):
                    flash('You\'re a very naughty boy!', 'error')
                # All OK log the user in
                else:
                    # We will also make the session permanent if the user
                    # has requested too
                    session.permanent = form.keep_signed_in.data
                    login(uid)
                    return redirect(redirect_url)
            else:
                flash('Invalid user name or password', 'error')
        else:
            flash('Invalid user name or password', 'error')
    return render_template('signin.html', form=form)
Пример #8
0
def downvote(username, post_id, reply_id=None):
    """Downvotes a post.

    """
    redirect_url = handle_next(request, url_for('posts.view_post',
                               username=username, post_id=post_id))

    user_id = get_uid(username)
    if not check_post(user_id, post_id, reply_id):
        return abort(404)

    try:
        if reply_id is None:
            vote_post(current_user['_id'], post_id, amount=-1)
        else:
            vote_post(current_user['_id'], reply_id, amount=-1)
    except AlreadyVoted:
        flash('You have already voted on this post', 'error')
    except CantVoteOnOwn:
        flash('You can not vote on your own posts', 'error')
    else:
        flash('You downvoted the ' + ("comment" if reply_id else "post"),
              'success')

    return redirect(redirect_url)
Пример #9
0
def comment(username, pid):
    """
    current_user creates a comment of post 'pid' with the author 'username'
    """
    # Rather than just 404 if someone tries to GET this URL which is default
    # if we don't specify it we will throw a 405.
    if request.method == 'GET':
        return abort(405)

    redirect_url = handle_next(request, url_for('view_post',
                               username=username, pid=pid))

    # Stop muted users from commenting
    if is_mute(current_user['uid']):
        flash('You have been silenced!', 'warning')
        return redirect(redirect_url)

    form = PostForm(request.form)
    if form.validate():
        cid = create_comment(current_user['uid'], pid, form.body.data)
        flash('Your comment has been added', 'success')
    else:
        # This flash can handle only 1 form error
        # There is an odd issue where are error is thrown with no errors
        # Can't recreate the issue
        if len(form.body.errors) > 0:
            flash(form.body.errors[0], 'error')
        else:
            flash('Oh no! There are errors in your comment.',
                  'error')  # pragma: no cover
    return redirect(redirect_url)
Пример #10
0
Файл: views.py Проект: pjuu/pjuu
def signin():
    """
    """
    form = SignInForm(request.form)
    if request.method == 'POST':
        # Handles the passing of the next argument to the login view
        redirect_url = handle_next(request, url_for('users.feed'))

        if form.validate():
            # Calls authenticate from backend.py
            user = authenticate(form.username.data, form.password.data)
            if user:
                # Ensure the user is active
                if not user.get('active', False):
                    flash('Please activate your account<br />'
                          'Check your e-mail', 'information')
                # Ensure the user is not banned
                elif user.get('banned', False):
                    flash('You\'re a very naughty boy!', 'error')
                # All OK log the user in
                else:
                    # We will also make the session permanent if the user
                    # has requested too
                    session.permanent = form.keep_signed_in.data
                    be_signin(user.get('_id'))
                    return redirect(redirect_url)
            else:
                flash('Invalid user name or password', 'error')
        else:
            flash('Invalid user name or password', 'error')

    return render_template('signin.html', form=form)
Пример #11
0
def downvote(username, pid=-1, cid=None):
    """
    Downvotes a post or comment.
    If this is a comment it _WILL_ update the comments authros score.
    The 'username' may seem a little confusing but the comment is on the
    'pid' which was created by 'username'.
    """
    redirect_url = handle_next(request, url_for('view_post',
                               username=username, pid=pid))

    uid = get_uid(username)
    if not check_post(uid, pid, cid):
        return abort(404)

    try:
        if cid:
            result = vote_comment(current_user['uid'], cid, amount=-1)
        else:
            result = vote_post(current_user['uid'], pid, amount=-1)
    except AlreadyVoted:
        flash('You have already voted on this post', 'error')
    except CantVoteOnOwn:
        flash('You can not vote on your own posts', 'error')
    else:
        flash('You downvoted the post', 'success')

    return redirect(redirect_url)
Пример #12
0
def post(redirect_url=None):
    """
    current_user creates a new post on Pjuu :)

    This view accepts GET and POST yet only acts on a POST. This is so that the
    Werkzeug router does not treat this like a profile lookup
    """
    # Rather than just 404 if someone tries to GET this URL which is default
    # if we don't specify it we will throw a 405.
    if request.method == 'GET':
        return abort(405)

    redirect_url = handle_next(request, url_for('profile',
                               username=current_user['username']))

    # Stop muted users from creating posts
    if is_mute(current_user['uid']):
        flash('You have been silenced!', 'warning')
        return redirect(redirect_url)

    form = PostForm(request.form)
    if form.validate():
        pid = create_post(current_user['uid'], form.body.data)
        flash('Your post has been added', 'success')
    else:
        # This flash can handle only 1 form error
        # There is an odd issue where are error is thrown with no errors
        # Can't recreate the issue
        if len(form.body.errors) > 0:
            flash(form.body.errors[0], 'error')
        else:
            flash('Oh no! There are errors in your post.',
                  'error')  # pragma: no cover
    return redirect(redirect_url)
Пример #13
0
def signin():
    """
    """
    form = SignInForm(request.form)
    if request.method == 'POST':
        # Handles the passing of the next argument to the login view
        redirect_url = handle_next(request, url_for('users.feed'))

        if form.validate():
            # Calls authenticate from backend.py
            user = authenticate(form.username.data, form.password.data)
            if user:
                # Ensure the user is active
                if not user.get('active', False):
                    flash(
                        'Please activate your account<br />'
                        'Check your e-mail', 'information')
                # Ensure the user is not banned
                elif user.get('banned', False):
                    flash('You\'re a very naughty boy!', 'error')
                # All OK log the user in
                else:
                    # We will also make the session permanent if the user
                    # has requested too
                    session.permanent = form.keep_signed_in.data
                    be_signin(user.get('_id'))
                    return redirect(redirect_url)
            else:
                flash('Invalid user name or password', 'error')
        else:
            flash('Invalid user name or password', 'error')
    return render_template('signin.html', form=form)
Пример #14
0
def reset_tips():
    """Allow a user to reset all the tips from their settings page"""
    redirect_url = handle_next(request, url_for('users.settings_profile'))

    # Actually reset the tips in the database
    be_reset_tips(current_user.get('_id'))
    flash('Tip\'s have successfully been reset', 'success')

    return redirect(redirect_url)
Пример #15
0
Файл: views.py Проект: pjuu/pjuu
def reset_tips():
    """Allow a user to reset all the tips from their settings page"""
    redirect_url = handle_next(request, url_for('users.settings_profile'))

    # Actually reset the tips in the database
    be_reset_tips(current_user.get('_id'))
    flash('Tip\'s have successfully been reset', 'success')

    return redirect(redirect_url)
Пример #16
0
def flag(username, post_id):
    """Flags a post so that moderators are aware of it.

    .. note: This is a requirement to enter the Apple app store.
    """
    if not check_post(get_uid(username), post_id):
        return abort(404)

    _post = get_post(post_id)

    # Ensure the default redirect is to the correct location.
    reply_id = get_post(post_id).get('reply_to')

    if reply_id is None:
        redirect_url = handle_next(
            request,
            url_for('posts.view_post', username=username, post_id=post_id))
    else:
        reply = get_post(reply_id)
        redirect_url = handle_next(
            request,
            url_for('posts.view_post',
                    username=reply.get('username'),
                    post_id=reply_id))

    # Ensue user has permission to perform the action
    current_user_id = current_user.get('_id')
    permission = get_user_permission(_post.get('user_id'), current_user_id)

    if permission < _post.get('permission', k.PERM_PUBLIC):
        flash('You do not have permission to flag this post', 'error')
        return redirect(redirect_url)

    try:
        flag_post(current_user['_id'], post_id)
    except CantFlagOwn:
        flash('You can not flag on your own posts', 'error')
    except AlreadyFlagged:
        flash('You have already flagged this post', 'error')
    else:
        flash('You flagged the ' + ('comment' if reply_id else 'post'),
              'success')

    return redirect(redirect_url)
Пример #17
0
Файл: views.py Проект: hnk/pjuu
def delete_alert(alert_id):
    """Remove an alert id (aid) from a users alerts feed."""
    user_id = current_user.get('_id')
    # Handle next
    redirect_url = handle_next(request, url_for('users.alerts'))

    if be_delete_alert(user_id, alert_id):
        flash('Alert has been hidden', 'success')

    return redirect(redirect_url)
Пример #18
0
def delete_alert(alert_id):
    """Remove an alert id (aid) from a users alerts feed."""
    user_id = current_user.get('_id')
    # Handle next
    redirect_url = handle_next(request, url_for('users.alerts'))

    if be_delete_alert(user_id, alert_id):
        flash('Alert has been hidden', 'success')

    return redirect(redirect_url)
Пример #19
0
def hide_tip(tip_name):
    """Will set a tip with `tip_name` to false for the `current_user`"""
    if tip_name not in k.VALID_TIP_NAMES:
        return abort(404)

    # Set the tip to False inside Mongo
    remove_tip(current_user.get('_id'), tip_name)

    redirect_url = handle_next(request, url_for('users.feed'))

    return redirect(redirect_url)
Пример #20
0
Файл: views.py Проект: pjuu/pjuu
def hide_tip(tip_name):
    """Will set a tip with `tip_name` to false for the `current_user`"""
    if tip_name not in k.VALID_TIP_NAMES:
        return abort(404)

    # Set the tip to False inside Mongo
    remove_tip(current_user.get('_id'), tip_name)

    redirect_url = handle_next(request, url_for('users.feed'))

    return redirect(redirect_url)
Пример #21
0
def delete_post(username, pid, cid=None):
    """
    Deletes posts and comments.
    """
    # The default redirect is different for a post/comment deletion
    # Comment deletion keeps you on the page and post deletion takes you
    # to your feed
    if cid is not None:
        redirect_url = handle_next(request, url_for('view_post',
                                   username=username, pid=pid))
    else:
        redirect_url = handle_next(request, url_for('feed'))

    uid = get_uid(username)
    if not check_post(uid, pid, cid):
        return abort(404)

    if cid is not None:
        author_uid = get_comment_author(cid)
        # Allow not only the comment author to remove the comment but also
        # allow the post author to do so!
        if author_uid != current_user['uid'] and \
           uid != current_user['uid']:
            return abort(403)
    else:
        # If this is a post ONLY allow the post author to delete
        if uid != current_user['uid']:
            return abort(403)

    if cid is not None:
        be_delete_comment(cid)
        flash('Comment has been deleted', 'success')
    else:
        be_delete_post(pid)
        flash('Post has been deleted along with all comments', 'success')

    return redirect(redirect_url)
Пример #22
0
def unsubscribe(username, post_id):
    """Unsubscribes a user from a post

    """
    if not check_post(get_uid(username), post_id):
        return abort(404)

    # The default URL is to go back to the posts view
    redirect_url = handle_next(request, url_for('posts.view_post',
                               username=username, post_id=post_id))

    # Unsubscribe the user from the post, only show them a message if they
    # were actually unsubscribed
    if be_unsubscribe(current_user['_id'], post_id):
        flash('You have been unsubscribed from this post', 'success')

    return redirect(redirect_url)
Пример #23
0
def unsubscribe(username, post_id):
    """Unsubscribes a user from a post

    """
    if not check_post(get_uid(username), post_id):
        return abort(404)

    # The default URL is to go back to the posts view
    redirect_url = handle_next(
        request, url_for('posts.view_post', username=username,
                         post_id=post_id))

    # Unsubscribe the user from the post, only show them a message if they
    # were actually unsubscribed
    if be_unsubscribe(current_user['_id'], post_id):
        flash('You have been unsubscribed from this post', 'success')

    return redirect(redirect_url)
Пример #24
0
Файл: views.py Проект: hnk/pjuu
def unfollow(username):
    """Unfollow a user"""
    redirect_url = handle_next(request, url_for('users.following',
                               username=current_user.get('username')))

    user_id = get_uid(username)

    # If we don't get a uid from the username the page doesn't exist
    if user_id is None:
        abort(404)

    # Unfollow user, ensure the user doesn't unfollow themself
    if user_id != current_user.get('_id'):
        if unfollow_user(current_user.get('_id'), user_id):
            flash('You are no longer following %s' % username, 'success')
    else:
        flash('You can\'t follow/unfollow yourself', 'information')

    return redirect(redirect_url)
Пример #25
0
def unfollow(username):
    """Unfollow a user"""
    redirect_url = handle_next(
        request,
        url_for('users.following', username=current_user.get('username')))

    user_id = get_uid(username)

    # If we don't get a uid from the username the page doesn't exist
    if user_id is None:
        abort(404)

    # Unfollow user, ensure the user doesn't unfollow themself
    if user_id != current_user.get('_id'):
        if unfollow_user(current_user.get('_id'), user_id):
            flash('You are no longer following %s' % username, 'success')
    else:
        flash('You can\'t follow/unfollow yourself', 'information')

    return redirect(redirect_url)
Пример #26
0
def unapprove(username):
    """Unfollow a user"""
    redirect_url = handle_next(
        request,
        url_for('users.followers', username=current_user.get('username')))

    user_id = get_uid(username)

    # If we don't get a uid from the username the page doesn't exist
    if user_id is None:
        abort(404)

    if user_id != current_user.get('_id'):
        if unapprove_user(current_user.get('_id'), user_id):
            flash('You have untrusted %s' % username, 'success')
        else:
            flash('You can\'t untrust a user who is not trusted', 'error')
    else:
        flash('You can\'t untrust your self', 'information')

    return redirect(redirect_url)
Пример #27
0
Файл: views.py Проект: pjuu/pjuu
def unapprove(username):
    """Unfollow a user"""
    redirect_url = handle_next(request, url_for('users.followers',
                               username=current_user.get('username')))

    user_id = get_uid(username)

    # If we don't get a uid from the username the page doesn't exist
    if user_id is None:
        abort(404)

    if user_id != current_user.get('_id'):
        if unapprove_user(current_user.get('_id'), user_id):
            flash('You have untrusted %s' % username, 'success')
        else:
            flash('You can\'t untrust a user who is not trusted',
                  'error')
    else:
        flash('You can\'t untrust your self', 'information')

    return redirect(redirect_url)
Пример #28
0
Файл: views.py Проект: hnk/pjuu
def remove_from_feed(post_id):
    """Removes ``post_id`` from current users feed"""
    if be_remove_from_feed(post_id, current_user.get('_id')):
        flash('Message has been removed from feed', 'success')

    return redirect(handle_next(request, url_for('users.feed')))
Пример #29
0
def vote(username, post_id, reply_id=None):
    """Upvotes a post.

    .. note: If the request is an XHR one the whole function will not run.
             It will exit out and the first chance and return JSON.
    """
    redirect_url = handle_next(request, url_for('posts.view_post',
                               username=username, post_id=post_id))

    if not check_post(get_uid(username), post_id, reply_id):
        if request.is_xhr:
            return jsonify({'message': 'Post not found'}), 404

        return abort(404)

    _post = get_post(post_id)

    # Ensuer user has permission to perform the action
    current_user_id = current_user.get('_id')
    permission = get_user_permission(_post.get('user_id'), current_user_id)

    # Since the upvote/downvote functions have been merged we need to
    # identify which action is going to be performed.
    if request.endpoint == 'posts.upvote':
        action = 'upvoted'
        amount = 1
    else:
        action = 'downvoted'
        amount = -1

    if permission < _post.get('permission', k.PERM_PUBLIC):
        message = 'You do not have permission to vote on this post'

        if request.is_xhr:
            return jsonify({'message': message}), 403

        xflash(message, 'error')
        return redirect(redirect_url)

    try:
        if reply_id is None:
            result = vote_post(current_user['_id'], post_id, amount=amount)
        else:
            result = vote_post(current_user['_id'], reply_id, amount=amount)
    except AlreadyVoted:
        message = 'You have already voted on this post'

        if request.is_xhr:
            return jsonify({'message': message}), 400

        xflash(message, 'error')
    except CantVoteOnOwn:
        message = 'You can not vote on your own posts'

        if request.is_xhr:
            return jsonify({'message': message}), 400

        xflash(message, 'error')
    else:
        if (amount > 0 < result) or (amount < 0 > result):
            message = 'You {} the '.format(action) + ("comment" if reply_id
                                                      else "post")
            xflash(message, 'success')
        else:
            message = 'You reversed your vote on the ' + ("comment" if reply_id
                                                          else "post")
            xflash(message, 'success')

    if request.is_xhr:
        return jsonify({'message': message}), 200

    return redirect(redirect_url)
Пример #30
0
def post(username=None, post_id=None):
    """Enabled current_user to create a new post on Pjuu :)

    This view accepts GET and POST yet only acts on a POST. This is so that the
    Werkzeug router does not treat this like a profile lookup.
    """
    # Rather than just 404 if someone tries to GET this URL (which is default),
    # we will throw a 405.
    if request.method == 'GET':
        return abort(405)

    # Stop un-approved users posting comments if permissions do not let them.
    if post_id is not None:
        if not check_post(get_uid(username), post_id):
            return abort(404)

        _post = get_post(post_id)

        permission = get_user_permission(current_user, _post.get('_id'))

        if permission < _post.get('permission', k.PERM_PUBLIC):
            return abort(403)

    # Set the default redirect URLs depending on type of post it is
    if post_id is None:
        redirect_url = handle_next(request, url_for('users.profile',
                                   username=current_user['username']))
    else:
        redirect_url = handle_next(request, url_for('posts.view_post',
                                   username=username, post_id=post_id))

    # Stop muted users from creating posts
    if current_user.get('muted', False):
        flash('You have been silenced!', 'warning')
        return redirect(redirect_url)

    form = PostForm()
    if form.validate():
        # If there is an uploaded File pass it on else pass nothing
        if form.upload.data:
            # Pass the BytesIO stream to the backend.
            upload = form.upload.data.stream
        else:
            upload = None

        try:
            permission = int(form.permission.data)
        except ValueError:  # pragma: no cover
            permission = -1

        # WTForms should stop this ever, ever firing
        if not (k.PERM_PUBLIC <= permission <=  # pragma: no cover
                k.PERM_APPROVED):  # pragma: no cover
            flash('Invalid post permission set', 'error')
            return redirect(redirect_url)

        # Create the post
        if create_post(current_user['_id'], current_user['username'],
                       unicode(escape(form.body.data)), post_id, upload,
                       permission=permission):
            # Inform the user we have created the post
            flash('Your post has been added', 'success')
        else:
            flash('There was an error creating your post',
                  'error')  # pragma: no cover
    else:
        # Will print out all errors that happen in a post form.
        # This is better than "There is an error in your post"
        for key, value in form.errors.iteritems():
            for error in value:
                flash(error, 'error')

    return redirect(redirect_url)
Пример #31
0
def post(username=None, post_id=None):
    """Enabled current_user to create a new post on Pjuu :)

    This view accepts GET and POST yet only acts on a POST. This is so that the
    Werkzeug router does not treat this like a profile lookup.
    """
    # Rather than just 404 if someone tries to GET this URL (which is default),
    # we will throw a 405.
    if request.method == 'GET':
        return abort(405)

    # Stop un-approved users posting comments if permissions do not let them.
    if post_id is not None:
        if not check_post(get_uid(username), post_id):
            return abort(404)

        _post = get_post(post_id)

        permission = get_user_permission(current_user, _post.get('_id'))

        if permission < _post.get('permission', k.PERM_PUBLIC):
            return abort(403)

    # Set the default redirect URLs depending on type of post it is
    if post_id is None:
        redirect_url = handle_next(
            request, url_for('users.profile',
                             username=current_user['username']))
    else:
        redirect_url = handle_next(
            request,
            url_for('posts.view_post', username=username, post_id=post_id))

    # Stop muted users from creating posts
    if current_user.get('muted', False):
        flash('You have been silenced!', 'warning')
        return redirect(redirect_url)

    form = PostForm()
    if form.validate():
        # If there is an uploaded File pass it on else pass nothing
        if form.upload.data:
            # Pass the BytesIO stream to the backend.
            upload = form.upload.data.stream
        else:
            upload = None

        try:
            permission = int(form.permission.data)
        except ValueError:  # pragma: no cover
            permission = -1

        # WTForms should stop this ever, ever firing
        if not (k.PERM_PUBLIC <= permission <=  # pragma: no cover
                k.PERM_APPROVED):  # pragma: no cover
            flash('Invalid post permission set', 'error')
            return redirect(redirect_url)

        # Create the post
        if create_post(current_user['_id'],
                       current_user['username'],
                       unicode(escape(form.body.data)),
                       post_id,
                       upload,
                       permission=permission):
            # Inform the user we have created the post
            flash('Your post has been added', 'success')
        else:
            flash('There was an error creating your post',
                  'error')  # pragma: no cover
    else:
        # Will print out all errors that happen in a post form.
        # This is better than "There is an error in your post"
        for key, value in form.errors.iteritems():
            for error in value:
                flash(error, 'error')

    return redirect(redirect_url)
Пример #32
0
def vote(username, post_id, reply_id=None):
    """Upvotes a post.

    .. note: If the request is an XHR one the whole function will not run.
             It will exit out and the first chance and return JSON.
    """
    redirect_url = handle_next(
        request, url_for('posts.view_post', username=username,
                         post_id=post_id))

    if not check_post(get_uid(username), post_id, reply_id):
        if request.is_xhr:
            return jsonify({'message': 'Post not found'}), 404

        return abort(404)

    _post = get_post(post_id)

    # Ensuer user has permission to perform the action
    current_user_id = current_user.get('_id')
    permission = get_user_permission(_post.get('user_id'), current_user_id)

    # Since the upvote/downvote functions have been merged we need to
    # identify which action is going to be performed.
    if request.endpoint == 'posts.upvote':
        action = 'upvoted'
        amount = 1
    else:
        action = 'downvoted'
        amount = -1

    if permission < _post.get('permission', k.PERM_PUBLIC):
        message = 'You do not have permission to vote on this post'

        if request.is_xhr:
            return jsonify({'message': message}), 403

        xflash(message, 'error')
        return redirect(redirect_url)

    try:
        if reply_id is None:
            result = vote_post(current_user['_id'], post_id, amount=amount)
        else:
            result = vote_post(current_user['_id'], reply_id, amount=amount)
    except AlreadyVoted:
        message = 'You have already voted on this post'

        if request.is_xhr:
            return jsonify({'message': message}), 400

        xflash(message, 'error')
    except CantVoteOnOwn:
        message = 'You can not vote on your own posts'

        if request.is_xhr:
            return jsonify({'message': message}), 400

        xflash(message, 'error')
    else:
        if (amount > 0 < result) or (amount < 0 > result):
            message = 'You {} the '.format(action) + ("comment"
                                                      if reply_id else "post")
            xflash(message, 'success')
        else:
            message = 'You reversed your vote on the ' + ("comment" if reply_id
                                                          else "post")
            xflash(message, 'success')

    if request.is_xhr:
        return jsonify({'message': message}), 200

    return redirect(redirect_url)