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
async def delete(self): if self.absolute.is_dir(): shutil.rmtree(str(self.absolute)) elif not self.absolute.exists(): raise errors.ResourceDoesNotExist() else: self.absolute.unlink()
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
async def populate_collection(self): self._collection = [] collections = [] files = [] try: for child in self.absolute.iterdir(): relative = self.with_relative(child.relative_to(self.absolute)) relative._stat = os.stat(str(relative.absolute)) if child.is_dir(): collections.append(relative) else: files.append(relative) except FileNotFoundError: raise errors.ResourceDoesNotExist() self._collection.extend(sorted(collections, key=lambda r: r.name)) self._collection.extend(sorted(files, key=lambda r: r.name))
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")
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
async def populate_props(self): try: self._stat = os.stat(str(self.absolute)) except FileNotFoundError: raise errors.ResourceDoesNotExist()
async def delete(self): if not self._exists: raise errors.ResourceDoesNotExist() # noinspection PyProtectedMember del self._parent._resources[self.name]
async def populate_collection(self): if not self._exists: raise errors.ResourceDoesNotExist() return
async def populate_props(self): if not self._exists: raise errors.ResourceDoesNotExist() return