Николай обнови решението на 28.04.2015 21:38 (преди над 9 години)
+class Directory:
+ def __init__(self, name,dd):
+
+ self.is_directory = True
+ self.name = name
+ self.directories = []
+ self.files = []
+ self.nodes = []
+ self.dd = dd
+ self.size = 1
+
+ def add_dir(self, dir):
+ self.directories.append(dir)
+ self.nodes.append(dir)
+ self.size +=dir.size
+
+ def add_file(self, file):
+ self.files.append(file)
+ self.nodes.append(file)
+ self.size += file.size
+
+ def remove_file(self, file):
+ self.files.remove(file)
+ self.nodes.remove(file)
+ self.size -= file.size
+
+ def remove_dir(self, dir):
+ self.directories.remove(dir)
+ self.nodes.remove(dir)
+ self.size -= dir.size
+
+ def add_slink(self, link):
+ self.files.append(link)
+ self.nodes.append(link)
+ self.size += 1
+
+ def remove_link(self, link):
+ self.files.remove(link)
+ self.nodes.remove(link)
+ self.size -= 1
+
+
+class File:
+ def __init__(self, name, content, dd):
+ self.name = name
+ self.content = content
+ self.is_directory = False
+ self.size = len(content) + 1
+ self.dd = dd
+
+ def append(self, text):
+ self.content += text
+ self.size += len(text)
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(text) + 1
+
+class SLink:
+ def __init__(self, name, link_path, fs):
+ self.name = name
+ self.link_path = link_path
+ self.size = 1
+ self.fs = fs
+ self.content = self.get_content()
+
+ def get_content(self):
+ node = self.fs.get_node(self.link_path)
+ if node.is_directory:
+ return node
+ else:
+ return node.content
+
+
+class MountPoint:
+ def __init__(self, name, fs, mount_point):
+ self.name = name
+ self.fs = fs
+ self.mount_point = mount_point
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.size = size
+ self.available_size = size - 1
+ self.root = Directory('/', None)
+
+ def get_node(self, path):
+ def get_node_rec(start_node, path):
+ index = path.find("/")
+
+ if index is -1:
+ node = list(filter(lambda x: x.name == path, start_node.nodes))
+ if len(node) == 1:
+ return node[0]
+ else:
+ raise NodeDoesNotExistError
+
+ if index is 0:
+ return get_node_rec(start_node, path[1:])
+
+ name = path[:index]
+ next_node = None
+ for node in start_node.nodes:
+ if node.name == name:
+ next_node = node
+ break
+ if next_node is None:
+ raise NodeDoesNotExistError
+ else:
+ return get_node_rec(next_node, path[index+1:])
+ if path == "/":
+ return self.root
+ return get_node_rec(self.root, path[1:])
+
+ def create(self, path, directory=False, content=''):
+ exception = None
+ index = path.rfind("/")
+ if index == -1:
+ raise DestinationNodeDoesNotExistError
+ if index != 0:
+ name = path[index+1:]
+ path = path[:index]
+ else:
+ name = path[1:]
+ path = '/'
+
+ try:
+ node = self.get_node(path)
+ except NodeDoesNotExistError as e:
+ exception = e
+
+ if exception or not node.is_directory:
+ raise DestinationNodeDoesNotExistError
+
+ if name in [n.name for n in node.nodes]:
+ raise DestinationNodeExistsError
+
+ if directory:
+ new_directory = Directory(name, node)
+ if self.available_size < new_directory.size:
+ raise NotEnoughSpaceError
+ node.add_dir(new_directory)
+ self.available_size -= new_directory.size
+ else:
+ new_file = File(name, content, node)
+ if self.available_size < new_file.size:
+ raise NotEnoughSpaceError
+ node.add_file(new_file)
+ self.available_size -= new_file.size
+
+ def remove(self, path, directory=False, force=True):
+ try:
+ node = self.get_node(path)
+ except NodeDoesNotExistError:
+ raise
+ if node.is_directory:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ if len(node.nodes) > 0 and not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ if directory:
+ raise NonExplicitDirectoryDeletionError
+ dd = node.dd
+ if node.is_directory:
+ dd.remove_dir(node)
+ else:
+ dd.remove_file(node)
+ self.available_size += node.size
+ #del node
+
+ def move(self, source, destination):
+ exception = None
+ try:
+ src_node = self.get_node(source)
+ except Exception as e:
+ exception = e
+
+ if exception:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ dest_node = self.get_node(destination)
+ except Exception as e:
+ exception = e
+
+ if exception:
+ raise DestinationNodeDoesNotExistError
+ if not dest_node.is_directory:
+ raise DestinationNotADirectoryError
+
+ if src_node.name in [n.name for n in dest_node.nodes]:
+ raise DestinationNodeExistsError
+
+ destination = destination + "/" + node.name
+ if src_node.is_directory:
+ self.remove(source, directory=True)
+ self.create(destination, directory=True)
+ else:
+ self.remove(source)
+ self.create(destination, directory=False, content=src_node.content)
+
+ def link(self, source, destination, symbolic=True):
+ exception = None
+ try:
+ src_node = self.get_node(source)
+ except Exception as e:
+ exception = e
+
+ if exception:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+
+ if src_node.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+
+ index = destination.rfind("/")
+ name = destination[index+1:]
+ destination = destination[:index]
+ dest_node = self.get_node(destination)
+ if symbolic:
+ dest_node.add_slink(SLink(name,source, self))
+ else:
+ dest_node.add_file(File(name, src_node.content))
+
+ def mount(self, file_system, path):
+ exception = None
+ index = path.rfind("/")
+ name = path[index+1:]
+ path = path[:index]
+ try:
+ node = self.get_node(path)
+ except Exception as e:
+ exception = e
+
+ if exception:
+ raise exception
+
+ if not node.is_directory:
+ raise MountPointNotADirectoryError
+
+ if len(node.nodes) is not 0:
+ raise MountPointNotEmptyError
+
+ mount_point = MountPoint(name, fs, path)
+
+ node.add_dir(mount_point)
+
+ def unmount(self, path):
+ exception = None
+ try:
+ node = self.get_node(path)
+ except Exception as e:
+ exception = e
+
+ if exception:
+ raise NodeDoesNotExistError
+
+ if type(node) is not MountPoint:
+ raise NotAMountpointError
+
+ index = path.rfind("/")
+ name = path[index+1:]
+ path = path[:index]
+ parent_node = self.get_node(path)
+ parent_node.remove_dir(node)
+
+
+
+
+class FileSystemError(Exception):
+ def __init__(self):
+ self.message = "FileSystemError"
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ self.message = "NonExplicitDirectoryDeletionError"
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ self.message = "NonEmptyDirectoryDeletionError"
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self):
+ self.message = "DestinationNodeExistsError"
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self):
+ self.message = "NodeDoesNotExistError"
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ self.message = "SourceNodeDoesNotExistError"
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ self.message = "DestinationNodeDoesNotExistError"
+
+
+class FileSystemMountError(FileSystemError):
+ def __init__(self):
+ self.message = "FileSystemMountError"
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ def __init__(self):
+ self.message = "MountPointDoesNotExistError"
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ def __init__(self):
+ self.message = "MountPointNotADirectoryError"
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ def __init__(self):
+ self.message = "MountPointNotEmptyError"
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self):
+ self.message = "NotEnoughSpaceError"
+
+
+class DirectoryHardLinkError(FileSystemError):
+ def __init__(self):
+ self.message = "DirectoryHardLinkError"
+
+
+class LinkPathError(FileSystemError):
+ def __init__(self):
+ self.message = "LinkPathError"
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self):
+ self.message = "DestinationNotADirectoryError"
+
+
+class NotAMountpointError(FileSystemMountError):
+ def __init__(self):
+ self.message = "NotAMountpointError"
+
+
+
+if __name__ == '__main__':
+ fs = FileSystem(20)
+ dir1 = Directory("home", fs.root)
+ dir2 = Directory("nikolay", fs.root)
+ file1 = File("ffdf", "fffffdf", dir2)
+ # fs.root.nodes.append(dir1)
+ # fs.root.nodes[0].nodes.append(dir2)
+ # fs.root.nodes[0].nodes[0].nodes.append(file1)
+ fs.create("/home", directory=True)
+ fs.create("/home/nikolay", directory=True)
+ #fs.create("/home/nikolay/ffdf",content="ffdfd")
+
+ #fs.get_node("/home")
+ node = fs.get_node("/home")
+ print(node.is_directory)