def tags_subscribe(): user: User = get_user_from_app_context() tags = request.json.get("tags") if tags is None: raise InputDataError("tags field is mandatory") tags = list(set(tags)) # make sure tags are unique ts = user.tag_subscription ts.tags = tags ts.save() json_response({"data": ts.to_dict(fields=TAG_SUBSCRIPTION_FIELDS)})
def create(): user: User = get_user_from_app_context() attrs = request.json attrs["author_id"] = user._id q = Question(attrs) q.save() return json_response({"data": q.api_dict(fields=QUESTION_FIELDS)})
def users_subscription(): user: User = get_user_from_app_context() us = user.user_subscription users = [] for user in us.subscribed_to: users.append(user.to_dict(fields=USER_FIELDS)) return json_response({"data": users})
def suggest(): import re query = {} prefix = request.values.get("prefix") if prefix: try: prefix = re.compile("^" + prefix) query = { "$or": [ { "username": prefix }, { "first_name": prefix }, { "last_name": prefix }, ] } except re.error: pass users = User.find(query).sort("username", 1).limit(10) users = [ user.to_dict(fields=["username", "first_name", "last_name"]) for user in users ] return json_response({"data": users})
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 index(): routes = [] for rule in app.flask.url_map.iter_rules(): routes.append({ "endpoint": rule.endpoint, "route": rule.rule, "methods": rule.methods }) return json_response({"routes": routes})
def dismiss_all(): user: User = get_user_from_app_context() Event.update_many({ "user_id": user._id, "dismissed": False }, {"$set": { "dismissed": True }}) return json_response({"status": "dismissed"})
def search(): query = request.values.get("q") if query is None: raise InputDataError("'q' param is missing") posts = paginated(search_posts(query), transform=transform) author_ids = {ObjectId(x["author_id"]) for x in posts["data"]} authors = User.find({"_id": {"$in": list(author_ids)}}).all() return json_response({"results": posts, "authors": {"data": authors}})
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_comment(question_id): q = Question.get(question_id, "question not found") user: User = get_user_from_app_context() attrs = request.json if "body" not in attrs: raise ApiError("body is missing") c = q.create_comment({"body": attrs["body"], "author_id": user._id}) c.save() return json_response({"data": c.api_dict(COMMENT_FIELDS)})
def create_answer(question_id): q: Optional[Question] = Question.get(question_id, "question not found") user: User = get_user_from_app_context() attrs = request.json if "body" not in attrs: raise ApiError("body is missing") a = q.create_answer({"author_id": user._id, "body": attrs["body"]}) a.save() return json_response({"data": a.api_dict()})
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 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 vote_question(question_id): q: Optional[Question] = Question.get(question_id, "question not found") u: User = get_user_from_app_context() if q.author_id == u._id: raise Forbidden("you can't vote for your own question") attrs = request.json if "value" not in attrs: raise ApiError("value field is mandatory") Vote.vote(q._id, u._id, attrs["value"]) q.reload() return json_response({"data": q.api_dict(fields=QUESTION_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 app_info(): results = dict(app={ "name": "Knowledge Hub", "version": app.version }, mongodb=ctx.db.mongodb_info(), cache={ "type": ctx.cache.__class__.__name__, "active": check_cache() }, flask_version=flask.__version__) for shard_id, shard in ctx.db.shards.items(): results["mongodb"]["shards"][ shard_id] = shard.conn.client.server_info() return json_response({"app_info": results})
def index(): u: User = get_user_from_app_context() if "_sort" in request.values: srt = request.values["_sort"] else: srt = "rating" sortExpr = SORT_MAP.get(srt) if sortExpr is None: raise ApiError(f"unknown sort operator \"{srt}\"") if get_boolean_request_param("_mine"): if u: # only mine posts query = {"author_id": u._id} else: # nothing to show, user is not logged in query = {"_id": NilObjectId} else: # otherwise show all not deleted posts query = { "$or": [ { "deleted": False }, ] } if u: # if user is logged in, he can view his own deleted posts query["$or"].append({"author_id": u._id}) questions = Question.find(query).sort(sortExpr) results = paginated( questions, transform=default_transform(fields=QUESTION_LIST_FIELDS)) author_ids = set() for q in results["data"]: author_ids.add(resolve_id(q["author_id"])) authors = User.find({"_id": {"$in": list(author_ids)}}) return json_response({"questions": results, "authors": {"data": authors}})
def show(tagname): tag = Tag.get(tagname, "tag not found") return json_response({"data": tag.to_dict()})
def unsubscribe(tagname): Tag.get(tagname, "tag not found") user: User = get_user_from_app_context() user.unsubscribe_from_tag(tagname) return json_response({"data": user.tag_subscription.to_dict()})
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(question_id): q: Optional[Question] = Question.get(question_id, "question not found") restore_post(q) return json_response({"data": q.api_dict(QUESTION_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)})
def index(): user: User = get_user_from_app_context() events = user.get_new_events().sort("created_at", -1) return json_response( paginated(events, limit=5, transform=lambda event: event.api_dict()))
def update_settings(): user: User = get_user_from_app_context() user.update(request.json) return json_response({ "data": account_dict(user), })
def replace_subscription(): if "tags" not in request.json: raise ApiError("tags field is mandatory") user: User = get_user_from_app_context() user.replace_tags(request.json["tags"]) return json_response({"data": user.tag_subscription.to_dict()})
def oauth(): return json_response({"providers": BaseProvider.list_provider_info()})
def show(question_id): q: Optional[Question] = Question.get(question_id, "question not found") q.inc_views() return json_response({"data": q.everything()})