Example #1
0
    def siteadmin_comments_spam(self):
        if not (current_auth.user.is_comment_moderator
                or current_auth.user.is_user_moderator):
            return abort(403)

        comment_spam_form = Form()
        comment_spam_form.form_nonce.data = comment_spam_form.form_nonce.default(
        )
        if comment_spam_form.validate_on_submit():
            comments = Comment.query.filter(
                Comment.uuid_b58.in_(request.form.getlist('comment_id')))
            for comment in comments:
                CommentModeratorReport.submit(actor=current_auth.user,
                                              comment=comment)
            db.session.commit()
            flash(_("Comment(s) successfully reported as spam"),
                  category='info')
        else:
            flash(
                _("There was a problem marking the comments as spam. Please try again"
                  ),
                category='error',
            )

        return redirect(url_for('siteadmin_comments'))
Example #2
0
def playlist_delete(channel, playlist):
    if request.method == 'GET':
        return {'playlist': dict(playlist.current_access())}
    form = Form()
    if form.validate_on_submit():
        db.session.delete(playlist)
        db.session.commit()
        return {'status': 'ok', 'doc': _("Deleted playlist {title}.".format(title=playlist.title)), 'result': {}}
    return {'status': 'error', 'errors': {'error': form.errors}}, 400
Example #3
0
    def delete(self):
        form = Form()
        if request.method == 'POST':
            if form.validate_on_submit():
                previous_membership = self.obj
                if previous_membership.user == current_auth.user:
                    return {
                        'status':
                        'error',
                        'error_description':
                        _("You can’t revoke your own membership"),
                        'form_nonce':
                        form.form_nonce.data,
                    }
                if previous_membership.is_active:
                    previous_membership.revoke(actor=current_auth.user)
                    db.session.commit()
                    dispatch_notification(
                        OrganizationAdminMembershipRevokedNotification(
                            document=previous_membership.organization,
                            fragment=previous_membership,
                        ))
                return {
                    'status':
                    'ok',
                    'message':
                    _("The member has been removed"),
                    'memberships': [
                        membership.current_access(datasets=('without_parent',
                                                            'related'))
                        for membership in
                        self.obj.organization.active_admin_memberships
                    ],
                }
            else:
                return (
                    {
                        'status': 'error',
                        'errors': form.errors,
                        'form_nonce': form.form_nonce.data,
                    },
                    400,
                )

        form_html = render_form(
            form=form,
            title=_("Confirm removal"),
            message=_("Remove {member} as an admin from {profile}?").format(
                member=self.obj.user.fullname,
                profile=self.obj.organization.title),
            submit=_("Remove"),
            ajax=False,
            with_chrome=False,
        )
        return {'form': form_html}
Example #4
0
def video_delete(channel, playlist, video):
    """
    Delete video
    """
    if request.method == 'GET':
        return {'video': dict(video.current_access())}
    form = Form()
    if form.validate_on_submit():
        db.session.delete(video)
        db.session.commit()
        return {'status': 'ok', 'doc': _("Delete video {title}.".format(title=video.title)), 'result': {}}
    return {'status': 'error', 'errors': {'error': form.errors}}, 400
Example #5
0
def video_playlist_add(channel, playlist, video):
    form = Form()
    if form.validate_on_submit():
        if video not in playlist.videos:
            playlist.videos.append(video)
            db.session.commit()
            cache.delete('data/featured-channels')
            message = "Added video to playlist"
        else:
            message = "This video is already in that playlist"
        return {'status': 'ok', 'doc': _(message), 'result': {'url': playlist.url_for()}}
    else:
        message = _("CSRF validation failed. Please reload this page and try again.")
        return {'status': 'error', 'errors': {'error': [message]}}, 400
Example #6
0
    def siteadmin_comments(self, query='', page=None, per_page=100):
        if not (current_auth.user.is_comment_moderator
                or current_auth.user.is_user_moderator):
            return abort(403)

        comments = Comment.query.filter(~(Comment.state.REMOVED)).order_by(
            Comment.created_at.desc())
        if query:
            comments = comments.join(User).filter(
                db.or_(
                    Comment.search_vector.match(for_tsquery(query or '')),
                    User.search_vector.match(for_tsquery(query or '')),
                ))

        pagination = comments.paginate(page=page, per_page=per_page)

        return {
            'query': query,
            'comments': pagination.items,
            'total_comments': pagination.total,
            'pages': list(range(1,
                                pagination.pages + 1)),  # list of page numbers
            'current_page': pagination.page,
            'comment_spam_form': Form(),
        }
Example #7
0
def reopen(domain, hashid, key):
    post = JobPost.query.filter_by(hashid=hashid).first_or_404()
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    # Only closed posts can be reopened
    if not post.is_closed():
        flash("Your job post can't be reopened.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.confirm()
        post.closed_datetime = datetime.utcnow()
        db.session.commit()
        return redirect(post.url_for(), code=303)
    return render_template("reopen.html", post=post, form=form)
Example #8
0
def reopen(domain, hashid, key):
    post = JobPost.query.filter_by(hashid=hashid).first_or_404()
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    # Only closed posts can be reopened
    if not post.is_closed():
        flash("Your job post can't be reopened.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.confirm()
        post.closed_datetime = datetime.utcnow()
        db.session.commit()
        return redirect(post.url_for(), code=303)
    return render_template("reopen.html", post=post, form=form)
Example #9
0
def close(domain, hashid, key):
    post = JobPost.get(hashid)
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    if request.method == 'GET' and post.is_closed():
        return redirect(post.url_for('reopen'), code=303)
    if not post.is_public():
        flash("Your job post can't be closed.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.close()
        post.closed_datetime = datetime.utcnow()
        db.session.commit()
        return redirect(post.url_for(), code=303)
    return render_template("close.html", post=post, form=form)
Example #10
0
def close(domain, hashid, key):
    post = JobPost.get(hashid)
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    if request.method == 'GET' and post.is_closed():
        return redirect(post.url_for('reopen'), code=303)
    if not post.is_public():
        flash("Your job post can't be closed.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.close()
        post.closed_datetime = datetime.utcnow()
        db.session.commit()
        return redirect(post.url_for(), code=303)
    return render_template("close.html", post=post, form=form)
Example #11
0
def reopen(domain, hashid, key):
    post = JobPost.query.filter_by(hashid=hashid).first_or_404()
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    # Only closed posts can be reopened
    if not post.state.CLOSED:
        flash("Your job post can't be reopened.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.reopen()
        db.session.commit()
        # cache bust
        # dogpile.invalidate_region('hasjob_index')
        return redirect(post.url_for(), code=303)
    return render_template("reopen.html.jinja2", post=post, form=form)
Example #12
0
def video_remove(channel, playlist, video):
    """
    Remove video from playlist
    """
    if request.method == 'GET':
        return {'playlist': dict(playlist.current_access()), 'video': dict(video.current_access())}
    if playlist not in video.playlists:
        return {'status': 'error', 'errors': {'error': ['Video not playlist and cannot be removed']}}, 400

    # If this is the primary playlist for this video, refuse to remove it.
    if playlist == video.playlist:
        return {'status': 'error', 'errors': {'error': ['Videos cannot be removed from their primary playlist']}}, 400
    form = Form()
    if form.validate_on_submit():
        connection = PlaylistVideo.query.filter_by(playlist_id=playlist.id, video_id=video.id).first_or_404()
        db.session.delete(connection)
        db.session.commit()
        return {'status': 'ok', 'doc': _("Remove video {video} from {playlist}.".format(video=video.title, playlist=playlist.title)), 'result': {}}
    return {'status': 'error', 'errors': {'error': form.errors}}, 400
Example #13
0
def close(domain, hashid, key):
    post = JobPost.get(hashid)
    if not post:
        abort(404)
    if not post.admin_is(g.user):
        abort(403)
    if request.method == 'GET' and post.state.CLOSED:
        return redirect(post.url_for('reopen'), code=303)
    if not post.state.PUBLIC:
        flash("Your job post can't be closed.", "info")
        return redirect(post.url_for(), code=303)
    form = Form()
    if form.validate_on_submit():
        post.close()
        db.session.commit()
        flash(post.close.data['message'], "success")
        # cache bust
        # dogpile.invalidate_region('hasjob_index')
        return redirect(post.url_for(), code=303)
    return render_template("close.html.jinja2", post=post, form=form)
Example #14
0
    def delete(self):
        delcommentform = Form()

        if delcommentform.validate_on_submit():
            commentset = self.obj.commentset
            self.obj.delete()
            commentset.count = Commentset.count - 1
            db.session.commit()
            return {
                'status': 'ok',
                'message': _("Your comment has been deleted"),
                'comments': self.obj.commentset.views.json_comments(),
            }

        delcommentform_html = render_form(
            form=delcommentform,
            title='Delete this comment?',
            submit=_("Delete"),
            ajax=False,
            with_chrome=False,
        )
        return {'form': delcommentform_html}
Example #15
0
    def delete(self):
        form = Form()
        if request.method == 'POST':
            if form.validate_on_submit():
                previous_membership = self.obj
                if previous_membership.is_active:
                    previous_membership.revoke(actor=current_auth.user)
                    signals.project_crew_membership_revoked.send(
                        self.obj.project,
                        project=self.obj.project,
                        membership=previous_membership,
                        actor=current_auth.user,
                        user=previous_membership.user,
                    )
                    db.session.commit()
                return {
                    'status':
                    'ok',
                    'message':
                    _("The member has been removed"),
                    'memberships': [
                        membership.current_access(datasets=('without_parent',
                                                            'related')) for
                        membership in self.obj.project.active_crew_memberships
                    ],
                }
            else:
                return ({'status': 'error', 'errors': form.errors}, 400)

        form_html = render_form(
            form=form,
            title=_("Confirm removal"),
            message=_("Remove {member} as a crew member from this project?").
            format(member=self.obj.user.fullname),
            submit=_("Remove"),
            ajax=False,
            with_chrome=False,
        )
        return {'form': form_html}
Example #16
0
    def view(self):
        if request_is_xhr():
            return jsonify(
                {'comments': self.obj.commentset.views.json_comments()})

        commentform = CommentForm(model=Comment)

        links = [
            Markup(linkify(str(escape(link))))
            for link in self.obj.links.replace('\r\n', '\n').split('\n')
            if link
        ]

        transition_form = ProposalTransitionForm(obj=self.obj)
        proposal_transfer_form = ProposalTransferForm()

        proposal_move_form = None
        if 'move_to' in self.obj.current_access():
            proposal_move_form = ProposalMoveForm()

        proposal_label_admin_form = ProposalLabelsAdminForm(
            model=Proposal, obj=self.obj, parent=self.obj.project)

        return {
            'project': self.obj.project,
            'proposal': self.obj,
            'comments': self.obj.commentset.views.json_comments(),
            'commentform': commentform,
            'delcommentform': Form(),
            'links': links,
            'transition_form': transition_form,
            'proposal_move_form': proposal_move_form,
            'csrf_form': Form(),
            'proposal_transfer_form': proposal_transfer_form,
            'proposal_label_admin_form': proposal_label_admin_form,
        }
Example #17
0
 def form(self):
     """Convenience method for action form CSRF"""
     return Form()
Example #18
0
def proposal_view(profile, space, proposal):
    if proposal.proposal_space != space:
        return redirect(proposal.url_for(), code=301)

    comments = sorted(
        Comment.query.filter_by(commentspace=proposal.comments,
                                parent=None).order_by('created_at').all(),
        key=lambda c: c.votes.count,
        reverse=True)
    commentform = CommentForm(model=Comment)
    delcommentform = DeleteCommentForm()
    if request.method == 'POST':
        if request.form.get(
                'form.id') == 'newcomment' and commentform.validate(
                ) and 'new-comment' in g.permissions:
            send_mail_info = []
            if commentform.comment_edit_id.data:
                comment = Comment.query.get(
                    int(commentform.comment_edit_id.data))
                if comment:
                    if 'edit-comment' in comment.permissions(
                            g.user, g.permissions):
                        comment.message = commentform.message.data
                        comment.edited_at = datetime.utcnow()
                        flash(_("Your comment has been edited"), 'info')
                    else:
                        flash(_("You can only edit your own comments"), 'info')
                else:
                    flash(_("No such comment"), 'error')
            else:
                comment = Comment(user=g.user,
                                  commentspace=proposal.comments,
                                  message=commentform.message.data)
                if commentform.parent_id.data:
                    parent = Comment.query.get(int(commentform.parent_id.data))
                    if parent.user.email:
                        if parent.user == proposal.user:  # check if parent comment & proposal owner are same
                            if not g.user == parent.user:  # check if parent comment is by proposal owner
                                send_mail_info.append({
                                    'to':
                                    proposal.user.email or proposal.email,
                                    'subject':
                                    u"{space} Funnel: {proposal}".format(
                                        space=space.title,
                                        proposal=proposal.title),
                                    'template':
                                    'proposal_comment_reply_email.md'
                                })
                        else:  # send mail to parent comment owner & proposal owner
                            if not parent.user == g.user:
                                send_mail_info.append({
                                    'to':
                                    parent.user.email,
                                    'subject':
                                    u"{space} Funnel: {proposal}".format(
                                        space=space.title,
                                        proposal=proposal.title),
                                    'template':
                                    'proposal_comment_to_proposer_email.md'
                                })
                            if not proposal.user == g.user:
                                send_mail_info.append({
                                    'to':
                                    proposal.user.email or proposal.email,
                                    'subject':
                                    u"{space} Funnel: {proposal}".format(
                                        space=space.title,
                                        proposal=proposal.title),
                                    'template':
                                    'proposal_comment_email.md'
                                })

                    if parent and parent.commentspace == proposal.comments:
                        comment.parent = parent
                else:  # for top level comment
                    if not proposal.user == g.user:
                        send_mail_info.append({
                            'to':
                            proposal.user.email or proposal.email,
                            'subject':
                            u"{space} Funnel: {proposal}".format(
                                space=space.title, proposal=proposal.title),
                            'template':
                            'proposal_comment_email.md'
                        })
                proposal.comments.count += 1
                comment.votes.vote(g.user)  # Vote for your own comment
                db.session.add(comment)
                flash(_("Your comment has been posted"), 'info')
            db.session.commit()
            to_redirect = comment.url_for(proposal=proposal, _external=True)
            for item in send_mail_info:
                email_body = render_template(item.pop('template'),
                                             proposal=proposal,
                                             comment=comment,
                                             link=to_redirect)
                if item.get('to'):
                    # Sender is set to None to prevent revealing email.
                    send_mail(sender=None, body=email_body, **item)
            # Redirect despite this being the same page because HTTP 303 is required to not break
            # the browser Back button
            return redirect(to_redirect, code=303)
        elif request.form.get(
                'form.id') == 'delcomment' and delcommentform.validate():
            comment = Comment.query.get(int(delcommentform.comment_id.data))
            if comment:
                if 'delete-comment' in comment.permissions(
                        g.user, g.permissions):
                    comment.delete()
                    proposal.comments.count -= 1
                    db.session.commit()
                    flash(_("Your comment was deleted"), 'info')
                else:
                    flash(_("You did not post that comment"), 'error')
            else:
                flash(_("No such comment"), 'error')
            return redirect(proposal.url_for(), code=303)
    links = [
        Markup(linkify(unicode(escape(l))))
        for l in proposal.links.replace('\r\n', '\n').split('\n') if l
    ]
    if proposal.status != PROPOSALSTATUS.DRAFT:
        statusform = ProposalStatusForm(status=proposal.status)
    else:
        statusform = None

    return render_template(
        'proposal.html',
        space=space,
        proposal=proposal,
        comments=comments,
        commentform=commentform,
        delcommentform=delcommentform,
        votes_groups=proposal.votes_by_group(),
        PROPOSALSTATUS=PROPOSALSTATUS,
        links=links,
        statusform=statusform,
        part_a=space.proposal_part_a.get('title', 'Objective'),
        part_b=space.proposal_part_b.get('title', 'Description'),
        csrf_form=Form())
Example #19
0
 def invite(self):
     return {
         'membership':
         self.obj.current_access(datasets=('primary', 'related')),
         'form': Form(),
     }