Валентин обнови решението на 30.04.2015 16:13 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class SystemNode:
+ def __init__(self, is_directory):
+ self.__is_directory = is_directory
+
+ @property
+ def is_directory(self):
+ return self.__is_directory
+
+
+class SystemFile(SystemNode):
+ def __init__(self, data, file_sys):
+ super().__init__(False)
+ self.__data = data
+ self.__file_sys = file_sys
+
+ def __repr__(self):
+ return self.__data
+
+ @property
+ def content(self):
+ return self.__data
+
+ @property
+ def size(self):
+ return len(self.__data)
+
+ def append(self, text):
+ FS = self.__file_sys
+ if FS.available_size - len(text) < 0:
+ raise NotEnoughSpaceError
+ self.__data += text
+
+ def truncate(self, text):
+ FS = self.__file_sys
+ if FS.available_size - len(text) + len(self.__data) < 0:
+ raise NotEnoughSpaceError
+ self.__data = text
+
+ def taken_space(self):
+ return len(self.__data) + 1
+
+ def get_node(self, *args, **kwarg):
+ raise NodeDoesNotExistError
+
+
+class SystemDirectory(SystemNode):
+ def __init__(self, file_sys):
+ super().__init__(True)
+ self.__dir = {}
+ self.__file_sys = file_sys
+
+ def __getitem__(self, index):
+ return self.__dir[sorted(list(self.__dir))[index]]
+
+ def __repr__(self):
+ return str(self.__dir)
+
+ @property
+ def directories(self):
+ return [val for key, val in self.__dir.items() if val.is_directory]
+
+ @property
+ def files(self):
+ return [val for key, val in self.__dir.items() if not val.is_directory]
+
+ @property
+ def nodes(self):
+ return [val for key, val in self.__dir.items()]
+
+ def get_node(self, name):
+ if name == '':
+ return self
+ elif name in self.__dir:
+ return self.__dir[name]
+ else:
+ raise NodeDoesNotExistError
+
+ def add_node(self, name, node):
+ if name == '':
+ raise SourceNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = node
+
+ def add_directory(self, name, file_sys):
+ if name == '' or name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemDirectory(file_sys)
+
+ def add_file(self, name, data, file_sys):
+ if name == '':
+ raise DestinationNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemFile(data, file_sys)
+
+ def add_link(self, name, node, symbolic, file_sys):
+ if name == '':
+ raise DestinationNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemLink(node, symbolic, file_sys)
+
+ def remove_node(self, name):
+ if name == '' or name not in self.__dir:
+ raise NodeDoesNotExistError
+ else:
+ del self.__dir[name]
+
+ def taken_space(self):
+ to_return = 1
+ for node in self.__dir:
+ to_return += self.__dir[node].taken_space()
+ return to_return
+
+
+class SystemLink(SystemNode):
+ def __init__(self, link_path, symbolic, file_sys):
+ super().__init__(False)
+ self.__link_path = link_path
+ self.__symbolic = symbolic
+ self.__file_sys = file_sys
+
+ @property
+ def link_path(self):
+ return self.__file_sys.get_node(self.__link_path)
+
+ @property
+ def content(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).content
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def files(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).files
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def nodes(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).nodes
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def directories(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).directories
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ def taken_space(self):
+ return 1
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.__size = size
+ self.__root = SystemDirectory(None)
+
+ def _set_root(self, directory):
+ self.__root = directory
+
+ @property
+ def size(self):
+ return self.__size
+
+ @property
+ def available_size(self):
+ return self.__size - self.__root.taken_space()
+
+ def get_node(self, path):
+ if len(path) == 0:
+ raise NodeDoesNotExistError
+ path_list = path.split('/')
+ to_return = self.__root
+ for name in path_list:
+ to_return = to_return.get_node(name)
+ return to_return
+
+ def create(self, path, *, directory=False, content=''):
+ path_list = path.split('/')
+ if len(path_list) < 2:
+ raise DestinationNodeDoesNotExistError
+ node = self.__root
+ try:
+ for name in path_list[:-1]:
+ node = node.get_node(name)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if node.is_directory:
+ Aval_space = self.available_size
+ if directory:
+ if Aval_space - 1 < 0:
+ raise NotEnoughSpaceError
+ else:
+ node.add_directory(path_list[-1], self)
+ else:
+ if Aval_space - len(content) - 1 < 0:
+ raise NotEnoughSpaceError
+ else:
+ node.add_file(path_list[-1], content, self)
+ else:
+ raise DestinationNodeDoesNotExistError
+
+ def remove(self, path, *, directory=False, force=True):
+ path_list = path.split('/')
+ if len(path_list) < 2:
+ raise NodeDoesNotExistError
+ node = self.__root
+ for name in path_list[:-1]:
+ node = node.get_node(name)
+ temp = node.get_node(path_list[-1])
+ if temp.is_directory:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ if len(temp.nodes) and not force:
+ raise NonEmptyDirectoryDeletionError
+ node.remove_node(path_list[-1])
+
+ def move(self, source, destination):
+ try:
+ source_node = self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+ try:
+ destination_node = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not destination_node.is_directory:
+ raise DestinationNotADirectoryError
+ destination_node.add_node(source.split('/')[-1], source_node)
+ self.remove(source, directory=source_node.is_directory)
+
+ def link(self, source, destination, *, symbolic=True):
+ try:
+ node = self.get_node(source)
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise
+ else:
+ raise SourceNodeDoesNotExistError
+ if node.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ path_list = destination.split('/')
+ destination_node = self.__root
+ for name in path_list[:-1]:
+ destination_node = destination_node.get_node(name)
+ if destination_node.is_directory:
+ destination_node.add_link(path_list[-1], node, symbolic, self)
+ else:
+ raise DestinationNotADirectoryError
+
+ def mount(self, file_system, path):
+ try:
+ node = self.get_node(path)
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+ if node.is_directory:
+ if node.nodes:
+ raise MountPointNotEmptyError
+ else:
+ file_system._set_root(node)
+ else:
+ raise MountPointNotADirectoryError
+
+ def unmount(self, path):
+ pass