Rename 'stored playlists' to 'playlists'

This commit is contained in:
Stein Magnus Jodal 2012-11-14 09:23:19 +01:00
parent 1eef3f6c0e
commit 3a24deaec3
22 changed files with 172 additions and 174 deletions

View File

@ -19,10 +19,10 @@ Playback provider
:members:
Stored playlists provider
=========================
Playlists provider
==================
.. autoclass:: mopidy.backends.base.BaseStoredPlaylistsProvider
.. autoclass:: mopidy.backends.base.BasePlaylistsProvider
:members:

View File

@ -53,7 +53,7 @@ See :ref:`core-api` for more details.
Core -> "Tracklist\ncontroller"
Core -> "Library\ncontroller"
Core -> "Playback\ncontroller"
Core -> "Stored\nplaylists\ncontroller"
Core -> "Playlists\ncontroller"
"Library\ncontroller" -> "Local backend"
"Library\ncontroller" -> "Spotify backend"
@ -62,8 +62,8 @@ See :ref:`core-api` for more details.
"Playback\ncontroller" -> "Spotify backend"
"Playback\ncontroller" -> Audio
"Stored\nplaylists\ncontroller" -> "Local backend"
"Stored\nplaylists\ncontroller" -> "Spotify backend"
"Playlists\ncontroller" -> "Local backend"
"Playlists\ncontroller" -> "Spotify backend"
Backends
@ -80,12 +80,12 @@ See :ref:`backend-api` for more details.
"Local backend" -> "Local\nlibrary\nprovider" -> "Local disk"
"Local backend" -> "Local\nplayback\nprovider" -> "Local disk"
"Local backend" -> "Local\nstored\nplaylists\nprovider" -> "Local disk"
"Local backend" -> "Local\nplaylists\nprovider" -> "Local disk"
"Local\nplayback\nprovider" -> Audio
"Spotify backend" -> "Spotify\nlibrary\nprovider" -> "Spotify service"
"Spotify backend" -> "Spotify\nplayback\nprovider" -> "Spotify service"
"Spotify backend" -> "Spotify\nstored\nplaylists\nprovider" -> "Spotify service"
"Spotify backend" -> "Spotify\nplaylists\nprovider" -> "Spotify service"
"Spotify\nplayback\nprovider" -> Audio

View File

@ -35,12 +35,12 @@ Manages everything related to the tracks we are currently playing.
:members:
Stored playlists controller
===========================
Playlists controller
====================
Manages stored playlist.
Manages persistence of playlists.
.. autoclass:: mopidy.core.StoredPlaylistsController
.. autoclass:: mopidy.core.PlaylistsController
:members:

View File

@ -20,10 +20,10 @@ class Backend(object):
#: the backend doesn't provide playback.
playback = None
#: The stored playlists provider. An instance of
#: :class:`mopidy.backends.base.BaseStoredPlaylistsProvider`, or
#: class:`None` if the backend doesn't provide stored playlists.
stored_playlists = None
#: The playlists provider. An instance of
#: :class:`mopidy.backends.base.BasePlaylistsProvider`, or class:`None` if
#: the backend doesn't provide playlists.
playlists = None
#: List of URI schemes this backend can handle.
uri_schemes = []
@ -38,8 +38,8 @@ class Backend(object):
def has_playback(self):
return self.playback is not None
def has_stored_playlists(self):
return self.stored_playlists is not None
def has_playlists(self):
return self.playlists is not None
class BaseLibraryProvider(object):
@ -167,7 +167,7 @@ class BasePlaybackProvider(object):
return self.audio.get_position().get()
class BaseStoredPlaylistsProvider(object):
class BasePlaylistsProvider(object):
"""
:param backend: backend the controller is a part of
:type backend: :class:`mopidy.backends.base.Backend`
@ -182,7 +182,7 @@ class BaseStoredPlaylistsProvider(object):
@property
def playlists(self):
"""
Currently stored playlists.
Currently available playlists.
Read/write. List of :class:`mopidy.models.Playlist`.
"""
@ -194,7 +194,7 @@ class BaseStoredPlaylistsProvider(object):
def create(self, name):
"""
See :meth:`mopidy.core.StoredPlaylistsController.create`.
See :meth:`mopidy.core.PlaylistsController.create`.
*MUST be implemented by subclass.*
"""
@ -202,7 +202,7 @@ class BaseStoredPlaylistsProvider(object):
def delete(self, uri):
"""
See :meth:`mopidy.core.StoredPlaylistsController.delete`.
See :meth:`mopidy.core.PlaylistsController.delete`.
*MUST be implemented by subclass.*
"""
@ -210,7 +210,7 @@ class BaseStoredPlaylistsProvider(object):
def lookup(self, uri):
"""
See :meth:`mopidy.core.StoredPlaylistsController.lookup`.
See :meth:`mopidy.core.PlaylistsController.lookup`.
*MUST be implemented by subclass.*
"""
@ -218,7 +218,7 @@ class BaseStoredPlaylistsProvider(object):
def refresh(self):
"""
See :meth:`mopidy.core.StoredPlaylistsController.refresh`.
See :meth:`mopidy.core.PlaylistsController.refresh`.
*MUST be implemented by subclass.*
"""
@ -226,7 +226,7 @@ class BaseStoredPlaylistsProvider(object):
def save(self, playlist):
"""
See :meth:`mopidy.core.StoredPlaylistsController.save`.
See :meth:`mopidy.core.PlaylistsController.save`.
*MUST be implemented by subclass.*
"""

View File

@ -28,7 +28,7 @@ class DummyBackend(pykka.ThreadingActor, base.Backend):
self.library = DummyLibraryProvider(backend=self)
self.playback = DummyPlaybackProvider(audio=audio, backend=self)
self.stored_playlists = DummyStoredPlaylistsProvider(backend=self)
self.playlists = DummyPlaylistsProvider(backend=self)
self.uri_schemes = ['dummy']
@ -80,7 +80,7 @@ class DummyPlaybackProvider(base.BasePlaybackProvider):
return self._time_position
class DummyStoredPlaylistsProvider(base.BaseStoredPlaylistsProvider):
class DummyPlaylistsProvider(base.BasePlaylistsProvider):
def create(self, name):
playlist = Playlist(name=name)
self._playlists.append(playlist)

View File

@ -7,7 +7,7 @@ import pykka
from mopidy.backends import base
from .library import LocalLibraryProvider
from .stored_playlists import LocalStoredPlaylistsProvider
from .playlists import LocalPlaylistsProvider
logger = logging.getLogger('mopidy.backends.local')
@ -18,6 +18,6 @@ class LocalBackend(pykka.ThreadingActor, base.Backend):
self.library = LocalLibraryProvider(backend=self)
self.playback = base.BasePlaybackProvider(audio=audio, backend=self)
self.stored_playlists = LocalStoredPlaylistsProvider(backend=self)
self.playlists = LocalPlaylistsProvider(backend=self)
self.uri_schemes = ['file']

View File

@ -16,9 +16,9 @@ from .translator import parse_m3u
logger = logging.getLogger('mopidy.backends.local')
class LocalStoredPlaylistsProvider(base.BaseStoredPlaylistsProvider):
class LocalPlaylistsProvider(base.BasePlaylistsProvider):
def __init__(self, *args, **kwargs):
super(LocalStoredPlaylistsProvider, self).__init__(*args, **kwargs)
super(LocalPlaylistsProvider, self).__init__(*args, **kwargs)
self._path = settings.LOCAL_PLAYLIST_PATH
self.refresh()

View File

@ -20,11 +20,11 @@ class SpotifyBackend(pykka.ThreadingActor, base.Backend):
from .library import SpotifyLibraryProvider
from .playback import SpotifyPlaybackProvider
from .session_manager import SpotifySessionManager
from .stored_playlists import SpotifyStoredPlaylistsProvider
from .playlists import SpotifyPlaylistsProvider
self.library = SpotifyLibraryProvider(backend=self)
self.playback = SpotifyPlaybackProvider(audio=audio, backend=self)
self.stored_playlists = SpotifyStoredPlaylistsProvider(backend=self)
self.playlists = SpotifyPlaylistsProvider(backend=self)
self.uri_schemes = ['spotify']

View File

@ -17,7 +17,7 @@ class SpotifyContainerManager(PyspotifyContainerManager):
"""Callback used by pyspotify"""
logger.debug('Callback called: playlist container loaded')
self.session_manager.refresh_stored_playlists()
self.session_manager.refresh_playlists()
count = 0
for playlist in self.session_manager.session.playlist_container():

View File

@ -68,9 +68,9 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider):
def search(self, **query):
if not query:
# Since we can't search for the entire Spotify library, we return
# all tracks in the stored playlists when the query is empty.
# all tracks in the playlists when the query is empty.
tracks = []
for playlist in self.backend.stored_playlists.playlists:
for playlist in self.backend.playlists.playlists:
tracks += playlist.tracks
return Playlist(tracks=tracks)
spotify_query = []

View File

@ -19,7 +19,7 @@ class SpotifyPlaylistManager(PyspotifyPlaylistManager):
'Callback called: '
'%d track(s) added to position %d in playlist "%s"',
len(tracks), position, playlist.name())
self.session_manager.refresh_stored_playlists()
self.session_manager.refresh_playlists()
def tracks_moved(self, playlist, tracks, new_position, userdata):
"""Callback used by pyspotify"""
@ -27,7 +27,7 @@ class SpotifyPlaylistManager(PyspotifyPlaylistManager):
'Callback called: '
'%d track(s) moved to position %d in playlist "%s"',
len(tracks), new_position, playlist.name())
self.session_manager.refresh_stored_playlists()
self.session_manager.refresh_playlists()
def tracks_removed(self, playlist, tracks, userdata):
"""Callback used by pyspotify"""
@ -35,13 +35,13 @@ class SpotifyPlaylistManager(PyspotifyPlaylistManager):
'Callback called: '
'%d track(s) removed from playlist "%s"',
len(tracks), playlist.name())
self.session_manager.refresh_stored_playlists()
self.session_manager.refresh_playlists()
def playlist_renamed(self, playlist, userdata):
"""Callback used by pyspotify"""
logger.debug(
'Callback called: Playlist renamed to "%s"', playlist.name())
self.session_manager.refresh_stored_playlists()
self.session_manager.refresh_playlists()
def playlist_state_changed(self, playlist, userdata):
"""Callback used by pyspotify"""

View File

@ -3,7 +3,7 @@ from __future__ import unicode_literals
from mopidy.backends import base
class SpotifyStoredPlaylistsProvider(base.BaseStoredPlaylistsProvider):
class SpotifyPlaylistsProvider(base.BasePlaylistsProvider):
def create(self, name):
pass # TODO

View File

@ -122,30 +122,29 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager):
if 'offline-mgr' in data and 'files unlocked' in data:
# XXX This is a very very fragile and ugly hack, but we get no
# proper event when libspotify is done with initial data loading.
# We delay the expensive refresh of Mopidy's stored playlists until
# this message arrives. This way, we avoid doing the refresh once
# for every playlist or other change. This reduces the time from
# We delay the expensive refresh of Mopidy's playlists until this
# message arrives. This way, we avoid doing the refresh once for
# every playlist or other change. This reduces the time from
# startup until the Spotify backend is ready from 35s to 12s in one
# test with clean Spotify cache. In cases with an outdated cache
# the time improvements should be a lot better.
# the time improvements should be a lot greater.
self._initial_data_receive_completed = True
self.refresh_stored_playlists()
self.refresh_playlists()
def end_of_track(self, session):
"""Callback used by pyspotify"""
logger.debug('End of data stream reached')
self.audio.emit_end_of_stream()
def refresh_stored_playlists(self):
"""Refresh the stored playlists in the backend with fresh meta data
from Spotify"""
def refresh_playlists(self):
"""Refresh the playlists in the backend with data from Spotify"""
if not self._initial_data_receive_completed:
logger.debug('Still getting data; skipped refresh of playlists')
return
playlists = map(
translator.to_mopidy_playlist, self.session.playlist_container())
playlists = filter(None, playlists)
self.backend.stored_playlists.playlists = playlists
self.backend.playlists.playlists = playlists
logger.info('Loaded %d Spotify playlist(s)', len(playlists))
def search(self, query, queue):

View File

@ -5,5 +5,5 @@ from .actor import Core
from .library import LibraryController
from .listener import CoreListener
from .playback import PlaybackController, PlaybackState
from .stored_playlists import StoredPlaylistsController
from .playlists import PlaylistsController
from .tracklist import TracklistController

View File

@ -8,7 +8,7 @@ from mopidy.audio import AudioListener
from .library import LibraryController
from .playback import PlaybackController
from .stored_playlists import StoredPlaylistsController
from .playlists import PlaylistsController
from .tracklist import TracklistController
@ -21,9 +21,9 @@ class Core(pykka.ThreadingActor, AudioListener):
#: :class:`mopidy.core.PlaybackController`.
playback = None
#: The stored playlists controller. An instance of
#: :class:`mopidy.core.StoredPlaylistsController`.
stored_playlists = None
#: The playlists controller. An instance of
#: :class:`mopidy.core.PlaylistsController`.
playlists = None
#: The tracklist controller. An instance of
#: :class:`mopidy.core.TracklistController`.
@ -39,7 +39,7 @@ class Core(pykka.ThreadingActor, AudioListener):
self.playback = PlaybackController(
audio=audio, backends=self.backends, core=self)
self.stored_playlists = StoredPlaylistsController(
self.playlists = PlaylistsController(
backends=self.backends, core=self)
self.tracklist = TracklistController(core=self)
@ -66,8 +66,8 @@ class Backends(list):
# the X_by_uri_scheme dicts below.
self.with_library = [b for b in backends if b.has_library().get()]
self.with_playback = [b for b in backends if b.has_playback().get()]
self.with_stored_playlists = [b for b in backends
if b.has_stored_playlists().get()]
self.with_playlists = [b for b in backends
if b.has_playlists().get()]
self.by_uri_scheme = {}
for backend in backends:
@ -82,12 +82,12 @@ class Backends(list):
self.with_library_by_uri_scheme = {}
self.with_playback_by_uri_scheme = {}
self.with_stored_playlists_by_uri_scheme = {}
self.with_playlists_by_uri_scheme = {}
for uri_scheme, backend in self.by_uri_scheme.items():
if backend.has_library().get():
self.with_library_by_uri_scheme[uri_scheme] = backend
if backend.has_playback().get():
self.with_playback_by_uri_scheme[uri_scheme] = backend
if backend.has_stored_playlists().get():
self.with_stored_playlists_by_uri_scheme[uri_scheme] = backend
if backend.has_playlists().get():
self.with_playlists_by_uri_scheme[uri_scheme] = backend

View File

@ -6,7 +6,7 @@ import urlparse
import pykka
class StoredPlaylistsController(object):
class PlaylistsController(object):
pykka_traversable = True
def __init__(self, backends, core):
@ -16,12 +16,12 @@ class StoredPlaylistsController(object):
@property
def playlists(self):
"""
Currently stored playlists.
The available playlists.
Read-only. List of :class:`mopidy.models.Playlist`.
"""
futures = [b.stored_playlists.playlists
for b in self.backends.with_stored_playlists]
futures = [b.playlists.playlists
for b in self.backends.with_playlists]
results = pykka.get_all(futures)
return list(itertools.chain(*results))
@ -43,11 +43,11 @@ class StoredPlaylistsController(object):
:type uri_scheme: string
:rtype: :class:`mopidy.models.Playlist`
"""
if uri_scheme in self.backends.with_stored_playlists_by_uri_scheme:
if uri_scheme in self.backends.with_playlists_by_uri_scheme:
backend = self.backends.by_uri_scheme[uri_scheme]
else:
backend = self.backends.with_stored_playlists[0]
return backend.stored_playlists.create(name).get()
backend = self.backends.with_playlists[0]
return backend.playlists.create(name).get()
def delete(self, uri):
"""
@ -60,14 +60,14 @@ class StoredPlaylistsController(object):
:type uri: string
"""
uri_scheme = urlparse.urlparse(uri).scheme
backend = self.backends.with_stored_playlists_by_uri_scheme.get(
backend = self.backends.with_playlists_by_uri_scheme.get(
uri_scheme, None)
if backend:
backend.stored_playlists.delete(uri).get()
backend.playlists.delete(uri).get()
def get(self, **criteria):
"""
Get playlist by given criterias from the set of stored playlists.
Get playlist by given criterias from the set of playlists.
Raises :exc:`LookupError` if a unique match is not found.
@ -97,24 +97,24 @@ class StoredPlaylistsController(object):
def lookup(self, uri):
"""
Lookup playlist with given URI in both the set of stored playlists and
in any other playlist sources. Returns :class:`None` if not found.
Lookup playlist with given URI in both the set of playlists and in any
other playlist sources. Returns :class:`None` if not found.
:param uri: playlist URI
:type uri: string
:rtype: :class:`mopidy.models.Playlist` or :class:`None`
"""
uri_scheme = urlparse.urlparse(uri).scheme
backend = self.backends.with_stored_playlists_by_uri_scheme.get(
backend = self.backends.with_playlists_by_uri_scheme.get(
uri_scheme, None)
if backend:
return backend.stored_playlists.lookup(uri).get()
return backend.playlists.lookup(uri).get()
else:
return None
def refresh(self, uri_scheme=None):
"""
Refresh the stored playlists in :attr:`playlists`.
Refresh the playlists in :attr:`playlists`.
If ``uri_scheme`` is :class:`None`, all backends are asked to refresh.
If ``uri_scheme`` is an URI scheme handled by a backend, only that
@ -125,18 +125,18 @@ class StoredPlaylistsController(object):
:type uri_scheme: string
"""
if uri_scheme is None:
futures = [b.stored_playlists.refresh()
for b in self.backends.with_stored_playlists]
futures = [b.playlists.refresh()
for b in self.backends.with_playlists]
pykka.get_all(futures)
else:
backend = self.backends.with_stored_playlists_by_uri_scheme.get(
backend = self.backends.with_playlists_by_uri_scheme.get(
uri_scheme, None)
if backend:
backend.stored_playlists.refresh().get()
backend.playlists.refresh().get()
def save(self, playlist):
"""
Save the playlist to the set of stored playlists.
Save the playlist.
For a playlist to be saveable, it must have the ``uri`` attribute set.
You should not set the ``uri`` atribute yourself, but use playlist
@ -159,7 +159,7 @@ class StoredPlaylistsController(object):
if playlist.uri is None:
return
uri_scheme = urlparse.urlparse(playlist.uri).scheme
backend = self.backends.with_stored_playlists_by_uri_scheme.get(
backend = self.backends.with_playlists_by_uri_scheme.get(
uri_scheme, None)
if backend:
return backend.stored_playlists.save(playlist).get()
return backend.playlists.save(playlist).get()

View File

@ -24,7 +24,7 @@ def listplaylist(context, name):
file: relative/path/to/file3.mp3
"""
try:
playlist = context.core.stored_playlists.get(name=name).get()
playlist = context.core.playlists.get(name=name).get()
return ['file: %s' % t.uri for t in playlist.tracks]
except LookupError:
raise MpdNoExistError('No such playlist', command='listplaylist')
@ -46,7 +46,7 @@ def listplaylistinfo(context, name):
Album, Artist, Track
"""
try:
playlist = context.core.stored_playlists.get(name=name).get()
playlist = context.core.playlists.get(name=name).get()
return playlist_to_mpd_format(playlist)
except LookupError:
raise MpdNoExistError('No such playlist', command='listplaylistinfo')
@ -74,7 +74,7 @@ def listplaylists(context):
Last-Modified: 2010-02-06T02:11:08Z
"""
result = []
for playlist in context.core.stored_playlists.playlists.get():
for playlist in context.core.playlists.playlists.get():
result.append(('playlist', playlist.name))
last_modified = (
playlist.last_modified or dt.datetime.now()).isoformat()
@ -101,7 +101,7 @@ def load(context, name):
- ``load`` appends the given playlist to the current playlist.
"""
try:
playlist = context.core.stored_playlists.get(name=name).get()
playlist = context.core.playlists.get(name=name).get()
context.core.tracklist.append(playlist.tracks)
except LookupError:
raise MpdNoExistError('No such playlist', command='load')

View File

@ -13,7 +13,7 @@ from mopidy.models import Playlist
from tests import unittest, path_to_data_dir
class StoredPlaylistsControllerTest(object):
class PlaylistsControllerTest(object):
def setUp(self):
settings.LOCAL_PLAYLIST_PATH = tempfile.mkdtemp()
settings.LOCAL_TAG_CACHE_FILE = path_to_data_dir('library_tag_cache')
@ -22,7 +22,6 @@ class StoredPlaylistsControllerTest(object):
self.audio = mock.Mock(spec=audio.Audio)
self.backend = self.backend_class.start(audio=self.audio).proxy()
self.core = core.Core(backends=[self.backend])
self.stored = self.core.stored_playlists
def tearDown(self):
pykka.ActorRegistry.stop_all()
@ -33,74 +32,74 @@ class StoredPlaylistsControllerTest(object):
settings.runtime.clear()
def test_create_returns_playlist_with_name_set(self):
playlist = self.stored.create('test')
playlist = self.core.playlists.create('test')
self.assertEqual(playlist.name, 'test')
def test_create_returns_playlist_with_uri_set(self):
playlist = self.stored.create('test')
playlist = self.core.playlists.create('test')
self.assert_(playlist.uri)
def test_create_adds_playlist_to_playlists_collection(self):
playlist = self.stored.create('test')
self.assert_(self.stored.playlists)
self.assertIn(playlist, self.stored.playlists)
playlist = self.core.playlists.create('test')
self.assert_(self.core.playlists.playlists)
self.assertIn(playlist, self.core.playlists.playlists)
def test_playlists_empty_to_start_with(self):
self.assert_(not self.stored.playlists)
self.assert_(not self.core.playlists.playlists)
def test_delete_non_existant_playlist(self):
self.stored.delete('file:///unknown/playlist')
self.core.playlists.delete('file:///unknown/playlist')
def test_delete_playlist_removes_it_from_the_collection(self):
playlist = self.stored.create('test')
self.assertIn(playlist, self.stored.playlists)
playlist = self.core.playlists.create('test')
self.assertIn(playlist, self.core.playlists.playlists)
self.stored.delete(playlist.uri)
self.core.playlists.delete(playlist.uri)
self.assertNotIn(playlist, self.stored.playlists)
self.assertNotIn(playlist, self.core.playlists.playlists)
def test_get_without_criteria(self):
test = self.stored.get
test = self.core.playlists.get
self.assertRaises(LookupError, test)
def test_get_with_wrong_cirteria(self):
test = lambda: self.stored.get(name='foo')
test = lambda: self.core.playlists.get(name='foo')
self.assertRaises(LookupError, test)
def test_get_with_right_criteria(self):
playlist1 = self.stored.create('test')
playlist2 = self.stored.get(name='test')
playlist1 = self.core.playlists.create('test')
playlist2 = self.core.playlists.get(name='test')
self.assertEqual(playlist1, playlist2)
def test_get_by_name_returns_unique_match(self):
playlist = Playlist(name='b')
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='a'), playlist]
self.assertEqual(playlist, self.stored.get(name='b'))
self.assertEqual(playlist, self.core.playlists.get(name='b'))
def test_get_by_name_returns_first_of_multiple_matches(self):
playlist = Playlist(name='b')
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
playlist, Playlist(name='a'), Playlist(name='b')]
try:
self.stored.get(name='b')
self.core.playlists.get(name='b')
self.fail('Should raise LookupError if multiple matches')
except LookupError as e:
self.assertEqual('"name=b" match multiple playlists', e[0])
def test_get_by_name_raises_keyerror_if_no_match(self):
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='a'), Playlist(name='b')]
try:
self.stored.get(name='c')
self.core.playlists.get(name='c')
self.fail('Should raise LookupError if no match')
except LookupError as e:
self.assertEqual('"name=c" match no playlists', e[0])
def test_lookup_finds_playlist_by_uri(self):
original_playlist = self.stored.create('test')
original_playlist = self.core.playlists.create('test')
looked_up_playlist = self.stored.lookup(original_playlist.uri)
looked_up_playlist = self.core.playlists.lookup(original_playlist.uri)
self.assertEqual(original_playlist, looked_up_playlist)
@ -108,14 +107,14 @@ class StoredPlaylistsControllerTest(object):
def test_refresh(self):
pass
def test_save_replaces_stored_playlist_with_updated_playlist(self):
playlist1 = self.stored.create('test1')
self.assertIn(playlist1, self.stored.playlists)
def test_save_replaces_existing_playlist_with_updated_playlist(self):
playlist1 = self.core.playlists.create('test1')
self.assertIn(playlist1, self.core.playlists.playlists)
playlist2 = playlist1.copy(name='test2')
playlist2 = self.stored.save(playlist2)
self.assertNotIn(playlist1, self.stored.playlists)
self.assertIn(playlist2, self.stored.playlists)
playlist2 = self.core.playlists.save(playlist2)
self.assertNotIn(playlist1, self.core.playlists.playlists)
self.assertIn(playlist2, self.core.playlists.playlists)
@unittest.SkipTest
def test_playlist_with_unknown_track(self):

View File

@ -8,13 +8,13 @@ from mopidy.models import Track
from mopidy.utils.path import path_to_uri
from tests import unittest, path_to_data_dir
from tests.backends.base.stored_playlists import (
StoredPlaylistsControllerTest)
from tests.backends.base.playlists import (
PlaylistsControllerTest)
from tests.backends.local import generate_song
class LocalStoredPlaylistsControllerTest(
StoredPlaylistsControllerTest, unittest.TestCase):
class LocalPlaylistsControllerTest(
PlaylistsControllerTest, unittest.TestCase):
backend_class = LocalBackend
@ -22,14 +22,14 @@ class LocalStoredPlaylistsControllerTest(
path = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test.m3u')
self.assertFalse(os.path.exists(path))
self.stored.create('test')
self.core.playlists.create('test')
self.assertTrue(os.path.exists(path))
def test_create_slugifies_playlist_name(self):
path = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test-foo-bar.m3u')
self.assertFalse(os.path.exists(path))
playlist = self.stored.create('test FOO baR')
playlist = self.core.playlists.create('test FOO baR')
self.assertEqual('test-foo-bar', playlist.name)
self.assertTrue(os.path.exists(path))
@ -37,7 +37,7 @@ class LocalStoredPlaylistsControllerTest(
path = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test-foo-bar.m3u')
self.assertFalse(os.path.exists(path))
playlist = self.stored.create('../../test FOO baR')
playlist = self.core.playlists.create('../../test FOO baR')
self.assertEqual('test-foo-bar', playlist.name)
self.assertTrue(os.path.exists(path))
@ -45,13 +45,13 @@ class LocalStoredPlaylistsControllerTest(
path1 = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test1.m3u')
path2 = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test2-foo-bar.m3u')
playlist = self.stored.create('test1')
playlist = self.core.playlists.create('test1')
self.assertTrue(os.path.exists(path1))
self.assertFalse(os.path.exists(path2))
playlist = playlist.copy(name='test2 FOO baR')
playlist = self.stored.save(playlist)
playlist = self.core.playlists.save(playlist)
self.assertEqual('test2-foo-bar', playlist.name)
self.assertFalse(os.path.exists(path1))
@ -61,19 +61,19 @@ class LocalStoredPlaylistsControllerTest(
path = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test.m3u')
self.assertFalse(os.path.exists(path))
playlist = self.stored.create('test')
playlist = self.core.playlists.create('test')
self.assertTrue(os.path.exists(path))
self.stored.delete(playlist.uri)
self.core.playlists.delete(playlist.uri)
self.assertFalse(os.path.exists(path))
def test_playlist_contents_is_written_to_disk(self):
track = Track(uri=generate_song(1))
track_path = track.uri[len('file://'):]
playlist = self.stored.create('test')
playlist = self.core.playlists.create('test')
playlist_path = playlist.uri[len('file://'):]
playlist = playlist.copy(tracks=[track])
playlist = self.stored.save(playlist)
playlist = self.core.playlists.save(playlist)
with open(playlist_path) as playlist_file:
contents = playlist_file.read()
@ -84,20 +84,20 @@ class LocalStoredPlaylistsControllerTest(
playlist_path = os.path.join(settings.LOCAL_PLAYLIST_PATH, 'test.m3u')
track = Track(uri=path_to_uri(path_to_data_dir('uri2')))
playlist = self.stored.create('test')
playlist = self.core.playlists.create('test')
playlist = playlist.copy(tracks=[track])
playlist = self.stored.save(playlist)
playlist = self.core.playlists.save(playlist)
backend = self.backend_class(audio=self.audio)
self.assert_(backend.stored_playlists.playlists)
self.assert_(backend.playlists.playlists)
self.assertEqual(
path_to_uri(playlist_path),
backend.stored_playlists.playlists[0].uri)
backend.playlists.playlists[0].uri)
self.assertEqual(
playlist.name, backend.stored_playlists.playlists[0].name)
playlist.name, backend.playlists.playlists[0].name)
self.assertEqual(
track.uri, backend.stored_playlists.playlists[0].tracks[0].uri)
track.uri, backend.playlists.playlists[0].tracks[0].uri)
@unittest.SkipTest
def test_santitising_of_playlist_filenames(self):

View File

@ -9,23 +9,23 @@ from mopidy.models import Playlist, Track
from tests import unittest
class StoredPlaylistsTest(unittest.TestCase):
class PlaylistsTest(unittest.TestCase):
def setUp(self):
self.backend1 = mock.Mock()
self.backend1.uri_schemes.get.return_value = ['dummy1']
self.sp1 = mock.Mock(spec=base.BaseStoredPlaylistsProvider)
self.backend1.stored_playlists = self.sp1
self.sp1 = mock.Mock(spec=base.BasePlaylistsProvider)
self.backend1.playlists = self.sp1
self.backend2 = mock.Mock()
self.backend2.uri_schemes.get.return_value = ['dummy2']
self.sp2 = mock.Mock(spec=base.BaseStoredPlaylistsProvider)
self.backend2.stored_playlists = self.sp2
self.sp2 = mock.Mock(spec=base.BasePlaylistsProvider)
self.backend2.playlists = self.sp2
# A backend without the optional stored playlists provider
# A backend without the optional playlists provider
self.backend3 = mock.Mock()
self.backend3.uri_schemes.get.return_value = ['dummy3']
self.backend3.has_stored_playlists().get.return_value = False
self.backend3.stored_playlists = None
self.backend3.has_playlists().get.return_value = False
self.backend3.playlists = None
self.pl1a = Playlist(tracks=[Track(uri='dummy1:a')])
self.pl1b = Playlist(tracks=[Track(uri='dummy1:b')])
@ -39,7 +39,7 @@ class StoredPlaylistsTest(unittest.TestCase):
self.backend3, self.backend1, self.backend2])
def test_get_playlists_combines_result_from_backends(self):
result = self.core.stored_playlists.playlists
result = self.core.playlists.playlists
self.assertIn(self.pl1a, result)
self.assertIn(self.pl1b, result)
@ -51,7 +51,7 @@ class StoredPlaylistsTest(unittest.TestCase):
self.sp1.create().get.return_value = playlist
self.sp1.reset_mock()
result = self.core.stored_playlists.create('foo')
result = self.core.playlists.create('foo')
self.assertEqual(playlist, result)
self.sp1.create.assert_called_once_with('foo')
@ -62,7 +62,7 @@ class StoredPlaylistsTest(unittest.TestCase):
self.sp2.create().get.return_value = playlist
self.sp2.reset_mock()
result = self.core.stored_playlists.create('foo', uri_scheme='dummy2')
result = self.core.playlists.create('foo', uri_scheme='dummy2')
self.assertEqual(playlist, result)
self.assertFalse(self.sp1.create.called)
@ -73,75 +73,75 @@ class StoredPlaylistsTest(unittest.TestCase):
self.sp1.create().get.return_value = playlist
self.sp1.reset_mock()
result = self.core.stored_playlists.create('foo', uri_scheme='dummy3')
result = self.core.playlists.create('foo', uri_scheme='dummy3')
self.assertEqual(playlist, result)
self.sp1.create.assert_called_once_with('foo')
self.assertFalse(self.sp2.create.called)
def test_delete_selects_the_dummy1_backend(self):
self.core.stored_playlists.delete('dummy1:a')
self.core.playlists.delete('dummy1:a')
self.sp1.delete.assert_called_once_with('dummy1:a')
self.assertFalse(self.sp2.delete.called)
def test_delete_selects_the_dummy2_backend(self):
self.core.stored_playlists.delete('dummy2:a')
self.core.playlists.delete('dummy2:a')
self.assertFalse(self.sp1.delete.called)
self.sp2.delete.assert_called_once_with('dummy2:a')
def test_delete_with_unknown_uri_scheme_does_nothing(self):
self.core.stored_playlists.delete('unknown:a')
self.core.playlists.delete('unknown:a')
self.assertFalse(self.sp1.delete.called)
self.assertFalse(self.sp2.delete.called)
def test_delete_ignores_backend_without_playlist_support(self):
self.core.stored_playlists.delete('dummy3:a')
self.core.playlists.delete('dummy3:a')
self.assertFalse(self.sp1.delete.called)
self.assertFalse(self.sp2.delete.called)
def test_lookup_selects_the_dummy1_backend(self):
self.core.stored_playlists.lookup('dummy1:a')
self.core.playlists.lookup('dummy1:a')
self.sp1.lookup.assert_called_once_with('dummy1:a')
self.assertFalse(self.sp2.lookup.called)
def test_lookup_selects_the_dummy2_backend(self):
self.core.stored_playlists.lookup('dummy2:a')
self.core.playlists.lookup('dummy2:a')
self.assertFalse(self.sp1.lookup.called)
self.sp2.lookup.assert_called_once_with('dummy2:a')
def test_lookup_track_in_backend_without_playlists_fails(self):
result = self.core.stored_playlists.lookup('dummy3:a')
result = self.core.playlists.lookup('dummy3:a')
self.assertIsNone(result)
self.assertFalse(self.sp1.lookup.called)
self.assertFalse(self.sp2.lookup.called)
def test_refresh_without_uri_scheme_refreshes_all_backends(self):
self.core.stored_playlists.refresh()
self.core.playlists.refresh()
self.sp1.refresh.assert_called_once_with()
self.sp2.refresh.assert_called_once_with()
def test_refresh_with_uri_scheme_refreshes_matching_backend(self):
self.core.stored_playlists.refresh(uri_scheme='dummy2')
self.core.playlists.refresh(uri_scheme='dummy2')
self.assertFalse(self.sp1.refresh.called)
self.sp2.refresh.assert_called_once_with()
def test_refresh_with_unknown_uri_scheme_refreshes_nothing(self):
self.core.stored_playlists.refresh(uri_scheme='foobar')
self.core.playlists.refresh(uri_scheme='foobar')
self.assertFalse(self.sp1.refresh.called)
self.assertFalse(self.sp2.refresh.called)
def test_refresh_ignores_backend_without_playlist_support(self):
self.core.stored_playlists.refresh(uri_scheme='dummy3')
self.core.playlists.refresh(uri_scheme='dummy3')
self.assertFalse(self.sp1.refresh.called)
self.assertFalse(self.sp2.refresh.called)
@ -151,7 +151,7 @@ class StoredPlaylistsTest(unittest.TestCase):
self.sp1.save().get.return_value = playlist
self.sp1.reset_mock()
result = self.core.stored_playlists.save(playlist)
result = self.core.playlists.save(playlist)
self.assertEqual(playlist, result)
self.sp1.save.assert_called_once_with(playlist)
@ -162,28 +162,28 @@ class StoredPlaylistsTest(unittest.TestCase):
self.sp2.save().get.return_value = playlist
self.sp2.reset_mock()
result = self.core.stored_playlists.save(playlist)
result = self.core.playlists.save(playlist)
self.assertEqual(playlist, result)
self.assertFalse(self.sp1.save.called)
self.sp2.save.assert_called_once_with(playlist)
def test_save_does_nothing_if_playlist_uri_is_unset(self):
result = self.core.stored_playlists.save(Playlist())
result = self.core.playlists.save(Playlist())
self.assertIsNone(result)
self.assertFalse(self.sp1.save.called)
self.assertFalse(self.sp2.save.called)
def test_save_does_nothing_if_playlist_uri_has_unknown_scheme(self):
result = self.core.stored_playlists.save(Playlist(uri='foobar:a'))
result = self.core.playlists.save(Playlist(uri='foobar:a'))
self.assertIsNone(result)
self.assertFalse(self.sp1.save.called)
self.assertFalse(self.sp2.save.called)
def test_save_ignores_backend_without_playlist_support(self):
result = self.core.stored_playlists.save(Playlist(uri='dummy3:a'))
result = self.core.playlists.save(Playlist(uri='dummy3:a'))
self.assertIsNone(result)
self.assertFalse(self.sp1.save.called)

View File

@ -123,7 +123,7 @@ class IssueGH69RegressionTest(protocol.BaseTestCase):
"""
def test(self):
self.core.stored_playlists.create('foo')
self.core.playlists.create('foo')
self.core.tracklist.append([
Track(uri='dummy:a'), Track(uri='dummy:b'), Track(uri='dummy:c'),
Track(uri='dummy:d'), Track(uri='dummy:e'), Track(uri='dummy:f')])
@ -148,7 +148,7 @@ class IssueGH113RegressionTest(protocol.BaseTestCase):
"""
def test(self):
self.core.stored_playlists.create(
self.core.playlists.create(
u'all lart spotify:track:\w\{22\} pastes')
self.sendRequest('lsinfo "/"')

View File

@ -7,9 +7,9 @@ from mopidy.models import Track, Playlist
from tests.frontends.mpd import protocol
class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
class PlaylistsHandlerTest(protocol.BaseTestCase):
def test_listplaylist(self):
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
self.sendRequest('listplaylist "name"')
@ -17,7 +17,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
self.assertInResponse('OK')
def test_listplaylist_without_quotes(self):
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
self.sendRequest('listplaylist name')
@ -29,7 +29,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
self.assertEqualResponse('ACK [50@0] {listplaylist} No such playlist')
def test_listplaylistinfo(self):
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
self.sendRequest('listplaylistinfo "name"')
@ -39,7 +39,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
self.assertInResponse('OK')
def test_listplaylistinfo_without_quotes(self):
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='name', tracks=[Track(uri='file:///dev/urandom')])]
self.sendRequest('listplaylistinfo name')
@ -55,7 +55,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
def test_listplaylists(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='a', last_modified=last_modified)]
self.sendRequest('listplaylists')
@ -67,7 +67,7 @@ class StoredPlaylistsHandlerTest(protocol.BaseTestCase):
def test_load_known_playlist_appends_to_tracklist(self):
self.core.tracklist.append([Track(uri='a'), Track(uri='b')])
self.assertEqual(len(self.core.tracklist.tracks.get()), 2)
self.backend.stored_playlists.playlists = [
self.backend.playlists.playlists = [
Playlist(name='A-list', tracks=[
Track(uri='c'), Track(uri='d'), Track(uri='e')])]