Мартина обнови решението на 30.04.2015 14:08 (преди над 9 години)
+class File:
+ def __init__(self, name, content=''):
+ self.name = name
+ self.content = content
+ self.size = len(content) + 1
+
+ @property
+ def is_directory(self):
+ return False
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = ''
+ self.content = text
+
+
+class Directory():
+ def __init__(self, name='/'):
+ self.name = name
+ self.directories = []
+ self.files = []
+ self.nodes = []
+
+ @property
+ def is_directory(self):
+ return True
+
+ @staticmethod
+ def __pr(d):
+ print("(Directory " + d.name + ": ")
+ print("Files: ", end="")
+ for f in d.files:
+ print(f.name, end=" ")
+ if len(d.directories) is 0:
+ print(")", end="")
+ else:
+ for sub in d.directories:
+ Directory.__pr(sub)
+ print(")", end="")
+
+ def get_contents(self):
+ for d in self.directories:
+ Directory.__pr(d)
+
+
+class FileSystem(Directory):
+ def __init__(self, size):
+ super().__init__()
+ self.directories = [Directory('/')]
+ self.size = size
+ self.available_size = size - 1 # for the root dir
+
+ @staticmethod
+ def __get_n(dirs, path):
+ for d in dirs:
+ if path[0] == d.name and len(path) is not 1:
+ i = dirs.index(d)
+ return FileSystem.__get_n(dirs[i].directories, path[1:])
+ elif path[0] == d.name and len(path) is 1: # end of route reached, route is valid
+ return d
+ else:
+ raise NodeDoesNotExistError()
+
+ def get_node(self, path):
+ if path is '/':
+ return self.directories[0]
+ else:
+ p = path.split('/')
+ p[0] = '/'
+ prev_node = FileSystem.__get_n(self.directories, p[:-1]) # without the last dir or file
+ for n in prev_node.nodes:
+ if p[-1] == n.name:
+ return n
+ raise NodeDoesNotExistError()
+
+ def create(self, path, directory=False, content=''):
+ p = path.rsplit('/', 1) # split on first occurrence of '/' backwards
+ if p[0] is '':
+ node = self.directories[0]
+ else:
+ try:
+ node = self.get_node(p[0])
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+ if directory is True:
+ if self.available_size is 1:
+ raise NotEnoughSpaceError()
+ else:
+ d = Directory(p[1])
+ if d in node.directories:
+ raise DestinationNodeExistsError()
+ else:
+ node.directories.append(d)
+ node.nodes.append(d)
+ self.available_size -= 1
+ else:
+ if self.available_size + 1 <= len(content):
+ raise NotEnoughSpaceError()
+ else:
+ f = File(p[1], content)
+ if f in node.files:
+ raise DestinationNodeExistsError()
+ else:
+ node.files.append(f)
+ node.nodes.append(f)
+ self.available_size -= len(content)
+
+ def remove(self, path, directory=False, force=True):
+ try:
+ node = self.get_node(path)
+ except DestinationNodeDoesNotExistError:
+ raise NodeDoesNotExistError()
+ if node.is_directory:
+ if directory is not True:
+ raise NonExplicitDirectoryDeletionError
+ else:
+ if directory is True:
+ if len(node.directories) > 0 and force is not True:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ p = path.rsplit('/', 1)
+ parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
+ dir_to_remove = self.get_node(path)
+ parent_dir.directories.remove(dir_to_remove)
+ parent_dir.nodes.remove(dir_to_remove)
+ self.available_size += 1
+ else: # not a directory, i.e. - file
+ p = path.rsplit('/')
+ if path.count('/') == 1: # i.e. - file is in the root directory
+ p[0] = '/'
+ parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
+ file_to_remove = self.get_node(path)
+ parent_dir.files.remove(file_to_remove)
+ parent_dir.nodes.remove(file_to_remove)
+ self.available_size += file_to_remove.size
+
+ def move(self, source, destination):
+ try:
+ to_move = self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError()
+ try:
+ dest = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+ except not dest.is_directory:
+ raise DestinationNotADirectoryError()
+ src = source.rsplit('/', 1)[1]
+ # check if node with the same name exists in directory
+ for node in dest.nodes:
+ if src == node.name:
+ raise DestinationNodeExistsError()
+ # delete node from source directory
+ if to_move.is_directory:
+ self.remove(source, True)
+ else:
+ self.remove(source)
+ if to_move.is_directory:
+ dest.directories.append(to_move)
+ dest.nodes.append(to_move)
+ else:
+ destination += '/' + src
+ self.create(destination, to_move.content)
+
+ def link(self, source, destination, symbolic=True):
+ pass
+
+ def mount(self, file_system, path):
+ pass
+
+ def unmount(self, path):
+ pass
+
+
+class FileSystemError(Exception):
+ def __init__(self):
+ self.message = "Error"
+
+ def __str__(self):
+ return self.message
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Node does not exist", self.message)
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Source", self.message)
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Destination", self.message)
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Not Enough Space Error"
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Destination Node Exists Error"
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Non Explicit Directory Deletion Error"
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Non Empty Directory Deletion Error"
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Destination Not A Directory Error"