Пример #1
0
    def _refresh_metadata(self) -> None:
        """
        Refreshes the API metadata: updates the artist and title of the song.

        The SwSpotify API works with exceptions so `SpotifyPaused` means
        the song isn't currently playing (the artist and title should remain
        the same), and `SpotifyClosed` means that there isn't a Spotify
        session open at that moment.
        """

        try:
            self.title, self.artist = spotify.current()
            self.is_playing = True
        except SpotifyPaused:
            self.is_playing = False
        except SpotifyClosed:
            raise ConnectionNotReady("No song currently playing") from None

        # Splitting the artist and title for local songs
        if self.artist == '':
            self.artist, self.title = split_title(self.title)

        # Checking that the metadata is valid
        if "" in (self.artist, self.title):
            raise ConnectionNotReady(
                "No Spotify session currently running or no song currently"
                " playing.") from None
Пример #2
0
    def connect_api(self) -> None:
        """
        Connects to the DBus session. Tries to access the proxy object
        and configures the call on property changes.
        """

        self._bus = pydbus.SessionBus()
        self._bus_name, self._obj = self._get_player()

        self.player_name = self._obj['org.mpris.MediaPlayer2'].Identity
        self._player_interface = self._obj['org.mpris.MediaPlayer2.Player']

        try:
            self._refresh_metadata()
        except IndexError:
            raise ConnectionNotReady("Metadata unavailable")

        self._start_event_loop()
Пример #3
0
    def _refresh_metadata(self) -> None:
        """
        Refreshes the metadata of the player: artist, title, whether
        it's playing or not, and the current position.
        """

        metadata = self._spotify.playback_currently_playing()
        if metadata is None or metadata.item is None:
            raise ConnectionNotReady("No song currently playing")
        self.artist = metadata.item.artists[0].name
        self.title = metadata.item.name

        # Some local songs don't have an artist name so `split_title`
        # is called in an attempt to manually get it from the title.
        if self.artist == '':
            self.artist, self.title = split_title(self.title)

        self._position = metadata.progress_ms
        self.is_playing = metadata.is_playing
Пример #4
0
    def connect_api(self) -> None:
        """
        Connects to the DBus session. Tries to access the proxy object
        and configures the call on property changes.
        """

        self._bus = pydbus.SessionBus()
        self._bus_name, self._obj = self._get_player()

        # Some MPRIS players don't support the position feature, so this
        # checks if it's in the blacklist to act accordingly when the
        # position is requested.
        position_blacklist = ('org.mpris.MediaPlayer2.spotify', )
        self._no_position = self._bus_name in position_blacklist
        self._player_interface = self._obj['org.mpris.MediaPlayer2.Player']

        try:
            self._refresh_metadata()
        except IndexError:
            raise ConnectionNotReady("No song is currently playing")

        self._start_event_loop()
Пример #5
0
    def _get_player(self) -> Tuple[str, 'CompositeObject']:
        """
        Method used to find the available players in the DBus bus. It returns
        the bus' name and object if it was found, or raises ConnectionNotReady
        otherwise.
        """

        logging.info("Looking for players")

        # Iterating through every bus name and checking that it's valid.
        for bus_name in self._bus.get(".DBus", "DBus").ListNames():
            # It must be from MediaPlayer2
            if not bus_name.startswith('org.mpris.MediaPlayer2'):
                continue

            # Trying to obtain the bus object
            try:
                obj = self._bus.get(bus_name, '/org/mpris/MediaPlayer2')
            except GLib.Error as e:
                logging.info("Skipping %s because of error: %s", bus_name,
                             str(e))
                continue

            # And making sure that it's playing at the moment (otherwise
            # only the first player found would be returned, but it could
            # not be the one actually being used).
            if not self._bool_status(obj.PlaybackStatus):
                logging.info(
                    "Skipping %s because it's not playing at"
                    " the moment", bus_name)
                continue

            logging.info("Using %s", bus_name)
            return bus_name, obj

        # ConnectionNotReady is raised at the end, in case that no valid
        # players were found.
        raise ConnectionNotReady("No players found")