Александър обнови решението на 30.04.2015 16:57 (преди над 9 години)
+class NodeDoesNotExistError(Exception):
+ pass
+
+
+class DestinationNodeDoesNotExistError(Exception):
+ pass
+
+
+class NotEnoughSpaceError(Exception):
+ pass
+
+
+class DestinationNodeExistsError(Exception):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(Exception):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(Exception):
+ pass
+
+
+class SourceNodeDoesNotExistError(Exception):
+ pass
+
+
+class DestinationNotADirectoryError(Exception):
+ pass
+
+
+class DirectoryHardLinkError(Exception):
+ pass
+
+
+class FileSystemMountError(Exception):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+def defracture_path(path):
+ return list(filter(lambda x: x != "", path.split("/")))
+
+
+def reconstruct_path(defractured):
+ return ("/".join(defractured))
+
+
+class AvailableSize:
+ def __init__(self, available_size):
+ self.available_size = available_size
+
+ def add(self, amount):
+ if amount > self.available_size:
+ raise NotEnoughSpaceError
+ self.available_size -= amount
+
+ def remove(self, amount):
+ self.available_size += amount
+
+ def get_amount(self):
+ return self.available_size
+
+
+class Content:
+ def __init__(self, content):
+ self.content = content
+
+ def get_content(self):
+ return self.content
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+
+
+class File:
+ FILE_SIZE = 1
+
+ def __init__(self, name, content, path, system_availble_size):
+ self.name = name
+ self.content = Content(content)
+ self.path = path
+ self.size = len(content) + self.FILE_SIZE
+ self.available_size = system_availble_size
+
+ def content(self):
+ return self.content.get_content()
+
+ def get_name(self):
+ return self.name
+
+ def size(self):
+ return self.size
+
+ def append(self, text):
+ self.available_size.add(len(text))
+ self.content.append(text)
+ self.size += len(text)
+
+ def truncate(self, text):
+ self.content.truncate(text)
+ self.size = len(text) + self.FILE_SIZE
+
+ def is_directory(self):
+ return False
+
+
+class Directory:
+ DIRECTORY_SIZE = 1
+
+ def __init__(self, name, content={}):
+ self.name = name
+ self.content = content
+ self.size = self.DIRECTORY_SIZE
+
+ def get_name(self):
+ return self.name
+
+ def size(self):
+ return sum(file.size() for file in self.content.values()) + self.size
+
+ def get_node(self, path):
+ defractured_path = defracture_path(path)
+ node_name = defractured_path[0]
+ if node_name not in self.content:
+ raise NodeDoesNotExistError
+ elif isinstance(self.content[node_name], Directory):
+ if len(defractured_path) > 1:
+ defractured_path.pop()
+ self.content.get_node(reconstruct_path(defractured_path))
+
+ return self.content[node_name]
+
+ def content(self):
+ return self.content
+
+ def nodes(self):
+ return list(self.content.values())
+
+ def directories(self):
+ all_files = self.content.values()
+ return [dir for dir in all_files if isinstance(dir, Directory)]
+
+ def files(self):
+ all_files = self.content.values()
+ return [dir for dir in all_files if isinstance(dir, File)]
+
+ def add_content(self, content):
+ self.content[content.get_name()] = content
+
+ def is_directory(self):
+ return True
+
+ def remove(self, content):
+ del self.content[content.get_name]
+
+class Symbolic:
+ def __init__(self, name, path, type):
+ self.name = name
+ self.path = path
+
+
+class FileSystem:
+ def __init__(self, size, path=''):
+ self.path = path
+ self.size = size
+ self.content = {"root": Directory("root")}
+ self._available_size = AvailableSize(size - Directory.DIRECTORY_SIZE)
+
+ def get_node(self, path):
+ self.content["root"].get_node(path)
+
+ def create(self, path, directory=False, content=''):
+ defractured = defracture_path(path)[-1]
+ node_name = defractured.pop(-1)
+ path_to_directory = reconstruct_path(defractured)
+ try:
+ node_directory = self.get_node(path_to_directory)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+
+ if not node_directory.is_directory():
+ raise DestinationNodeDoesNotExistError
+
+ elif node_name in node_directory.content:
+ raise DestinationNodeExistsError
+
+ elif directory:
+ self.available_size.add(Directory.DIRECTORY_SIZE)
+ node_directory.add_content(Directory(node_name))
+
+ else:
+ self.available_size.add(len(content) + File.FILE_SIZE)
+ node_directory.add_content(File(node_name,
+ content,
+ path_to_directory,
+ self._available_size))
+
+ def remove(self, path, directory=False, force=True):
+ defractured = defracture_path(path)[-1]
+ path_to_directory = reconstruct_path(defractured)
+ file_to_delete = self.get_node(path)
+ if file_to_delete.is_directory() and not directory:
+ raise NonExplicitDirectoryDeletionError
+ elif directory.content and not force:
+ raise NonEmptyDirectoryDeletionError
+
+ file_directory = self.get_node(path_to_directory)
+ self._available_size.remove(file_to_delete.size)
+ file_directory.remove(file_to_delete)
+
+ def move(self, source, destination):
+ pass
+
+ def link(source, destination):
+ pass
+
+ def mount(file_system, path):
+ pass
+
+ def unmount(path):
+ pass
+
+ @property
+ def available_size(self):
+ return self._available_size.get_amount()