Мартин обнови решението на 30.04.2015 16:49 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass # ???
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass # ????
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class FileSystemRemoveError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemRemoveError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemRemoveError):
+ pass
+
+
+class File:
+
+ def __init__(self, name, content=''):
+ self.is_directory = False
+ self.name = name
+ self.content = content
+ self.size = len(self.content) + 1
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+
+
+class Directory:
+
+ def __init__(self, name, size):
+ self.is_directory = True
+ self.name = name
+ self.size = size
+ self.empty = True
+ self.nodes = list()
+
+ @property
+ def files(self):
+ return [x for x in self.nodes if type(x) is File]
+
+ @property
+ def directories(self):
+ return [x for x in self.nodes if type(x) is Directory]
+
+ def add_node(self, node):
+ self.nodes.append(node)
+ self.size += node.size
+ self.empty = False
+
+ def remove_node(self, node):
+ if node in self.nodes:
+ self.size -= node.size
+ self.nodes.remove(node)
+
+ def contains(self, node_name):
+ return any(node_name == node.name for node in self.nodes)
+
+ def get_node_with_name(self, node_name):
+ for node in self.nodes:
+ if node.name == node_name:
+ return node
+
+
+class FileSystem:
+
+ def __init__(self, size):
+ self.size = size
+ self.available_size = self.size - 1
+ self.root = Directory('/', 1)
+
+ def __is_valid_path(self, path):
+ splitted_path = path.split('/')
+ if path == '/':
+ return True
+ if splitted_path[0] != '' or not path:
+ return False
+ current_node = self.root
+ for index in range(1, len(splitted_path)):
+ if not current_node.is_directory:
+ return False
+ if not current_node.contains(splitted_path[index]):
+ return False
+ current_node = \
+ current_node.get_node_with_name(splitted_path[index])
+ return True
+
+ def __get_parent(self, path):
+ if path.count('/') == 1:
+ return '/'
+ else:
+ return path.rsplit('/', maxsplit=1)[0]
+
+ def get_node(self, path):
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError
+ current_node = self.root
+ splitted_path = path.split('/')
+ if path == '/':
+ return self.root
+ for index in range(1, len(splitted_path)):
+ current_node = \
+ current_node.get_node_with_name(splitted_path[index])
+ return current_node
+
+ def create(self, path, directory=False, content=''):
+ # sizes need fixes
+ space_amount_needed = len(content) + 1
+ if space_amount_needed > self.available_size:
+ raise NotEnoughSpaceError
+ self.available_size -= space_amount_needed
+ node_name = path.rsplit('/', maxsplit=1)[1]
+ if not self.__is_valid_path(self.__get_parent(path)):
+ raise DestinationNodeDoesNotExistError
+ if self.__is_valid_path(path):
+ raise DestinationNodeExistsError
+ if directory:
+ self.get_node(
+ self.__get_parent(path)).add_node(Directory(node_name, 1))
+ else:
+ if self.get_node(self.__get_parent(path)).is_directory:
+ self.get_node(self.__get_parent(path)).add_node(
+ File(node_name, content))
+ else:
+ raise NodeDoesNotExistError # ??
+ self.get_node(self.__get_parent(path)).size += space_amount_needed
+
+ def remove(self, path, directory=False, force=True):
+ # sizes need fixes
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError # ?
+ if self.get_node(path).is_directory and not directory:
+ raise NonExplicitDirectoryDeletionError
+ if directory and not self.get_node(path).empty and not force:
+ raise NonEmptyDirectoryDeletionError
+ self.available_size += self.get_node(path).size
+ self.get_node(self.__get_parent(path)).size -= self.get_node(path).size
+ self.get_node(self.__get_parent(path)).remove_node(
+ self.get_node(path))
+
+ def move(self, source, destination):
+ if not self.__is_valid_path(source):
+ raise SourceNodeDoesNotExistError
+ if not self.__is_valid_path(destination):
+ raise DestinationNodeDoesNotExistError
+ if not self.get_node(destination).is_directory:
+ raise DestinationNotADirectoryError
+ if self.get_node(destination).contains(
+ source.rsplit('/', maxsplit=1)[1]):
+ raise DestinationNodeExistsError
+
+ self.get_node(destination).add_node(self.get_node(source))
+ for node in self.get_node(self.__get_parent(source)).nodes:
+ self.get_node(self.__get_parent(source)).remove_node(node)
+
+ def ls(self, path):
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError
+ if not self.get_node(path).is_directory:
+ raise NotADirectoryError
+ node_list = list()
+ for node in self.get_node(path).nodes:
+ node_list.append(node.name)
+ return node_list
+
+ def mount(self, file_system, path):
+ pass
+
+ def unmount(self, path):
+ pass
+
+ def link(self, source, destination, symbolic=True):
+ pass