core: Expose getters/setters for all properties

This will be useful when exposing the core API over various protocols, e.g.
JSON-RPC.
This commit is contained in:
Stein Magnus Jodal 2012-11-20 09:13:34 +01:00
parent e9658453b0
commit f588787ac3
4 changed files with 145 additions and 139 deletions

View File

@ -46,14 +46,15 @@ class Core(pykka.ThreadingActor, AudioListener, BackendListener):
self.tracklist = TracklistController(core=self)
@property
def uri_schemes(self):
"""List of URI schemes we can handle"""
def get_uri_schemes(self):
futures = [b.uri_schemes for b in self.backends]
results = pykka.get_all(futures)
uri_schemes = itertools.chain(*results)
return sorted(uri_schemes)
uri_schemes = property(get_uri_schemes)
"""List of URI schemes we can handle"""
def reached_end_of_stream(self):
self.playback.on_end_of_track()

View File

@ -79,42 +79,28 @@ class PlaybackController(object):
uri_scheme = urlparse.urlparse(uri).scheme
return self.backends.with_playback_by_uri_scheme.get(uri_scheme, None)
def _get_tlid(self, tl_track):
if tl_track is None:
return None
return tl_track.tlid
def get_current_tlid(self):
return self.current_tl_track and self.current_tl_track.tlid
def _get_track(self, tl_track):
if tl_track is None:
return None
return tl_track.track
current_tlid = property(get_current_tlid)
"""
The TLID (tracklist ID) of the currently playing or selected
track.
@property
def current_tlid(self):
"""
The TLID (tracklist ID) of the currently playing or selected
track.
Read-only. Extracted from :attr:`current_tl_track` for convenience.
"""
Read-only. Extracted from :attr:`current_tl_track` for convenience.
"""
return self._get_tlid(self.current_tl_track)
def get_current_track(self):
return self.current_tl_track and self.current_tl_track.track
@property
def current_track(self):
"""
The currently playing or selected :class:`mopidy.models.Track`.
current_track = property(get_current_track)
"""
The currently playing or selected :class:`mopidy.models.Track`.
Read-only. Extracted from :attr:`current_tl_track` for convenience.
"""
return self._get_track(self.current_tl_track)
Read-only. Extracted from :attr:`current_tl_track` for convenience.
"""
@property
def tracklist_position(self):
"""
The position of the current track in the tracklist.
Read-only.
"""
def get_tracklist_position(self):
if self.current_tl_track is None:
return None
try:
@ -122,25 +108,25 @@ class PlaybackController(object):
except ValueError:
return None
@property
def track_at_eot(self):
"""
The track that will be played at the end of the current track.
tracklist_position = property(get_tracklist_position)
"""
The position of the current track in the tracklist.
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_eot` for convenience.
"""
return self._get_track(self.tl_track_at_eot)
Read-only.
"""
@property
def tl_track_at_eot(self):
"""
The track that will be played at the end of the current track.
def get_track_at_eot(self):
return self.tl_track_at_eot and self.tl_track_at_eot.track
Read-only. A :class:`mopidy.models.TlTrack`.
track_at_eot = property(get_track_at_eot)
"""
The track that will be played at the end of the current track.
Not necessarily the same track as :attr:`tl_track_at_next`.
"""
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_eot` for convenience.
"""
def get_tl_track_at_eot(self):
# pylint: disable = R0911
# Too many return statements
@ -173,28 +159,27 @@ class PlaybackController(object):
except IndexError:
return None
@property
def track_at_next(self):
"""
The track that will be played if calling :meth:`next()`.
tl_track_at_eot = property(get_tl_track_at_eot)
"""
The track that will be played at the end of the current track.
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_next` for convenience.
"""
return self._get_track(self.tl_track_at_next)
Read-only. A :class:`mopidy.models.TlTrack`.
@property
def tl_track_at_next(self):
"""
The track that will be played if calling :meth:`next()`.
Not necessarily the same track as :attr:`tl_track_at_next`.
"""
Read-only. A :class:`mopidy.models.TlTrack`.
def get_track_at_next(self):
return self.tl_track_at_next and self.tl_track_at_next.track
For normal playback this is the next track in the playlist. If repeat
is enabled the next track can loop around the playlist. When random is
enabled this should be a random track, all tracks should be played once
before the list repeats.
"""
track_at_next = property(get_track_at_next)
"""
The track that will be played if calling :meth:`next()`.
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_next` for convenience.
"""
def get_tl_track_at_next(self):
tl_tracks = self.core.tracklist.tl_tracks
if not tl_tracks:
@ -221,27 +206,30 @@ class PlaybackController(object):
except IndexError:
return None
@property
def track_at_previous(self):
"""
The track that will be played if calling :meth:`previous()`.
tl_track_at_next = property(get_tl_track_at_next)
"""
The track that will be played if calling :meth:`next()`.
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_previous` for convenience.
"""
return self._get_track(self.tl_track_at_previous)
Read-only. A :class:`mopidy.models.TlTrack`.
@property
def tl_track_at_previous(self):
"""
The track that will be played if calling :meth:`previous()`.
For normal playback this is the next track in the playlist. If repeat
is enabled the next track can loop around the playlist. When random is
enabled this should be a random track, all tracks should be played once
before the list repeats.
"""
A :class:`mopidy.models.TlTrack`.
def get_track_at_previous(self):
return self.tl_track_at_previous and self.tl_track_at_previous.track
For normal playback this is the previous track in the playlist. If
random and/or consume is enabled it should return the current track
instead.
"""
track_at_previous = property(get_track_at_previous)
"""
The track that will be played if calling :meth:`previous()`.
Read-only. A :class:`mopidy.models.Track` extracted from
:attr:`tl_track_at_previous` for convenience.
"""
def get_tl_track_at_previous(self):
if self.repeat or self.consume or self.random:
return self.current_tl_track
@ -250,59 +238,71 @@ class PlaybackController(object):
return self.core.tracklist.tl_tracks[self.tracklist_position - 1]
@property
def state(self):
"""
The playback state. Must be :attr:`PLAYING`, :attr:`PAUSED`, or
:attr:`STOPPED`.
tl_track_at_previous = property(get_tl_track_at_previous)
"""
The track that will be played if calling :meth:`previous()`.
Possible states and transitions:
A :class:`mopidy.models.TlTrack`.
.. digraph:: state_transitions
For normal playback this is the previous track in the playlist. If
random and/or consume is enabled it should return the current track
instead.
"""
"STOPPED" -> "PLAYING" [ label="play" ]
"STOPPED" -> "PAUSED" [ label="pause" ]
"PLAYING" -> "STOPPED" [ label="stop" ]
"PLAYING" -> "PAUSED" [ label="pause" ]
"PLAYING" -> "PLAYING" [ label="play" ]
"PAUSED" -> "PLAYING" [ label="resume" ]
"PAUSED" -> "STOPPED" [ label="stop" ]
"""
def get_state(self):
return self._state
@state.setter # noqa
def state(self, new_state):
def set_state(self, new_state):
(old_state, self._state) = (self.state, new_state)
logger.debug('Changing state: %s -> %s', old_state, new_state)
self._trigger_playback_state_changed(old_state, new_state)
@property
def time_position(self):
"""Time position in milliseconds."""
state = property(get_state, set_state)
"""
The playback state. Must be :attr:`PLAYING`, :attr:`PAUSED`, or
:attr:`STOPPED`.
Possible states and transitions:
.. digraph:: state_transitions
"STOPPED" -> "PLAYING" [ label="play" ]
"STOPPED" -> "PAUSED" [ label="pause" ]
"PLAYING" -> "STOPPED" [ label="stop" ]
"PLAYING" -> "PAUSED" [ label="pause" ]
"PLAYING" -> "PLAYING" [ label="play" ]
"PAUSED" -> "PLAYING" [ label="resume" ]
"PAUSED" -> "STOPPED" [ label="stop" ]
"""
def get_time_position(self):
backend = self._get_backend()
if backend:
return backend.playback.get_time_position().get()
else:
return 0
@property
def volume(self):
"""Volume as int in range [0..100] or :class:`None`"""
time_position = property(get_time_position)
"""Time position in milliseconds."""
def get_volume(self):
if self.audio:
return self.audio.get_volume().get()
else:
# For testing
return self._volume
@volume.setter # noqa
def volume(self, volume):
def set_volume(self, volume):
if self.audio:
self.audio.set_volume(volume)
else:
# For testing
self._volume = volume
volume = property(get_volume, set_volume)
"""Volume as int in range [0..100] or :class:`None`"""
def change_track(self, tl_track, on_error_step=1):
"""
Change to the given track, keeping the current playback state.

View File

@ -15,18 +15,19 @@ class PlaylistsController(object):
self.backends = backends
self.core = core
@property
def playlists(self):
"""
The available playlists.
Read-only. List of :class:`mopidy.models.Playlist`.
"""
def get_playlists(self):
futures = [
b.playlists.playlists for b in self.backends.with_playlists]
results = pykka.get_all(futures)
return list(itertools.chain(*results))
playlists = property(get_playlists)
"""
The available playlists.
Read-only. List of :class:`mopidy.models.Playlist`.
"""
def create(self, name, uri_scheme=None):
"""
Create a new playlist.

View File

@ -20,37 +20,33 @@ class TracklistController(object):
self._tl_tracks = []
self._version = 0
@property
def tl_tracks(self):
"""
List of :class:`mopidy.models.TlTrack`.
Read-only.
"""
def get_tl_tracks(self):
return self._tl_tracks[:]
@property
def tracks(self):
"""
List of :class:`mopidy.models.Track` in the tracklist.
tl_tracks = property(get_tl_tracks)
"""
List of :class:`mopidy.models.TlTrack`.
Read-only.
"""
Read-only.
"""
def get_tracks(self):
return [tl_track.track for tl_track in self._tl_tracks]
@property
def length(self):
"""
Length of the tracklist.
"""
tracks = property(get_tracks)
"""
List of :class:`mopidy.models.Track` in the tracklist.
Read-only.
"""
def get_length(self):
return len(self._tl_tracks)
@property
def version(self):
"""
The tracklist version. Integer which is increased every time the
tracklist is changed. Is not reset before Mopidy is restarted.
"""
length = property(get_length)
"""Length of the tracklist."""
def get_version(self):
return self._version
def _increase_version(self):
@ -58,6 +54,14 @@ class TracklistController(object):
self._core.playback.on_tracklist_change()
self._trigger_tracklist_changed()
version = property(get_version)
"""
The tracklist version.
Read-only. Integer which is increased every time the tracklist is changed.
Is not reset before Mopidy is restarted.
"""
def add(self, track, at_position=None, increase_version=True):
"""
Add the track to the end of, or at the given position in the tracklist.