Example #1
0
 def _browse_genre_stations(self, uri):
     return [
         models.Ref.directory(name=station.name, uri=PandoraUri.factory(station).uri)
         for station in self.backend.api.get_genre_stations()[
             PandoraUri.factory(uri).category_name
         ]
     ]
Example #2
0
def test_search_uri_parse():

    obj = PandoraUri._from_uri("pandora:search:S1234567")
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == "S1234567"

    obj = PandoraUri._from_uri("pandora:search:R123456")
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == "R123456"

    obj = PandoraUri._from_uri("pandora:search:C12345")
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == "C12345"

    obj = PandoraUri._from_uri("pandora:search:G123")
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == "G123"
Example #3
0
def test_search_uri_parse():

    obj = PandoraUri._from_uri('pandora:search:S1234567')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'S1234567'

    obj = PandoraUri._from_uri('pandora:search:R123456')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'R123456'

    obj = PandoraUri._from_uri('pandora:search:C12345')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'C12345'

    obj = PandoraUri._from_uri('pandora:search:G123')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'G123'
Example #4
0
 def _browse_genre_stations(self, uri):
     return [
         models.Ref.directory(name=station.name,
                              uri=PandoraUri.factory(station).uri)
         for station in self.backend.api.get_genre_stations()[
             PandoraUri.factory(uri).category_name]
     ]
Example #5
0
def test_search_uri_parse():

    obj = PandoraUri._from_uri('pandora:search:S1234567')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'S1234567'

    obj = PandoraUri._from_uri('pandora:search:R123456')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'R123456'

    obj = PandoraUri._from_uri('pandora:search:C12345')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'C12345'

    obj = PandoraUri._from_uri('pandora:search:G123')
    assert type(obj) is SearchUri

    assert obj.uri_type == SearchUri.uri_type
    assert obj.token == 'G123'
Example #6
0
def test_track_uri_is_ad(playlist_item_mock, ad_item_mock):
    track_uri = TrackUri._from_track(ad_item_mock)
    obj = PandoraUri._from_uri(track_uri.uri)

    assert type(obj) is AdItemUri

    track_uri = TrackUri._from_track(playlist_item_mock)
    obj = PandoraUri._from_uri(track_uri.uri)

    assert type(obj) is not AdItemUri
Example #7
0
def test_factory_returns_correct_station_uri_types():
        station_mock = mock.PropertyMock(spec=GenreStation)
        station_mock.id = 'G100'
        station_mock.token = 'G100'
        assert type(PandoraUri.factory(station_mock)) is GenreStationUri

        station_mock = mock.PropertyMock(spec=Station)
        station_mock.id = 'id_mock'
        station_mock.token = 'token_mock'
        assert type(PandoraUri.factory(station_mock)) is StationUri
Example #8
0
def test_track_uri_is_ad(playlist_item_mock, ad_item_mock):
    track_uri = TrackUri._from_track(ad_item_mock)
    obj = PandoraUri._from_uri(track_uri.uri)

    assert type(obj) is AdItemUri

    track_uri = TrackUri._from_track(playlist_item_mock)
    obj = PandoraUri._from_uri(track_uri.uri)

    assert type(obj) is not AdItemUri
Example #9
0
def test_factory_returns_correct_station_uri_types():
    station_mock = mock.PropertyMock(spec=GenreStation)
    station_mock.id = 'G100'
    station_mock.token = 'G100'
    assert type(PandoraUri.factory(station_mock)) is GenreStationUri

    station_mock = mock.PropertyMock(spec=Station)
    station_mock.id = 'id_mock'
    station_mock.token = 'token_mock'
    assert type(PandoraUri.factory(station_mock)) is StationUri
Example #10
0
 def is_station_changed(self, track):
     try:
         previous_track_uri = PandoraUri.factory(
             self.core.history.get_history().get()[1][1].uri)
         if previous_track_uri.station_id != PandoraUri.factory(
                 track.uri).station_id:
             return True
     except (IndexError, NotImplementedError):
         # No tracks in history, or last played track was not a Pandora track. Ignore
         pass
     return False
Example #11
0
 def is_station_changed(self, track):
     try:
         previous_track_uri = PandoraUri.factory(
             self.core.history.get_history().get()[1][1].uri
         )
         if (
             previous_track_uri.station_id
             != PandoraUri.factory(track.uri).station_id
         ):
             return True
     except (IndexError, NotImplementedError):
         # No tracks in history, or last played track was not a Pandora track. Ignore
         pass
     return False
Example #12
0
    def change_track(self, track):
        if track.uri is None:
            logger.warning(
                "No URI for Pandora track '{}'. Track cannot be played.".
                format(track))
            return False

        pandora_uri = PandoraUri.factory(track.uri)
        if isinstance(pandora_uri, StationUri):
            # Change to first track in station playlist.
            logger.warning(
                "Cannot play Pandora stations directly. "
                f"Retrieving tracks for station with ID: {pandora_uri.station_id}"
            )
            self.backend.end_of_tracklist_reached(
                station_id=pandora_uri.station_id, auto_play=True)
            return False
        try:
            self._trigger_track_changing(track)
            self.check_skip_limit()
            self.change_pandora_track(track)
            return super().change_track(track)

        except KeyError:
            logger.exception(
                f"Error changing Pandora track: failed to lookup {track.uri!r}"
            )
            return False
        except (MaxSkipLimitExceeded, Unplayable) as e:
            logger.warning(e)
            return False
Example #13
0
def test_get_images_for_unsupported_uri_type_issues_warning(config, caplog):
    backend = conftest.get_backend(config)

    search_uri = PandoraUri.factory('pandora:search:R12345')
    results = backend.library.get_images([search_uri.uri])
    assert len(results[search_uri.uri]) == 0
    assert "No images available for Pandora URIs of type 'search'.".format(search_uri.uri) in caplog.text
Example #14
0
 def update_tracklist(self, track):
     if self.is_station_changed(track):
         # Station has changed, remove tracks from previous station from tracklist.
         self._trim_tracklist(keep_only=track)
     if self.is_end_of_tracklist_reached(track):
         self._trigger_end_of_tracklist_reached(
             PandoraUri.factory(track).station_id, auto_play=False)
Example #15
0
    def track_unplayable(self, track):
        if self.is_end_of_tracklist_reached(track):
            self.core.playback.stop()
            self._trigger_end_of_tracklist_reached(
                PandoraUri.factory(track).station_id, auto_play=True)

        self.core.tracklist.remove({'uri': [track.uri]})
Example #16
0
def test_get_images_for_unknown_uri_returns_empty_list(config, caplog):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory('pandora:track:mock_id:mock_token')
    results = backend.library.get_images([track_uri.uri])
    assert len(results[track_uri.uri]) == 0
    assert "Failed to lookup image for Pandora URI '{}'.".format(track_uri.uri) in caplog.text
Example #17
0
    def change_track(self, track):
        if track.uri is None:
            logger.warning(
                "No URI for Pandora track '{}'. Track cannot be played.".format(track)
            )
            return False

        pandora_uri = PandoraUri.factory(track.uri)
        if isinstance(pandora_uri, StationUri):
            # Change to first track in station playlist.
            logger.warning(
                "Cannot play Pandora stations directly. Retrieving tracks for station with ID: {}...".format(
                    pandora_uri.station_id
                )
            )
            self.backend.end_of_tracklist_reached(
                station_id=pandora_uri.station_id, auto_play=True
            )
            return False
        try:
            self._trigger_track_changing(track)
            self.check_skip_limit()
            self.change_pandora_track(track)
            return super(PandoraPlaybackProvider, self).change_track(track)

        except KeyError:
            logger.exception(
                "Error changing Pandora track: failed to lookup '{}'.".format(track.uri)
            )
            return False
        except (MaxSkipLimitExceeded, Unplayable) as e:
            logger.warning(e)
            return False
Example #18
0
def test_pandora_parse_mock_uri():
    uri = 'pandora:station:id_mock:token_mock'
    obj = PandoraUri._from_uri(uri)

    assert isinstance(obj, PandoraUri)
    assert type(obj) is StationUri
    assert obj.uri == uri
Example #19
0
 def get_images(self, uris):
     result = {}
     for uri in uris:
         image_uris = set()
         try:
             track = self.lookup_pandora_track(uri)
             if track.is_ad is True:
                 image_uri = track.image_url
             else:
                 image_uri = track.album_art_url
             if image_uri:
                 image_uris.update([image_uri])
         except (TypeError, KeyError):
             pandora_uri = PandoraUri.factory(uri)
             if isinstance(pandora_uri, TrackUri):
                 # Could not find the track as expected - exception.
                 logger.exception(
                     "Failed to lookup image for Pandora URI '{}'.".format(
                         uri))
             else:
                 # Lookup
                 logger.warning(
                     "No images available for Pandora URIs of type '{}'.".
                     format(pandora_uri.uri_type))
             pass
         result[uri] = [models.Image(uri=u) for u in image_uris]
     return result
Example #20
0
def test_pandora_parse_mock_uri():
    uri = 'pandora:station:id_mock:token_mock'
    obj = PandoraUri._from_uri(uri)

    assert isinstance(obj, PandoraUri)
    assert type(obj) is StationUri
    assert obj.uri == uri
def test_change_track_skips_if_track_not_available_in_buffer(provider, playlist_item_mock, caplog):
    track = PandoraUri.factory(playlist_item_mock)

    provider.backend.prepare_next_track = mock.PropertyMock()

    assert provider.change_track(track) is False
    assert "Error changing Pandora track: failed to lookup '{}'.".format(track.uri) in caplog.text
Example #22
0
def test_browse_directory_uri(config, get_station_list_return_value_mock,
                              station_list_result_mock):
    with mock.patch.object(APIClient,
                           'get_station_list',
                           return_value=get_station_list_return_value_mock):
        backend = conftest.get_backend(config)
        results = backend.library.browse(backend.library.root_directory.uri)

        assert len(results) == 4

        assert results[0].type == models.Ref.DIRECTORY
        assert results[0].uri == PandoraUri('genres').uri

        assert results[1].type == models.Ref.DIRECTORY
        assert results[1].name.startswith('QuickMix')
        assert results[1].uri == StationUri._from_station(
            Station.from_json(backend.api,
                              station_list_result_mock['stations'][2])).uri

        assert results[2].type == models.Ref.DIRECTORY
        assert results[2].uri == StationUri._from_station(
            Station.from_json(backend.api,
                              station_list_result_mock['stations'][1])).uri

        assert results[3].type == models.Ref.DIRECTORY
        assert results[3].uri == StationUri._from_station(
            Station.from_json(backend.api,
                              station_list_result_mock['stations'][0])).uri
Example #23
0
def test_factory_track():
    track = models.Track(name='name_mock', uri='pandora:track:station_id_mock:track_token_mock')

    obj = PandoraUri.factory(track)

    assert type(obj) is PlaylistItemUri
    assert obj.uri == track.uri
Example #24
0
def test_change_track_enforces_skip_limit_if_no_audio_url(
        provider, playlist_item_mock, caplog):
    with mock.patch.object(
            PandoraLibraryProvider,
            "lookup_pandora_track",
            return_value=playlist_item_mock,
    ):
        track = PandoraUri.factory(playlist_item_mock)

        provider._trigger_track_unplayable = mock.PropertyMock()
        provider._trigger_skip_limit_exceeded = mock.PropertyMock(0)

        playlist_item_mock.audio_url = None

        for i in range(PandoraPlaybackProvider.SKIP_LIMIT + 1):
            assert provider.change_track(track) is False
            if i < PandoraPlaybackProvider.SKIP_LIMIT - 1:
                assert provider._trigger_track_unplayable.called
                provider._trigger_track_unplayable.reset_mock()
                assert not provider._trigger_skip_limit_exceeded.called
            else:
                assert not provider._trigger_track_unplayable.called
                assert provider._trigger_skip_limit_exceeded.called

        assert ("Maximum track skip limit ({:d}) exceeded.".format(
            PandoraPlaybackProvider.SKIP_LIMIT) in caplog.text)
Example #25
0
def test_change_track_enforces_skip_limit_on_request_exceptions(
        provider, playlist_item_mock, caplog):
    with mock.patch.object(
            PandoraLibraryProvider,
            "lookup_pandora_track",
            return_value=playlist_item_mock,
    ):
        with mock.patch.object(
                APITransport,
                "__call__",
                side_effect=conftest.request_exception_mock,
        ):
            track = PandoraUri.factory(playlist_item_mock)

            provider._trigger_track_unplayable = mock.PropertyMock()
            provider._trigger_skip_limit_exceeded = mock.PropertyMock(0)
            playlist_item_mock.audio_url = "pandora:track:mock_id:mock_token"

            for i in range(PandoraPlaybackProvider.SKIP_LIMIT + 1):
                assert provider.change_track(track) is False
                if i < PandoraPlaybackProvider.SKIP_LIMIT - 1:
                    assert provider._trigger_track_unplayable.called
                    provider._trigger_track_unplayable.reset_mock()
                    assert not provider._trigger_skip_limit_exceeded.called
                else:
                    assert not provider._trigger_track_unplayable.called
                    assert provider._trigger_skip_limit_exceeded.called

            assert ("Maximum track skip limit ({:d}) exceeded.".format(
                PandoraPlaybackProvider.SKIP_LIMIT) in caplog.text)
Example #26
0
 def get_images(self, uris):
     result = {}
     for uri in uris:
         image_uris = set()
         try:
             track = self.lookup_pandora_track(uri)
             if track.is_ad is True:
                 image_uri = track.image_url
             else:
                 image_uri = track.album_art_url
             if image_uri:
                 image_uris.update([image_uri])
         except (TypeError, KeyError):
             pandora_uri = PandoraUri.factory(uri)
             if isinstance(pandora_uri, TrackUri):
                 # Could not find the track as expected - exception.
                 logger.exception(
                     "Failed to lookup image for Pandora URI '{}'.".format(uri)
                 )
             else:
                 # Lookup
                 logger.warning(
                     "No images available for Pandora URIs of type '{}'.".format(
                         pandora_uri.uri_type
                     )
                 )
             pass
         result[uri] = [models.Image(uri=u) for u in image_uris]
     return result
Example #27
0
    def lookup(self, uri):
        pandora_uri = PandoraUri.factory(uri)
        logger.info("Looking up Pandora {} {}...".format(
            pandora_uri.uri_type, pandora_uri.uri))
        if isinstance(pandora_uri, SearchUri):
            # Create the station first so that it can be browsed.
            station_uri = self._create_station_for_token(pandora_uri.token)
            track = self._browse_tracks(station_uri.uri)[0]

            # Recursive call to look up first track in station that was searched for.
            return self.lookup(track.uri)

        track_kwargs = {"uri": uri}
        (album_kwargs, artist_kwargs) = {}, {}

        if isinstance(pandora_uri, TrackUri):
            try:
                track = self.lookup_pandora_track(uri)
            except KeyError:
                logger.exception(f"Failed to lookup Pandora URI '{uri}'.")
                return []
            else:
                if isinstance(pandora_uri, AdItemUri):
                    track_kwargs["name"] = "Advertisement"

                    if not track.title:
                        track.title = "(Title not specified)"
                    artist_kwargs["name"] = track.title

                    if not track.company_name:
                        track.company_name = "(Company name not specified)"
                    album_kwargs["name"] = track.company_name
                else:
                    track_kwargs["name"] = track.song_name
                    track_kwargs["length"] = track.track_length * 1000
                    try:
                        track_kwargs["bitrate"] = int(track.bitrate)
                    except TypeError:
                        # Bitrate not specified for this stream, ignore.
                        pass
                    artist_kwargs["name"] = track.artist_name
                    album_kwargs["name"] = track.album_name
        elif isinstance(pandora_uri, StationUri):
            station = self.backend.api.get_station(pandora_uri.station_id)
            track_kwargs["name"] = station.name
            artist_kwargs["name"] = "Pandora Station"
            album_kwargs["name"] = ", ".join(station.genre)
        else:
            raise ValueError(
                "Unexpected type to perform Pandora track lookup: {}.".format(
                    pandora_uri.uri_type))

        artist_kwargs[
            "uri"] = uri  # Artist lookups should just point back to the track itself.
        track_kwargs["artists"] = [models.Artist(**artist_kwargs)]
        album_kwargs[
            "uri"] = uri  # Album lookups should just point back to the track itself.
        track_kwargs["album"] = models.Album(**album_kwargs)
        return [models.Track(**track_kwargs)]
Example #28
0
def test_get_images_for_ad_with_images(config, ad_item_mock):
    backend = conftest.get_backend(config)

    ad_uri = PandoraUri.factory('pandora:ad:{}:{}'.format(conftest.MOCK_STATION_ID, conftest.MOCK_TRACK_AD_TOKEN))
    backend.library.pandora_track_cache[ad_uri.uri] = TrackCacheItem(mock.Mock(spec=models.Ref.track), ad_item_mock)
    results = backend.library.get_images([ad_uri.uri])
    assert len(results[ad_uri.uri]) == 1
    assert results[ad_uri.uri][0].uri == ad_item_mock.image_url
Example #29
0
 def update_tracklist(self, track):
     if self.is_station_changed(track):
         # Station has changed, remove tracks from previous station from tracklist.
         self._trim_tracklist(keep_only=track)
     if self.is_end_of_tracklist_reached(track):
         self._trigger_end_of_tracklist_reached(
             PandoraUri.factory(track).station_id, auto_play=False
         )
Example #30
0
def test_lookup_of_missing_track(config, playlist_item_mock, caplog):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory(playlist_item_mock)
    results = backend.library.lookup(track_uri.uri)

    assert len(results) == 0
    assert f"Failed to lookup Pandora URI '{track_uri.uri}'." in caplog.text
Example #31
0
def test_lookup_of_missing_track(config, playlist_item_mock, caplog):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory(playlist_item_mock)
    results = backend.library.lookup(track_uri.uri)

    assert len(results) == 0
    assert "Failed to lookup Pandora URI '{}'.".format(track_uri.uri) in caplog.text
Example #32
0
def test_genres_uri_parse():
    mock_uri = "pandora:genres"
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is GenresUri

    assert obj.uri_type == "genres"
    assert obj.uri == mock_uri
Example #33
0
    def track_unplayable(self, track):
        if self.is_end_of_tracklist_reached(track):
            self.core.playback.stop()
            self._trigger_end_of_tracklist_reached(
                PandoraUri.factory(track).station_id, auto_play=True
            )

        self.core.tracklist.remove({"uri": [track.uri]})
Example #34
0
def test_get_images_for_unsupported_uri_type_issues_warning(config, caplog):
    backend = conftest.get_backend(config)

    search_uri = PandoraUri.factory('pandora:search:R12345')
    results = backend.library.get_images([search_uri.uri])
    assert len(results[search_uri.uri]) == 0
    assert "No images available for Pandora URIs of type 'search'.".format(
        search_uri.uri) in caplog.text
Example #35
0
def test_factory_track_ref():
    track_ref = models.Ref(
        name="name_mock", uri="pandora:track:station_id_mock:track_token_mock")

    obj = PandoraUri.factory(track_ref)

    assert type(obj) is PlaylistItemUri
    assert obj.uri == track_ref.uri
Example #36
0
def test_factory_track():
    track = models.Track(name='name_mock',
                         uri='pandora:track:station_id_mock:track_token_mock')

    obj = PandoraUri.factory(track)

    assert type(obj) is PlaylistItemUri
    assert obj.uri == track.uri
Example #37
0
def test_get_images_for_unknown_uri_returns_empty_list(config, caplog):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory('pandora:track:mock_id:mock_token')
    results = backend.library.get_images([track_uri.uri])
    assert len(results[track_uri.uri]) == 0
    assert "Failed to lookup image for Pandora URI '{}'.".format(
        track_uri.uri) in caplog.text
Example #38
0
    def lookup(self, uri):
        pandora_uri = PandoraUri.factory(uri)
        if isinstance(pandora_uri, SearchUri):
            # Create the station first so that it can be browsed.
            station_uri = self._create_station_for_token(pandora_uri.token)
            track = self._browse_tracks(station_uri.uri)[0]

            # Recursive call to look up first track in station that was searched for.
            return self.lookup(track.uri)

        if isinstance(pandora_uri, TrackUri):
            try:
                track = self.lookup_pandora_track(uri)
            except KeyError:
                logger.exception(
                    "Failed to lookup Pandora URI '{}'.".format(uri))
                return []
            else:
                track_kwargs = {'uri': uri}
                (album_kwargs, artist_kwargs) = {}, {}
                # TODO: Album.images has been deprecated in Mopidy 1.2. Remove this code when all frontends have been
                #       updated to make use of the newer LibraryController.get_images()
                images = self.get_images([uri])[uri]
                if len(images) > 0:
                    album_kwargs = {'images': [image.uri for image in images]}

                if isinstance(pandora_uri, AdItemUri):
                    track_kwargs['name'] = 'Advertisement'

                    if not track.title:
                        track.title = '(Title not specified)'
                    artist_kwargs['name'] = track.title

                    if not track.company_name:
                        track.company_name = '(Company name not specified)'
                    album_kwargs['name'] = track.company_name
                else:
                    track_kwargs['name'] = track.song_name
                    track_kwargs['length'] = track.track_length * 1000
                    try:
                        track_kwargs['bitrate'] = int(track.bitrate)
                    except TypeError:
                        # Bitrate not specified for this stream, ignore.
                        pass
                    artist_kwargs['name'] = track.artist_name
                    album_kwargs['name'] = track.album_name
        else:
            raise ValueError(
                'Unexpected type to perform Pandora track lookup: {}.'.format(
                    pandora_uri.uri_type))

        artist_kwargs[
            'uri'] = uri  # Artist lookups should just point back to the track itself.
        track_kwargs['artists'] = [models.Artist(**artist_kwargs)]
        album_kwargs[
            'uri'] = uri  # Album lookups should just point back to the track itself.
        track_kwargs['album'] = models.Album(**album_kwargs)
        return [models.Track(**track_kwargs)]
Example #39
0
def test_change_track_skips_if_track_not_available_in_buffer(
        provider, playlist_item_mock, caplog):
    track = PandoraUri.factory(playlist_item_mock)

    provider.backend.prepare_next_track = mock.PropertyMock()

    assert provider.change_track(track) is False
    assert (f"Error changing Pandora track: failed to lookup '{track.uri}'"
            in caplog.text)
def test_change_track_resets_skips_on_success(provider, playlist_item_mock):
    with mock.patch.object(PandoraLibraryProvider, 'lookup_pandora_track', return_value=playlist_item_mock):
        with mock.patch.object(PlaylistItem, 'get_is_playable', return_value=True):
            track = PandoraUri.factory(playlist_item_mock)

            provider._consecutive_track_skips = 1

            assert provider.change_track(track) is True
            assert provider._consecutive_track_skips == 0
def test_change_track_triggers_event_on_success(provider, playlist_item_mock):
    with mock.patch.object(PandoraLibraryProvider, 'lookup_pandora_track', return_value=playlist_item_mock):
        with mock.patch.object(PlaylistItem, 'get_is_playable', return_value=True):
            track = PandoraUri.factory(playlist_item_mock)

            provider._trigger_track_changing = mock.PropertyMock()

            assert provider.change_track(track) is True
            assert provider._trigger_track_changing.called
Example #42
0
def test_get_images_for_track_with_images(config, playlist_item_mock):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory('pandora:track:mock_id:mock_token')
    backend.library.pandora_track_cache[track_uri.uri] = TrackCacheItem(mock.Mock(spec=models.Ref.track),
                                                                        playlist_item_mock)
    results = backend.library.get_images([track_uri.uri])
    assert len(results[track_uri.uri]) == 1
    assert results[track_uri.uri][0].uri == playlist_item_mock.album_art_url
def test_change_track_fetches_next_track_if_station_uri(provider, get_station_mock_return_value, caplog):
    station = PandoraUri.factory(get_station_mock_return_value)

    provider.backend._trigger_next_track_available = mock.PropertyMock()

    assert provider.change_track(station) is False
    assert 'Cannot play Pandora stations directly. Retrieving tracks for station with ID: {}...'.format(
        station.station_id) in caplog.text
    assert provider.backend._trigger_next_track_available.called
Example #44
0
def test_get_images_for_track_with_images(config, playlist_item_mock):
    backend = conftest.get_backend(config)

    track_uri = PandoraUri.factory('pandora:track:mock_id:mock_token')
    backend.library.pandora_track_cache[track_uri.uri] = TrackCacheItem(
        mock.Mock(spec=models.Ref.track), playlist_item_mock)
    results = backend.library.get_images([track_uri.uri])
    assert len(results[track_uri.uri]) == 1
    assert results[track_uri.uri][0].uri == playlist_item_mock.album_art_url
Example #45
0
    def get_images(self, uris):
        result = {}
        for uri in uris:
            image_uris = set()
            try:
                image_uri = None
                pandora_uri = PandoraUri.factory(uri)

                logger.info("Retrieving images for Pandora {} {}...".format(
                    pandora_uri.uri_type, pandora_uri.uri))

                if isinstance(pandora_uri, AdItemUri) or isinstance(
                        pandora_uri, TrackUri):
                    track = self.lookup_pandora_track(uri)
                    if track.is_ad is True:
                        image_uri = track.image_url
                    else:
                        image_uri = track.album_art_url
                elif isinstance(pandora_uri, StationUri):
                    # GenreStations don't appear to have artwork available via the
                    # json API
                    if not isinstance(pandora_uri, GenreStationUri):
                        station = self.backend.api.get_station(
                            pandora_uri.station_id)
                        image_uri = station.art_url
                else:
                    # Lookup
                    logger.warning(
                        "No images available for Pandora URIs of type '{}'.".
                        format(pandora_uri.uri_type))

                if image_uri:
                    image_uris.update(
                        [image_uri.replace("http://", "https://", 1)])
            except (TypeError, KeyError):
                pandora_uri = PandoraUri.factory(uri)
                if isinstance(pandora_uri, TrackUri):
                    # Could not find the track as expected - exception.
                    logger.exception(
                        "Failed to lookup image for Pandora URI '{}'.".format(
                            uri))

            result[uri] = [models.Image(uri=u) for u in image_uris]
        return result
def test_change_track_fetches_next_track_if_unplayable(provider, playlist_item_mock, caplog):
    with mock.patch.object(PandoraLibraryProvider, 'lookup_pandora_track', return_value=None):
        track = PandoraUri.factory(playlist_item_mock)

        provider._trigger_track_unplayable = mock.PropertyMock()

        assert provider.change_track(track) is False
        assert provider._trigger_track_unplayable.called

        assert 'Error changing Pandora track' in caplog.text
Example #47
0
def test_get_images_for_ad_with_images(config, ad_item_mock):
    backend = conftest.get_backend(config)

    ad_uri = PandoraUri.factory('pandora:ad:{}:{}'.format(
        conftest.MOCK_STATION_ID, conftest.MOCK_TRACK_AD_TOKEN))
    backend.library.pandora_track_cache[ad_uri.uri] = TrackCacheItem(
        mock.Mock(spec=models.Ref.track), ad_item_mock)
    results = backend.library.get_images([ad_uri.uri])
    assert len(results[ad_uri.uri]) == 1
    assert results[ad_uri.uri][0].uri == ad_item_mock.image_url
Example #48
0
def test_genre_uri_parse():
    mock_uri = 'pandora:genre:category_mock'
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is GenreUri

    assert obj.uri_type == 'genre'
    assert obj.category_name == 'category_mock'

    assert obj.uri == mock_uri
Example #49
0
    def check_pandora(self, *args, **kwargs):
        """ Check if a pandora track is currently being played.

        :param args: all arguments will be passed to the target function.
        :param kwargs: all kwargs will be passed to the target function.
        :return: the return value of the function if it was run or 'None' otherwise.
        """
        uri = get_active_uri(self.core, *args, **kwargs)
        if uri and PandoraUri.is_pandora_uri(uri):
            return func(self, *args, **kwargs)
Example #50
0
def test_genre_uri_parse():
    mock_uri = 'pandora:genre:category_mock'
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is GenreUri

    assert obj.uri_type == 'genre'
    assert obj.category_name == 'category_mock'

    assert obj.uri == mock_uri
Example #51
0
    def check_pandora(self, *args, **kwargs):
        """ Check if a pandora track is currently being played.

        :param args: all arguments will be passed to the target function.
        :param kwargs: all kwargs will be passed to the target function.
        :return: the return value of the function if it was run or 'None' otherwise.
        """
        uri = get_active_uri(self.core, *args, **kwargs)
        if uri and PandoraUri.is_pandora_uri(uri):
            return func(self, *args, **kwargs)
Example #52
0
def test_genre_uri_parse():
    mock_uri = "pandora:genre:category_mock"
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is GenreUri

    assert obj.uri_type == "genre"
    assert obj.category_name == "category_mock"

    assert obj.uri == mock_uri
Example #53
0
def test_change_track_fetches_next_track_if_station_uri(
        provider, get_station_mock_return_value, caplog):
    station = PandoraUri.factory(get_station_mock_return_value)

    provider.backend._trigger_next_track_available = mock.PropertyMock()

    assert provider.change_track(station) is False
    assert 'Cannot play Pandora stations directly. Retrieving tracks for station with ID: {}...'.format(
        station.station_id) in caplog.text
    assert provider.backend._trigger_next_track_available.called
Example #54
0
def test_get_next_pandora_track_fetches_track(config, playlist_item_mock):
    backend = conftest.get_backend(config)

    station_mock = mock.Mock(spec=Station)
    station_mock.id = 'id_token_mock'
    backend.library.pandora_station_cache[station_mock.id] = StationCacheItem(station_mock, iter([playlist_item_mock]))

    ref = backend.library.get_next_pandora_track('id_token_mock')
    assert ref.uri == PandoraUri.factory(playlist_item_mock).uri
    assert backend.library.pandora_track_cache[ref.uri].ref == ref
    assert backend.library.pandora_track_cache[ref.uri].track == playlist_item_mock
Example #55
0
def test_genre_station_uri_parse():
    mock_uri = 'pandora:genre_station:G100:G100'
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is GenreStationUri

    assert obj.uri_type == 'genre_station'
    assert obj.station_id == 'G100'
    assert obj.token == 'G100'

    assert obj.uri == mock_uri
Example #56
0
def test_ad_uri_parse():
    mock_uri = 'pandora:ad:id_mock:ad_token_mock'
    obj = PandoraUri._from_uri(mock_uri)

    assert type(obj) is AdItemUri

    assert obj.uri_type == 'ad'
    assert obj.station_id == 'id_mock'
    assert obj.ad_token == 'ad_token_mock'

    assert obj.uri == mock_uri
Example #57
0
def test_track_uri_parse(playlist_item_mock):
    track_uri = TrackUri._from_track(playlist_item_mock)

    obj = PandoraUri._from_uri(track_uri.uri)

    assert type(obj) is PlaylistItemUri

    assert obj.uri_type == conftest.MOCK_TRACK_TYPE
    assert obj.station_id == conftest.MOCK_STATION_ID
    assert obj.token == conftest.MOCK_TRACK_TOKEN

    assert obj.uri == track_uri.uri
Example #58
0
def test_station_uri_parse(get_station_mock_return_value):
    station_uri = StationUri._from_station(get_station_mock_return_value)

    obj = PandoraUri._from_uri(station_uri.uri)

    assert type(obj) is StationUri

    assert obj.uri_type == conftest.MOCK_STATION_TYPE
    assert obj.station_id == conftest.MOCK_STATION_ID
    assert obj.token == conftest.MOCK_STATION_TOKEN

    assert obj.uri == station_uri.uri
Example #59
0
    def browse(self, uri):
        self.backend.playback.reset_skip_limits()
        if uri == self.root_directory.uri:
            return self._browse_stations()

        if uri == self.genre_directory.uri:
            return self._browse_genre_categories()

        pandora_uri = PandoraUri.factory(uri)

        if isinstance(pandora_uri, GenreUri):
            return self._browse_genre_stations(uri)

        if isinstance(pandora_uri, StationUri):
            return self._browse_tracks(uri)
Example #60
0
def test_lookup_of_station_uri(config, get_station_list_return_value_mock, get_station_mock_return_value):
    with mock.patch.object(MopidyAPIClient, 'get_station', return_value=get_station_mock_return_value):
        with mock.patch.object(APIClient, 'get_station_list', return_value=get_station_list_return_value_mock):
            backend = conftest.get_backend(config)

            station_uri = PandoraUri.factory(get_station_mock_return_value)
            results = backend.library.lookup(station_uri.uri)
            assert len(results) == 1

            track = results[0]
            assert track.uri == station_uri.uri
            assert next(iter(track.album.images)) == conftest.MOCK_STATION_ART_URL
            assert track.name == conftest.MOCK_STATION_NAME
            assert next(iter(track.artists)).name == 'Pandora Station'
            assert track.album.name == conftest.MOCK_STATION_GENRE