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}
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}
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}
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}
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)
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}
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}
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)