Галина обнови решението на 30.04.2015 00:00 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class File(object):
+ def __init__(self, path, content=""):
+ self.path = path
+ self.is_directory = False
+ self.content = content
+ self.size = len(content) + 1
+
+ def __str__(self):
+ return self.content
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(content) + 1
+
+
+class Directory(object):
+ def __init__(self, path, directories=[], files=[]):
+ self.path = path
+ self.is_directory = True
+ self.directories = directories
+ self.files = files
+ self.nodes = directories + files
+ self.size = 1
+
+
+class FileSystem(object):
+ def __init__(self, system_size):
+ if system_size < 1:
+ raise NotEnoughSpaceError()
+ self.nodes = {}
+ self.nodes["/"] = Directory("/")
+ self.size = system_size
+ self.available_size = self.set_available_size()
+
+ def set_available_size(self):
+ system_size = self.size
+ used_size = 0
+ for node in self.nodes.values():
+ used_size += node.size
+ system_size -= used_size
+ return system_size
+
+ def all_paths(self):
+ return [obj.path for obj in self.nodes.values()]
+
+ def valid_path(self, path):
+ valid = ""
+ for item in path.split("/"):
+ if item != "":
+ valid += "/" + item
+ if valid == "":
+ valid = "/"
+ return valid
+
+ def get_node(self, path):
+ path = self.valid_path(path)
+ if path in self.all_paths():
+ return self.nodes[path]
+ raise NodeDoesNotExistError()
+
+ def new_path(self, source, destination):
+ return destination + "/" + source.split("/")[-1]
+
+ def add_nodes_to_dir(self, path, is_dir):
+ b_dir = path.split("/")[:-1]
+ items = b_dir if b_dir != [""] else "/"
+ base_dir = "/".join(items)
+ if is_dir:
+ self.nodes[base_dir].directories.append(self.nodes[path])
+ self.nodes[base_dir].files.append(self.nodes[path])
+
+ def create(self, path, directory=False, content=''):
+ path = self.valid_path(path)
+ b_dir = path.split("/")[:-1]
+ items = b_dir if b_dir != [""] else "/"
+ base_dir = "/".join(items)
+ paths = self.all_paths()
+ if base_dir not in paths:
+ raise DestinationNodeDoesNotExistError
+ elif self.available_size < (len(content) + 1):
+ raise NotEnoughSpaceError()
+ elif path in paths:
+ raise DestinationNodeExistsError
+ else:
+ if directory:
+ self.nodes[path] = Directory(path)
+ self.add_nodes_to_dir(path, True)
+ self.available_size = self.set_available_size()
+ return self.nodes[path]
+ self.nodes[path] = File(path, content)
+ self.add_nodes_to_dir(path, False)
+ self.available_size = self.set_available_size()
+ return self.nodes[path]
+
+ def remove(self, path, directory=False, force=True):
+ path = self.valid_path(path)
+ obj = self.get_node(path)
+ if obj.is_directory and not directory:
+ raise NonExplicitDirectoryDeletionError()
+ elif obj.is_directory and obj.nodes != [] and not force:
+ raise NonEmptyDirectoryDeletionError()
+ else:
+ self.available_size += obj.size
+ self.nodes.pop(path)
+
+ def move(self, source, destination):
+ source = self.valid_path(source)
+ destination = self.valid_path(destination)
+
+ paths = self.all_paths()
+ dest_obj = self.get_node(destination)
+ if source not in paths:
+ raise SourceNodeDoesNotExistError()
+ elif destination not in paths:
+ raise DestinationNodeDoesNotExistError()
+ elif not dest_obj.is_directory:
+ raise DestinationNotADirectoryError()
+ elif self.new_path(source, destination) in dest_obj.nodes:
+ raise DestinationNodeExistsError()
+ else:
+ if self.nodes[source].is_directory:
+ self.create(self.new_path(source, destination), True)
+ else:
+ self.create(self.new_path(source, destination),
+ False,
+ self.nodes[source].content)
+ self.nodes.pop(source)
+
+ def link(self, source, destination, symbolic=True):
+ source = self.valid_path(source)
+ destination = self.valid_path(destination)
+ source_exists = source in self.all_paths()
+ is_dir = self.get_node(source).is_directory
+ if not source_exists and symbolic:
+ raise NodeDoesNotExistError()
+ if is_dir and not symbolic:
+ raise DirectoryHardLinkError()
+ if not source_exists and not symbolic and not is_dir:
+ raise SourceNodeDoesNotExistError()
+ else:
+ pass