def add_votes(url, entry_url): """Получить оценки для заявки на джем""" 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() JamEntryVote.delete().where((JamEntryVote.entry == entry) & ( JamEntryVote.voter == get_user_from_request())).execute() json = request.json json_criterias = json for criteria_id, vote in json_criterias.items(): JamEntryVote.create( entry=entry, voter=get_user_from_request(), vote=vote, criteria=criteria_id, ) return jsonify({"success": 1})
def _get_post(post): if post is None: return errors.not_found() if post.is_draft: user = get_user_from_request() if user is None: return errors.no_access() if post.creator != user: return errors.no_access() user = get_user_from_request() if post.blog is not None: # workaround, delete later. Sometime in the past you can save post # without blog, so this check will fail. has_access = Blog.has_access(post.blog, user) if not has_access: return errors.no_access() post_dict = post.to_json() post_dict = Vote.add_votes_info(post_dict, 3, user) entries = JamEntry.get_entries_for_post(post) post_dict["jam_entries"] = [e.to_json() for e in entries] return jsonify({"success": 1, "post": post_dict})
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 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 _edit_post(post): if post is None: return errors.not_found() user = get_user_from_request() role = Blog.get_user_role(post.blog, user) if post.creator == user or role == 1 or user.is_admin: json = request.get_json() error = set_blog(post, json, user) if error is not None: error_response = { BlogError.NoBlog: errors.blog_not_found(), BlogError.NoAccess: errors.blog_no_access(), }[error] return error_response fill_post_from_json(post, json) if not validate_url(post): return errors.post_url_already_taken() post.save() set_tags_for_post(post, json) manage_jam_entries(post, json) return jsonify({"success": 1, "post": post.to_json()}) else: return errors.no_access()
def _delete_post(post): if post is None: return errors.not_found() user = get_user_from_request() if post.creator == user or user.is_admin: Comment.delete().where((Comment.object_type == "post") & (Comment.object_id == post.id)).execute() TagMark.delete().where(TagMark.post == post).execute() post.delete_instance() return jsonify({"success": 1}) if post.blog is None: return errors.no_access() role = Blog.get_user_role(post.blog, user) # only blog owner can delete posts if role != 1: return errors.no_access() Comment.delete().where((Comment.object_type == "post") & (Comment.object_id == post.id)).execute() TagMark.delete().where(TagMark.post == post).execute() post.delete_instance() return jsonify({"success": 1})
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 current_user(): """Получить текущего пользователя или отредактировать профиль""" user = get_user_from_request() if request.method == "POST": json = request.get_json() user.email = json.get("email", user.email) user.name = json.get("name", user.name) user.about = sanitize(json.get("about", user.about)) user.birthday = json.get("birthday", user.birthday) if "avatar" in json: content = Content.get_or_none(Content.id == json["avatar"]) if content: if not content.is_image: return errors.user_avatar_is_not_image() elif content.size > 1024 * 500: # 500kb return errors.user_avatar_too_large() else: user.avatar = content user.save() user = User.get(User.id == user.id) return jsonify({"success": 1, "user": user.to_json_with_email()})
def posts(url): """Получить список постов для блога""" blog = Blog.get_or_none(Blog.url == url) if blog is None: return errors.not_found() user = get_user_from_request() has_access = Blog.has_access(blog, user) if not has_access: return errors.no_access() query = Post.get_posts_for_blog(blog) limit = max(1, min(int(request.args.get("limit") or 20), 100)) paginated_query = PaginatedQuery(query, paginate_by=limit) posts = [p.to_json() for p in paginated_query.get_object_list()] posts = [Vote.add_votes_info(p, 3, user) for p in posts] return jsonify( { "success": 1, "posts": posts, "meta": {"page_count": paginated_query.get_page_count()}, } )
def create_post(): """Создать пост""" user = get_user_from_request() post = Post( created_date=datetime.datetime.now(), updated_date=datetime.datetime.now(), creator=user, ) json = request.get_json() url = json["url"] if Post.get_or_none(Post.url == url) is not None: return errors.post_url_already_taken() error = set_blog(post, json, user) if error is not None: error_response = { BlogError.NoBlog: errors.blog_not_found(), BlogError.NoAccess: errors.blog_no_access(), }[error] return error_response fill_post_from_json(post, json) post.save() set_tags_for_post(post, json) manage_jam_entries(post, json) return jsonify({"success": 1, "post": post.to_json()})
def test_notification(): """Создать тестовое уведомление""" user = get_user_from_request() n = Notification.create(user=user, created_date=datetime.datetime.now(), text="Это тестовое уведомление") return jsonify({"success": 1, "notification": n.to_json()})
def user_drafts(): """Получить список черновиков""" user = get_user_from_request() query = Post.get_user_drafts(user) limit = max(1, min(int(request.args.get("limit") or 20), 100)) paginated_query = PaginatedQuery(query, paginate_by=limit) posts = [p.to_json() for p in paginated_query.get_object_list()] posts = [Vote.add_votes_info(p, 3, get_user_from_request()) for p in posts] return jsonify({ "success": 1, "posts": posts, "meta": { "page_count": paginated_query.get_page_count() }, })
def get_feedback(): """Получить список отзывов""" user = get_user_from_request() if user.is_admin: return jsonify( {"success": 1, "feedback": [f.to_json() for f in Feedback.select()]} ) else: return errors.no_access()
def invites(url): """Пригласить пользователя или принять инвайт""" blog = Blog.get_or_none(Blog.url == url) if blog is None: return errors.not_found() user = get_user_from_request() json = request.get_json() if "invite" in json: invite = BlogInvite.get_or_none(BlogInvite.id == json["invite"]) if invite is None: return errors.invite_not_found() if invite.user_to.id != user.id: return errors.no_access() invite.is_accepted = True invite.save() BlogParticipiation.create(blog=invite.blog, user=user, role=invite.role) return jsonify({"success": 1}) elif "user" in json and "role" in json: user_to = User.get_or_none(User.id == json["user"]) if user_to is None: return errors.not_found() role = Blog.get_user_role(blog, user) if role is None: return errors.no_access() role_to = json["role"] roles = {"owner": 1, "writer": 2, "reader": 3} if role_to not in roles: return errors.invite_wrong_role() role_to = roles[role_to] if role > role_to: return errors.no_access() invite = BlogInvite.create( blog=blog, user_from=user, user_to=user_to, role=role_to ) Notification.create( user=user, created_date=datetime.datetime.now(), text='Вас пригласили в блог "{0}"'.format(blog.title), object_type="invite", object_id=invite.id, ) return jsonify({"success": 1, "invite": invite.id})
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 edit_my_entry(url): """Редактировать заявку на джем от текущего пользователя""" user = get_user_from_request() jam = Jam.get_or_none(Jam.url == url) if jam is None: return errors.not_found() entry = JamEntry.get_or_none(jam=jam, creator=user) if entry is None: return errors.not_found() json = request.json title = json.get("title", entry.title) url = json.get("url", entry.url) description = json.get("info", entry.info) short_description = json.get("short_info", entry.short_info) links = json.get("links", []) has_entry_with_same_url = False entries_with_same_url = JamEntry.select().where((JamEntry.url == url) & (JamEntry.jam == jam)) for e in entries_with_same_url: if e.id != entry.id: has_entry_with_same_url = True if has_entry_with_same_url: return errors.jam_entry_url_already_taken() image = None if "logo" in json: image = json["logo"] entry.title = title entry.url = url entry.info = sanitize(description) entry.short_info = sanitize(short_description) if image: entry.logo = Content.get_or_none(Content.id == image) JamEntryLink.delete().where(JamEntryLink.entry == entry).execute() for link in links: JamEntryLink.create( entry=entry, title=link["title"], href=link["href"], order=link["order"], ) entry.save() return jsonify({"success": 1, "entry": _entry_to_json(entry)})
def my_entry(url): """Получить заявку на джем от текущего пользователя""" user = get_user_from_request() jam = Jam.get_or_none(Jam.url == url) if jam is None: return errors.not_found() entry = JamEntry.get_or_none(jam=jam, creator=user) return jsonify({"success": 1, "entry": _entry_to_json(entry)})
def get_owned(): query = Content.get_user_files(get_user_from_request()) limit = max(1, min(int(request.args.get("limit") or 20), 100)) paginated = PaginatedQuery(query, paginate_by=limit) return jsonify({ "success": 1, "files": [p.to_json() for p in paginated.get_object_list()], "meta": { "page_count": paginated.get_page_count() }, })
def user(username): """Получить подробную информацию о пользователе""" user = User.get_or_none(User.username == username) if user is None: return errors.not_found() user_dict = user.to_json() user_dict = Vote.add_votes_info(user_dict, 1, get_user_from_request()) user_dict = Achievement.add_achievements(user_dict) return jsonify({"success": 1, "user": user_dict})
def upload(): """Загрузить файл""" import magic if "file" not in request.files: return errors.content_no_file() uploaded_file = request.files["file"] if uploaded_file.filename == "": return errors.content_no_file() if not allowed_file(uploaded_file.filename): return errors.content_forbidden_extension() file_content = uploaded_file.read(MAX_FILE_SIZE + 1) size = len(file_content) if size > MAX_FILE_SIZE: return errors.content_file_size_exceeded() uploaded_file.seek(0) name = hashlib.md5(uploaded_file.read()).hexdigest() uploaded_file.seek(0) _, ext = ntpath.splitext(uploaded_file.filename) today = datetime.date.today() user = get_user_from_request() filename = os.path.join( current_app.config["UPLOAD_FOLDER"], str(user.id) + "/" + str(today.year) + "/" + str(today.month) + "/", ) os.makedirs(filename, exist_ok=True) new_path = filename + name + ext uploaded_file.save(new_path) full_path = os.path.abspath(new_path) mime = magic.from_file(full_path, mime=True) content = Content.create(user=user.id, path=full_path, size=size, mime=mime) return jsonify({"success": 1, "file": content.to_json()})
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 leave(url): """Не участвовать в джеме""" user = get_user_from_request() jam = Jam.get_or_none(Jam.url == url) if jam is None: return errors.not_found() entry = JamEntry.get_or_none(jam=jam, creator=user) if entry: entry.is_archived = True entry.save() return jsonify({"success": 1})
def _jam_to_json(jam): jam_dict = jam.to_json() jam_dict["is_participiating"] = False user = get_user_from_request() if user: entry = JamEntry.get_or_none(jam=jam, creator=user) if entry: jam_dict["is_participiating"] = True jam_dict["participators"] = JamEntry.select().where( JamEntry.jam == jam).count() return jam_dict
def resolve(id): """Пометить отзыв как решенный""" user = get_user_from_request() if user.is_admin: f = Feedback.get_or_none(Feedback.id == id) if f is None: return errors.not_found() f.is_resolved = True f.save() return jsonify({"success": 1}) else: return errors.no_access()
def get_new(): """Получить список новых уведомлений""" query = Notification.get_user_unread_notifications(get_user_from_request()) limit = max(1, min(int(request.args.get("limit") or 20), 100)) paginated = PaginatedQuery(query, paginate_by=limit) return jsonify({ "success": 1, "notifications": [p.to_json() for p in paginated.get_object_list()], "meta": { "page_count": paginated.get_page_count() }, })
def get_criterias(url, entry_url): """Получить оценки для заявки на джем""" 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() criterias = JamEntryVote.select().where((JamEntryVote.entry == entry) & ( JamEntryVote.voter == get_user_from_request())) return jsonify({"success": 1, "criterias": _criterias_to_json(criterias)})
def delete_blog(url): """Удалить блог""" blog = Blog.get_or_none(Blog.url == url) if blog is None: return errors.not_found() user = get_user_from_request() role = Blog.get_user_role(blog, user) if role != 1: return errors.no_access() blog.delete_instance() return jsonify({"success": 1})
def join(url): """Присоеденится к блогу. Работает только с открытми блогами""" blog = Blog.get_or_none(Blog.url == url) if blog is None: return errors.not_found() if blog.blog_type != 1: return errors.no_access() user = get_user_from_request() if user is None: return errors.not_authorized() if BlogParticipiation.get_or_none(blog=blog, user=user) is None: BlogParticipiation.create(blog=blog, user=user, role=3) return jsonify({"success": 1})
def get_single_blog(url): """Получить блог по указанному url""" blog = Blog.get_or_none(Blog.url == url) if blog is None: return errors.not_found() user = get_user_from_request() has_access = Blog.has_access(blog, user) if not has_access: return errors.no_access() blog_dict = blog.to_json() blog_dict = Vote.add_votes_info(blog_dict, 2, user) return jsonify({"success": 1, "blog": blog_dict})
def finish(url): """Закончить джем""" user = get_user_from_request() jam = Jam.get_or_none(Jam.url == url) if jam is None: return errors.not_found() if jam.creator != user: return errors.no_access() jam.status = 2 jam.save() return jsonify({"success": 1})