Константин обнови решението на 30.04.2015 16:51 (преди над 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 File(object):
+ def __init__(self, name, content):
+ self.name = name
+ self.content = content
+ self.size = len(content)
+
+
+class Directory(object):
+ def __init__(self, name):
+ self.name = name
+ self.files = []
+ self.directories = []
+ self.size = 0
+
+ @property
+ def nodes(self):
+ return self.files + self.directories
+
+ def add_item(self, item):
+ if type(item) is Directory:
+ self.directories.append(item)
+ else:
+ self.files.append(item)
+
+ self.size += item.size
+
+ def get_node(self, path):
+ item = path[-1]
+ if len(path) == 1:
+ for node in self.nodes:
+ if item == node.name:
+ return node
+
+ raise NodeDoesNotExistError
+
+ return item[1].get_node(path[1:])
+
+
+class FileSystem(Directory):
+ def __init__(self, size):
+ super(FileSystem, self).__init__('/')
+ self.buffer_size = size
+ self.memory_avaliable = size
+
+ def size(self):
+ return self.buffer_size
+
+ def avaliable_size(self):
+ return self.memory_avaliable
+
+ def get_node(self, path):
+ if type(path) is str:
+ path = filter(lambda a: a != '', path.split('/'))
+
+ super(FileSystem, self).get_node(path)
+
+ def create(self, path, directory=False, content=''):
+ size = len(content)
+
+ path = filter(lambda a: a != '', path.split('/'))
+
+ try:
+ last_dir = self.get_node(path[:-1]) if len(path) > 1 else self
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ if size > self.memory_avaliable:
+ raise NotEnoughSpaceError
+
+ if path[-1] in [item.name for item in last_dir.nodes]:
+ raise DestinationNodeExistsError
+
+ if directory:
+ new_item = Directory(path[-1])
+ else:
+ new_item = File(path[-1], content)
+
+ last_dir.add_item(new_item)
+ last_dir.size += new_item.size
+ self.memory_avaliable -= new_item.size
+
+ def remove(self, path, directory=False, force=True):
+ path = filter(lambda a: a != '', path.split('/'))
+ item = self.get_node(path)
+
+ if type(item) is Directory:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+
+ else:
+ if (item.directories or item.files) and not force:
+ raise NonEmptyDirectoryDeletionError
+
+ last_directory = self.get_node(path[:-1])
+ if directory:
+ last_directory.directories.remove(path[-1])
+ else:
+ last_directory.files.remove(path[-1])
+
+ last_directory.size -= item.size
+ self.memory_avaliable += item.size
+
+ def move(self, source, destination):
+ try:
+ source_item = self.get_node(source)
+ except:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ destination_item = self.get_node(destination)
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ if type(destination_item) is not Directory:
+ raise DestinationNotADirectoryError
+
+ if source_item in destination_item.files or\
+ source_item in destination_item.directories:
+ raise DestinationNodeExistsError
+
+ last_directory = source.split('/')[:-1]
+ if type(source_item) is Directory:
+ destination_item.directories.append(source_item)
+ self.get_node(last_directory).directories.remove(source_item)
+ else:
+ destination_item.files.append(source_item)
+ self.get_node(last_directory).files.remove(source_item)
+
+ destination_item.size += source_item.size
+ last_directory.size -= source_item.size