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'([^/]+)') splitpath_re = re.compile(r'([^/]+)')
def __init__(self, uris): def __init__(self, uris):
"""Create a dictionary tree for quick browsing. # {parent_uri: {uri: ref}}
self._cache = {}
{'foo': {'bar': {None: [ref1, ref2]}, for track_uri in uris:
'baz': {}, path = translator.local_track_uri_to_path(track_uri, b'/')
None: [ref3]}}
"""
self._root = collections.OrderedDict()
for uri in uris:
path = translator.local_track_uri_to_path(uri, b'/')
parts = self.splitpath_re.findall( parts = self.splitpath_re.findall(
path.decode(self.encoding, 'replace')) path.decode(self.encoding, 'replace'))
filename = parts.pop() track_ref = models.Ref.track(uri=track_uri, name=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)
def lookup(self, path): parent = 'local:directory'
results = [] for i in range(len(parts)):
node = self._root self._cache.setdefault(parent, collections.OrderedDict())
for part in self.splitpath_re.findall(path): directory = b'/'.join(parts[:i+1])
node = node.get(part, {}) 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(): parent = dir_uri
if key is not None:
uri = os.path.join(path, key)
results.append(models.Ref.directory(uri=uri, name=key))
# Get tracks afterwards to ensure ordering. self._cache.setdefault(parent, collections.OrderedDict())
results.extend(node.get(None, [])) self._cache[parent][track_uri] = track_ref
return results def lookup(self, uri):
return self._cache.get(uri, {}).values()
class JsonLibrary(local.Library): 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) 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): def m3u_extinf_to_track(line):
"""Convert extended M3U directive to track template.""" """Convert extended M3U directive to track template."""
m = M3U_EXTINF_RE.match(line) m = M3U_EXTINF_RE.match(line)

View File

@ -14,23 +14,19 @@ class BrowseCacheTest(unittest.TestCase):
self.cache = json._BrowseCache(self.uris) self.cache = json._BrowseCache(self.uris)
def test_lookup_root(self): def test_lookup_root(self):
expected = [Ref.directory(uri='/foo', name='foo')] expected = [Ref.directory(uri='local:directory:foo', name='foo')]
self.assertEqual(expected, self.cache.lookup('/')) self.assertEqual(expected, self.cache.lookup('local:directory'))
def test_lookup_foo(self): 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')] 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): def test_lookup_foo_bar(self):
expected = [Ref.track(uri=self.uris[0], name='song1'), expected = [Ref.track(uri=self.uris[0], name='song1'),
Ref.track(uri=self.uris[1], name='song2')] 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): def test_lookup_foo_baz(self):
self.assertEqual([], self.cache.lookup('/foo/baz')) self.assertEqual([], self.cache.lookup('local:directory: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/'))