Мартин обнови решението на 30.04.2015 03:22 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotAMountpointError(FileSystemMountError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+# remove
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+# move
+# pogore
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+# za vrski
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class Content:
+ def __init__(self, content=''):
+ self.__content = content
+
+ @property
+ def content(self):
+ return self.__content
+
+ @content.setter
+ def content(self):
+ return self.__content
+
+
+class File:
+ def __init__(self, name='', content=Content()):
+ self._content = content
+ self.name = name
+
+ def append(self, text):
+ self._content.content = self._content.content + text
+
+ def truncate(self, text):
+ self._content.content = text
+
+ def size(self):
+ return len(self._content.content) + 1
+
+ @property
+ def content(self):
+ return self._content.content
+
+ @property
+ def is_directory(self):
+ return False
+
+
+class Linker:
+ def __init__(self, name='', link_path=None):
+ self.link_path = link_path
+ self.name = name
+
+ @property
+ def is_directory(self):
+ return False
+
+ @property
+ def content(self):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ return self.link_path.content
+
+ def append(self, text):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ self.link_path.append
+
+ def truncate(self, text):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ self.link_path.truncate(text)
+
+ def size(self):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ return self.link_path.size()
+
+ @property
+ def directories(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.directories
+
+ @property
+ def files(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.files
+
+ @property
+ def node(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.node
+
+
+class Directory:
+ def __init__(self, name='', path='/'):
+ self.name = name
+ self.path = path
+ self.directories = []
+ self.files = []
+
+ @property
+ def node(self):
+ return self.directories + self.files
+
+ @property
+ def is_directory(self):
+ return True
+
+# /
+# /root
+# /root/home
+# /root/home/spells
+# /root/home/spells/mage.txt
+# /root/home/spells/asshole.txt
+# /root/shit
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.__system_size = size
+ self.__available_size = size - 1
+ self.__root = Directory()
+
+ @property
+ def root(self):
+ return self.__root
+
+ @property
+ def available_size(self):
+ return self.__available_size
+
+ @available_size.setter
+ def available_size(self, value):
+ self.__available_size = value
+
+ def set_ava(self, value):
+ self.__available_size = value
+
+ @property
+ def size(self):
+ return self.__system_size
+
+ def print_it(self, dir, path=''):
+ for element in dir.node:
+ if element.is_directory:
+ new_path = path + '/' + element.name
+ self.print_it(element, path=new_path)
+ else:
+ print(path + '/' + element.name)
+
+ if len(dir.node) == 0:
+ print(path)
+
+ def print_paths(self):
+ self.print_it(self.__root)
+ print('')
+
+ def get_node(self, path):
+ split_path = path.split('/')
+
+ if split_path[0] == split_path[1]:
+ return self.__root
+
+ current_directory = self.__root
+ for element in split_path[1:-1:1]:
+ next_directory = [directory
+ for directory
+ in current_directory.directories
+ if directory.name == element]
+
+ if len(next_directory) == 1:
+ current_directory = next_directory[0]
+ else:
+ raise NodeDoesNotExistError
+
+ result = [last_node
+ for last_node
+ in current_directory.node
+ if last_node.name == split_path[-1]]
+
+ if len(result) == 1:
+ return result[0]
+ else:
+ raise NodeDoesNotExistError
+
+ raise NodeDoesNotExistError
+
+ def __enough_space(self, directory=False, content=''):
+ directory_space = directory and self.available_size == 0
+ enough_size = self.available_size < len(content)+1
+ file_space = not directory and enough_size
+ if directory_space or file_space:
+ raise NotEnoughSpaceError
+
+ def __get_path(self, path):
+ if len(path.split('/')) <= 2:
+ return '/'
+ the_path = ''
+ for element in path.split('/')[1:-1:1]:
+ the_path = the_path + '/' + element
+ return the_path
+
+ def __get_name(self, path):
+ return path.split('/')[-1]
+
+ def create(self, path, directory=False, content=''):
+ self.__enough_space(directory, content)
+ if len(path.split('/')) > 2:
+ try:
+ location = self.get_node(self.__get_path(path))
+ except:
+ raise DestinationNodeDoesNotExistError
+ else:
+ location = self.__root
+
+ if not location.is_directory:
+ raise DestinationNodeDoesNotExistError
+
+ if directory:
+ name = self.__get_name(path)
+ item = Directory(name=name, path=path)
+ directories = list(filter(lambda x: x.name == name,
+ location.directories))
+ if len(directories) > 0:
+ raise DestinationNodeExistsError
+ else:
+ location.directories.append(item)
+ self.available_size -= 1
+ else:
+ file_content = Content(content)
+ file_name = self.__get_name(path)
+ item = File(name=file_name, content=file_content)
+ files = list(filter(lambda x: x.name == file_name,
+ location.files))
+ if len(files) > 0:
+ raise DestinationNodeExistsError
+
+ location.files.append(item)
+ self.available_size -= item.size()
+
+ def __calculate_size(self, directory):
+ return 1
+
+ def remove(self, path, directory=False, force=True):
+ location = self.get_node(self.__get_path(path))
+ name = self.__get_name(path)
+ item = [x for x in location.node if x.name == name][0]
+
+ if item.is_directory:
+ if len(item.node) > 0:
+ if not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ self.available_size += self.__calculate_size(item)
+ location.directories.remove(item)
+ # NOT NOT
+ else:
+ self.available_size -= item.size()
+ location.files.remove(item)
+
+ def move(self, source, destination):
+ try:
+ source_location = self.get_node(self.__get_path(source))
+ source_item = self.get_node(source)
+ except:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ destination_item = self.get_node(destination)
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ source_name = self.__get_name(source)
+
+ if not destination_item.is_directory:
+ raise DestinationNotADirectoryError
+ directories = map(lambda item: item.name, destination_item.node)
+ if source_name in list(directories):
+ raise DestinationNodeExistsError
+
+ if source_item.is_directory:
+ destination_item.directories.append(source_item)
+ source_location.directories.remove(source_item)
+ else:
+ destination_item.files.append(source_item)
+ source_location.files.remove(source_item)
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ source_item = self.get_node(source)
+ except:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ path = self.__get_path(destination)
+ destination_location = self.get_node(path)
+ destination_name = self.__get_name(destination)
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ if source_item.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+
+ if symbolic:
+ temp = Linker(name=destination_name, link_path=source_item)
+ if source_item.is_directory:
+ destination_location.directories.append(temp)
+ else:
+ destination_location.files.append(temp)
+ else:
+ content = source_item._content
+ temp = File(name=destination_name, content=content)
+ destination_location.files.append(temp)
+ self.available_size -= 1
+
+ def mount(self, file_system, path):
+ try:
+ destination = self.get_node(path)
+ except:
+ raise MountPointDoesNotExistError
+
+ if not destination.is_directory:
+ raise MountPointNotADirectoryError
+
+ if len(destination.node) > 0:
+ raise MountPointNotEmptyError
+
+ destination.directories = file_system.root.directories
+ destination.files = file_system.root.files
+
+ def unmount(self, path):
+ source = self.get_node(path)
+
+ source.directories = []
+ source.files = []