示例#1
0
    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
示例#2
0
文件: network.py 项目: mopidy/mopidy
    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
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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)
示例#6
0
文件: playback.py 项目: connrs/mopidy
    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)
示例#7
0
    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
示例#8
0
    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
示例#9
0
文件: playback.py 项目: connrs/mopidy
    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
示例#10
0
    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
示例#11
0
文件: playback.py 项目: aefo/mopidy
    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
示例#12
0
    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
示例#13
0
    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)
示例#14
0
    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)
示例#15
0
    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)
示例#16
0
文件: playback.py 项目: aefo/mopidy
    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)
示例#17
0
    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
示例#18
0
    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