Skip to content

Commit

Permalink
Merge bdbe0b0 into add79d9
Browse files Browse the repository at this point in the history
  • Loading branch information
txomon committed Oct 25, 2013
2 parents add79d9 + bdbe0b0 commit 96e38d9
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 5 deletions.
155 changes: 155 additions & 0 deletions mopidy/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class Backend(object):
#: the backend doesn't provide playlists.
playlists = None

#: The tracklist provider. An instance of
#: :class:`~mopidy.backends.base.BaseTracklistProvider`, or class:`None` if
#: the backend doesn't provide additional tracklist control logic.
tracklist = None

#: List of URI schemes this backend can handle.
uri_schemes = []

Expand All @@ -41,6 +46,9 @@ def has_playback(self):
def has_playlists(self):
return self.playlists is not None

def has_tracklist(self):
return self.tracklist is not None


class BaseLibraryProvider(object):
"""
Expand Down Expand Up @@ -279,3 +287,150 @@ def save(self, playlist):
*MUST be implemented by subclass.*
"""
raise NotImplementedError


class BaseTracklistProvider(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 next_track(self, tracklist, tl_track):
"""
Get the next track to be played if the user used next button. The
Provider should be careful with all the tracklist states. See
:meth:`mopidy.core.TracklistController.next_track` code to know which
parameters to take care of.
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param tl_track: The track to have the next song's of
:type tl_track: :class:`mopidy.models.TlTrack`
:rtype: It should be a :class:`mopidy.models.TlTrack`, None if the
intention is to tell there is no way to go onwards. For example under
a continuous non-seekable stream. Or finally, any other datatype than
:class:`mopidy.models.TlTrack` or None, which will denote that normal
actions should be following.
"""
return str()

def previous_track(self, tracklist, tl_track):
"""
Get the track to be played if the user used previous button. The
Provider should be careful with all the tracklist states. See
:meth:`mopidy.core.TracklistController.previous_track` code to know
which parameters to take care of.
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param tl_track: The track to have the previous song's of
:type tl_track: :class:`mopidy.models.TlTrack`
:rtype: It should be a :class:`mopidy.models.TlTrack`, None if the
intention is to tell there is no way to go backwards. For example under
a continuous non-seekable stream. Or finally, any other datatype than
:class:`mopidy.models.TlTrack` or None, which will denote that normal
actions should be following.
"""
return str()

def eot_track(self, tracklist, tl_track):
"""
Get the track to be played if the previous track ended naturally. The
Provider should be careful with all the tracklist states. See
:meth:`mopidy.core.TracklistController.eot_track` code to know
which parameters to take care of.
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param tl_track: The track to have the next song's of
:type tl_track: :class:`mopidy.models.TlTrack`
:rtype: It should be a :class:`mopidy.models.TlTrack`, None if the
intention is to tell there is no way to go onwards for example when the
tracklist is finished. Or finally, any other datatype than
:class:`mopidy.models.TlTrack` or None, which will denote that normal
actions should be following.
"""
return str()

def add(self, tracklist, tracks=None, at_position=None, uri=None):
"""
When adding a new song, the Provider may decide to add or replace
:meth:`mopidy.core.TracklistController.add`.
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param tracks: tracks to add
:type tracks: list of :class:`mopidy.models.Track`
:param at_position: position in tracklist to add track
:type at_position: int or :class:`None`
:param uri: URI for tracks to add
:type uri: string
:rtype: It should be a list of :class:`mopidy.models.TlTrack`, pointing
out which where actually the added songs. Anything else will be
considered as that the Controller should be running standard behaviour
"""
return None

def move(self, tracklist, start, end, to_position):
"""
When moving songs from one position to another, this method can be
used to add or replace the logic into
:meth:`mopidy.core.TracklistController.move`.
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param start: Where to move tracks from tracklist position start
:type start: int
:param end: Where to move tracks from tracklist position end
:type end: int
:rtype: In order to add some login before, the Provider must return
False, to replace the logic, the Provider must return True.
"""
return False

def remove(self, tracklist, tl_tracks):
"""
When revmoving a song list, more logic can be added before or replacing
completelly the standard one in
:meth:`mopidy.core.TracklistController.remove`
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param tl_tracks: The tracks we are trying to remove from the tracklist
:type tl_tracks: list of :class:`mopidy.models.TlTrack`
:rtype: It should be a list of :class:`mopidy.models.TlTrack`, pointing
out which where actually the removed songs. Anything else will be
considered as that the Controller should be running standard behaviour
"""
return None

def shuffle(self, tracklist, start, end):
"""
When suffling a slice of the tracklist, more logic can be added before
or replacing completelly the standard one in
:meth:`mopidy.core.TracklistController.shuffle`
:param tracklist: The instance of core's TracklistController
:type tracklist: :class:`mopidy.core.TracklistController`
:param start: Where to shuffle tracklist from
:type start: int
:param end: Where to shuffle tracklist to
:type end: int
:rtype: In order to add some login before, the Provider must return
False, to replace the logic, the Provider must return True.
"""
return False

def mark_played(self, tracklist, tl_track):
return None

def mark_playing(self, tracklist, tl_track):
return None

def mark_unplayable(self, tracklist, tl_track):
return None
33 changes: 33 additions & 0 deletions mopidy/backends/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self, config, audio):
self.library = DummyLibraryProvider(backend=self)
self.playback = DummyPlaybackProvider(audio=audio, backend=self)
self.playlists = DummyPlaylistsProvider(backend=self)
self.tracklist = DummyTracklistProvider(backend=self)

self.uri_schemes = ['dummy']

Expand Down Expand Up @@ -113,3 +114,35 @@ def save(self, playlist):
self._playlists.append(playlist)

return playlist


class DummyTracklistProvider(base.BaseTracklistProvider):
def next_track(self, tracklist, tl_track):
return str()

def previous_track(self, tracklist, tl_track):
return str()

def eot_track(self, tracklist, tl_track):
return str()

def add(self, tracklist, tracks=None, at_position=None, uri=None):
return False

def move(self, tracklist, start, end, to_position):
return False

def remove(self, tracklist, criteria=None, **kwargs):
return False

def shuffle(self, tracklist, start, end):
return False

def mark_played(self, tracklist, tl_track):
return None

def mark_playing(self, tracklist, tl_track):
return None

def mark_unplayable(self, tracklist, tl_track):
return None
9 changes: 6 additions & 3 deletions mopidy/core/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, audio=None, backends=None):
self.playlists = PlaylistsController(
backends=self.backends, core=self)

self.tracklist = TracklistController(core=self)
self.tracklist = TracklistController(backends=self.backends, core=self)

def get_uri_schemes(self):
futures = [b.uri_schemes for b in self.backends]
Expand Down Expand Up @@ -85,8 +85,8 @@ def __init__(self, backends):
# 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_playlists = [
b for b in backends if b.has_playlists().get()]
self.with_playlists = [b for b in backends if b.has_playlists().get()]
self.with_tracklist = [b for b in backends if b.has_tracklist().get()]

self.by_uri_scheme = {}
for backend in backends:
Expand All @@ -102,6 +102,7 @@ def __init__(self, backends):
self.with_library_by_uri_scheme = {}
self.with_playback_by_uri_scheme = {}
self.with_playlists_by_uri_scheme = {}
self.with_tracklist_by_uri_scheme = {}

for uri_scheme, backend in self.by_uri_scheme.items():
if backend.has_library().get():
Expand All @@ -110,3 +111,5 @@ def __init__(self, backends):
self.with_playback_by_uri_scheme[uri_scheme] = backend
if backend.has_playlists().get():
self.with_playlists_by_uri_scheme[uri_scheme] = backend
if backend.has_tracklist().get():
self.with_tracklist_by_uri_scheme[uri_scheme] = backend

0 comments on commit 96e38d9

Please sign in to comment.