From d6aa9fb0133c2c75f0e741a41f4fa76e96eb189e Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Fri, 17 Jan 2014 01:06:23 +0100 Subject: [PATCH] local: Convert local browsing to uri based system. --- mopidy/local/json.py | 44 +++++++++++++++----------------------- mopidy/local/translator.py | 7 ++++++ tests/local/json_test.py | 18 ++++++---------- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/mopidy/local/json.py b/mopidy/local/json.py index ce11f058..f25b3813 100644 --- a/mopidy/local/json.py +++ b/mopidy/local/json.py @@ -49,41 +49,31 @@ class _BrowseCache(object): splitpath_re = re.compile(r'([^/]+)') def __init__(self, uris): - """Create a dictionary tree for quick browsing. + # {parent_uri: {uri: ref}} + self._cache = {} - {'foo': {'bar': {None: [ref1, ref2]}, - 'baz': {}, - None: [ref3]}} - """ - self._root = collections.OrderedDict() - - for uri in uris: - path = translator.local_track_uri_to_path(uri, b'/') + for track_uri in uris: + path = translator.local_track_uri_to_path(track_uri, b'/') parts = self.splitpath_re.findall( path.decode(self.encoding, 'replace')) - filename = parts.pop() - node = self._root - for part in parts: - node = node.setdefault(part, collections.OrderedDict()) - ref = models.Ref.track(uri=uri, name=filename) - node.setdefault(None, []).append(ref) + track_ref = models.Ref.track(uri=track_uri, name=parts.pop()) - def lookup(self, path): - results = [] - node = self._root + parent = 'local:directory' + for i in range(len(parts)): + self._cache.setdefault(parent, collections.OrderedDict()) - for part in self.splitpath_re.findall(path): - node = node.get(part, {}) + directory = b'/'.join(parts[:i+1]) + dir_uri = translator.path_to_local_directory_uri(directory) + dir_ref = models.Ref.directory(uri=dir_uri, name=parts[i]) + self._cache[parent][dir_uri] = dir_ref - for key, value in node.items(): - if key is not None: - uri = os.path.join(path, key) - results.append(models.Ref.directory(uri=uri, name=key)) + parent = dir_uri - # Get tracks afterwards to ensure ordering. - results.extend(node.get(None, [])) + self._cache.setdefault(parent, collections.OrderedDict()) + self._cache[parent][track_uri] = track_ref - return results + def lookup(self, uri): + return self._cache.get(uri, {}).values() class JsonLibrary(local.Library): diff --git a/mopidy/local/translator.py b/mopidy/local/translator.py index 7ec6d3fe..7d28be01 100644 --- a/mopidy/local/translator.py +++ b/mopidy/local/translator.py @@ -33,6 +33,13 @@ def path_to_local_track_uri(relpath): return b'local:track:%s' % urllib.quote(relpath) +def path_to_local_directory_uri(relpath): + """Convert path releative to media_dir to local directory URI.""" + if isinstance(relpath, unicode): + relpath = relpath.encode('utf-8') + return b'local:directory:%s' % urllib.quote(relpath) + + def m3u_extinf_to_track(line): """Convert extended M3U directive to track template.""" m = M3U_EXTINF_RE.match(line) diff --git a/tests/local/json_test.py b/tests/local/json_test.py index af606c05..9c8686e9 100644 --- a/tests/local/json_test.py +++ b/tests/local/json_test.py @@ -14,23 +14,19 @@ class BrowseCacheTest(unittest.TestCase): self.cache = json._BrowseCache(self.uris) def test_lookup_root(self): - expected = [Ref.directory(uri='/foo', name='foo')] - self.assertEqual(expected, self.cache.lookup('/')) + expected = [Ref.directory(uri='local:directory:foo', name='foo')] + self.assertEqual(expected, self.cache.lookup('local:directory')) def test_lookup_foo(self): - expected = [Ref.directory(uri='/foo/bar', name='bar'), + expected = [Ref.directory(uri='local:directory:foo/bar', name='bar'), Ref.track(uri=self.uris[2], name='song3')] - self.assertEqual(expected, self.cache.lookup('/foo')) + self.assertEqual(expected, self.cache.lookup('local:directory:foo')) def test_lookup_foo_bar(self): expected = [Ref.track(uri=self.uris[0], name='song1'), Ref.track(uri=self.uris[1], name='song2')] - self.assertEqual(expected, self.cache.lookup('/foo/bar')) + self.assertEqual( + expected, self.cache.lookup('local:directory:foo/bar')) def test_lookup_foo_baz(self): - self.assertEqual([], self.cache.lookup('/foo/baz')) - - def test_lookup_normalize_slashes(self): - expected = [Ref.track(uri=self.uris[0], name='song1'), - Ref.track(uri=self.uris[1], name='song2')] - self.assertEqual(expected, self.cache.lookup('/foo//bar/')) + self.assertEqual([], self.cache.lookup('local:directory:foo/baz'))