def create_server_socket(self, host, port): socket_path = path.get_unix_socket_path(host) if socket_path is not None: # host is a path so use unix socket sock = create_unix_socket() sock.bind(socket_path) else: # ensure the port is supplied validation.check_integer(port) sock = create_tcp_socket() sock.bind((host, port)) sock.setblocking(False) sock.listen(1) return sock
def index(self, tl_track=None, tlid=None): """ The position of the given track in the tracklist. If neither *tl_track* or *tlid* is given we return the index of the currently playing track. :param tl_track: the track to find the index of :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to find the index of :type tlid: :class:`int` or :class:`None` :rtype: :class:`int` or :class:`None` .. versionadded:: 1.1 The *tlid* parameter """ tl_track is None or validation.check_instance(tl_track, TlTrack) tlid is None or validation.check_integer(tlid, min=1) if tl_track is None and tlid is None: tl_track = self.core.playback.get_current_tl_track() if tl_track is not None: try: return self._tl_tracks.index(tl_track) except ValueError: pass elif tlid is not None: for i, tl_track in enumerate(self._tl_tracks): if tl_track.tlid == tlid: return i return None
def seek(self, time_position): """ Seeks to time position given in milliseconds. :param time_position: time position in milliseconds :type time_position: int :rtype: :class:`True` if successful, else :class:`False` """ # TODO: seek needs to take pending tracks into account :( validation.check_integer(time_position) if time_position < 0: logger.debug( 'Client seeked to negative position. Seeking to zero.') time_position = 0 if not self.core.tracklist.tracks: return False if self.get_state() == PlaybackState.STOPPED: self.play() # We need to prefer the still playing track, but if nothing is playing # we fall back to the pending one. tl_track = self._current_tl_track or self._pending_tl_track if tl_track and tl_track.track.length is None: return False if time_position < 0: time_position = 0 elif time_position > tl_track.track.length: # TODO: GStreamer will trigger a about-to-finish for us, use that? self.next() return True # Store our target position. self._pending_position = time_position # Make sure we switch back to previous track if we get a seek while we # have a pending track. if self._current_tl_track and self._pending_tl_track: self._change(self._current_tl_track, self.get_state()) else: return self._seek(time_position)
def play(self, tl_track=None, tlid=None): """ Play the given track, or if the given tl_track and tlid is :class:`None`, play the currently active track. Note that the track **must** already be in the tracklist. .. deprecated:: 3.0 The ``tl_track`` argument. Use ``tlid`` instead. :param tl_track: track to play :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to play :type tlid: :class:`int` or :class:`None` """ if sum(o is not None for o in [tl_track, tlid]) > 1: raise ValueError('At most one of "tl_track" and "tlid" may be set') tl_track is None or validation.check_instance(tl_track, models.TlTrack) tlid is None or validation.check_integer(tlid, min=1) if tl_track: deprecation.warn("core.playback.play:tl_track_kwarg") if tl_track is None and tlid is not None: for tl_track in self.core.tracklist.get_tl_tracks(): if tl_track.tlid == tlid: break else: tl_track = None if tl_track is not None: # TODO: allow from outside tracklist, would make sense given refs? assert tl_track in self.core.tracklist.get_tl_tracks() elif tl_track is None and self.get_state() == PlaybackState.PAUSED: self.resume() return current = self._pending_tl_track or self._current_tl_track pending = tl_track or current or self.core.tracklist.next_track(None) # avoid endless loop if 'repeat' is 'true' and no track is playable # * 2 -> second run to get all playable track in a shuffled playlist count = self.core.tracklist.get_length() * 2 while pending: if self._change(pending, PlaybackState.PLAYING): break else: self.core.tracklist._mark_unplayable(pending) current = pending pending = self.core.tracklist.next_track(current) count -= 1 if not count: logger.info("No playable track in the list.") break
def set_volume(self, volume): """Set the volume. The volume is defined as an integer in range [0..100]. The volume scale is linear. Returns :class:`True` if call is successful, otherwise :class:`False`. """ validation.check_integer(volume, min=0, max=100) if self._mixer is None: return False # TODO: 2.0 return None with _mixer_error_handling(self._mixer): result = self._mixer.set_volume(volume).get() validation.check_instance(result, bool) return result return False
def play(self, tl_track=None, tlid=None): """ Play the given track, or if the given tl_track and tlid is :class:`None`, play the currently active track. Note that the track **must** already be in the tracklist. :param tl_track: track to play :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to play :type tlid: :class:`int` or :class:`None` """ if sum(o is not None for o in [tl_track, tlid]) > 1: raise ValueError('At most one of "tl_track" and "tlid" may be set') tl_track is None or validation.check_instance(tl_track, models.TlTrack) tlid is None or validation.check_integer(tlid, min=1) if tl_track: deprecation.warn('core.playback.play:tl_track_kwarg', pending=True) if tl_track is None and tlid is not None: for tl_track in self.core.tracklist.get_tl_tracks(): if tl_track.tlid == tlid: break else: tl_track = None if tl_track is not None: # TODO: allow from outside tracklist, would make sense given refs? assert tl_track in self.core.tracklist.get_tl_tracks() elif tl_track is None and self.get_state() == PlaybackState.PAUSED: self.resume() return current = self._pending_tl_track or self._current_tl_track pending = tl_track or current or self.core.tracklist.next_track(None) # avoid endless loop if 'repeat' is 'true' and no track is playable # * 2 -> second run to get all playable track in a shuffled playlist count = self.core.tracklist.get_length() * 2 while pending: if self._change(pending, PlaybackState.PLAYING): break else: self.core.tracklist._mark_unplayable(pending) current = pending pending = self.core.tracklist.next_track(current) count -= 1 if not count: logger.info('No playable track in the list.') break
def seek(self, time_position): """ Seeks to time position given in milliseconds. :param time_position: time position in milliseconds :type time_position: int :rtype: :class:`True` if successful, else :class:`False` """ validation.check_integer(time_position) if time_position < 0: logger.debug( 'Client seeked to negative position. Seeking to zero.') time_position = 0 if not self.core.tracklist.tracks: return False if self.current_track and self.current_track.length is None: return False if self.get_state() == PlaybackState.STOPPED: self.play() if time_position < 0: time_position = 0 elif time_position > self.current_track.length: self.next() return True backend = self._get_backend() if not backend: return False success = backend.playback.seek(time_position).get() if success: self._trigger_seeked(time_position) return success
def get_volume(self): """Get the volume. Integer in range [0..100] or :class:`None` if unknown. The volume scale is linear. """ if self._mixer is None: return None with _mixer_error_handling(self._mixer): volume = self._mixer.get_volume().get() volume is None or validation.check_integer(volume, min=0, max=100) return volume return None
def play(self, tl_track=None, tlid=None): """ Play the given track, or if the given tl_track and tlid is :class:`None`, play the currently active track. Note that the track **must** already be in the tracklist. :param tl_track: track to play :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to play :type tlid: :class:`int` or :class:`None` """ if sum(o is not None for o in [tl_track, tlid]) > 1: raise ValueError('At most one of "tl_track" and "tlid" may be set') tl_track is None or validation.check_instance(tl_track, models.TlTrack) tlid is None or validation.check_integer(tlid, min=1) if tl_track: deprecation.warn("core.playback.play:tl_track_kwarg", pending=True) if tl_track is None and tlid is not None: for tl_track in self.core.tracklist.get_tl_tracks(): if tl_track.tlid == tlid: break else: tl_track = None if tl_track is not None: # TODO: allow from outside tracklist, would make sense given refs? assert tl_track in self.core.tracklist.get_tl_tracks() elif tl_track is None and self.get_state() == PlaybackState.PAUSED: self.resume() return current = self._pending_tl_track or self._current_tl_track pending = tl_track or current or self.core.tracklist.next_track(None) while pending: # TODO: should we consume unplayable tracks in this loop? if self._change(pending, PlaybackState.PLAYING): break else: self.core.tracklist._mark_unplayable(pending) current = pending pending = self.core.tracklist.next_track(current)
def play(self, tl_track=None, tlid=None): """ Play the given track, or if the given tl_track and tlid is :class:`None`, play the currently active track. Note that the track **must** already be in the tracklist. :param tl_track: track to play :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to play :type tlid: :class:`int` or :class:`None` """ if sum(o is not None for o in [tl_track, tlid]) > 1: raise ValueError('At most one of "tl_track" and "tlid" may be set') tl_track is None or validation.check_instance(tl_track, models.TlTrack) tlid is None or validation.check_integer(tlid, min=1) if tl_track: deprecation.warn('core.playback.play:tl_track_kwarg', pending=True) if tl_track is None and tlid is not None: for tl_track in self.core.tracklist.get_tl_tracks(): if tl_track.tlid == tlid: break else: tl_track = None if tl_track is not None: # TODO: allow from outside tracklist, would make sense given refs? assert tl_track in self.core.tracklist.get_tl_tracks() elif tl_track is None and self.get_state() == PlaybackState.PAUSED: self.resume() return current = self._pending_tl_track or self._current_tl_track pending = tl_track or current or self.core.tracklist.next_track(None) while pending: if self._change(pending, PlaybackState.PLAYING): break else: self.core.tracklist._mark_unplayable(pending) current = pending pending = self.core.tracklist.next_track(current)
def play(self, tl_track=None, tlid=None): """ Play the given track, or if the given tl_track and tlid is :class:`None`, play the currently active track. Note that the track **must** already be in the tracklist. :param tl_track: track to play :type tl_track: :class:`mopidy.models.TlTrack` or :class:`None` :param tlid: TLID of the track to play :type tlid: :class:`int` or :class:`None` """ if sum(o is not None for o in [tl_track, tlid]) > 1: raise ValueError('At most one of "tl_track" and "tlid" may be set') tl_track is None or validation.check_instance(tl_track, models.TlTrack) tlid is None or validation.check_integer(tlid, min=0) if tl_track: deprecation.warn('core.playback.play:tl_track_kwarg', pending=True) self._play(tl_track=tl_track, tlid=tlid, on_error_step=1)
def add(self, tracks=None, at_position=None, uri=None, uris=None): """ Add tracks to the tracklist. If ``uri`` is given instead of ``tracks``, the URI is looked up in the library and the resulting tracks are added to the tracklist. If ``uris`` is given instead of ``uri`` or ``tracks``, the URIs are looked up in the library and the resulting tracks are added to the tracklist. If ``at_position`` is given, the tracks are inserted at the given position in the tracklist. If ``at_position`` is not given, the tracks are appended to the end of the tracklist. Triggers the :meth:`mopidy.core.CoreListener.tracklist_changed` event. :param tracks: tracks to add :type tracks: list of :class:`mopidy.models.Track` or :class:`None` :param at_position: position in tracklist to add tracks :type at_position: int or :class:`None` :param uri: URI for tracks to add :type uri: string or :class:`None` :param uris: list of URIs for tracks to add :type uris: list of string or :class:`None` :rtype: list of :class:`mopidy.models.TlTrack` .. versionadded:: 1.0 The ``uris`` argument. .. deprecated:: 1.0 The ``tracks`` and ``uri`` arguments. Use ``uris``. """ if sum(o is not None for o in [tracks, uri, uris]) != 1: raise ValueError( 'Exactly one of "tracks", "uri" or "uris" must be set') tracks is None or validation.check_instances(tracks, Track) uri is None or validation.check_uri(uri) uris is None or validation.check_uris(uris) validation.check_integer(at_position or 0) if tracks: deprecation.warn('core.tracklist.add:tracks_arg') if uri: deprecation.warn('core.tracklist.add:uri_arg') if tracks is None: if uri is not None: uris = [uri] tracks = [] track_map = self.core.library.lookup(uris=uris) for uri in uris: tracks.extend(track_map[uri]) tl_tracks = [] max_length = self.core._config['core']['max_tracklist_length'] for track in tracks: if self.get_length() >= max_length: raise exceptions.TracklistFull( 'Tracklist may contain at most %d tracks.' % max_length) tl_track = TlTrack(self._next_tlid, track) self._next_tlid += 1 if at_position is not None: self._tl_tracks.insert(at_position, tl_track) at_position += 1 else: self._tl_tracks.append(tl_track) tl_tracks.append(tl_track) if tl_tracks: self._increase_version() return tl_tracks
def add(self, tracks=None, at_position=None, uris=None): """ Add tracks to the tracklist. If ``uris`` is given instead of ``tracks``, the URIs are looked up in the library and the resulting tracks are added to the tracklist. If ``at_position`` is given, the tracks are inserted at the given position in the tracklist. If ``at_position`` is not given, the tracks are appended to the end of the tracklist. Triggers the :meth:`mopidy.core.CoreListener.tracklist_changed` event. :param tracks: tracks to add :type tracks: list of :class:`mopidy.models.Track` or :class:`None` :param at_position: position in tracklist to add tracks :type at_position: int or :class:`None` :param uris: list of URIs for tracks to add :type uris: list of string or :class:`None` :rtype: list of :class:`mopidy.models.TlTrack` .. versionadded:: 1.0 The ``uris`` argument. .. deprecated:: 1.0 The ``tracks`` argument. Use ``uris``. """ if sum(o is not None for o in [tracks, uris]) != 1: raise ValueError('Exactly one of "tracks" or "uris" must be set') tracks is None or validation.check_instances(tracks, Track) uris is None or validation.check_uris(uris) validation.check_integer(at_position or 0) if tracks: deprecation.warn("core.tracklist.add:tracks_arg") if tracks is None: tracks = [] track_map = self.core.library.lookup(uris=uris) for uri in uris: tracks.extend(track_map[uri]) tl_tracks = [] max_length = self.core._config["core"]["max_tracklist_length"] for track in tracks: if self.get_length() >= max_length: raise exceptions.TracklistFull( f"Tracklist may contain at most {max_length:d} tracks." ) tl_track = TlTrack(self._next_tlid, track) self._next_tlid += 1 if at_position is not None: self._tl_tracks.insert(at_position, tl_track) at_position += 1 else: self._tl_tracks.append(tl_track) tl_tracks.append(tl_track) if tl_tracks: self._increase_version() return tl_tracks