Beispiel #1
0
async def get_folder_by_path(sid: str, folder):
    user = asset_state.get_user(sid)

    folder = folder.strip("/")
    target_folder = Asset.get_root_folder(user)

    id_path = []

    if folder:
        for path in folder.split("/"):
            try:
                target_folder = target_folder.get_child(path)
                id_path.append(target_folder.id)
            except Asset.DoesNotExist:
                return await get_folder_by_path(sid, "/")

    await sio.emit(
        "Folder.Set",
        {
            "folder": target_folder.as_dict(children=True),
            "path": id_path
        },
        room=sid,
        namespace=ASSET_NS,
    )
Beispiel #2
0
async def handle_paa_file(upload_data: UploadData, data: bytes, sid: str):
    with tempfile.TemporaryDirectory() as tmpdir:
        with tarfile.open(fileobj=io.BytesIO(data), mode="r:bz2") as tar:
            files = tarfile.TarInfo("files")
            files.type = tarfile.DIRTYPE
            # We need to explicitly list our members for security reasons
            # this is upload data so people could upload malicious stuff that breaks out of the path etc
            tar.extractall(
                path=tmpdir, members=get_safe_members(tar.getmembers(), tmpdir)
            )

        tmp_path = Path(tmpdir)
        for asset in os.listdir(tmp_path / "files"):
            if not (ASSETS_DIR / asset).exists():
                shutil.move(str(tmp_path / "files" / asset), str(ASSETS_DIR / asset))

        with open(tmp_path / "data") as json_data:
            raw_assets: List[AssetDict] = json.load(json_data)

    user = asset_state.get_user(sid)
    parent_map: Dict[int, int] = defaultdict(lambda: upload_data["directory"])

    for raw_asset in raw_assets:
        new_asset = Asset.create(
            name=raw_asset["name"],
            file_hash=raw_asset["file_hash"],
            owner=user,
            parent=parent_map[raw_asset["parent"]],
            options=raw_asset["options"],
        )
        parent_map[raw_asset["id"]] = new_asset.id

    await sio.emit(
        "Asset.Import.Finish", upload_data["name"], room=sid, namespace=ASSET_NS
    )
Beispiel #3
0
async def assetmgmt_upload(sid: str, upload_data: UploadData):
    uuid = upload_data["uuid"]

    if uuid not in asset_state.pending_file_upload_cache:
        asset_state.pending_file_upload_cache[uuid] = {}
    asset_state.pending_file_upload_cache[uuid][upload_data["slice"]] = upload_data
    if len(asset_state.pending_file_upload_cache[uuid]) != upload_data["totalSlices"]:
        # wait for the rest of the slices
        return

    # All slices are present
    data = b""
    for slice_ in range(upload_data["totalSlices"]):
        data += asset_state.pending_file_upload_cache[uuid][slice_]["data"]

    del asset_state.pending_file_upload_cache[upload_data["uuid"]]

    file_name = upload_data["name"]
    if file_name.endswith(".paa"):
        await handle_paa_file(upload_data, data, sid)
    elif file_name.endswith(".dd2vtt"):
        await handle_ddraft_file(upload_data, data, sid)
    else:
        await handle_regular_file(upload_data, data, sid)
    
    user = asset_state.get_user(sid)
    await update_live_game(user)
Beispiel #4
0
async def create_folder(sid: str, data):
    user = asset_state.get_user(sid)
    parent = data.get("parent", None)
    if parent is None:
        parent = Asset.get_root_folder(user)
    asset = Asset.create(name=data["name"], owner=user, parent=parent)
    await sio.emit("Folder.Create", asset.as_dict(), room=sid, namespace=ASSET_NS)
Beispiel #5
0
async def assetmgmt_rename(sid: str, data):
    user = asset_state.get_user(sid)
    asset = Asset.get_by_id(data["asset"])
    if asset.owner != user:
        logger.warning(f"{user.name} attempted to rename a file it doesn't own.")
        return
    asset.name = data["name"]
    asset.save()
Beispiel #6
0
async def move_inode(sid: str, data):
    user = asset_state.get_user(sid)
    target = data.get("target", None)
    if target is None:
        target = Asset.get_root_folder(user)

    asset = Asset[data["inode"]]
    if asset.owner != user:
        logger.warning(f"{user.name} attempted to move files it doesn't own.")
        return
    asset.parent = target
    asset.save()
Beispiel #7
0
async def assetmgmt_rm(sid: str, data):
    user = asset_state.get_user(sid)
    asset = Asset.get_by_id(data)
    if asset.owner != user:
        logger.warning(f"{user.name} attempted to remove a file it doesn't own.")
        return
    asset.delete_instance(recursive=True, delete_nullable=True)

    if asset.file_hash is not None and (ASSETS_DIR / asset.file_hash).exists():
        if Asset.select().where(Asset.file_hash == asset.file_hash).count() == 0:
            logger.info(
                f"No asset maps to file {asset.file_hash}, removing from server"
            )
            (ASSETS_DIR / asset.file_hash).unlink()
Beispiel #8
0
async def get_folder(sid: str, folder=None):
    user = asset_state.get_user(sid)

    if folder is None:
        folder = Asset.get_root_folder(user)
    else:
        folder = Asset[folder]

    if folder.owner != user:
        raise web.HTTPForbidden
    await sio.emit(
        "Folder.Set",
        {"folder": folder.as_dict(children=True)},
        room=sid,
        namespace=ASSET_NS,
    )
Beispiel #9
0
async def handle_regular_file(upload_data: UploadData, data: bytes, sid: str):
    sh = hashlib.sha1(data)
    hashname = sh.hexdigest()

    if not (ASSETS_DIR / hashname).exists():
        with open(ASSETS_DIR / hashname, "wb") as f:
            f.write(data)

    user = asset_state.get_user(sid)

    asset = Asset.create(
        name=upload_data["name"],
        file_hash=hashname,
        owner=user,
        parent=upload_data["directory"],
    )

    await sio.emit("Asset.Upload.Finish", asset.as_dict(), room=sid, namespace=ASSET_NS)
Beispiel #10
0
async def assetmgmt_upload(sid: str, file_data):
    uuid = file_data["uuid"]

    if uuid not in asset_state.pending_file_upload_cache:
        asset_state.pending_file_upload_cache[uuid] = {}
    asset_state.pending_file_upload_cache[uuid][file_data["slice"]] = file_data
    if len(asset_state.pending_file_upload_cache[uuid]
           ) != file_data["totalSlices"]:
        # wait for the rest of the slices
        return

    # All slices are present
    data = b""
    for slice_ in range(file_data["totalSlices"]):
        data += asset_state.pending_file_upload_cache[uuid][slice_]["data"]

    sh = hashlib.sha1(data)
    hashname = sh.hexdigest()

    if not (ASSETS_DIR / hashname).exists():
        with open(ASSETS_DIR / hashname, "wb") as f:
            f.write(data)

    del asset_state.pending_file_upload_cache[uuid]

    user = asset_state.get_user(sid)

    asset = Asset.create(
        name=file_data["name"],
        file_hash=hashname,
        owner=user,
        parent=file_data["directory"],
    )

    await sio.emit("Asset.Upload.Finish",
                   asset.as_dict(),
                   room=sid,
                   namespace=ASSET_NS)
Beispiel #11
0
async def handle_ddraft_file(upload_data: UploadData, data: bytes, sid: str):
    ddraft_file: DDraftData = json.loads(data)

    image = base64.b64decode(ddraft_file["image"])

    sh = hashlib.sha1(image)
    hashname = sh.hexdigest()

    if not (ASSETS_DIR / hashname).exists():
        with open(ASSETS_DIR / hashname, "wb") as f:
            f.write(image)

    template = {
        "version": "0",
        "shape": "assetrect",
        "templates": {
            "default": {
                "options":
                json.dumps([[f"ddraft_{k}", v] for k, v in ddraft_file.items()
                            if k != "image"])
            }
        },
    }

    user = asset_state.get_user(sid)

    asset = Asset.create(
        name=upload_data["name"],
        file_hash=hashname,
        owner=user,
        parent=upload_data["directory"],
        options=json.dumps(template),
    )

    await sio.emit("Asset.Upload.Finish",
                   asset.as_dict(),
                   room=sid,
                   namespace=ASSET_NS)