def vote(cls, post_id: ObjectId, user_id: ObjectId, value: int) -> 'Vote': p = BasePost.find_one({"_id": post_id}) if p is None: raise NotFound("post not found") if isinstance(p, Comment): if value < 0: raise InvalidVote("comments can only be up-voted") v = cls.find_one({"post_id": post_id, "user_id": user_id}) if v: if value != v.value: v.value = value v.added_at = now() v.save() else: return v else: v = cls({"post_id": post_id, "user_id": user_id, "value": value}) v.save() p.recalculate_points() if p.submodel != "question": p = p.question p.update_last_activity() p.save(skip_callback=True) return v
def restore_answer_comment(question_id, answer_id, comment_id): c: Optional[Comment] = Comment.get(comment_id, "comment not found") a: Optional[Answer] = Answer.get(answer_id, "comment not found") q: Optional[Question] = Question.get(question_id, "comment not found") if a.parent_id != q._id or c.parent_id != a._id: raise NotFound("comment not found") restore_post(c) return json_response({"data": c.api_dict(COMMENT_FIELDS)})
def dismiss(event_id): user: User = get_user_from_app_context() event = Event.get(event_id, "event not found") if event.user_id != user._id: raise NotFound("event not found") if not event.dismissed: event.dismiss() return json_response({"data": event.api_dict()})
def accept_answer(question_id, answer_id): u: User = get_user_from_app_context() q: Optional[Question] = Question.get(question_id, "answer not found") a: Optional[Answer] = Answer.get(answer_id, "answer not found") if a.parent_id != q._id: raise NotFound("answer not found") if q.author_id != u._id: raise Forbidden("only question's author can accept answers") q.set_accepted_answer(a) return json_response({"data": a.api_dict(ANSWER_FIELDS)})
def create_answer_comment(question_id, answer_id): a: Optional[Answer] = Answer.get(answer_id, "answer not found") if a.parent_id != resolve_id(question_id): raise NotFound("answer not found") user: User = get_user_from_app_context() attrs = request.json if "body" not in attrs: raise ApiError("body is missing") c = a.create_comment({"body": attrs["body"], "author_id": user._id}) c.save() return json_response({"data": c.api_dict(COMMENT_FIELDS)})
def revoke_answer(question_id, answer_id): u: User = get_user_from_app_context() q: Optional[Question] = Question.get(question_id, "answer not found") a: Optional[Answer] = Answer.get(answer_id, "answer not found") if a.parent_id != q._id: raise NotFound("answer not found") if q.author_id != u._id: raise Forbidden("only question's author can revoke answers") if not a.accepted: raise NotAccepted("answer is not accepted so can't be revoked") q.set_accepted_answer(None) a.reload() return json_response({"data": a.api_dict(ANSWER_FIELDS)})
def bots(): bot_cfg = ctx.cfg.get("bot") if bot_cfg is None: raise NotFound("no bots are configured") bots = [] for net_type, conf in bot_cfg.items(): bots.append({ "network_type": net_type, "link": conf["link"], "name": conf["name"] }) return json_response({"bots": bots})
def vote_comment(question_id, comment_id): c: Optional[Comment] = Comment.get(comment_id, "comment not found") if c.parent_id != resolve_id(question_id): raise NotFound("comment not found") u: User = get_user_from_app_context() if c.author_id == u._id: raise Forbidden("you can't vote for your own comments") attrs = request.json if "value" not in attrs: raise ApiError("value field is mandatory") Vote.vote(c._id, u._id, attrs["value"]) c.reload() return json_response({"data": c.api_dict(fields=COMMENT_FIELDS)})
def vote_answer(question_id, answer_id): a: Optional[Answer] = Answer.get(answer_id, "answer not found") if a.parent_id != resolve_id(question_id): raise NotFound("answer not found") u: User = get_user_from_app_context() if a.author_id == u._id: raise Forbidden("you can't vote for your own answers") attrs = request.json if "value" not in attrs: raise ApiError("value field is mandatory") Vote.vote(a._id, u._id, attrs["value"]) a.reload() return json_response({"data": a.api_dict(fields=ANSWER_FIELDS)})
def get(cls, expression, raise_if_none=None): post: Optional[BasePost] = super().get(expression, raise_if_none) if post and post.deleted: if has_request_context(): user: User = get_user_from_app_context() # if user logged in and he is moderator or post.author # he can view deleted post if not user or (user._id != post.author_id and not user.moderator): post = None if post is None and raise_if_none: if isinstance(raise_if_none, str): raise NotFound(raise_if_none) else: raise raise_if_none return post
def restore_comment(question_id, comment_id): c: Optional[Comment] = Comment.get(comment_id, "comment not found") if c.parent_id != resolve_id(question_id): raise NotFound("comment not found") restore_post(c) return json_response({"data": c.api_dict(COMMENT_FIELDS)})
def restore_answer(question_id, answer_id): a: Optional[Answer] = Answer.get(answer_id, "answer not found") if a.parent_id != resolve_id(question_id): raise NotFound("answer not found") restore_post(a) return json_response({"data": a.api_dict(ANSWER_FIELDS)})