Решение на In-memory файлова система от Антоан Ангелов

Обратно към всички решения

Към профила на Антоан Ангелов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 8 успешни тест(а)
  • 10 неуспешни тест(а)

Код

import re
class FileSystem:
def __init__(self, size):
self.root = Directory("/", None, "/", self)
self.size = size
self.available_size = size - 1
def get_node(self, path):
path = re.sub(r"(/)\1+", r"\1", path)
path = path[:-1] if path[-1:] == "/" else path
if path == "/":
return self.root
segments = path.split("/")[1:]
num_segments = len(segments)
node = self.root
for index, segment in enumerate(segments):
if node.is_directory():
node = node.get_node(segment)
if not node:
raise NodeDoesNotExistError()
else:
if not index == num_segments - 1 or not node.name == segment:
raise NodeDoesNotExistError()
return node
def create(self, path, directory=False, content=''):
path = re.sub(r"(/)\1+", r"\1", path)
path = path[:-1] if path[-1:] == "/" else path
parent_dir = "/".join(path.split("/")[:-1])
name = path.split("/")[-1]
try:
parent = self.get_node(parent_dir)
if not parent.is_directory():
raise DestinationNodeDoesNotExistError()
if parent.get_node(name):
raise DestinationNodeExistsError()
if directory and parent.is_directory():
new_node = Directory(path, parent, name, self)
elif not directory:
new_node = File(path, content, parent, name, self)
if self.available_size - new_node.size < 0:
raise NotEnoughSpaceError()
parent.add_node(new_node)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
def remove(self, path, directory=False, force=True):
try:
del_node = self.get_node(path)
if del_node.is_directory():
if not directory:
raise NonExplicitDirectoryDeletionError()
elif not del_node.nodes and not force:
raise NonEmptyDirectoryDeletionError()
del_node.parent.remove_node(del_node)
except NodeDoesNotExistError:
raise
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
destination_node = self.get_node(destination)
if not destination_node.is_directory():
raise DestinationNotADirectoryError()
if destination_node.get_node(source_node.name):
raise DestinationNodeExistsError()
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
old_size = self.available_size
source_node.parent.remove_node(source_node)
destination_node.add_node(source_node)
self.available_size = old_size
def link(self, source, destination, symbolic=True):
try:
source_node = self.get_node(source)
if source_node.is_directory() and not symbolic:
raise DirectoryHardLinkError()
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError()
self.create(destination)
link = self.get_node(destination)
if symbolic:
link.link_path = source
else:
link.make_hardlink(source_node)
def mount(self, file_system, path):
try:
source_node = self.get_node(path)
if source_node.is_directory() and source_node.nodes:
raise MountPointNotEmptyError()
if not source_node.is_directory():
raise MountPointNotADirectoryError()
source_node.mount = file_system
except NodeDoesNotExistError:
raise MountPointDoesNotExistError()
def unmount(self, path):
try:
source_node = self.get_node(path)
except NodeDoesNotExistError:
raise
if not source_node.is_directory() or not source_node.mount:
raise NotAMountpointError()
source_node.mount = None
class Node:
def __init__(self, path, is_dir, parent, name, file_system):
self.path = self
self.parent = parent
self.name = name
self.file_system = file_system
class RawContent:
def __init__(self, content):
self.content = content
self.refs = 0
class File(Node):
def __init__(self, path, content, parent, name, file_system):
Node.__init__(self, path, False, parent, name, file_system)
self.__raw_content__ = RawContent(content)
self.link_path = None
self.is_hardlink = False
@property
def size(self):
return len(self.__raw_content__.content) + 1
@property
def content(self):
return self.__raw_content__.content
def decrease_refs(self):
self.__raw_content__.refs -= 1
return self.__raw_content__.refs
def make_hardlink(self, source):
self.__raw_content__ = source.__raw_content__
self.__raw_content__.refs += 1
self.is_hardlink = True
def append(self, text):
length = len(text)
if self.file_system.available_size - length < 0:
raise NotEnoughSpaceError()
self.__raw_content__.content += text
self.file_system.available_size -= length
def truncate(self, text):
length = len(text)
if self.file_system.available_size + self.size - length < 0:
raise NotEnoughSpaceError()
self.file_system.available_size += self.size - length
self.__raw_content__.content = text
def is_directory(self):
return False
def __getattribute__(self, name):
file_attrs = {"content"}
dir_attrs = {"files", "directories", "nodes"}
if name in file_attrs or name in dir_attrs:
if not self.link_path:
return object.__getattribute__(self, name)
try:
node = self.file_system.get_node(self.link_path)
except NodeDoesNotExistError:
raise LinkPathError()
is_dir = node.is_directory()
if (is_dir and name in dir_attrs) or \
(not is_dir and name in file_attrs):
return node.__getattribute__(name)
return object.__getattribute__(self, name)
class Directory(Node):
def __init__(self, path, parent, name, file_system):
Node.__init__(self, path, True, parent, name, file_system)
self.directories = []
self.files = []
self.nodes = []
self.mount = None
def add_node(self, node):
if node.is_directory():
self.directories.append(node)
else:
self.files.append(node)
self.file_system.available_size -= node.size
self.nodes.append(node)
node.parent = self
def remove_node(self, node):
size = node.size
if node.is_directory():
self.directories.remove(node)
for sub in node.nodes:
node.remove_node(sub)
node.nodes = []
self.nodes.remove(node)
else:
self.files.remove(node)
if node.is_hardlink and node.decrease_refs():
size = 1
node.parent = None
self.file_system.available_size += size
def get_node(self, node_name):
if not self.nodes and self.mount:
return self.mount.get_node("/" + node_name)
for node in self.nodes:
if node.name == node_name:
if node.is_directory() and node.mount:
return node.mount.root
return node
return None
@property
def size(self):
return 1
def is_directory(self):
return True
class FileSystemError(Exception):
def __init__(self):
pass
class FileSystemMountError(FileSystemError):
def __init__(self):
pass
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
pass
class MountPointNotADirectoryError(FileSystemMountError):
def __init__(self):
pass
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
pass
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
pass
class DestinationNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class SourceNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
pass
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
pass
class NotAMountpointError(FileSystemError):
def __init__(self):
pass
class LinkPathError(FileSystemError):
def __init__(self):
pass

Лог от изпълнението

.E...EE.EE...EEEEE
======================================================================
ERROR: test_create_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_hard_link_to_missing_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_link_create (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_mounting (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_move_not_to_a_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_empty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_nonempty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_symlink_to_missing_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_valid_move (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

----------------------------------------------------------------------
Ran 18 tests in 20.189s

FAILED (errors=10)

История (5 версии и 0 коментара)

Антоан обнови решението на 30.04.2015 04:06 (преди над 9 години)

+class FileSystem:
+
+ def __init__(self, size):
+ self.root = Directory("/", None, "/", self)
+ self.size = size
+ self.available_size = size
+
+ def get_node(self, path):
+
+ if path == "/":
+ return self.root
+
+ segments = path.split("/")[1:]
+ num_segments = len(segments)
+ node = self.root
+ for index, segment in enumerate(segments):
+ if node.is_directory():
+ node = node.get_node(segment)
+
+ if not node:
+ raise NodeDoesNotExistError()
+ else:
+ if not index == num_segments - 1 or not node.name == segment:
+ raise NodeDoesNotExistError()
+
+ return node
+
+ def create(self, path, directory=False, content=''):
+ parent_dir = "/".join(path.split("/")[:-1])
+ name = path.split("/")[-1]
+
+ try:
+ parent = self.get_node(parent_dir)
+
+ if not parent.is_directory():
+ raise DestinationNodeDoesNotExistError()
+
+ if parent.get_node(name):
+ raise DestinationNodeExistsError()
+
+ if directory and parent.is_directory():
+ new_node = Directory(path, parent, name, self)
+ elif not directory:
+ new_node = File(path, content, parent, name, self)
+
+ if self.available_size - new_node.size < 0:
+ raise NotEnoughSpaceError()
+
+ parent.add_node(new_node)
+
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+
+ def remove(self, path, directory=False, force=True):
+ try:
+ del_node = self.get_node(path)
+ if del_node.is_directory():
+ if not directory:
+ raise NonExplicitDirectoryDeletionError()
+ elif not del_node.nodes and not force:
+ raise NonEmptyDirectoryDeletionError()
+
+ del_node.parent.remove_node(del_node)
+
+ except NodeDoesNotExistError:
+ raise
+
+ def move(self, source, destination):
+ try:
+ source_node = self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError()
+
+ try:
+ destination_node = self.get_node(destination)
+ if not destination_node.is_directory():
+ raise DestinationNotADirectoryError()
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+
+ source_node.parent.remove_node(source_node)
+ destination_node.add_node(source_node)
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ source_node = self.get_node(source)
+ if source_node.is_directory() and not symbolic:
+ raise DirectoryHardLinkError()
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise
+ else:
+ raise SourceNodeDoesNotExistError()
+
+ self.create(destination)
+ link = self.get_node(destination)
+
+ if symbolic:
+ link.link_path = source
+ else:
+ link.make_hardlink(source_node)
+
+ def mount(self, file_system, path):
+ try:
+ source_node = self.get_node(path)
+ if source_node.is_directory() and source_node.nodes:
+ raise MountPointNotEmptyError()
+
+ if not source_node.is_directory():
+ raise MountPointNotADirectoryError()
+
+ source_node.mount = file_system
+
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError()
+
+ def unmount(self, path):
+ try:
+ source_node = self.get_node(path)
+ except NodeDoesNotExistError:
+ raise
+
+ if not source_node.is_directory() or not source_node.mount:
+ raise NotAMountpointError()
+
+ source_node.mount = None
+
+
+class Node:
+
+ def __init__(self, path, is_dir, parent, name, file_system):
+ self.path = self
+ self.parent = parent
+ self.name = name
+ self.file_system = file_system
+
+
+class RawContent:
+
+ def __init__(self, content):
+ self.content = content
+ self.refs = 0
+
+
+class File(Node):
+
+ def __init__(self, path, content, parent, name, file_system):
+ Node.__init__(self, path, False, parent, name, file_system)
+ self.__raw_content__ = RawContent(content)
+ self.link_path = None
+ self.is_hardlink = False
+
+ @property
+ def size(self):
+ return len(self.__raw_content__.content) + 1
+
+ @property
+ def content(self):
+ return self.__raw_content__.content
+
+ def decrease_refs(self):
+ self.__raw_content__.refs -= 1
+ return self.__raw_content__.refs
+
+ def make_hardlink(self, source):
+ self.__raw_content__ = source.__raw_content__
+ self.__raw_content__.refs += 1
+ self.is_hardlink = True
+
+ def append(self, text):
+
+ length = len(text)
+ if self.file_system.available_size - length < 0:
+ raise NotEnoughSpaceError()
+
+ self.__raw_content__.content += text
+ self.file_system.available_size -= length
+
+ def truncate(self, text):
+
+ length = len(text)
+ if self.file_system.available_size + self.size - length < 0:
+ raise NotEnoughSpaceError()
+
+ self.file_system.available_size += self.size - length
+ self.__raw_content__.content = text
+
+ def is_directory(self):
+ return False
+
+ def __getattribute__(self, name):
+ file_attrs = {"content"}
+ dir_attrs = {"files", "directories", "nodes"}
+ if name in file_attrs or name in dir_attrs:
+
+ if not self.link_path:
+ return object.__getattribute__(self, name)
+
+ try:
+ node = self.file_system.get_node(self.link_path)
+ except NodeDoesNotExistError:
+ raise LinkPathError()
+
+ is_dir = node.is_directory()
+ if (is_dir and name in dir_attrs) or \
+ (not is_dir and name in file_attrs):
+ return node.__getattribute__(name)
+
+ return object.__getattribute__(self, name)
+
+
+class Directory(Node):
+
+ def __init__(self, path, parent, name, file_system):
+ Node.__init__(self, path, True, parent, name, file_system)
+ self.directories = []
+ self.files = []
+ self.nodes = []
+ self.mount = None
+
+ def add_node(self, node):
+ if node.is_directory():
+ self.directories.append(node)
+ else:
+ self.files.append(node)
+
+ self.nodes.append(node)
+ node.parent = self
+ self.file_system.available_size -= node.size
+
+ def remove_node(self, node):
+
+ size = node.size
+
+ if node.is_directory():
+ self.directories.remove(node)
+ else:
+ self.files.remove(node)
+ if node.is_hardlink and node.decrease_refs():
+ size = 1
+
+ self.nodes.remove(node)
+ node.parent = None
+ self.file_system.available_size += size
+
+ def get_node(self, node_name):
+
+ if not self.nodes and self.mount:
+ return self.mount.get_node("/" + node_name)
+
+ for node in self.nodes:
+ if node.name == node_name:
+ if node.mount:
+ return node.mount.root
+ return node
+ return None
+
+ @property
+ def size(self):
+ return 1
+
+ def is_directory(self):
+ return True
+
+
+class FileSystemError(Exception):
+
+ def __init__(self):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+
+ def __init__(self):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+
+ def __init__(self):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+
+ def __init__(self):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class DestinationNodeDoesNotExistError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class SourceNodeDoesNotExistError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class NotAMountpointError(FileSystemError):
+
+ def __init__(self):
+ pass
+
+
+class LinkPathError(FileSystemError):
+
+ def __init__(self):
+ pass

Антоан обнови решението на 30.04.2015 04:39 (преди над 9 години)

+import re
+
class FileSystem:
def __init__(self, size):
self.root = Directory("/", None, "/", self)
self.size = size
self.available_size = size
def get_node(self, path):
-
+ path = re.sub(r"(/)\1+", r"\1", path)
if path == "/":
return self.root
segments = path.split("/")[1:]
num_segments = len(segments)
node = self.root
for index, segment in enumerate(segments):
if node.is_directory():
node = node.get_node(segment)
if not node:
raise NodeDoesNotExistError()
else:
if not index == num_segments - 1 or not node.name == segment:
raise NodeDoesNotExistError()
return node
def create(self, path, directory=False, content=''):
+ path = re.sub(r"(/)\1+", r"\1", path)
parent_dir = "/".join(path.split("/")[:-1])
name = path.split("/")[-1]
try:
parent = self.get_node(parent_dir)
if not parent.is_directory():
raise DestinationNodeDoesNotExistError()
if parent.get_node(name):
raise DestinationNodeExistsError()
if directory and parent.is_directory():
new_node = Directory(path, parent, name, self)
elif not directory:
new_node = File(path, content, parent, name, self)
if self.available_size - new_node.size < 0:
raise NotEnoughSpaceError()
parent.add_node(new_node)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
def remove(self, path, directory=False, force=True):
try:
del_node = self.get_node(path)
if del_node.is_directory():
if not directory:
raise NonExplicitDirectoryDeletionError()
elif not del_node.nodes and not force:
raise NonEmptyDirectoryDeletionError()
del_node.parent.remove_node(del_node)
except NodeDoesNotExistError:
raise
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
destination_node = self.get_node(destination)
if not destination_node.is_directory():
raise DestinationNotADirectoryError()
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
source_node.parent.remove_node(source_node)
destination_node.add_node(source_node)
def link(self, source, destination, symbolic=True):
try:
source_node = self.get_node(source)
if source_node.is_directory() and not symbolic:
raise DirectoryHardLinkError()
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError()
self.create(destination)
link = self.get_node(destination)
if symbolic:
link.link_path = source
else:
link.make_hardlink(source_node)
def mount(self, file_system, path):
try:
source_node = self.get_node(path)
if source_node.is_directory() and source_node.nodes:
raise MountPointNotEmptyError()
if not source_node.is_directory():
raise MountPointNotADirectoryError()
source_node.mount = file_system
except NodeDoesNotExistError:
raise MountPointDoesNotExistError()
def unmount(self, path):
try:
source_node = self.get_node(path)
except NodeDoesNotExistError:
raise
if not source_node.is_directory() or not source_node.mount:
raise NotAMountpointError()
source_node.mount = None
class Node:
def __init__(self, path, is_dir, parent, name, file_system):
self.path = self
self.parent = parent
self.name = name
self.file_system = file_system
class RawContent:
def __init__(self, content):
self.content = content
self.refs = 0
class File(Node):
def __init__(self, path, content, parent, name, file_system):
Node.__init__(self, path, False, parent, name, file_system)
self.__raw_content__ = RawContent(content)
self.link_path = None
self.is_hardlink = False
@property
def size(self):
return len(self.__raw_content__.content) + 1
@property
def content(self):
return self.__raw_content__.content
def decrease_refs(self):
self.__raw_content__.refs -= 1
return self.__raw_content__.refs
def make_hardlink(self, source):
self.__raw_content__ = source.__raw_content__
self.__raw_content__.refs += 1
self.is_hardlink = True
def append(self, text):
length = len(text)
if self.file_system.available_size - length < 0:
raise NotEnoughSpaceError()
self.__raw_content__.content += text
self.file_system.available_size -= length
def truncate(self, text):
length = len(text)
if self.file_system.available_size + self.size - length < 0:
raise NotEnoughSpaceError()
self.file_system.available_size += self.size - length
self.__raw_content__.content = text
def is_directory(self):
return False
def __getattribute__(self, name):
file_attrs = {"content"}
dir_attrs = {"files", "directories", "nodes"}
if name in file_attrs or name in dir_attrs:
if not self.link_path:
return object.__getattribute__(self, name)
try:
node = self.file_system.get_node(self.link_path)
except NodeDoesNotExistError:
raise LinkPathError()
is_dir = node.is_directory()
if (is_dir and name in dir_attrs) or \
(not is_dir and name in file_attrs):
return node.__getattribute__(name)
return object.__getattribute__(self, name)
class Directory(Node):
def __init__(self, path, parent, name, file_system):
Node.__init__(self, path, True, parent, name, file_system)
self.directories = []
self.files = []
self.nodes = []
self.mount = None
def add_node(self, node):
if node.is_directory():
self.directories.append(node)
else:
self.files.append(node)
self.nodes.append(node)
node.parent = self
self.file_system.available_size -= node.size
def remove_node(self, node):
size = node.size
if node.is_directory():
self.directories.remove(node)
else:
self.files.remove(node)
if node.is_hardlink and node.decrease_refs():
size = 1
self.nodes.remove(node)
node.parent = None
self.file_system.available_size += size
def get_node(self, node_name):
if not self.nodes and self.mount:
return self.mount.get_node("/" + node_name)
for node in self.nodes:
if node.name == node_name:
if node.mount:
return node.mount.root
return node
return None
@property
def size(self):
return 1
def is_directory(self):
return True
class FileSystemError(Exception):
def __init__(self):
pass
class FileSystemMountError(FileSystemError):
def __init__(self):
pass
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
pass
class MountPointNotADirectoryError(FileSystemMountError):
def __init__(self):
pass
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
pass
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
pass
class DestinationNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class SourceNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
pass
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
pass
class NotAMountpointError(FileSystemError):
def __init__(self):
pass
class LinkPathError(FileSystemError):
def __init__(self):
pass

Антоан обнови решението на 30.04.2015 15:41 (преди над 9 години)

import re
+
class FileSystem:
def __init__(self, size):
self.root = Directory("/", None, "/", self)
self.size = size
- self.available_size = size
+ self.available_size = size - 1
def get_node(self, path):
path = re.sub(r"(/)\1+", r"\1", path)
if path == "/":
return self.root
segments = path.split("/")[1:]
num_segments = len(segments)
node = self.root
for index, segment in enumerate(segments):
if node.is_directory():
node = node.get_node(segment)
if not node:
raise NodeDoesNotExistError()
else:
if not index == num_segments - 1 or not node.name == segment:
raise NodeDoesNotExistError()
return node
def create(self, path, directory=False, content=''):
path = re.sub(r"(/)\1+", r"\1", path)
parent_dir = "/".join(path.split("/")[:-1])
name = path.split("/")[-1]
try:
parent = self.get_node(parent_dir)
if not parent.is_directory():
raise DestinationNodeDoesNotExistError()
if parent.get_node(name):
raise DestinationNodeExistsError()
if directory and parent.is_directory():
new_node = Directory(path, parent, name, self)
elif not directory:
new_node = File(path, content, parent, name, self)
if self.available_size - new_node.size < 0:
raise NotEnoughSpaceError()
parent.add_node(new_node)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
def remove(self, path, directory=False, force=True):
try:
del_node = self.get_node(path)
if del_node.is_directory():
if not directory:
raise NonExplicitDirectoryDeletionError()
elif not del_node.nodes and not force:
raise NonEmptyDirectoryDeletionError()
del_node.parent.remove_node(del_node)
except NodeDoesNotExistError:
raise
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
destination_node = self.get_node(destination)
if not destination_node.is_directory():
raise DestinationNotADirectoryError()
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
source_node.parent.remove_node(source_node)
destination_node.add_node(source_node)
def link(self, source, destination, symbolic=True):
try:
source_node = self.get_node(source)
if source_node.is_directory() and not symbolic:
raise DirectoryHardLinkError()
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError()
self.create(destination)
link = self.get_node(destination)
if symbolic:
link.link_path = source
else:
link.make_hardlink(source_node)
def mount(self, file_system, path):
try:
source_node = self.get_node(path)
if source_node.is_directory() and source_node.nodes:
raise MountPointNotEmptyError()
if not source_node.is_directory():
raise MountPointNotADirectoryError()
source_node.mount = file_system
except NodeDoesNotExistError:
raise MountPointDoesNotExistError()
def unmount(self, path):
try:
source_node = self.get_node(path)
except NodeDoesNotExistError:
raise
if not source_node.is_directory() or not source_node.mount:
raise NotAMountpointError()
source_node.mount = None
class Node:
def __init__(self, path, is_dir, parent, name, file_system):
self.path = self
self.parent = parent
self.name = name
self.file_system = file_system
class RawContent:
def __init__(self, content):
self.content = content
self.refs = 0
class File(Node):
def __init__(self, path, content, parent, name, file_system):
Node.__init__(self, path, False, parent, name, file_system)
self.__raw_content__ = RawContent(content)
self.link_path = None
self.is_hardlink = False
@property
def size(self):
return len(self.__raw_content__.content) + 1
@property
def content(self):
return self.__raw_content__.content
def decrease_refs(self):
self.__raw_content__.refs -= 1
return self.__raw_content__.refs
def make_hardlink(self, source):
self.__raw_content__ = source.__raw_content__
self.__raw_content__.refs += 1
self.is_hardlink = True
def append(self, text):
length = len(text)
if self.file_system.available_size - length < 0:
raise NotEnoughSpaceError()
self.__raw_content__.content += text
self.file_system.available_size -= length
def truncate(self, text):
length = len(text)
if self.file_system.available_size + self.size - length < 0:
raise NotEnoughSpaceError()
self.file_system.available_size += self.size - length
self.__raw_content__.content = text
def is_directory(self):
return False
def __getattribute__(self, name):
file_attrs = {"content"}
dir_attrs = {"files", "directories", "nodes"}
if name in file_attrs or name in dir_attrs:
if not self.link_path:
return object.__getattribute__(self, name)
try:
node = self.file_system.get_node(self.link_path)
except NodeDoesNotExistError:
raise LinkPathError()
is_dir = node.is_directory()
if (is_dir and name in dir_attrs) or \
(not is_dir and name in file_attrs):
return node.__getattribute__(name)
return object.__getattribute__(self, name)
class Directory(Node):
def __init__(self, path, parent, name, file_system):
Node.__init__(self, path, True, parent, name, file_system)
self.directories = []
self.files = []
self.nodes = []
self.mount = None
def add_node(self, node):
if node.is_directory():
self.directories.append(node)
else:
self.files.append(node)
self.nodes.append(node)
node.parent = self
self.file_system.available_size -= node.size
def remove_node(self, node):
size = node.size
if node.is_directory():
self.directories.remove(node)
+
+ for sub in node.nodes:
+ node.remove_node(sub)
+
+ node.nodes = []
+ self.nodes.remove(node)
else:
self.files.remove(node)
if node.is_hardlink and node.decrease_refs():
size = 1
- self.nodes.remove(node)
node.parent = None
+
self.file_system.available_size += size
def get_node(self, node_name):
if not self.nodes and self.mount:
return self.mount.get_node("/" + node_name)
for node in self.nodes:
if node.name == node_name:
if node.mount:
return node.mount.root
return node
return None
@property
def size(self):
return 1
def is_directory(self):
return True
class FileSystemError(Exception):
def __init__(self):
pass
class FileSystemMountError(FileSystemError):
def __init__(self):
pass
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
pass
class MountPointNotADirectoryError(FileSystemMountError):
def __init__(self):
pass
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
pass
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
pass
class DestinationNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class SourceNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
pass
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
pass
class NotAMountpointError(FileSystemError):
def __init__(self):
pass
class LinkPathError(FileSystemError):
def __init__(self):
pass

Антоан обнови решението на 30.04.2015 15:44 (преди над 9 години)

import re
class FileSystem:
def __init__(self, size):
self.root = Directory("/", None, "/", self)
self.size = size
self.available_size = size - 1
def get_node(self, path):
path = re.sub(r"(/)\1+", r"\1", path)
+ path = path[:-1] if path[-1:] == "/" else path
+
if path == "/":
return self.root
segments = path.split("/")[1:]
num_segments = len(segments)
node = self.root
for index, segment in enumerate(segments):
if node.is_directory():
node = node.get_node(segment)
if not node:
raise NodeDoesNotExistError()
else:
if not index == num_segments - 1 or not node.name == segment:
raise NodeDoesNotExistError()
return node
def create(self, path, directory=False, content=''):
path = re.sub(r"(/)\1+", r"\1", path)
+ path = path[:-1] if path[-1:] == "/" else path
parent_dir = "/".join(path.split("/")[:-1])
name = path.split("/")[-1]
try:
parent = self.get_node(parent_dir)
if not parent.is_directory():
raise DestinationNodeDoesNotExistError()
if parent.get_node(name):
raise DestinationNodeExistsError()
if directory and parent.is_directory():
new_node = Directory(path, parent, name, self)
elif not directory:
new_node = File(path, content, parent, name, self)
if self.available_size - new_node.size < 0:
raise NotEnoughSpaceError()
parent.add_node(new_node)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
def remove(self, path, directory=False, force=True):
try:
del_node = self.get_node(path)
if del_node.is_directory():
if not directory:
raise NonExplicitDirectoryDeletionError()
elif not del_node.nodes and not force:
raise NonEmptyDirectoryDeletionError()
del_node.parent.remove_node(del_node)
except NodeDoesNotExistError:
raise
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
destination_node = self.get_node(destination)
if not destination_node.is_directory():
raise DestinationNotADirectoryError()
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
source_node.parent.remove_node(source_node)
destination_node.add_node(source_node)
def link(self, source, destination, symbolic=True):
try:
source_node = self.get_node(source)
if source_node.is_directory() and not symbolic:
raise DirectoryHardLinkError()
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError()
self.create(destination)
link = self.get_node(destination)
if symbolic:
link.link_path = source
else:
link.make_hardlink(source_node)
def mount(self, file_system, path):
try:
source_node = self.get_node(path)
if source_node.is_directory() and source_node.nodes:
raise MountPointNotEmptyError()
if not source_node.is_directory():
raise MountPointNotADirectoryError()
source_node.mount = file_system
except NodeDoesNotExistError:
raise MountPointDoesNotExistError()
def unmount(self, path):
try:
source_node = self.get_node(path)
except NodeDoesNotExistError:
raise
if not source_node.is_directory() or not source_node.mount:
raise NotAMountpointError()
source_node.mount = None
class Node:
def __init__(self, path, is_dir, parent, name, file_system):
self.path = self
self.parent = parent
self.name = name
self.file_system = file_system
class RawContent:
def __init__(self, content):
self.content = content
self.refs = 0
class File(Node):
def __init__(self, path, content, parent, name, file_system):
Node.__init__(self, path, False, parent, name, file_system)
self.__raw_content__ = RawContent(content)
self.link_path = None
self.is_hardlink = False
@property
def size(self):
return len(self.__raw_content__.content) + 1
@property
def content(self):
return self.__raw_content__.content
def decrease_refs(self):
self.__raw_content__.refs -= 1
return self.__raw_content__.refs
def make_hardlink(self, source):
self.__raw_content__ = source.__raw_content__
self.__raw_content__.refs += 1
self.is_hardlink = True
def append(self, text):
length = len(text)
if self.file_system.available_size - length < 0:
raise NotEnoughSpaceError()
self.__raw_content__.content += text
self.file_system.available_size -= length
def truncate(self, text):
length = len(text)
if self.file_system.available_size + self.size - length < 0:
raise NotEnoughSpaceError()
self.file_system.available_size += self.size - length
self.__raw_content__.content = text
def is_directory(self):
return False
def __getattribute__(self, name):
file_attrs = {"content"}
dir_attrs = {"files", "directories", "nodes"}
if name in file_attrs or name in dir_attrs:
if not self.link_path:
return object.__getattribute__(self, name)
try:
node = self.file_system.get_node(self.link_path)
except NodeDoesNotExistError:
raise LinkPathError()
is_dir = node.is_directory()
if (is_dir and name in dir_attrs) or \
(not is_dir and name in file_attrs):
return node.__getattribute__(name)
return object.__getattribute__(self, name)
class Directory(Node):
def __init__(self, path, parent, name, file_system):
Node.__init__(self, path, True, parent, name, file_system)
self.directories = []
self.files = []
self.nodes = []
self.mount = None
def add_node(self, node):
if node.is_directory():
self.directories.append(node)
else:
self.files.append(node)
self.nodes.append(node)
node.parent = self
self.file_system.available_size -= node.size
def remove_node(self, node):
size = node.size
if node.is_directory():
self.directories.remove(node)
for sub in node.nodes:
node.remove_node(sub)
node.nodes = []
self.nodes.remove(node)
else:
self.files.remove(node)
if node.is_hardlink and node.decrease_refs():
size = 1
node.parent = None
self.file_system.available_size += size
def get_node(self, node_name):
if not self.nodes and self.mount:
return self.mount.get_node("/" + node_name)
for node in self.nodes:
if node.name == node_name:
if node.mount:
return node.mount.root
return node
return None
@property
def size(self):
return 1
def is_directory(self):
return True
class FileSystemError(Exception):
def __init__(self):
pass
class FileSystemMountError(FileSystemError):
def __init__(self):
pass
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
pass
class MountPointNotADirectoryError(FileSystemMountError):
def __init__(self):
pass
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
pass
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
pass
class DestinationNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class SourceNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
pass
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
pass
class NotAMountpointError(FileSystemError):
def __init__(self):
pass
class LinkPathError(FileSystemError):
def __init__(self):
pass

Антоан обнови решението на 30.04.2015 16:00 (преди над 9 години)

import re
class FileSystem:
def __init__(self, size):
self.root = Directory("/", None, "/", self)
self.size = size
self.available_size = size - 1
def get_node(self, path):
path = re.sub(r"(/)\1+", r"\1", path)
path = path[:-1] if path[-1:] == "/" else path
if path == "/":
return self.root
segments = path.split("/")[1:]
num_segments = len(segments)
node = self.root
for index, segment in enumerate(segments):
if node.is_directory():
node = node.get_node(segment)
if not node:
raise NodeDoesNotExistError()
else:
if not index == num_segments - 1 or not node.name == segment:
raise NodeDoesNotExistError()
return node
def create(self, path, directory=False, content=''):
path = re.sub(r"(/)\1+", r"\1", path)
path = path[:-1] if path[-1:] == "/" else path
parent_dir = "/".join(path.split("/")[:-1])
name = path.split("/")[-1]
try:
parent = self.get_node(parent_dir)
if not parent.is_directory():
raise DestinationNodeDoesNotExistError()
if parent.get_node(name):
raise DestinationNodeExistsError()
if directory and parent.is_directory():
new_node = Directory(path, parent, name, self)
elif not directory:
new_node = File(path, content, parent, name, self)
if self.available_size - new_node.size < 0:
raise NotEnoughSpaceError()
parent.add_node(new_node)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
def remove(self, path, directory=False, force=True):
try:
del_node = self.get_node(path)
if del_node.is_directory():
if not directory:
raise NonExplicitDirectoryDeletionError()
elif not del_node.nodes and not force:
raise NonEmptyDirectoryDeletionError()
del_node.parent.remove_node(del_node)
except NodeDoesNotExistError:
raise
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
destination_node = self.get_node(destination)
if not destination_node.is_directory():
raise DestinationNotADirectoryError()
+
+ if destination_node.get_node(source_node.name):
+ raise DestinationNodeExistsError()
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
+ old_size = self.available_size
source_node.parent.remove_node(source_node)
destination_node.add_node(source_node)
+ self.available_size = old_size
def link(self, source, destination, symbolic=True):
try:
source_node = self.get_node(source)
if source_node.is_directory() and not symbolic:
raise DirectoryHardLinkError()
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError()
self.create(destination)
link = self.get_node(destination)
if symbolic:
link.link_path = source
else:
link.make_hardlink(source_node)
def mount(self, file_system, path):
try:
source_node = self.get_node(path)
if source_node.is_directory() and source_node.nodes:
raise MountPointNotEmptyError()
if not source_node.is_directory():
raise MountPointNotADirectoryError()
source_node.mount = file_system
except NodeDoesNotExistError:
raise MountPointDoesNotExistError()
def unmount(self, path):
try:
source_node = self.get_node(path)
except NodeDoesNotExistError:
raise
if not source_node.is_directory() or not source_node.mount:
raise NotAMountpointError()
source_node.mount = None
class Node:
def __init__(self, path, is_dir, parent, name, file_system):
self.path = self
self.parent = parent
self.name = name
self.file_system = file_system
class RawContent:
def __init__(self, content):
self.content = content
self.refs = 0
class File(Node):
def __init__(self, path, content, parent, name, file_system):
Node.__init__(self, path, False, parent, name, file_system)
self.__raw_content__ = RawContent(content)
self.link_path = None
self.is_hardlink = False
@property
def size(self):
return len(self.__raw_content__.content) + 1
@property
def content(self):
return self.__raw_content__.content
def decrease_refs(self):
self.__raw_content__.refs -= 1
return self.__raw_content__.refs
def make_hardlink(self, source):
self.__raw_content__ = source.__raw_content__
self.__raw_content__.refs += 1
self.is_hardlink = True
def append(self, text):
length = len(text)
if self.file_system.available_size - length < 0:
raise NotEnoughSpaceError()
self.__raw_content__.content += text
self.file_system.available_size -= length
def truncate(self, text):
length = len(text)
if self.file_system.available_size + self.size - length < 0:
raise NotEnoughSpaceError()
self.file_system.available_size += self.size - length
self.__raw_content__.content = text
def is_directory(self):
return False
def __getattribute__(self, name):
file_attrs = {"content"}
dir_attrs = {"files", "directories", "nodes"}
if name in file_attrs or name in dir_attrs:
if not self.link_path:
return object.__getattribute__(self, name)
try:
node = self.file_system.get_node(self.link_path)
except NodeDoesNotExistError:
raise LinkPathError()
is_dir = node.is_directory()
if (is_dir and name in dir_attrs) or \
(not is_dir and name in file_attrs):
return node.__getattribute__(name)
return object.__getattribute__(self, name)
class Directory(Node):
def __init__(self, path, parent, name, file_system):
Node.__init__(self, path, True, parent, name, file_system)
self.directories = []
self.files = []
self.nodes = []
self.mount = None
def add_node(self, node):
if node.is_directory():
self.directories.append(node)
else:
self.files.append(node)
+ self.file_system.available_size -= node.size
self.nodes.append(node)
node.parent = self
- self.file_system.available_size -= node.size
def remove_node(self, node):
size = node.size
if node.is_directory():
self.directories.remove(node)
for sub in node.nodes:
node.remove_node(sub)
node.nodes = []
self.nodes.remove(node)
else:
self.files.remove(node)
if node.is_hardlink and node.decrease_refs():
size = 1
node.parent = None
self.file_system.available_size += size
def get_node(self, node_name):
if not self.nodes and self.mount:
return self.mount.get_node("/" + node_name)
for node in self.nodes:
if node.name == node_name:
- if node.mount:
+ if node.is_directory() and node.mount:
return node.mount.root
return node
return None
@property
def size(self):
return 1
def is_directory(self):
return True
class FileSystemError(Exception):
def __init__(self):
pass
class FileSystemMountError(FileSystemError):
def __init__(self):
pass
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
pass
class MountPointNotADirectoryError(FileSystemMountError):
def __init__(self):
pass
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
pass
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
pass
class DestinationNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
pass
class SourceNodeDoesNotExistError(FileSystemError):
def __init__(self):
pass
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
pass
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
pass
class NotAMountpointError(FileSystemError):
def __init__(self):
pass
class LinkPathError(FileSystemError):
def __init__(self):
pass