Калоян обнови решението на 30.04.2015 10:23 (преди над 9 години)
+import copy
+
+
+class Record:
+ def __init__(self, name, is_directory):
+ self.name = name
+ self.is_directory = is_directory
+
+ '''
+ def __getattr__(self, name):
+ if self.fail_to_link is not None:
+ if self.fail_to_link:
+ raise LinkPathError()
+ else:
+ return name
+ else:
+ return name
+
+ def __setattr__(self, name, value):
+ if self.fail_to_link is not None:
+ if self.fail_to_link:
+ raise LinkPathError()
+ else:
+ return object.__setattr__(self, name, value)
+ else:
+ return object.__setattr__(self, name, value)
+ '''
+
+
+class File(Record):
+ def __init__(self, name, content):
+ Record.__init__(self, name, False)
+ self.content = content
+ self.set_size()
+
+ def append(self, text):
+ self.content += text
+ self._set_size()
+
+ def truncate(self, text):
+ self.content = text
+ self._set_size()
+
+ def set_size(self):
+ self.size = len(self.content) + 1
+
+
+class Directory(Record):
+ def __init__(self, name, directories, files):
+ Record.__init__(self, name, True)
+ self.directories = directories
+ self.files = files
+ self.__set_nodes()
+ self.content_size = 1
+ self.mount_point_reference = None
+
+ def __set_nodes(self):
+ self.nodes = []
+ self.nodes += self.directories
+ self.nodes += self.files
+
+ def add_file(self, file):
+ self.files.append(file)
+ self.content_size += len(file.content)+1
+ self.__set_nodes()
+
+ def remove_file(self, file):
+ self.files.remove(file)
+ self.content_size -= len(file.content)+1
+ self.__set_nodes()
+
+ def add_directory(self, directory):
+ self.directories.append(directory)
+ self.content_size += directory.content_size
+ self.__set_nodes()
+
+ def remove_directory(self, directory):
+ self.directories.remove(directory)
+ self.content_size -= directory.content_size
+ self.__set_nodes()
+
+
+'''moite greshki'''
+
+
+class FileSystemError(Exception):
+ def __init__(self, message='Problem s failovata sistema'):
+ self.message = message
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self, message='Nyama takav pat'):
+ FileSystemError.__init__(self, message)
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self, message='veche ima takav node'):
+ FileSystemError.__init__(self, message)
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self, message='lipsva myasto za sazdavane'):
+ FileSystemError.__init__(self, message)
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self, message='lipsva myasto za sazdavane'):
+ FileSystemError.__init__(self, message)
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self, message='direktoriyata ne e prazna'):
+ FileSystemError.__init__(self, message)
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self, message='source-a ne sashtestvuva'):
+ NodeDoesNotExistError.__init__(self, message)
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self, message='dst-a ne sashtestvuva'):
+ NodeDoesNotExistError.__init__(self, message)
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self, message='dst ne e directoriya'):
+ FileSystemError.__init__(self, message)
+
+
+class LinkPathError(FileSystemError):
+ def __init__(self, message='ne moje da go linkne'):
+ FileSystemError.__init__(self, message)
+
+
+class FileSystemMountError(FileSystemError):
+ def __init__(self, message='ne moje se mountne ili unmountne '):
+ FileSystemError.__init__(self, message)
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ def __init__(self, message='nyama takav mount point'):
+ FileSystemMountError.__init__(self, message)
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ def __init__(self, message='mount point-a ne e direktoriya'):
+ FileSystemMountError.__init__(self, message)
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ def __init__(self, message='v mount point ima drugi zapisi'):
+ FileSystemMountError.__init__(self, message)
+
+
+class FileSystem:
+ def __init__(self, size):
+ if size == 0:
+ raise NotEnoughSpaceError()
+ self.size = size
+ self.available_size = size - 1
+ self.root = Directory(None, [], [])
+
+ '''vrashta node ot podadeni ime na node i list'''
+ def __get_node_from_list(self, name, list_of_nodes):
+ found_node = None
+ for directory in list_of_nodes:
+ if directory.name == name:
+ found_node = directory
+ break
+ return found_node
+
+ def __allocate_space(self, bytes_to_allocate):
+ if self.available_size - bytes_to_allocate < 0:
+ raise NotEnoughSpaceError()
+ else:
+ self.available_size -= bytes_to_allocate
+
+ def __init_node_list(self, path):
+ node = path.split('/')
+ node.pop(0)
+ return node
+
+ '''preizpolzvaem method da hodi rekursivno vrashta predposlen i posleden
+ element po daden pat | if not node <=> "if node is empty set"
+ is_destination_exists <=> dali krainiya node v dadeniya pat sashtestvuva'''
+ def __traverse_walk(self, root, node, is_destination_exist=True):
+ top = node.pop(0)
+ next_root = self.__get_node_from_list(top, root.nodes)
+ if not next_root and node:
+ raise NodeDoesNotExistError()
+ if not node:
+ if is_destination_exist:
+ if next_root:
+ return [root, next_root]
+ else:
+ raise DestinationNodeExistsError()
+ else:
+ if next_root:
+ raise DestinationNodeExistsError()
+ else:
+ return [root, next_root]
+ else:
+ return self.__traverse_walk(next_root, node, is_destination_exist)
+
+ '''sazdava file i po patya ako nyama takiva direktroii gi sazdava'''
+ def __create_link(self, root, node):
+ top = node.pop(0)
+ next_root = self.__get_node_from_list(top, root.nodes)
+ if not next_root and node:
+ next_root = Directory(top, [], [])
+ root.add_directory(next_root)
+ self.__allocate_space(1)
+ if not node:
+ self.__create_node(root, top, False, '')
+ return self.__get_node_from_list(top, root.nodes)
+ else:
+ return self.__create_link(next_root, node)
+
+ def __get_node(self, root, next_root):
+ return next_root
+
+ def __remove(self, root, next_root, directory=False, force=True):
+ if next_root.is_directory is True:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError()
+ if force is False and next_root.content_size is not 1:
+ raise NonEmptyDirectoryDeletionError()
+ root.remove_directory(next_root)
+ self.available_size += next_root.content_size
+ else:
+ root.remove_file(next_root)
+
+ def __create_node(self, root, name, directory=False, content=''):
+ if directory is True:
+ self.__allocate_space(1)
+ end_node = Directory(name, [], [])
+ root.add_directory(end_node)
+ else:
+ self.__allocate_space(len(content)+1)
+ end_node = File(name, content)
+ root.add_file(end_node)
+
+ def get_node(self, path):
+ if path is "/":
+ return self.root
+ result = self.__traverse_walk(self.root, self.__init_node_list(path))
+ target = self.__get_node(result[0], result[1])
+ if isinstance(target, Directory) and target.mount_point_reference:
+ return target.mount_point_reference
+ else:
+ return target
+
+ def create(self, path, directory=False, content=''):
+ result = self.__traverse_walk(self.root, self.__init_node_list(path),
+ False)
+ self.__create_node(result[0], self.__init_node_list(path)[-1],
+ directory, content)
+
+ def remove(self, path, directory=False, force=True):
+ result = self.__traverse_walk(self.root, self.__init_node_list(path))
+ self.__remove(result[0], result[1], directory, force)
+
+ def move(self, source, destination):
+ source_record, dst_record = None, None
+ try:
+ source_record = self.get_node(source)
+ except FileSystemError:
+ raise SourceNodeDoesNotExistError()
+
+ try:
+ dst_record = self.get_node(destination)
+ except FileSystemError:
+ raise DestinationNodeDoesNotExistError()
+
+ if not dst_record.is_directory:
+ raise DestinationNotADirectoryError()
+ else:
+ if self.__get_node_from_list(source_record.name, dst_record.nodes):
+ raise DestinationNodeExistsError()
+
+ size_of_source = source_record.content_size
+ copy_of_source = copy.deepcopy(source_record)
+ source_record = None
+ self.available_size -= size_of_source
+ dst_record.add_directory(copy_of_source)
+
+ def mount(self, file_system, path):
+ mount_point = None
+ try:
+ mount_point = self.get_node(path)
+ except FileSystemError:
+ raise MountPointDoesNotExistError()
+
+ if not mount_point.is_directory:
+ raise MountPointNotADirectoryError()
+
+ if mount_point.nodes:
+ raise MountPointNotEmptyError()
+
+ mount_point.files = file_system.root.files
+ mount_point.directories = file_system.root.directories
+ mount_point.nodes = file_system.root.nodes
+ mount_point.mount_point_reference = file_system.root
+
+ def link(self, source, destination, symbolic=True):
+ source_record = None
+ if symbolic:
+ try:
+ source_record = self.get_node(source)
+ except FileSystemError:
+ raise NodeDoesNotExistError()
+ link_file = self.__create_link(self.root,
+ self.__init_node_list(destination))
+ link_file.content = None
+ link_file.link_path = source_record
+ link_file.path_string = source