diff --git a/mopidy/backends/base.py b/mopidy/backends/base.py index c45eb771..9f531450 100644 --- a/mopidy/backends/base.py +++ b/mopidy/backends/base.py @@ -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 diff --git a/mopidy/scanner.py b/mopidy/scanner.py index 0cc51d2a..ba8f2ff9 100644 --- a/mopidy/scanner.py +++ b/mopidy/scanner.py @@ -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():