Ejemplo n.º 1
0
async def os_char_update_name(
    update_info: models.Update,
    account: Account = Depends(depends.AccountFromRequest),
    character: Character = Depends(depends.CharacterFromPath)):
    if character.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()

    if not res.verify(update_info.update.name, res.CharacterName):
        raise exceptions.NonCompliantMsg()

    with orm.db_session:
        if Character.get(PlayerName=update_info.update.name):
            raise exceptions.OccupyExistedAddress()

        character.PlayerName = update_info.update.name
        character.PlayerId = OfflinePlayerUUID(update_info.update.name)
        character.update_UpdatedAt()
        orm.commit()
    return {
        "operator": "success",
        "metadata": {
            "account": account.Id,
            "character": character.Id
        }
    }
Ejemplo n.º 2
0
async def os_reso_update(
    update_info: models.ResourceUpdate,
    account: Account = Depends(depends.AccountFromRequest),
    resource: Resource = Depends(depends.ResourceFromPath)):
    if resource.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()
    with orm.db_session:
        try:
            if update_info.update.name:
                resource.Name = update_info.update.name
            if update_info.update.type:
                resource.Type = update_info.update.type
                if update_info.update.type == "cape":
                    resource.Model = "none"
            if update_info.update.model:
                if update_info.update.type == "cape":
                    if update_info.update.model != 'none':
                        raise exceptions.UnrecognizedContent({
                            "field":
                            "update_info.update.model",
                            "conflictItems": [{
                                "update_info.update.type": "cape"
                            }]
                        })
                resource.Model = update_info.update.model
            orm.commit()
        except ValueError:
            raise exceptions.NonCompliantMsg()
    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 3
0
async def rs_char_publicStats(
        account: Account = Depends(depends.AccountFromRequest),
        character: Character = Depends(depends.CharacterFromPath)):
    if account.Id != character.Owner.Id:
        raise exceptions.PermissionDenied()

    return {"publicStats": character.Public}
Ejemplo n.º 4
0
async def rs_reso_publicStats(
        account: Account = Depends(depends.AccountFromRequest),
        resource: Resource = Depends(depends.ResourceFromPath)):
    if account.Id != resource.Owner.Id:
        raise exceptions.PermissionDenied()

    return {"publicStats": not resource.IsPrivate}
Ejemplo n.º 5
0
async def rs_reso_protectStats(
        account: Account = Depends(depends.AccountFromRequest),
        resource: Resource = Depends(depends.ResourceFromPath)):
    if account.Id != resource.Owner.Id:
        raise exceptions.PermissionDenied()

    return {"protectStats": resource.Protect}
Ejemplo n.º 6
0
async def os_char_delete(
        account: Account = Depends(depends.AccountFromRequest),
        character: Character = Depends(depends.CharacterFromPath)):
    if character.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()

    character.delete()
    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 7
0
async def os_reso_transform_protectStats(
    stats: bool,
    account: Account = Depends(depends.AccountFromRequest),
    resource: Resource = Depends(depends.ResourceFromPath)):
    if resource.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()
    with orm.db_session:
        # 检查是否有origin
        if resource.Origin:
            if resource.Origin.Protect or resource.Origin.Private:
                # 如果是私有或带保护, 则不准更改保护状态.
                # 注意: 这里需要强制转变保护状态
                if resource.Protect:
                    resource.Protect = False
                    orm.commit()
                raise exceptions.PermissionDenied()

        resource.Protect = stats
        orm.commit()
    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 8
0
async def resources_resource_forks(
        resource: Resource = Depends(depends.ResourceFromPath),
        Account: Account = Depends(depends.AccountFromRequest)):
    if not resource.Owner.Id != Account.Id:
        raise exceptions.PermissionDenied()
    return [{
        "id": i.Id,
        "name": i.Name,
        "uploader": i.Owner,
        "createAt": i.CreatedAt
    } for i in resource.Forks]
Ejemplo n.º 9
0
async def os_reso_transform_publicStats(
    public: enums.PublicStatus,
    account: Account = Depends(depends.AccountFromRequest),
    resource: Resource = Depends(depends.ResourceFromPath)):
    if resource.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()

    with orm.db_session:
        # 检查是否有origin
        if resource.Origin:
            if resource.Origin.Protect or resource.Origin.Private:
                # 如果是私有或带保护, 则不准公开.
                if public == "public":
                    raise exceptions.PermissionDenied()

        resource.IsPrivate = public != "public"
        if public == "private":
            resource.Protect = False
        orm.commit()

    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 10
0
async def os_char_publicStats_transform(
    public: enums.PublicStatus,
    account: Account = Depends(depends.AccountFromRequest),
    character: Character = Depends(depends.CharacterFromPath)):
    if character.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()

    character.Public = public == enums.PublicStatus.Public
    character.update_UpdatedAt()
    orm.commit()

    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 11
0
async def os_char_textures_bind(
        character: Character = Depends(depends.CharacterFromPath),
        account: Account = Depends(depends.AccountFromRequest),
        resource: Resource = Depends(depends.ResourceFromPath)):
    if resource.IsPrivate and resource.Owner != account.Id:
        raise exceptions.PermissionDenied()

    if resource.Type == 'skin':
        character.Skin = resource
    elif resource.Type == "cape":
        character.Cape = resource
    character.update_UpdatedAt()

    orm.commit()
    return character.format_self()
Ejemplo n.º 12
0
async def os_reso_delete(
    bgTasks: BackgroundTasks,
    account: Account = Depends(depends.AccountFromRequest),
    resource: Resource = Depends(depends.ResourceFromPath)):
    if resource.Owner.Id != account.Id:
        raise exceptions.PermissionDenied()
    with orm.db_session:
        # 检查其fork, 因为该资源被删除, 所以资源的各个Fork也应该被删除.
        if resource.Forks[:]:
            for i in resource.Forks:
                # 解除角色绑定
                if i.UsedforSkin:
                    for ii in i.UsedforSkin:
                        ii.Skin = None
                if i.UsedforCape:
                    for ii in i.UsedforCape:
                        ii.Cape = None
                # 删除.
                i.delete()

        bgTasks.add_task(resource_manager.Delete, resource.PicHash)
        resource.delete()
        orm.commit()
    return {"operator": "success", "metadata": {"account": account.Id}}
Ejemplo n.º 13
0
async def amadeus_upload(
        bgTasks: BackgroundTasks,

        file: UploadFile = File(...),
        name: str = Query(..., min_length=4, max_length=60, regex=res.ResourceName),

        Model: enums.MCTextureModel = Query("auto", alias="model"),
        Type: enums.MCTextureType = Query(..., alias="type"),
        
        Private: bool = False,
        Protect: bool = False,

        uploader: Account = Depends(depends.AccountFromRequestForm(alias="auth"))
    ):
    """参数name为要创建的资源名称.\n 
    通过表单API上传图片, 名称"file"\n
    通过表单发送认证, 名称"auth".\n

    可用get query传参: \n
    
    ``` url
    http://127.0.0.1:8000/natrium/amadeus/upload/aResourceName?type=skin&strict=true&model=alex
    ```
    """
    # 常量分配
    Original: bool = True # 在库中是否是第一个被创建的
    OriginalResource: Optional[Resource] = None
    OriginalUploader: Optional[Account] = None

    if Private and Protect:
        raise exceptions.DuplicateRegulations()

    try:
        image: Image.Image = Image.open(BytesIO(await file.read()))
    except PIL.UnidentifiedImageError:
        raise exceptions.NonCompliantMsg({
            "filename": file.filename
        })
    finally:
        await file.close()

    width, height = image.size

    if image.format != "PNG":
        raise exceptions.NonCompliantMsg({
            "image.format": {
                "value": image.format,
                "assert": "PNG"
            }
        })

    if height > config['natrium']['upload']['picture-size']['height'] or\
        width > config['natrium']['upload']['picture-size']['width']:
        raise exceptions.NonCompliantMsg()

    image.resize((
        int(width / 22) * 32 if width % 22 == 0 else width,
        int(width / 17) * 32 if height % 17 == 0 else height
    ))

    pictureContentHash = hashing.PicHash(image)

    attempt_select = orm.select(i for i in Resource if i.PicHash == pictureContentHash)
    if attempt_select.exists():
        # 如果真的有上传的数据一样的
        Original = False
        for i in attempt_select[:]:
            # 询问数据库, 找到原始作者
            # 考虑加入uploader找寻.
            if not i.Origin:
                OriginalResource = i
                OriginalUploader = i.Owner
                break

        if not OriginalResource or\
            not OriginalUploader: # 判断是否找到了, 如果没找到, 说明数据库信息受损
            raise exceptions.BrokenData({
                "PictureHash": pictureContentHash,
                "ExceptionRaisedTime": maya.now()
            })

        # 如果有attempt_select, 就一定有一个origin.
        # 判断是否是原作者闲着没事干, 重新上传了一个.
        if OriginalUploader.Id == uploader.Id:
            raise exceptions.OccupyExistedAddress({
                "originalResource": {
                    "id": OriginalResource.Id,
                    "owner": OriginalUploader.Id
                },
                "uploader": {
                    "id": uploader.Id
                }
            })
        else: # ...或者是其他人, 这种情况我们需要特殊处理
            # 由于Protect的受限度较低, 故放在上面点.
            if OriginalResource.Protect:
                if Protect or Private:
                    raise exceptions.PermissionDenied({
                        "originalResource": {
                            "id": OriginalResource.Id,
                            "owner": OriginalUploader.Id,
                            "protect": OriginalResource.Protect,
                            "private": OriginalResource.Private
                        },
                        "uploader": {
                            "id": uploader.Id
                        }
                    })
                else: # 但是你本来就可以设为这个啊, 为啥要自己整一路去?
                    raise exceptions.OccupyExistedAddress({
                        "originalResource": {
                            "id": OriginalResource.Id,
                            "owner": OriginalUploader.Id,
                            "protect": OriginalResource.Protect,
                        },
                        "uploader": {
                            "id": uploader.Id
                        }
                    })
            elif OriginalResource.IsPrivate:
                # 如果私有, 则不允许任何人上传/使用/设保护/私有等
                raise exceptions.OccupyExistedAddress({
                    "originalResource": {
                        "id": OriginalResource.Id,
                        "owner": OriginalUploader.Id,
                        "protect": OriginalResource.Protect,
                    },
                    "uploader": {
                        "id": uploader.Id
                    }
                })
            else:
                # 你什么私有保护什么的都没开? 别开你自己的私有保护什么的就OK.
                if Protect or Private:
                    raise exceptions.PermissionDenied({
                        "originalResource": {
                            "id": OriginalResource.Id,
                            "owner": OriginalUploader.Id
                        },
                        "uploader": {
                            "id": uploader.Id
                        },
                        "options": {
                            'protect': Protect,
                            "private": Private
                        }
                    })
                else:
                    # 找寻上传者是否也曾经上传过该材质
                    assert_the_same = orm.select(i for i in Resource\
                        if i.PicHash == pictureContentHash and \
                        i.Owner.Id == uploader.Id)
                    if assert_the_same.exists():
                        ats_first: Resource = assert_the_same.first()
                        raise exceptions.OccupyExistedAddress({
                            "ownedResource": {
                                "id": ats_first.Id,
                                "name": ats_first.Name
                            },
                            "uploader": {
                                "id": uploader.Id
                            }
                        })

        if Model == "auto":
            Model = ['steve', 'alex'][skin.isSilmSkin(image)]

        account = Account.get(Id=uploader.Id)
        resource = Resource(
            PicHash = pictureContentHash,
            Name = name,
            PicHeight = height, PicWidth = width,
            Model = Model, Type = Type,
            Owner = account,
            IsPrivate = Private, Protect = Protect,
            Origin = OriginalResource
        )
        if Original:
            bgTasks.add_task(Save, image, pictureContentHash)
        orm.commit()
        return {
            "operator": "success",
            "metadata": resource.format_self(requestHash=True)
        }
Ejemplo n.º 14
0
 async def PermissionWarpper(token: Token = Depends(TokenVerify())):
     if token.Account.Permission != Permission:
         raise exceptions.PermissionDenied()