Илиян обнови решението на 30.04.2015 01:58 (преди над 9 години)
+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class NotAMountpointError(FileSystemMountError):
+ pass
+
+
+class File:
+ def __init__(self, content):
+ self.content = content
+ self._is_directory = False
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+
+ def size(self):
+ return len(self.content) + 1
+
+ @property
+ def is_directory(self):
+ return self._is_directory
+
+ def __str__(self):
+ return self.content
+
+
+class Directory:
+ def __init__(self):
+ self._directories = []
+ self._files = []
+ self._nodes = []
+ self._is_directory = True
+
+ @property
+ def directories(self):
+ return self._directories
+
+ @directories.setter
+ def directories(self, value):
+ self._directories.append(value)
+
+ @property
+ def files(self):
+ return self._files
+
+ @files.setter
+ def files(self, value):
+ self._files.append(value)
+
+ @property
+ def nodes(self):
+ return self._nodes
+
+ @nodes.setter
+ def nodes(self, value):
+ self._nodes.append(value)
+
+ @property
+ def is_directory(self):
+ return self._is_directory
+
+
+def correct_path(path):
+ result = ""
+ for x in range(len(path)-1, -1, -1):
+ if path[x] != '/':
+ pass
+ else:
+ result = path[0:x]
+ return result
+
+
+class FileSystem:
+
+ def __init__(self, size):
+ self._size = size
+ self._available_size = size - 1
+ self.dirs = {}
+ self.dirs['/'] = Directory()
+
+ @property
+ def size(self):
+ return self._size
+
+ @property
+ def available_size(self):
+ return self._available_size
+
+ def get_node(self, path):
+ try:
+ if path in self.dirs:
+ return self.dirs[path]
+ else:
+ raise NodeDoesNotExistError
+ except NodeDoesNotExistError:
+ print("Unfortunately, path does not exist")
+
+ def create(self, path, directory=False, content=''):
+ try:
+ previous_path = correct_path(path)
+ if previous_path == "":
+ previous_path = '/'
+ if previous_path not in self.dirs:
+ raise DestinationNodeDoesNotExistError
+ elif self.available_size - 1 < 0 or \
+ self.available_size - (len(content) + 1) < 0:
+ raise NotEnoughSpaceError
+ elif path in self.dirs:
+ raise DestinationNodeExistsError
+ else:
+ if directory:
+ current_dir = Directory()
+ self._available_size -= 1
+ self.dirs[path] = current_dir
+ previous_dir = self.dirs[previous_path]
+ previous_dir.directories = current_dir
+ previous_dir.nodes = current_dir
+ else:
+ current_file = File(content)
+ self._available_size -= len(content) + 1
+ self.dirs[path] = current_file
+ previous_dir = self.dirs[previous_path]
+ previous_dir.files = current_file
+ previous_dir.nodes = current_file
+
+ except DestinationNodeDoesNotExistError:
+ print("Destination node does not exist")
+ except NotEnoughSpaceError:
+ print("Not enough space")
+ except DestinationNodeExistsError:
+ print("Destination node exists")
+
+ def remove(self, path, directory=False, force=True):
+ try:
+ if isinstance(self.dirs[path], Directory) and not directory:
+ raise NonExplicitDirectoryDeletionError
+ elif directory and len(self.dirs[path].nodes) and not force:
+ raise NonEmptyDirectoryDeletionError
+ elif path not in self.dirs:
+ raise NodeDoesNotExistError
+ elif directory and force:
+ paths = []
+ for x in self.dirs:
+ if path in x and path != x:
+ paths.append(x)
+ paths.sort()
+ paths.reverse()
+ while len(paths):
+ if paths[0] in self.dirs:
+ if self.dirs[paths[0]].is_directory:
+ if len(self.dirs[paths[0]].nodes):
+ self.remove(paths[0], True, True)
+ paths.remove(paths[0])
+ else:
+ self.remove(paths[0], True, False)
+ paths.remove(paths[0])
+
+ else:
+ self.remove(paths[0], False, False)
+ paths.remove(paths[0])
+ else:
+ paths.remove(paths[0])
+
+ elif directory:
+ object_dir = self.dirs[path]
+ previous_dir = correct_path(path)
+ del self.dirs[path]
+ if object_dir in self.dirs[previous_dir].directories:
+ self.dirs[previous_dir].directories.remove(object_dir)
+ self.dirs[previous_dir].nodes.remove(object_dir)
+
+ else:
+ object_file = self.dirs[path]
+ previous_dir = correct_path(path)
+ del self.dirs[path]
+ if object_file in self.dirs[previous_dir].files:
+ self.dirs[previous_dir].files.remove(object_file)
+ self.dirs[previous_dir].nodes.remove(object_file)
+
+ if path in self.dirs:
+ current = self.dirs[path]
+ previous = correct_path(path)
+ del self.dirs[path]
+ if current in self.dirs[previous].directories:
+ self.dirs[previous].directories.remove(current)
+ self.dirs[previous].nodes.remove(current)
+
+ except NonExplicitDirectoryDeletionError:
+ print("Non explicit directory deletion")
+ except NonEmptyDirectoryDeletionError:
+ print("Non empty directory deletion")
+ except NodeDoesNotExistError:
+ print("Node does not exist")
+
+ def move(self, source, destination):
+ name = source.split('/')[-1]
+ try:
+ if source not in self.dirs:
+ raise SourceNodeDoesNotExistError
+ elif destination not in self.dirs:
+ raise DestinationNodeDoesNotExistError
+ elif not self.dirs[destination].is_directory:
+ raise DestinationNotADirectoryError
+ elif destination in self.dirs:
+ if destination + '/' + name in self.dirs:
+ raise DestinationNodeExistsError
+
+ if self.dirs[source].is_directory:
+ element = self.dirs[source]
+ self.dirs[destination + '/' + name] = element
+ self.dirs[destination].directories.append(element)
+ self.dirs[destination].nodes.append(element)
+ previous_dir = correct_path(source)
+ self.dirs[previous_dir].directories.remove(element)
+ self.dirs[previous_dir].nodes.remove(element)
+
+ if len(self.dirs[source].nodes):
+ paths = []
+ for x in self.dirs:
+ if source in x and source != x:
+ paths.append(x)
+ paths.sort()
+ while len(paths):
+ if paths[0] in self.dirs:
+ p = paths[0]
+ self.move(paths.pop(0), destination + '/' + name)
+ if p in self.dirs:
+ del self.dirs[p]
+ else:
+ paths.remove(paths[0])
+
+ else:
+ element = self.dirs[source]
+ self.dirs[destination + '/' + name] = element
+ self.dirs[destination].files.append(element)
+ self.dirs[destination].nodes.append(element)
+ previous_dir = correct_path(source)
+ self.dirs[previous_dir].files.remove(element)
+ self.dirs[previous_dir].nodes.remove(element)
+
+ if source in self.dirs:
+ del self.dirs[source]
+
+ except SourceNodeDoesNotExistError:
+ print("Source node does not exist")
+ except DestinationNodeDoesNotExistError:
+ print("Destination node does not exist")
+ except DestinationNotADirectoryError:
+ print("Destination not a directory")
+ except DestinationNodeExistsError:
+ print("Destination node exists")
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ if symbolic and source not in self.dirs:
+ raise NodeDoesNotExistError
+ elif self.dirs[source].is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ elif not self.dirs[source].is_directory and not symbolic:
+ raise SourceNodeDoesNotExistError
+
+ if symbolic:
+ self.dirs[destination] = self.dirs[source]
+ self._available_size -= 1
+ else:
+ link = self.dirs[source]
+ self.dirs[destination] = link
+ self._available_size -= 1
+
+ except NodeDoesNotExistError:
+ print("Node does not exist")
+ except DirectoryHardLinkError:
+ print("Directory hard link error")
+ except SourceNodeDoesNotExistError:
+ print("Source node does not exist error")
+
+ def mount(self, file_system, path):
+ try:
+ if self.dirs[path].is_directory and len(self.dirs[path].nodes):
+ raise MountPointNotEmptyError
+ elif not self.dirs[path].is_directory:
+ raise MountPointNotADirectoryError
+ elif path not in self.dirs:
+ raise MountPointDoesNotExistError
+
+ paths = []
+ for x in file_system.dirs:
+ paths.append(x)
+
+ paths.sort()
+ for x in paths:
+ if x == '/':
+ self.dirs[path] = file_system.dirs['/']
+ else:
+ self.dirs[path + x] = file_system.dirs[x]
+
+ except MountPointNotEmptyError:
+ print("Mount point not empty error")
+ except MountPointNotADirectoryError:
+ print("Mount point not a directory error")
+ except MountPointDoesNotExistError:
+ print("Mount point does not exist error")
+
+ def unmount(self, path):
+ try:
+ if path not in self.dirs:
+ raise NodeDoesNotExistError
+ elif not self.dirs[path].is_directory:
+ raise NotAMountpointError
+
+ self.remove(path, True, True)
+
+ except NodeDoesNotExistError:
+ print("Node does not exist error")
+ except NotAMountpointError:
+ print("Not a mountpoint error")