core: Add library updater.
Idea behind this class is to have a clear sub-set of our library API that is only used for updating libraries. This makes it very clear what methods are needed for just libaries and additionally updatable libraries. Next couple of commits will build on this idea taking us closer to plugable local libraries.
This commit is contained in:
parent
5961a1f5c8
commit
7f80a188c9
@ -15,6 +15,11 @@ class Backend(object):
|
||||
#: the backend doesn't provide a library.
|
||||
library = None
|
||||
|
||||
#: The library update provider. An instance of
|
||||
#: :class:`~mopidy.backends.base.BaseLibraryUpdateProvider`, or
|
||||
#: :class:`None` if the backend doesn't provide a library.
|
||||
updater = None
|
||||
|
||||
#: The playback provider. An instance of
|
||||
#: :class:`~mopidy.backends.base.BasePlaybackProvider`, or :class:`None` if
|
||||
#: the backend doesn't provide playback.
|
||||
@ -35,6 +40,9 @@ class Backend(object):
|
||||
def has_library(self):
|
||||
return self.library is not None
|
||||
|
||||
def has_updater(self):
|
||||
return self.updater is not None
|
||||
|
||||
def has_playback(self):
|
||||
return self.playback is not None
|
||||
|
||||
@ -53,6 +61,7 @@ class BaseLibraryProvider(object):
|
||||
def __init__(self, backend):
|
||||
self.backend = backend
|
||||
|
||||
# TODO: replace with search(query, exact=Ture, ...)
|
||||
def find_exact(self, query=None, uris=None):
|
||||
"""
|
||||
See :meth:`mopidy.core.LibraryController.find_exact`.
|
||||
@ -86,6 +95,48 @@ class BaseLibraryProvider(object):
|
||||
pass
|
||||
|
||||
|
||||
class BaseLibraryUpdateProvider(object):
|
||||
"""
|
||||
:param backend: backend the controller is a part of
|
||||
:type backend: :class:`mopidy.backends.base.Backend`
|
||||
"""
|
||||
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, backend):
|
||||
self.backend = backend
|
||||
|
||||
def load(self):
|
||||
"""Loads the library and returns all tracks in it.
|
||||
|
||||
*MUST be implemented by subclass.*
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def add(self, track):
|
||||
"""Adds given track to library.
|
||||
|
||||
Overwrites any existing entry with same uri.
|
||||
|
||||
*MUST be implemented by subclass.*
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def remove(self, uri):
|
||||
"""Removes given track from library.
|
||||
|
||||
*MUST be implemented by subclass.*
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def commit(self):
|
||||
"""Persist changes to library.
|
||||
|
||||
*MAY be implemented by subclass.*
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class BasePlaybackProvider(object):
|
||||
"""
|
||||
:param audio: the audio actor
|
||||
|
||||
@ -111,15 +111,19 @@ def main():
|
||||
tmp = tempfile.NamedTemporaryFile(
|
||||
prefix=basename + '.', dir=directory, delete=False)
|
||||
|
||||
for row in mpd_translator.tracks_to_tag_cache_format(
|
||||
tracks.values(), config['local']['media_dir']):
|
||||
if len(row) == 1:
|
||||
tmp.write(('%s\n' % row).encode('utf-8'))
|
||||
else:
|
||||
tmp.write(('%s: %s\n' % row).encode('utf-8'))
|
||||
try:
|
||||
for row in mpd_translator.tracks_to_tag_cache_format(
|
||||
tracks.values(), config['local']['media_dir']):
|
||||
if len(row) == 1:
|
||||
tmp.write(('%s\n' % row).encode('utf-8'))
|
||||
else:
|
||||
tmp.write(('%s: %s\n' % row).encode('utf-8'))
|
||||
|
||||
os.rename(tmp.name, config['local']['tag_cache_file'])
|
||||
logging.info('Done writing; overwriting active tag cache.')
|
||||
logging.info('Done writing; overwriting active tag cache.')
|
||||
os.rename(tmp.name, config['local']['tag_cache_file'])
|
||||
finally:
|
||||
if os.path.exists(tmp.name):
|
||||
os.remove(tmp.name)
|
||||
|
||||
|
||||
def parse_args():
|
||||
|
||||
Loading…
Reference in New Issue
Block a user