Валентина обнови решението на 30.04.2015 16:32 (преди над 9 години)
+class FileSystem:
+
+ def __init__(self, size_in_bytes):
+ self.root = FSDirectory('/')
+ if size_in_bytes > 0:
+ self.size = size_in_bytes
+ else:
+ raise NotEnoughSpaceError
+ self.available_size = self.size - 1
+
+ def get_node(self, path):
+ if path[0] is "/":
+ current = self.root
+ path_nodes = self.__get_path_names(path)
+ if path_nodes:
+ path_directories = path_nodes[:-1]
+ path_node = path_nodes[-1]
+ for name in path_directories:
+ sub_dirs = self.__get_nodes_names(current.directories)
+ if name in sub_dirs:
+ current = current.directories[sub_dirs.index(name)]
+ else:
+ raise NodeDoesNotExistError
+ nodes = self.__get_nodes_names(current.nodes)
+ if path_node in nodes:
+ result = current.nodes[nodes.index(path_node)]
+ if result in current.directories:
+ result.is_directory = True
+ else:
+ result.is_directory = False
+ else:
+ raise NodeDoesNotExistError
+ else:
+ result = self.root
+ result.is_directory = True
+ return result
+ else:
+ raise NodeDoesNotExistError
+
+ def create(self, path, directory=False, content=''):
+ try:
+ parent = self.__get_parent_node(path)
+ new_node_name = self.__get_path_names(path)[-1]
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if new_node_name not in self.__get_nodes_names(parent.nodes):
+ if directory:
+ if self.available_size >= 1:
+ self.available_size -= 1
+ new_node = FSDirectory(new_node_name)
+ parent.directories.append(new_node)
+ else:
+ raise NotEnoughSpaceError
+ else:
+ if self.available_size >= len(content) + 1:
+ self.available_size -= (len(content) + 1)
+ new_node = FSFile(new_node_name)
+ new_node.append(content)
+ parent.files.append(new_node)
+ else:
+ raise NotEnoughSpaceError
+ parent.nodes.append(new_node)
+ else:
+ raise DestinationNodeExistsError
+
+ def remove(self, path, directory=False, force=True):
+ target = self.get_node(path)
+ parent = self.__get_parent_node(path)
+ if not target.is_directory:
+ self.available_size += target.size
+ del parent.files[parent.files.index(target)]
+ del parent.nodes[parent.nodes.index(target)]
+ else:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ else:
+ if not target.nodes:
+ self.available_size += 1
+ del parent.directories[parent.directories.index(target)]
+ del parent.nodes[parent.nodes.index(target)]
+ elif not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ for child in self.__get_children_paths(path):
+ self.remove(child, directory=True)
+
+ def move(self, source, destination):
+ try:
+ destination_node = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not destination_node.is_directory:
+ raise DestinationNotADirectoryError
+ moved_name = self.__get_path_names[-1]
+ if moved_name in self.__get_nodes_names(destination_node.nodes):
+ raise DestinationNodeExistsError
+ source_node = self.get_node(source)
+ parent = self.__get_parent_node(source)
+ if not source_node.is_directory:
+ destination_node.files.append(source_node)
+ del parent.files[parent.files.index(source_node)]
+ else:
+ destination_node.directories.append(source_node)
+ del parent.directories[parent.directories.index(source_node)]
+ destination_node.nodes.append(source_node)
+ del parent.nodes[parent.nodes.index(source_node)]
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ src = self.get_node(source)
+ if src.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ if symbolic: # LinkPathError to do yet
+ symbolic_link = self.create(destination)
+ symbolic_link.link_path = src
+ else:
+ if not src.is_directory:
+ hard_link = self.create(destination)
+ hard_link.content = src.content
+ hard_link.size += src.size
+ src.size = hard_link.size
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+
+ def mount(self, file_system, path):
+ try:
+ mount_point = self.get_node(path)
+ if mount_point.is_directory and mount_point.nodes:
+ raise MountPointNotEmptyError
+ if not mount_point.is_directory:
+ raise MountPointDoesNotExistError # or file error?
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+
+ mount_point.is_mount_point = True
+ mount_point_name = mount_point.name
+ mount_point = file_system.root
+ mount_point.name = mount_point_name
+ # not quite true fix it if there is enough time
+ # what about file_system.get_node('/')?
+ # also not working way:
+ # mount_point.directories.extend(file_system.root.directories)
+ # mount_point.files.extend(file_system.root.files)
+ # mount_point.nodes.extend(file_system.root.nodes)
+
+ def unmount(self, path):
+ try:
+ unmount_point = self.get_node(path)
+ if not unmount_point.is_mount_point:
+ raise NotAMountpointError
+ self.remove(path)
+ self.create(path)
+ except NodeDoesNotExistError:
+ raise NodeDoesNotExistError
+
+ def __get_path_names(self, path):
+ return [node for node in path.split('/') if node is not '']
+
+ def __get_nodes_names(self, nodes):
+ return [node.name for node in nodes]
+
+ def __get_parent_node(self, path):
+ split_index = path[::-1].index('/')
+ return self.get_node(path[:-split_index])
+
+ def __get_children_paths(self, path):
+ current = self.get_node(path)
+ return [path + '/' + child.name for child in current.nodes]
+
+
+class FSDirectory:
+
+ def __init__(self, name):
+ self.name = name
+ self.directories = []
+ self.files = []
+ self.nodes = []
+
+
+class FSFile:
+
+ def __init__(self, name):
+ self.name = name
+ self.content = ""
+ self.size = 1
+
+ def append(self, text):
+ self.content += text
+ self.size += len(text)
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(text) + 1
+
+
+class FileSystemError(Exception):
+ def __init__(self):
+ self.message = "There is some file system error: "
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Node doesn't exist"
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ super().__init__()
+ self.message += "at this destination"
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ super().__init__()
+ self.message += "at this source"
+
+
+class FileSystemMountError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Problem while mounting."
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Mount point should be empty."
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Mount point should be created first."
+
+
+class NotAMountpointError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Can't unmount. The directory isn't a mount point"
+
+
+class LinkPathError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Source node doesn't exist"
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Not enough space to do the operation"
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "There is already a node with that name"
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Attempt to delete a directory; Assure directory=True"
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Non empty directory to be deleted; Assure force=True"
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Attempt to move; Destination isn't a directory"
+
+
+class DirectoryHardLinkError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Can't make hard link to directory"