Илиан обнови решението на 30.04.2015 16:57 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotAMountPointError(FileSystemMountError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class File:
+ def __init__(self, content):
+ self.content = str(content)
+ self.is_directory = False
+
+ def append(self, text):
+ self.content.append(str(text))
+
+ def truncate(self, text):
+ self.content = str(text)
+
+ def size(self):
+ return 1 + len(self.content)
+
+
+class Directory:
+ def __init__(self, mount=False):
+ self.directories = dict()
+ self.files = dict()
+ self.nodes = dict()
+ self.mmount = mount
+ self.is_directory = True
+
+
+class FileSystem:
+ def __init__(self, size):
+ if size <= 1:
+ raise NotEnoughSpaceError
+ self.size = size
+ self.available_size = size - 1
+ self.root = Directory()
+
+ def resize(self, ammount):
+ if self.available_size + ammount < 0:
+ raise NotEnoughSpaceError
+ else:
+ self.available_size += ammount
+
+ def get_node_helper(self, path_levels, dir):
+ if len(path_levels) == 0:
+ raise NodeDoesNotExistError
+ elif len(path_levels) == 1:
+ if path_levels[0] in dir.files:
+ return dir.files[path_levels[0]]
+ elif path_levels[0] in dir.directories:
+ return dir.directories[path_levels[0]]
+ elif path_levels[0] in dir.directories:
+ return get_node_helper(path_levels[1:],
+ dir.directories[path_levels[0]])
+ else:
+ raise NodeDoesNotExistError
+
+ def get_node(self, path):
+ path_levels = str(path).split('/')
+ if len(path_levels) == 1 and path_levels[0] == '':
+ return self.root
+ return self.get_node_helper(path_levels[1:], self.root)
+
+ def create(self, path, directory=False, content=''):
+ levels = path.split('/')
+ node = Directory()
+ try:
+ node = self.get_node("/".join(levels[:-1]))
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ file_name = levels[-1]
+ if file_name in node.nodes:
+ raise DestinationNodeExistsError
+ if directory:
+ self.resize(-1)
+ node.directories[file_name] = Directory()
+ node.nodes[file_name] = node.directories[file_name]
+ else:
+ self.resize(-len(content))
+ node.files[file_name] = File(content)
+ node.nodes[file_name] = node.files[file_name]
+
+ def remove(self, path, directory=False, force=True):
+ node = self.get_node(path)
+ file_name = path.split('/')[-1]
+ if file_name not in node.nodes:
+ raise NodeDoesNotExistError
+ elif file_name in node.directories:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ else:
+ if node.directories[file_name].nodes and not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ del node.directories[file_name]
+ del node.nodes[file_name]
+ else:
+ del node.files[file_name]
+ del node.nodes[file_name]
+
+ def move(self, source, destination):
+ source_levels = source.split('/')
+ source_dir
+ destination_dir
+ try:
+ source_dir = self.get_node("/".join(source_levels[:-1]))
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+ try:
+ destination_dir = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not destination_dir.is_directory():
+ raise DestinationNotADirectoryError
+ else:
+ if source_path_levels[-1] in destination_dir.nodes:
+ raise DestinationNodeExistsError
+ else:
+ if source_levels[-1] in source_dir.directories:
+ destination_dir.directories[source_level[-1]] = source_dir.directories[source_level[-1]]
+ del source_dir.directories[source_level[-1]]
+ else:
+ destination_dir.files[source_level[-1]] = source_dir.files(source_level[-1])
+ del source_dir.files[source_level[-1]]
+ destination_dir.nodes[source_levels[-1]] = source_dir.nodes[source_levels[-1]]
+ del source_dir[source_levels[-1]]
+
+ def link(self, source, destination, symbolic=True):
+ source_levels = source.split('/')
+ if source_dir:
+ destination_dir = self.get_node(source_levels[:-1])
+ try:
+ source_dir = self.get_node(source_levels[:-1])
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+ if symbolic is False and source_dir[source_levels[-1]].is_directory():
+ raise DirectoryHardLinkError
+ elif symbolic is False and not source_dir.get(source_levels[0]):
+ raise SourceNodeDoesNotExistError
+ elif symbolic is True:
+ destination_dir[source_levels[-1]] = File(source)
+ elif symbolic is False:
+ destination_dir[source_levels[-1]] = source_dir[source_levels[-1]]
+ else:
+ raise NodeDoesNotExistError
+
+ def mount(self, file_system, path):
+ path_levels = path.split('/')
+ mount_dir
+ try:
+ mount_dir = self.get_node(path_levels[:-1])
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+ if path_levels[-1] not in mount_dir.nodes:
+ raise MountPointDoesNotExistError
+ elif not mount_dir.nodes[path_levels[-1]].is_directory():
+ raise MountPointNotADirectoryError
+ elif not mount_dir.nodes[path_levels[-1]]:
+ raise MountPointNotEmptyError
+ else:
+ mount_dir[path_levels[-1]] = file_system.root
+ mount_dir[path_levels[-1]].mount = True
+
+ def unmount(self, path):
+ path_levels = path.split('/')
+ mount_dir = self.get_node(path_levels[:-1])
+ if not mount_dir.mount:
+ raise NotAMountPointError
+ mount_dir = Directory()
+ mount_dir.mount = False