示例#1
0
def serialize_post(post, authenticated_user):
    if not post:
        return None

    ret = {
        'id': post.post_id,
        'creationTime': post.creation_time,
        'lastEditTime': post.last_edit_time,
        'safety': SAFETY_MAP[post.safety],
        'source': post.source,
        'type': TYPE_MAP[post.type],
        'checksum': post.checksum,
        'fileSize': post.file_size,
        'canvasWidth': post.canvas_width,
        'canvasHeight': post.canvas_height,
        'contentUrl': get_post_content_url(post),
        'thumbnailUrl': get_post_thumbnail_url(post),
        'flags': post.flags,
        'tags': [tag.first_name for tag in post.tags],
        'relations': [rel.post_id for rel in post.relations],
        'notes': sorted(serialize_note(note) for note in post.notes),
        'user': users.serialize_user(post.user, authenticated_user),
        'score': post.score,
        'featureCount': post.feature_count,
        'lastFeatureTime': post.last_feature_time,
        'favoritedBy': [users.serialize_user(rel.user, authenticated_user) \
            for rel in post.favorited_by],
        'hasCustomThumbnail': files.has(get_post_thumbnail_backup_path(post)),
    }

    if authenticated_user:
        ret['ownScore'] = scores.get_score(post, authenticated_user)

    return ret
示例#2
0
def serialize_post(post, auth_user, options=None):
    return util.serialize_entity(
        post,
        {
            'id': lambda: post.post_id,
            'version': lambda: post.version,
            'creationTime': lambda: post.creation_time,
            'lastEditTime': lambda: post.last_edit_time,
            'safety': lambda: SAFETY_MAP[post.safety],
            'source': lambda: post.source,
            'type': lambda: TYPE_MAP[post.type],
            'mimeType': lambda: post.mime_type,
            'checksum': lambda: post.checksum,
            'fileSize': lambda: post.file_size,
            'canvasWidth': lambda: post.canvas_width,
            'canvasHeight': lambda: post.canvas_height,
            'contentUrl': lambda: get_post_content_url(post),
            'thumbnailUrl': lambda: get_post_thumbnail_url(post),
            'flags': lambda: post.flags,
            'tags': lambda: [
                tag.names[0].name for tag in tags.sort_tags(post.tags)],
            'relations': lambda: sorted(
                {
                    post['id']:
                        post for post in [
                            serialize_micro_post(rel, auth_user)
                            for rel in post.relations]
                }.values(),
                key=lambda post: post['id']),
            'user': lambda: users.serialize_micro_user(post.user, auth_user),
            'score': lambda: post.score,
            'ownScore': lambda: scores.get_score(post, auth_user),
            'ownFavorite': lambda: len([
                user for user in post.favorited_by
                if user.user_id == auth_user.user_id]
            ) > 0,
            'tagCount': lambda: post.tag_count,
            'favoriteCount': lambda: post.favorite_count,
            'commentCount': lambda: post.comment_count,
            'noteCount': lambda: post.note_count,
            'relationCount': lambda: post.relation_count,
            'featureCount': lambda: post.feature_count,
            'lastFeatureTime': lambda: post.last_feature_time,
            'favoritedBy': lambda: [
                users.serialize_micro_user(rel.user, auth_user)
                for rel in post.favorited_by
            ],
            'hasCustomThumbnail':
                lambda: files.has(get_post_thumbnail_backup_path(post)),
            'notes': lambda: sorted(
                [serialize_note(note) for note in post.notes],
                key=lambda x: x['polygon']),
            'comments': lambda: [
                comments.serialize_comment(comment, auth_user)
                for comment in sorted(
                    post.comments,
                    key=lambda comment: comment.creation_time)],
        },
        options)
示例#3
0
def generate_post_thumbnail(post):
    if files.has(get_post_thumbnail_backup_path(post)):
        content = files.get(get_post_thumbnail_backup_path(post))
    else:
        content = files.get(get_post_content_path(post))
    try:
        image = images.Image(content)
        image.resize_fill(
            int(config.config['thumbnails']['post_width']),
            int(config.config['thumbnails']['post_height']))
        files.save(get_post_thumbnail_path(post), image.to_jpeg())
    except errors.ProcessingError:
        files.save(get_post_thumbnail_path(post), EMPTY_PIXEL)
示例#4
0
def populate_reverse_search() -> None:
    excluded_post_ids = image_hash.get_all_paths()

    post_ids_to_hash = (db.session.query(model.Post.post_id).filter(
        (model.Post.type == model.Post.TYPE_IMAGE)
        | (model.Post.type == model.Post.TYPE_ANIMATION)).filter(
            ~model.Post.post_id.in_(excluded_post_ids)).order_by(
                model.Post.post_id.asc()).all())

    for post_ids_chunk in util.chunks(post_ids_to_hash, 100):
        posts_chunk = (db.session.query(model.Post).filter(
            model.Post.post_id.in_(post_ids_chunk)).all())
        for post in posts_chunk:
            content_path = get_post_content_path(post)
            if files.has(content_path):
                image_hash.add_image(post.post_id, files.get(content_path))
示例#5
0
def generate_post_thumbnail(post: model.Post) -> None:
    assert post
    if files.has(get_post_thumbnail_backup_path(post)):
        content = files.get(get_post_thumbnail_backup_path(post))
    else:
        content = files.get(get_post_content_path(post))
    try:
        assert content
        image = images.Image(content)
        image.resize_fill(
            int(config.config["thumbnails"]["post_width"]),
            int(config.config["thumbnails"]["post_height"]),
        )
        files.save(get_post_thumbnail_path(post), image.to_jpeg())
    except errors.ProcessingError:
        files.save(get_post_thumbnail_path(post), EMPTY_PIXEL)
示例#6
0
文件: users.py 项目: yf-dev/yfbooru
def update_user_name(user: model.User, name: str) -> None:
    assert user
    if not name:
        raise InvalidUserNameError('닉네임(ID)은 빈 값일 수 없습니다.')
    if util.value_exceeds_column_size(name, model.User.name):
        raise InvalidUserNameError('닉네임(ID)이 너무 깁니다.')
    name = name.strip()
    name_regex = config.config['user_name_regex']
    if not re.match(name_regex, name):
        raise InvalidUserNameError('닉네임(ID) %r 은(는) 다음의 정규식을 만족해야 합니다: %r' %
                                   (name, name_regex))
    other_user = try_get_user_by_name(name)
    if other_user and other_user.user_id != user.user_id:
        raise UserAlreadyExistsError('사용자 %r 은(는) 이미 존재합니다.' % name)
    if user.name and files.has(get_avatar_path(user.name)):
        files.move(get_avatar_path(user.name), get_avatar_path(name))
    user.name = name
示例#7
0
def update_user_name(user: model.User, name: str) -> None:
    assert user
    if not name:
        raise InvalidUserNameError('Name cannot be empty.')
    if util.value_exceeds_column_size(name, model.User.name):
        raise InvalidUserNameError('User name is too long.')
    name = name.strip()
    name_regex = config.config['user_name_regex']
    if not re.match(name_regex, name):
        raise InvalidUserNameError('User name %r must satisfy regex %r.' %
                                   (name, name_regex))
    other_user = try_get_user_by_name(name)
    if other_user and other_user.user_id != user.user_id:
        raise UserAlreadyExistsError('User %r already exists.' % name)
    if user.name and files.has(get_avatar_path(user.name)):
        files.move(get_avatar_path(user.name), get_avatar_path(name))
    user.name = name
示例#8
0
文件: users.py 项目: rr-/szurubooru
def update_user_name(user: model.User, name: str) -> None:
    assert user
    if not name:
        raise InvalidUserNameError('Name cannot be empty.')
    if util.value_exceeds_column_size(name, model.User.name):
        raise InvalidUserNameError('User name is too long.')
    name = name.strip()
    name_regex = config.config['user_name_regex']
    if not re.match(name_regex, name):
        raise InvalidUserNameError(
            'User name %r must satisfy regex %r.' % (name, name_regex))
    other_user = try_get_user_by_name(name)
    if other_user and other_user.user_id != user.user_id:
        raise UserAlreadyExistsError('User %r already exists.' % name)
    if user.name and files.has(get_avatar_path(user.name)):
        files.move(get_avatar_path(user.name), get_avatar_path(name))
    user.name = name
示例#9
0
def update_user_avatar(user, avatar_style, avatar_content=None):
    assert user
    if avatar_style == 'gravatar':
        user.avatar_style = user.AVATAR_GRAVATAR
    elif avatar_style == 'manual':
        user.avatar_style = user.AVATAR_MANUAL
        avatar_path = 'avatars/' + user.name.lower() + '.png'
        if not avatar_content:
            if files.has(avatar_path):
                return
            raise InvalidAvatarError('Avatar content missing.')
        image = images.Image(avatar_content)
        image.resize_fill(
            int(config.config['thumbnails']['avatar_width']),
            int(config.config['thumbnails']['avatar_height']))
        files.save(avatar_path, image.to_png())
    else:
        raise InvalidAvatarError(
            'Avatar style %r is invalid. Valid avatar styles: %r.' % (
                avatar_style, ['gravatar', 'manual']))
示例#10
0
文件: users.py 项目: yf-dev/yfbooru
def update_user_avatar(user: model.User,
                       avatar_style: str,
                       avatar_content: Optional[bytes] = None) -> None:
    assert user
    if avatar_style == 'gravatar':
        user.avatar_style = user.AVATAR_GRAVATAR
    elif avatar_style == 'manual':
        user.avatar_style = user.AVATAR_MANUAL
        avatar_path = 'avatars/' + user.name.lower() + '.png'
        if not avatar_content:
            if files.has(avatar_path):
                return
            raise InvalidAvatarError('아바타 컨텐츠가 누락되었습니다.')
        image = images.Image(avatar_content)
        image.resize_fill(int(config.config['thumbnails']['avatar_width']),
                          int(config.config['thumbnails']['avatar_height']))
        files.save(avatar_path, image.to_png())
    else:
        raise InvalidAvatarError('아바타 스타일 %r 은(는) 잘못된 값입니다. 올바른 스타일 값: %r.' %
                                 (avatar_style, ['gravatar', 'manual']))
示例#11
0
def populate_reverse_search():
    excluded_post_ids = image_hash.get_all_paths()

    post_ids_to_hash = (db.session
        .query(db.Post.post_id)
        .filter(
            (db.Post.type == db.Post.TYPE_IMAGE) |
            (db.Post.type == db.Post.TYPE_ANIMATION))
        .filter(~db.Post.post_id.in_(excluded_post_ids))
        .order_by(db.Post.post_id.asc())
        .all())

    for post_ids_chunk in util.chunks(post_ids_to_hash, 100):
        posts_chunk = (db.session
            .query(db.Post)
            .filter(db.Post.post_id.in_(post_ids_chunk))
            .all())
        for post in posts_chunk:
            content_path = get_post_content_path(post)
            if files.has(content_path):
                image_hash.add_image(post.post_id, files.get(content_path))
示例#12
0
def generate_post_thumbnail(post: model.Post) -> None:
    assert post
    if files.has(get_post_thumbnail_backup_path(post)):
        content = files.get(get_post_thumbnail_backup_path(post))
    else:
        content = files.get(get_post_content_path(post))
    try:
        assert content
        if post.type == model.Post.TYPE_IMAGE:
            media = images.Image(content)
        elif post.type == model.Post.TYPE_VIDEO:
            media = images.Video(content)

        thumb = media.to_thumbnail(
            int(config.config["thumbnails"]["post_width"]),
            int(config.config["thumbnails"]["post_height"]),
        )

        files.save(get_post_thumbnail_path(post), thumb)
    except errors.ProcessingError:
        files.save(get_post_thumbnail_path(post), EMPTY_PIXEL)
示例#13
0
def update_user_avatar(user: model.User,
                       avatar_style: str,
                       avatar_content: Optional[bytes] = None) -> None:
    assert user
    if avatar_style == "gravatar":
        user.avatar_style = user.AVATAR_GRAVATAR
    elif avatar_style == "manual":
        user.avatar_style = user.AVATAR_MANUAL
        avatar_path = "avatars/" + user.name.lower() + ".png"
        if not avatar_content:
            if files.has(avatar_path):
                return
            raise InvalidAvatarError("Avatar content missing.")
        image = images.Image(avatar_content)
        image.resize_fill(
            int(config.config["thumbnails"]["avatar_width"]),
            int(config.config["thumbnails"]["avatar_height"]),
        )
        files.save(avatar_path, image.to_png())
    else:
        raise InvalidAvatarError(
            "Avatar style %r is invalid. Valid avatar styles: %r." %
            (avatar_style, ["gravatar", "manual"]))
示例#14
0
 def serialize_has_custom_thumbnail(self) -> Any:
     return files.has(get_post_thumbnail_backup_path(self.post))
示例#15
0
def save(content: bytes) -> str:
    checksum = util.get_sha1(content)
    path = _get_path(checksum)
    if not files.has(path):
        files.save(path, content)
    return checksum
示例#16
0
def save(content: bytes) -> str:
    checksum = util.get_sha1(content)
    path = _get_path(checksum)
    if not files.has(path):
        files.save(path, content)
    return checksum
示例#17
0
文件: posts.py 项目: rr-/szurubooru
 def serialize_has_custom_thumbnail(self) -> Any:
     return files.has(get_post_thumbnail_backup_path(self.post))