示例#1
0
    async def copy(self, destination: str) -> 'AbstractResource':
        new_resource = self.__class__(self.prefix,
                                      destination,
                                      root_dir=self._root_dir)
        if not self._stat:
            await self.populate_props()

        if not self.is_collection:
            try:
                shutil.copy(str(self.absolute), str(new_resource.absolute))
            except shutil.SameFileError:
                raise errors.ResourceAlreadyExists(
                    "destination file already exists")
            except FileNotFoundError:
                raise errors.ResourceDoesNotExist(
                    "destination dir does not exist")
            await new_resource.populate_props()
        else:
            try:
                shutil.copytree(str(self.absolute), str(new_resource.absolute))
            except FileExistsError:
                raise errors.InvalidResourceType("collection expected")
            await new_resource.populate_props()
            await new_resource.populate_collection()
        return new_resource
示例#2
0
 async def put_content(self, read_some: typing.Awaitable[bytes]) -> bool:
     created = not self.absolute.exists()
     mode = 'wb' if created else 'r+b'
     parent_exists = self.absolute.parent.exists()
     if not parent_exists:
         raise errors.ResourceDoesNotExist("parent resource does not exist")
     try:
         with self.absolute.open(mode) as f:
             if not read_some:
                 return created
             while True:
                 buffer = await read_some()
                 f.write(buffer)
                 if not buffer:
                     return created
     except NotADirectoryError:
         raise errors.InvalidResourceType(
             "parent resource is not a collection")
     except IsADirectoryError:
         raise errors.InvalidResourceType("file resource expected")
示例#3
0
 def _touch_file(self):
     # noinspection PyProtectedMember
     if not self.parent or not self.parent._exists:
         raise errors.ResourceDoesNotExist("Parent resource does not exist")
     if not self.parent.is_collection:
         raise errors.InvalidResourceType("Collection expected")
     # noinspection PyProtectedMember
     self._parent._resources[self.name] = self
     self._exists = True
     self._content = BytesIO()
     self._is_directory = False
示例#4
0
    async def make_collection(self, collection: str) -> 'AbstractResource':
        new_path = self.absolute / collection
        if new_path.exists():
            raise errors.ResourceAlreadyExists()
        try:
            new_path.mkdir(exist_ok=True)
        except NotADirectoryError:
            raise errors.InvalidResourceType("collection expected")

        path = str(new_path.relative_to(self._root_dir))
        return self.__class__(self.prefix, path, root_dir=self._root_dir)
示例#5
0
 async def get_content(self,
                       write: typing.Callable[[bytes], typing.Any],
                       *,
                       offset: int = 0,
                       limit: int = None):
     if self._is_directory:
         raise errors.InvalidResourceType("file resource expected")
     self._content.seek(offset)
     buffer = self._content.read(limit)
     if asyncio.iscoroutinefunction(write):
         await write(buffer)
     else:
         write(buffer)
示例#6
0
 async def move(self, destination: str) -> bool:
     old_name = self.name
     dest_resource = self._root.with_relative(destination)
     if not dest_resource._exists:
         self._path = dest_resource.path
         dest_resource = dest_resource._parent
     await dest_resource.populate_props()
     if not dest_resource.is_collection:
         raise errors.InvalidResourceType("collection expected")
     del self._parent._resources[old_name]
     self._parent = dest_resource
     self._path = os.path.join(self._parent.path, self.name)
     dest_resource._resources[self.name] = self
     return True
示例#7
0
    async def put_content(self, read_some: typing.Awaitable[bytes]) -> bool:
        if self._exists:
            created = False
            if self.is_collection:
                raise errors.InvalidResourceType("file resource expected")
        else:
            created = True
            self._touch_file()

        self._content.seek(0)
        self._content.truncate()
        if not read_some:
            return created
        while True:
            buffer = await read_some()
            self._content.write(buffer)
            if not buffer:
                return created
示例#8
0
    async def copy(self, destination: str) -> 'AbstractResource':
        if not self.is_collection:
            return self._copy_file(destination)

        dest = self._root / destination.strip('/')
        if not dest.is_collection:
            raise errors.InvalidResourceType("collection expected")
        if not dest._exists:
            name = dest.name
            dest = dest._parent
        else:
            name = self.name
        new_dir = self._clone()
        new_dir._parent = dest
        dest._resources[name] = new_dir
        new_dir._path = os.path.join(dest.path, name)
        for res in self.collection:
            await res.copy(new_dir.path)
        return new_dir
示例#9
0
 def with_relative(self, relative) -> 'AbstractResource':
     if relative == '/':
         return self
     res = self
     parts = relative.strip('/').split('/')
     for part in parts[:-1]:
         try:
             res = res._resources[part]
         except KeyError:
             raise errors.ResourceDoesNotExist(
                 "one of parent resources does not exist")
     part = parts[-1]
     try:
         if not res.is_collection:
             raise errors.InvalidResourceType("collection expected")
         res = res._resources[part]
     except KeyError:
         res = DummyResource(self.prefix,
                             os.path.join(res.path, part),
                             parent=res,
                             exists=False)
     return res
示例#10
0
    async def make_collection(self, collection: str) -> 'AbstractResource':
        collection = collection.strip('/')
        parent = os.path.dirname(collection)
        name = os.path.basename(collection)
        if not parent:
            parent = self
        else:
            parent = self._root.with_relative(parent)

        if not parent.is_collection:
            raise errors.InvalidResourceType("collection expected")
        # noinspection PyProtectedMember
        if name in parent._resources:
            raise errors.ResourceAlreadyExists("collection already exists")
        collection = DummyResource(prefix=self.prefix,
                                   path=os.path.join(parent.path, collection),
                                   parent=parent,
                                   is_collection=True,
                                   exists=True)
        # noinspection PyProtectedMember
        parent._resources[name] = collection
        return collection
示例#11
0
 async def get_content(self,
                       write: typing.Callable[[bytes], typing.Any],
                       *,
                       offset: int = None,
                       limit: int = None):
     try:
         with self.absolute.open('rb') as f:
             if offset:
                 f.seek(offset)
             block_size = 1024**2
             if not limit:
                 limit = None
             while True:
                 if limit is not None:
                     buffer = f.read(min(block_size, limit))
                 else:
                     buffer = f.read(block_size)
                 await write(buffer)
                 if limit is not None:
                     limit -= len(buffer)
                 if len(buffer) < block_size:
                     break
     except IsADirectoryError:
         raise errors.InvalidResourceType("file resource expected")