Example #1
0
def post_comment_reply(request: Request, markdown: str) -> dict:
    """Post a reply to a comment with Intercooler."""
    parent_comment = request.context
    new_comment = Comment(
        topic=parent_comment.topic,
        author=request.user,
        markdown=markdown,
        parent_comment=parent_comment,
    )
    request.db_session.add(new_comment)

    request.db_session.add(
        LogComment(LogEventType.COMMENT_POST, request, new_comment))

    if CommentNotification.should_create_reply_notification(new_comment):
        notification = CommentNotification(
            parent_comment.user, new_comment,
            CommentNotificationType.COMMENT_REPLY)
        request.db_session.add(notification)

    _mark_comment_read_from_interaction(request, parent_comment)

    # commit and then re-query the new comment to get complete data
    request.tm.commit()

    new_comment = (request.query(Comment).join_all_relationships().filter_by(
        comment_id=new_comment.comment_id).one())

    return {"comment": new_comment}
Example #2
0
def put_vote_comment(request: Request) -> dict:
    """Vote on a comment with Intercooler."""
    comment = request.context

    savepoint = request.tm.savepoint()

    new_vote = CommentVote(request.user, comment)
    request.db_session.add(new_vote)

    _mark_comment_read_from_interaction(request, comment)

    request.db_session.add(
        LogComment(LogEventType.COMMENT_VOTE, request, comment))

    try:
        # manually flush before attempting to commit, to avoid having all objects
        # detached from the session in case of an error
        request.db_session.flush()
        request.tm.commit()
    except IntegrityError:
        # the user has already voted on this comment
        savepoint.rollback()

    # re-query the comment to get updated data
    comment = (request.query(Comment).join_all_relationships().filter_by(
        comment_id=comment.comment_id).one())

    return {"name": "vote", "subject": comment, "is_toggled": True}
Example #3
0
def post_toplevel_comment(request: Request, markdown: str) -> dict:
    """Post a new top-level comment on a topic with Intercooler."""
    topic = request.context

    new_comment = Comment(topic=topic, author=request.user, markdown=markdown)
    request.db_session.add(new_comment)

    request.db_session.add(LogComment(LogEventType.COMMENT_POST, request, new_comment))

    if CommentNotification.should_create_reply_notification(new_comment):
        notification = CommentNotification(
            topic.user, new_comment, CommentNotificationType.TOPIC_REPLY
        )
        request.db_session.add(notification)

    # commit and then re-query the new comment to get complete data
    request.tm.commit()

    new_comment = (
        request.query(Comment)
        .join_all_relationships()
        .filter_by(comment_id=new_comment.comment_id)
        .one()
    )

    return {"comment": new_comment, "topic": topic}
Example #4
0
def delete_comment_remove(request: Request) -> dict:
    """Un-remove a comment with Intercooler."""
    comment = request.context

    comment.is_removed = False
    request.db_session.add(LogComment(LogEventType.COMMENT_UNREMOVE, request, comment))

    return {"name": "remove", "subject": comment, "is_toggled": False}
Example #5
0
def post_comment_on_topic(request: Request, markdown: str) -> HTTPFound:
    """Post a new top-level comment on a topic."""
    topic = request.context

    new_comment = Comment(topic=topic, author=request.user, markdown=markdown)
    request.db_session.add(new_comment)

    request.db_session.add(
        LogComment(LogEventType.COMMENT_POST, request, new_comment))

    if CommentNotification.should_create_reply_notification(new_comment):
        notification = CommentNotification(topic.user, new_comment,
                                           CommentNotificationType.TOPIC_REPLY)
        request.db_session.add(notification)

    raise HTTPFound(location=topic.permalink)
Example #6
0
def delete_vote_comment(request: Request) -> dict:
    """Remove the user's vote from a comment with Intercooler."""
    comment = request.context

    request.query(CommentVote).filter(
        CommentVote.comment == comment,
        CommentVote.user == request.user).delete(synchronize_session=False)

    _mark_comment_read_from_interaction(request, comment)

    request.db_session.add(
        LogComment(LogEventType.COMMENT_UNVOTE, request, comment))

    # manually commit the transaction so triggers will execute
    request.tm.commit()

    # re-query the comment to get updated data
    comment = (request.query(Comment).join_all_relationships().filter_by(
        comment_id=comment.comment_id).one())

    return {"name": "vote", "subject": comment, "is_toggled": False}
Example #7
0
def post_comment_reply(request: Request, markdown: str) -> dict:
    """Post a reply to a comment with Intercooler."""
    parent_comment = request.context

    wait_mins = _reply_wait_minutes(request, request.user, parent_comment.user)
    if wait_mins:
        incr_counter("comment_back_and_forth_warnings")
        raise HTTPUnprocessableEntity(
            f"You can't reply to this user yet. Please wait {wait_mins} minutes."
        )

    new_comment = Comment(
        topic=parent_comment.topic,
        author=request.user,
        markdown=markdown,
        parent_comment=parent_comment,
    )
    request.db_session.add(new_comment)

    request.db_session.add(
        LogComment(LogEventType.COMMENT_POST, request, new_comment))

    if CommentNotification.should_create_reply_notification(new_comment):
        notification = CommentNotification(
            parent_comment.user, new_comment,
            CommentNotificationType.COMMENT_REPLY)
        request.db_session.add(notification)

    _mark_comment_read_from_interaction(request, parent_comment)

    # commit and then re-query the new comment to get complete data
    request.tm.commit()

    new_comment = (request.query(Comment).join_all_relationships().filter_by(
        comment_id=new_comment.comment_id).one())

    return {"comment": new_comment}
Example #8
0
def post_group_topics(
    request: Request,
    title: str,
    markdown: str,
    link: str,
    tags: str,
    confirm_repost: bool,
) -> Union[HTTPFound, Response]:
    """Post a new topic to a group."""
    group = request.context

    if link:
        # check to see if this link has been posted before
        previous_topics = (request.query(Topic).filter(
            Topic.link == link).order_by(desc(
                Topic.created_time)).limit(5).all())

        if previous_topics and not confirm_repost:
            # Render partial form for Intercooler.js request, whole page for normal POST
            # (I don't like this much, there must be a better way to handle this)
            if "X-IC-Request" in request.headers:
                template = "tildes:templates/includes/new_topic_form.jinja2"
            else:
                template = "tildes:templates/new_topic.jinja2"

            return render_to_response(
                template,
                {
                    "group": group,
                    "title": title,
                    "link": link,
                    "markdown": markdown,
                    "tags": tags,
                    "previous_topics": previous_topics,
                },
                request=request,
            )

        new_topic = Topic.create_link_topic(group=group,
                                            author=request.user,
                                            title=title,
                                            link=link)

        # if they specified both a link and markdown, use the markdown to post an
        # initial comment on the topic
        if markdown:
            new_comment = Comment(topic=new_topic,
                                  author=request.user,
                                  markdown=markdown)
            request.db_session.add(new_comment)

            request.db_session.add(
                LogComment(LogEventType.COMMENT_POST, request, new_comment))
    else:
        new_topic = Topic.create_text_topic(group=group,
                                            author=request.user,
                                            title=title,
                                            markdown=markdown)

    try:
        new_topic.tags = tags.split(",")
    except ValidationError:
        raise ValidationError({"tags": ["Invalid tags"]})

    # remove any tag that's the same as the group's name
    new_topic.tags = [tag for tag in new_topic.tags if tag != str(group.path)]

    request.apply_rate_limit("topic_post")

    request.db_session.add(new_topic)

    request.db_session.add(
        LogTopic(LogEventType.TOPIC_POST, request, new_topic))

    # if the user added tags to the topic, show the field by default in the future
    if tags and not request.user.show_tags_on_new_topic:
        request.user.show_tags_on_new_topic = True
        request.db_session.add(request.user)

    # flush the changes to the database so the new topic's ID is generated
    request.db_session.flush()

    raise HTTPFound(location=new_topic.permalink)