def unassign_achievement(): user = get_user_from_request() if not user.is_admin: return errors.no_access() json = request.get_json() if "users" not in json or "achievement" not in json: return errors.wrong_payload("users", "achievement") if len(json["users"]) == 0: return errors.wrong_payload("users") achievement = Achievement.get_or_none( Achievement.id == json["achievement"]) if achievement is None: return errors.wrong_payload("achievement") assign_errors = [] for u in json["users"]: user_to_unassign = User.get_or_none(User.id == u) if user_to_unassign is None: assign_errors.append(f"Cannot unassign achievement from user {u}") else: assign = AchievementUser.get_or_none(achievement=achievement, user=user_to_unassign) assign.delete_instance() return jsonify({"success": 1, "errors": assign_errors})
def refresh(): """Обновить токен""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") token = json["token"] actual_token = Token.get_or_none((Token.token == token) & (Token.token_type == "refresh")) if actual_token is None: return errors.token_invalid() if actual_token.valid_until < datetime.datetime.now(): return errors.token_outdated() user = actual_token.user token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, })
def leave_feedback(): """Оставить отзыв""" json = request.get_json() if "text" in json: Feedback.create(text=json["text"], user=get_user_from_request()) Telegram(current_app.config).notify_admin_channel( "Пользователь %s оставил отзыв: %s" % (get_user_from_request().username, json["text"]) ) success = Trello(current_app.config).create_card(json["text"]) if not success: return errors.feedback_trello_error() for user in User.get_admins(): Notification.create( user=user, created_date=datetime.datetime.now(), text="Пользователь %s оставил отзыв: %s" % (get_user_from_request().username, json["text"]), object_type="feedback", ) return jsonify({"success": 1}) else: return errors.wrong_payload("text")
def edit_comment_in_entry(url, entry_url, comment_id): """Редактировать комментарий""" jam = Jam.get_or_none(Jam.url == url) if jam is None: return errors.not_found() entry = JamEntry.get_or_none(JamEntry.url == entry_url) if entry is None: return errors.not_found() user = get_user_from_request() if user is None: return errors.not_authorized() json = request.get_json() text = None if "text" in json: text = sanitize(json.get("text")) else: return errors.wrong_payload("text") comment = _edit_comment(comment_id, user, text) return jsonify({"success": 1, "comment": comment.to_json()})
def login(): """Авторизация""" json = request.get_json() has_login = "******" in json or "email" in json has_password = "******" in json if not has_login: return errors.wrong_payload("username", "email") if not has_password: return errors.wrong_payload("password") user = None if "username" in json: username = json["username"] user = User.get_or_none(User.username == username) if user is None: user = User.get_or_none(User.email == username) elif "email" in json: email = json["email"] user = User.get_or_none(User.username == email) if user is None: user = User.get_or_none(User.email == email) password = json["password"] if user is not None and authorize(user, password): token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, }) return errors.not_authorized()
def mark_as_read(): """Пометить уведомления как прочитанные""" user = get_user_from_request() json = request.get_json() if "ids" in json: for i in json["ids"]: Notification.mark_notification_as_readed(user, i) else: return errors.wrong_payload("ids") return jsonify({"success": 1})
def suggestion(): """Получить список предлагаемых тегов для автодополнения""" json = request.get_json() if "title" not in json: return errors.wrong_payload("title") title = json["title"] query = Tag.select().where(Tag.title.contains(title)) return jsonify({"success": 1, "tags": [t.to_json() for t in query]})
def get(): search_type = request.args.get("type") search_query = request.args.get("q") limit = max(1, min(int(request.args.get("limit") or 20), 100)) type = 0 if not search_query or len(search_query) == 0: return errors.wrong_payload("q") if search_type == "post": query = Post.get_public_posts().where( Post.title.contains(search_query) | Post.text.contains(search_query)) type = 3 elif search_type == "blog": query = Blog.get_public_blogs().where( Blog.title.contains(search_query) | Blog.description.contains(search_query)) type = 2 elif search_type == "user": query = User.select().where( User.username.contains(search_query) | User.name.contains(search_query)) type = 1 else: return errors.wrong_payload("type") paginated_query = PaginatedQuery(query, paginate_by=limit) items = [item.to_json() for item in paginated_query.get_object_list()] items = [ Vote.add_votes_info(i, type, get_user_from_request()) for i in items ] return jsonify({ "success": 1, "result": items, "meta": { "page_count": paginated_query.get_page_count() }, })
def register(): """Регистрация""" json = request.get_json() missed_payload = [] if "username" not in json: missed_payload.append("username") if "password" not in json: missed_payload.append("password") if "email" not in json: missed_payload.append("email") if "name" not in json: missed_payload.append("name") if len(missed_payload) > 0: return errors.wrong_payload(missed_payload) username = json["username"] password = json["password"] email = json["email"] name = json["name"] user = User.get_or_none(User.username == username) if user is not None: return errors.registration_username_busy() user = User.get_or_none(User.email == email) if user is not None: return errors.registration_email_busy() user = User.create( username=username, password=salted(password, current_app.config["PASSWORD_SALT"]), email=email, registration_date=datetime.datetime.now(), last_active_date=datetime.datetime.now(), name=name, ) token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, })
def assign_achievement(): user = get_user_from_request() if not user.is_admin: return errors.no_access() json = request.get_json() if "users" not in json or "achievement" not in json: return errors.wrong_payload("users", "achievement") if len(json["users"]) == 0: return errors.wrong_payload("users") achievement = Achievement.get_or_none( Achievement.id == json["achievement"]) if achievement is None: return errors.wrong_payload("achievement") assign_errors = [] for u in json["users"]: user_to_assign = User.get_or_none(User.id == u) if user_to_assign is None: assign_errors.append(f"Cannot assign achievement to user {u}") else: AchievementUser.create( achievement=achievement, user=user_to_assign, comment=json.get("comment", None), ) Notification.create( user=user_to_assign, created_date=datetime.datetime.now(), text=f"Новая награда: {achievement.title}", object_type="achievement", object_id=achievement.id, ) return jsonify({"success": 1, "errors": assign_errors})
def create_jam(): """Создать джем""" user = get_user_from_request() json = request.json required_fields = ["title", "url", "description", "short_description"] missed_fields = [] for field in required_fields: if field not in json: missed_fields.append(field) if len(missed_fields) > 0: return errors.wrong_payload(missed_fields) title = json["title"] url = json["url"] description = json["description"] short_description = json["short_description"] image = json.get("logo", None) start_date = json.get("start_date", None) end_date = json.get("end_date", None) criterias = json.get("criterias", []) if Jam.get_or_none(Jam.url == url) is not None: return errors.jam_url_already_taken() blog = create_blog_for_jam(user, title, url, image) jam = Jam.create( created_date=datetime.datetime.now(), updated_date=datetime.datetime.now(), creator=user, blog=blog, title=title, url=url, short_description=sanitize(short_description), description=sanitize(description), start_date=start_date, end_date=end_date, ) if image: jam.logo = Content.get_or_none(Content.id == image) jam.save() for criteria in criterias: JamCriteria.create(jam=jam, title=criteria["title"], order=criteria["order"]) return jsonify({"success": 1, "jam": jam.to_json()})
def new_pass(): """Поменять пароль""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") if "password" not in json: return errors.wrong_payload("password") token = Token.get_or_none(Token.token == json["token"]) if token is None: return errors.pass_recover_wrong_token() if token.valid_until < datetime.datetime.now(): return errors.token_outdated() user = token.user password = json["password"] user.password = salted(password, current_app.config["PASSWORD_SALT"]) user.save() token.delete_instance() return jsonify({"success": 1})
def add_achievement(): user = get_user_from_request() if not user.is_admin: return errors.no_access() json = request.get_json() if "title" not in json or "image" not in json: return errors.wrong_payload("title", "image") if len(json["title"]) == 0: return errors.wrong_payload("title") content = Content.get_or_none(Content.id == json["image"]) if content: if not content.is_image: return errors.achievement_is_not_image() elif not content.is_small_image: return errors.achievement_too_large() achievement = Achievement.create(title=json["title"], image=content) return jsonify({"success": 1, "achievement": achievement.to_json()})
def valid(): """Проверить, валиден ли токен""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") token = json["token"] actual_token = Token.get_or_none((Token.token == token) & (Token.token_type == "access")) if actual_token is None: return errors.token_invalid() if actual_token.valid_until < datetime.datetime.now(): return errors.token_outdated() return jsonify({"success": 1})
def recover_pass(): """Сделать запрос на восстановление пароля""" json = request.get_json() if "email" not in json: return errors.wrong_payload("email") user = User.get_or_none(User.email == json["email"]) if user is None: return errors.pass_recover_no_user() t = Token.generate_recover_token(user) url = current_app.config["HOSTNAME"] + "/recover-pass?token=" + t.token sender = EmailSender(current_app.config) sender.recover_pass(url, user) return jsonify({"success": 1})
def comments(url): """Получить список комментариев для поста или добавить новый комментарий""" post = Post.get_or_none(Post.url == url) if post is None: return errors.not_found() if request.method == "GET": user = get_user_from_request() if post.is_draft: if user is None: return errors.no_access() if post.creator != user: return errors.no_access() return _get_comments("post", post.id, user) elif request.method == "POST": user = get_user_from_request() if user is None: return errors.not_authorized() json = request.get_json() if "text" in json: text = sanitize(json.get("text")) else: return errors.wrong_payload("text") parent_id = None if "parent" in json: parent_id = json["parent"] parent = None if parent_id: parent = Comment.get_or_none(Comment.id == parent_id) comment = _add_comment("post", post.id, user, text, parent_id) if user.id != post.creator.id: t = "Пользователь {0} оставил комментарий к вашему посту {1}: {2}" notification_text = t.format(user.visible_name, post.title, text) Notification.create( user=post.creator, created_date=datetime.datetime.now(), text=notification_text, object_type="comment", object_id=comment.id, ) if parent is not None: if user.id != parent.creator.id: t = "Пользователь {0} ответил на ваш комментарий {1}: {2}" notification_text = t.format(user.visible_name, parent.text, text) Notification.create( user=parent.creator, created_date=datetime.datetime.now(), text=notification_text, object_type="comment", object_id=comment.id, ) return jsonify({"success": 1, "comment": comment.to_json()})