diff --git a/docs/api/core.rst b/docs/api/core.rst index de686028..abc046bd 100644 --- a/docs/api/core.rst +++ b/docs/api/core.rst @@ -53,10 +53,6 @@ in core see :class:`~mopidy.core.CoreListener`. .. automethod:: get_version - .. automethod:: save_state - - .. automethod:: load_state - Tracklist controller ==================== diff --git a/docs/api/models.rst b/docs/api/models.rst index cd6d1cf2..27c7647f 100644 --- a/docs/api/models.rst +++ b/docs/api/models.rst @@ -87,13 +87,6 @@ Data model (de)serialization .. autoclass:: mopidy.models.ModelJSONEncoder -Data model import/export ----------------------------- - -.. autofunction:: mopidy.models.storage.save - -.. autofunction:: mopidy.models.storage.load - Data model field types ---------------------- diff --git a/mopidy/core/actor.py b/mopidy/core/actor.py index 8b9010ab..9c03d035 100644 --- a/mopidy/core/actor.py +++ b/mopidy/core/actor.py @@ -18,7 +18,7 @@ from mopidy.core.mixer import MixerController from mopidy.core.playback import PlaybackController from mopidy.core.playlists import PlaylistsController from mopidy.core.tracklist import TracklistController -from mopidy.internal import storage, validation, versioning +from mopidy.internal import path, storage, validation, versioning from mopidy.internal.deprecation import deprecated_property from mopidy.internal.models import CoreState @@ -144,24 +144,10 @@ class Core( try: coverage = [] if self._config and 'restore_state' in self._config['core']: - value = self._config['core']['restore_state'] - if not value or 'off' == value: - pass - elif 'volume' == value: - coverage = ['volume'] - elif 'load' == value: - coverage = ['tracklist', 'mode', 'volume', 'history'] - elif 'last' == value: - coverage = ['tracklist', 'mode', 'play-last', 'volume', - 'history'] - elif 'play' == value: - coverage = ['tracklist', 'mode', 'play-always', 'volume', - 'history'] - else: - logger.warn('Unknown value for config ' - 'core.restore_state: %s', value) + coverage = self._config_to_coverage( + self._config['core']['restore_state']) if len(coverage): - self.load_state('persistent', coverage) + self._load_state(coverage) except Exception as e: logger.warn('Restore state: Unexpected error: %s', str(e)) @@ -170,23 +156,43 @@ class Core( if self._config and 'restore_state' in self._config['core']: amount = self._config['core']['restore_state'] if amount and 'off' != amount: - self.save_state('persistent') + self._save_state() except Exception as e: - logger.warn('Export state: Unexpected error: %s', str(e)) + logger.warn('Unexpected error while saving state: %s', str(e)) - def save_state(self, name): + @staticmethod + def _config_to_coverage(value): + coverage = [] + if not value or 'off' == value: + pass + elif 'volume' == value: + coverage = ['volume'] + elif 'load' == value: + coverage = ['tracklist', 'mode', 'volume', 'history'] + elif 'last' == value: + coverage = ['tracklist', 'mode', 'play-last', 'volume', + 'history'] + elif 'play' == value: + coverage = ['tracklist', 'mode', 'play-always', 'volume', + 'history'] + else: + logger.warn('Unknown value for config ' + 'core.restore_state: %s', value) + return coverage + + def _get_data_dir(self): + # get or create data director for core + data_dir_path = bytes( + os.path.join(self._config['core']['data_dir'], 'core')) + path.get_or_create_dir(data_dir_path) + return data_dir_path + + def _save_state(self): """ Save current state to disk. - - :param name: a name (for later use with :meth:`load_state`) - :type name: str """ - if not name: - raise TypeError('Missing file name.') - file_name = os.path.join( - self._config['core']['data_dir'], name) - file_name += '.state' + file_name = os.path.join(self._get_data_dir(), 'persistent.state') logger.info('Save state to %s', file_name) data = {} @@ -199,7 +205,7 @@ class Core( storage.save(file_name, data) logger.debug('Save state done.') - def load_state(self, name, coverage): + def _load_state(self, coverage): """ Restore state from disk. @@ -213,17 +219,11 @@ class Core( - 'volume' set mixer volume - 'history' restore history - :param name: a name (used previously with :meth:`save_state`) - :type path: str :param coverage: amount of data to restore :type coverage: list of string (see above) """ - if not name: - raise TypeError('Missing file name.') - file_name = os.path.join( - self._config['core']['data_dir'], name) - file_name += '.state' + file_name = os.path.join(self._get_data_dir(), 'persistent.state') logger.info('Load state from %s', file_name) data = storage.load(file_name) diff --git a/mopidy/http/handlers.py b/mopidy/http/handlers.py index 2994f8ed..a752a4f0 100644 --- a/mopidy/http/handlers.py +++ b/mopidy/http/handlers.py @@ -43,8 +43,6 @@ def make_jsonrpc_wrapper(core_actor): objects={ 'core.get_uri_schemes': core.Core.get_uri_schemes, 'core.get_version': core.Core.get_version, - 'core.load_state': core.Core.load_state, - 'core.save_state': core.Core.save_state, 'core.history': core.HistoryController, 'core.library': core.LibraryController, 'core.mixer': core.MixerController, @@ -57,8 +55,6 @@ def make_jsonrpc_wrapper(core_actor): 'core.describe': inspector.describe, 'core.get_uri_schemes': core_actor.get_uri_schemes, 'core.get_version': core_actor.get_version, - 'core.load_state': core_actor.load_state, - 'core.save_state': core_actor.save_state, 'core.history': core_actor.history, 'core.library': core_actor.library, 'core.mixer': core_actor.mixer, diff --git a/tests/core/test_actor.py b/tests/core/test_actor.py index fda24c4c..e0e9d9a0 100644 --- a/tests/core/test_actor.py +++ b/tests/core/test_actor.py @@ -54,7 +54,7 @@ class CoreActorExportRestoreTest(unittest.TestCase): config = { 'core': { 'max_tracklist_length': 10000, - 'restore_state': 'play', + 'restore_state': 'last', 'data_dir': self.temp_dir, } } @@ -66,8 +66,32 @@ class CoreActorExportRestoreTest(unittest.TestCase): pykka.ActorRegistry.stop_all() shutil.rmtree(self.temp_dir) - def test_restore_on_start(self): - # cover mopidy.core.actor.on_start and .on_stop - # starting the actor by calling any function: - self.core.get_version() - pass + def test_export_state(self): + self.core.teardown() + # TODO: implement meaningful test + + def test_restore_state(self): + self.core.setup() + # TODO: implement meaningful test + + def test_export_coverage_none(self): + result = Core._config_to_coverage(None) + self.assertEqual(result, []) + result = Core._config_to_coverage('off') + self.assertEqual(result, []) + + def test_export_coverage(self): + result = Core._config_to_coverage('volume') + self.assertEqual(result, ['volume']) + + result = Core._config_to_coverage('load') + target = ['tracklist', 'mode', 'volume', 'history'] + self.assertEqual(result, target) + + result = Core._config_to_coverage('last') + target = ['tracklist', 'mode', 'play-last', 'volume', 'history'] + self.assertEqual(result, target) + + result = Core._config_to_coverage('play') + target = ['tracklist', 'mode', 'play-always', 'volume', 'history'] + self.assertEqual(result, target)