Мартин обнови решението на 30.04.2015 15:51 (преди над 9 години)
+separator = "/"
+
+
+class FileSystem:
+ # examlple usage:
+ # sda1 = FileSystem(250 * (1024 ** 3)) # initialize a 250GB file system
+
+ def __init__(self, size): # working
+ if size < 1:
+ raise NotEnoughSpaceError
+ root = Directory("", "", {})
+ self.structure = {root.name: root}
+ """
+ empty directory: {name: {}}
+ not empty directory: {name: object(file or folder)}
+ if object is folder(dir) it has attribute subdirs which is of type dict
+ if object is empty folder(dir) its subdirs are {}
+
+ file: {name: object(file)}; file has only a content
+ """
+ self.flattened_structure = {}
+ self.size = size
+ self.available_size = size - 1
+
+ def calculate_system_size(self): # working
+ size = 0
+ for cur_file in flatten_dict(self.structure[""]).values():
+ if cur_file.endswith(".d"):
+ size += 1
+ if cur_file.endswith(".f"):
+ size += len(get_name(cur_file[:-2]))
+ return size + 1
+
+ def get_node(self, path): # working
+ if not file_or_folder_exist(path, self.structure[""]):
+ raise NodeDoesNotExistError
+ parent_folder = return_parent_folder_on_path(path, self.structure[""])
+ name = get_name(path)
+ if path == "":
+ return self.structure[""]
+ if parent_folder.subdirs[name].is_directory:
+ return parent_folder.subdirs[name]
+ elif not parent_folder.subdirs[name].is_directory:
+ return parent_folder.subdirs[name]
+
+ def create(self, path, directory=False, content=''): # working
+ if file_or_folder_exist(path, self.structure[""]):
+ raise DestinationNodeExistsError
+ if not file_or_folder_exist(get_path(path), self.structure[""]):
+ raise DestinationNodeDoesNotExistError
+
+ if directory:
+ if self.available_size < 1:
+ raise NotEnoughSpaceError
+ else:
+ insert_directory_with_path(
+ path,
+ self.structure[""],
+ {}
+ )
+ self.available_size = self.size - self.calculate_system_size()
+ else:
+ if self.available_size < 1 + len(content):
+ raise NotEnoughSpaceError
+ else:
+ insert_file_with_path(
+ path,
+ self.structure[""],
+ content
+ )
+ self.available_size = self.size - self.calculate_system_size()
+
+""" Insert files functions start"""
+
+
+def return_parent_folder_on_path(path, structure): # working
+ path = get_path(path)
+ subfolders = get_subfolders(path)[1:]
+ for name in subfolders:
+ structure = structure.subdirs[name]
+ return structure
+
+
+def file_or_folder_exist(path, structure): # working
+ subfolders = get_subfolders(path)[1:]
+ try:
+ for name in subfolders:
+ structure = structure.subdirs[name]
+ return True
+ except KeyError:
+ return False
+ except AttributeError:
+ return True
+
+
+def insert_directory_with_path(
+ path, structure, dict_from_structure
+ ): # working
+ if not file_or_folder_exist(get_path(path), structure) or \
+ (dict_from_structure != {}) and \
+ (not file_or_folder_exist(path, structure)
+ ):
+ return None
+ name = get_name(path)
+ folder = Directory(name, path, dict_from_structure)
+ cur_dict_from_structure = {folder.name: folder}
+ parent_folder = return_parent_folder_on_path(path, structure)
+ parent_folder.subdirs.update(cur_dict_from_structure)
+
+
+def insert_file_with_path(path, structure, content=""): # working
+ if not file_or_folder_exist(get_path(path), structure):
+ return None
+ cur_file = File(get_name(path), path, content)
+ cur_dict_from_structure = {cur_file.name: cur_file}
+ parent_folder = return_parent_folder_on_path(path, structure)
+ parent_folder.subdirs.update(cur_dict_from_structure)
+
+""" Insert files functions end"""
+
+
+""" File and Dir classes start"""
+
+
+class File: # working
+
+ def __init__(self, name, path="", content=''):
+ self.content = content
+
+ self.name = name
+ self.path = path
+ self.size = len(self.content) + 1
+ self.is_directory = False
+
+ def append(self, text):
+ self.content += text
+ self.size = len(self.content) + 1
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(self.content) + 1
+
+
+class Directory: # working
+
+ def __init__(self, name, path="", dirs={}):
+ self.subdirs = dirs
+
+ self.name = name
+ self.path = path
+ self.size = 1
+ self.is_directory = True
+""" File and Dir classes end"""
+
+""" slice the path start"""
+
+
+def get_name(path): # working
+ return path[path.rfind("/") + 1:]
+
+
+def get_path(path): # working
+ return path[:path.rfind("/")]
+
+
+def get_subfolders(path): # working
+ return path.split("/")
+
+
+def flatten_dict(structure, left_key=''): # working
+ result = {}
+ for right_key, object_with_structure in structure.subdirs.items():
+ key = left_key + right_key
+ if (object_with_structure.is_directory and
+ object_with_structure.subdirs != {}):
+ # if is directory and has subfolders
+ result[separator + key] = object_with_structure.name + ".d"
+ result.update(flatten_dict(object_with_structure, key + separator))
+
+ elif object_with_structure.is_directory:
+ # if is directory and is empty
+ result[separator + key] = object_with_structure.name + ".d"
+ else:
+ # if is file
+ result[separator + key] = object_with_structure.name + ".f"
+ # returns dict with keys - directories and values - content/None
+ return result
+""" slice the path end"""
+
+""" Exceptions start"""
+
+
+class FileSystemError(Exception):
+
+ def __init__(self, message="System error."):
+ self.message = message
+
+
+class NotEnoughSpaceError(FileSystemError):
+
+ def __init__(self, message="Insufficient recources."):
+ self.message = message
+
+
+class DestinationNodeExistsError(FileSystemError):
+
+ def __init__(self, message="File/ folder already exists."):
+ self.message = message
+
+
+class NodeDoesNotExistError(FileSystemError):
+
+ def __init__(self, message="File/ directory does not exist."):
+ self.message = message
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+
+ def __init__(self, message="Source does not exist."):
+ self.message = message
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+
+ def __init__(self, message="Destination does not exist"):
+ self.message = message
+
+
+class FileSystemMountError(FileSystemError):
+
+ def __init__(self, message="FileSystem mount error."):
+ self.message = message
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+
+ def __init__(self, message="Mount point does not exist."):
+ self.message = message
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+
+ def __init__(self, message="Mount point is not a directory."):
+ self.message = message
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+
+ def __init__(self, message="Mount point is not an empty directory."):
+ self.message = message
+""" Exceptions end"""