From 9362ec0103b19681f3a05e90401b3772e2d4d272 Mon Sep 17 00:00:00 2001 From: Damien Churchill Date: Tue, 4 Oct 2011 22:48:20 +0100 Subject: ui: add a new file tree geared towards ext Add a new file tree that is more suited to created a tree that an ext proxy will be able to load and convert into a data store. This file tree also has an improved file tree walk method that uses generators instead of callbacks. --- deluge/tests/test_file_tree.py | 46 +++++++++++++++++++++++++ deluge/ui/common.py | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 deluge/tests/test_file_tree.py diff --git a/deluge/tests/test_file_tree.py b/deluge/tests/test_file_tree.py new file mode 100644 index 000000000..34c018e68 --- /dev/null +++ b/deluge/tests/test_file_tree.py @@ -0,0 +1,46 @@ +from twisted.trial import unittest +from deluge.ui.common import ExtFileTree + +class ExtFileTreeTestCase(unittest.TestCase): + + def test_simple_tree(self): + paths = [ + "SomeRootFolder/file1", + "SomeRootFolder/file2", + "SomeRootFolder/subfolder1/subfile1", + "SomeRootFolder/subfolder1/subfile2" + ] + tree = ExtFileTree(paths) + self.assertEqual(tree.tree, {"children": [ + {"text": "SomeRootFolder", "children": [ + {"text": "file1"}, + {"text": "file2"}, + {"text": "subfolder1", "children": [ + {"text": "subfile1"}, + {"text": "subfile2"} + ]} + ]} + ], "text": ""}) + + def test_tree_walk(self): + paths = [ + "SomeRootFolder/file1", + "SomeRootFolder/file2", + "SomeRootFolder/subfolder1/subfile1", + "SomeRootFolder/subfolder1/subfile2" + ] + tree = ExtFileTree(paths) + for path, obj in tree.walk(): + if path == "SomeRootFolder/file1": + obj["size"] = 1024 + + self.assertEqual(tree.tree, {"children": [ + {"text": "SomeRootFolder", "children": [ + {"text": "file1", "size": 1024}, + {"text": "file2"}, + {"text": "subfolder1", "children": [ + {"text": "subfile1"}, + {"text": "subfile2"} + ]} + ]} + ], "text": ""}) diff --git a/deluge/ui/common.py b/deluge/ui/common.py index 239bb84c9..4ad0f12e4 100644 --- a/deluge/ui/common.py +++ b/deluge/ui/common.py @@ -244,6 +244,83 @@ class TorrentInfo(object): """ return self.__m_filedata +class ExtFileTree(object): + """ + Convert a list of paths into a compatible file tree format for Ext. + + :param paths: The paths to be converted + :type paths: list + """ + + def __init__(self, paths): + self.tree = {"children": [], "text": ""} + + def get_parent(path): + parent = self.tree + while "/" in path: + directory, sep, path = path.partition("/") + new_parent = None + for child in parent["children"]: + if child["text"] == directory: + new_parent = child + if not new_parent: + new_parent = {"children": [], "text": directory} + parent["children"].append(new_parent) + parent = new_parent + return parent, path + + for path in paths: + if path[-1] == "/": + path = path[:-1] + parent, path = get_parent(path) + parent["children"].append({ + "text": path, + "children": [] + }) + else: + parent, path = get_parent(path) + parent["children"].append({"text": path}) + + def get_tree(self): + """ + Return the tree. + + :returns: the file tree. + :rtype: dictionary + """ + return self.tree + + def walk(self): + """ + Walk through the file tree calling the callback function on each item + contained. + + :param callback: The function to be used as a callback, it should have + the signature func(item, path) where item is a `tuple` for a file + and `dict` for a directory. + :type callback: function + """ + for path, child in self.__walk(self.tree, ""): + yield path, child + + def __walk(self, directory, parent_path): + for item in directory["children"]: + path = path_join(parent_path, item["text"]) + if "children" in item: + for path, child in self.__walk(item, path): + yield path, child + yield path, item + + def __str__(self): + lines = [] + def write(path, item): + depth = path.count("/") + path = os.path.basename(path) + path = path + "/" if item["type"] == "dir" else path + lines.append(" " * depth + path) + self.walk(write) + return "\n".join(lines) + class FileTree2(object): """ Converts a list of paths in to a file tree. -- cgit