Павел обнови решението на 26.04.2015 12:41 (преди над 9 години)
+class FileSystem():
+
+ class SimpleFile():
+
+ def __init__(self, name, content):
+ self.name = name
+ self.is_directory = False
+ self.content = content
+ self.size = len(content) + 1
+
+ def append(self, text):
+ self.content += text
+ self._size_update_file()
+
+ def truncate(self, text):
+ self.content = text
+ self._size_update_file()
+
+ def _size_update_file(self):
+ self.size = len(self.content) + 1
+
+ class SimpleDirectory():
+
+ def __init__(self, name):
+ self.size = 1
+ self.name = name
+ self.is_directory = True
+ self.directories = list()
+ self.files = list()
+ self.nodes = list()
+
+ def __init__(self, size):
+ self.size = size
+ self.available_size = size - 1
+ self.root = self.SimpleDirectory("/")
+
+ def _size_update(self, path, bits_added):
+
+ self.available_size -= bits_added
+ if path == "/":
+ self.get_node("/").size += bits_added
+ else:
+ self.get_node("/").size += bits_added
+ path = path.split("/")
+ del path[0]
+ current_node_path = ""
+ for node_name in path:
+ current_node_path += "/" + node_name
+ self.get_node(current_node_path).size += bits_added
+
+ def get_node(self, path):
+ if path == "/":
+ return self.root
+ path = path.split("/")
+ del path[0]
+ current_dir = self.root
+ for index, current_node in enumerate(iter(path)):
+
+ sub_dir_names = [sub_dir_name.name for
+ sub_dir_name in current_dir.directories]
+
+ sub_node_names = [sub_node_name.name for
+ sub_node_name in current_dir.nodes]
+
+ if current_node in sub_dir_names and index != (len(path) - 1):
+ index_next_dir = sub_dir_names.index(current_node)
+ current_dir = current_dir.directories[index_next_dir]
+ continue
+
+ elif current_node in sub_node_names and index == (len(path) - 1):
+ for node in current_dir.nodes:
+ if node.name == current_node:
+ return node
+
+ elif current_node not in sub_node_names:
+ raise NodeDoesNotExistError
+
+ def create(self, path, directory=False, content=""):
+
+ is_directory = directory
+ bits_to_be_added = 1 + len(content)
+
+ path = path.split("/")
+ new_node_name = path[-1]
+ del path[-1]
+ del path[0]
+
+ path = "/" + "/".join(path)
+
+ try:
+ self.get_node(path)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+
+ if self.available_size < bits_to_be_added:
+ raise NotEnoughSpaceError
+
+ current_node = self.get_node(path)
+
+ sub_node_names = [sub_node_name.name for
+ sub_node_name in current_node.nodes]
+
+ if new_node_name in sub_node_names:
+ raise DestinationNodeExistsError
+
+ if is_directory:
+ new_directory = self.SimpleDirectory(new_node_name)
+ current_node.nodes.append(new_directory)
+ current_node.directories.append(new_directory)
+ else:
+
+ new_file = self.SimpleFile(new_node_name, content)
+ current_node.nodes.append(new_file)
+ current_node.files.append(new_file)
+
+ self._size_update(path, bits_to_be_added)
+
+ def remove(self, path, directory=False, force=True):
+ original_node_is_directory = self.get_node(path).is_directory
+ node_to_be_removed = self.get_node(path)
+ is_directory = directory
+ del_with_force = force
+ if node_to_be_removed.is_directory and not is_directory:
+ raise NonExplicitDirectoryDeletionError
+
+ if is_directory and node_to_be_removed.nodes != [] \
+ and not del_with_force:
+ raise NonEmptyDirectoryDeletionError
+
+ parent_path = path.split("/")
+
+ if len(parent_path) > 2:
+ del parent_path[0]
+ del parent_path[-1]
+ parent_path = "/" + "/".join(parent_path)
+ else:
+ parent_path = "/"
+
+ bits_to_be_removed = self.get_node(path).size
+ parent_of_node_to_be_removed = self.get_node(parent_path)
+
+ # if is_directory:
+ if original_node_is_directory:
+ parent_of_node_to_be_removed.directories.remove(node_to_be_removed)
+ parent_of_node_to_be_removed.nodes.remove(node_to_be_removed)
+ else:
+ parent_of_node_to_be_removed.files.remove(node_to_be_removed)
+ parent_of_node_to_be_removed.nodes.remove(node_to_be_removed)
+
+ self._size_update(parent_path, -bits_to_be_removed)
+
+ def move(self, source, destination):
+
+ try:
+ self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+
+ if not self.get_node(destination).is_directory:
+ raise DestinationNotADirectoryError
+
+ source_name = self.get_node(source).name
+ destination_node = self.get_node(destination)
+
+ for node in destination_node.nodes:
+ if node.name == source_name:
+ raise DestinationNodeExistsError
+
+ node_to_be_moved = self.get_node(source)
+
+ if node_to_be_moved.is_directory:
+ self.remove(source, True, True)
+ destination_node.directories.append(node_to_be_moved)
+ destination_node.nodes.append(node_to_be_moved)
+ else:
+ self.remove(source, False)
+ destination_node.files.append(node_to_be_moved)
+ destination_node.nodes.append(node_to_be_moved)
+
+ self._size_update(destination, node_to_be_moved.size)
+
+ def link(self, source, destination, symbolic=True):
+ pass
+
+ def mount(self, file_system, path):
+ pass
+
+ def unmount(self, path):
+ pass
+
+
+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError (NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass