local: Convert local browsing to uri based system.

This commit is contained in:
Thomas Adamcik 2014-01-17 01:06:23 +01:00
parent 999f478010
commit d6aa9fb013
3 changed files with 31 additions and 38 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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'))