From 4c98d7e8282533e92ca597d2f03cca6be72c49f8 Mon Sep 17 00:00:00 2001 From: Todd Lucas Date: Fri, 1 Mar 2024 17:36:44 -0600 Subject: [PATCH] [ 1.0.4 ] [ 1.0.4 ] * Added service `search_albums` to search the Spotify catalog for matching album criteria. * Added service `search_artists` to search the Spotify catalog for matching artist criteria. * Added service `search_audiobooks` to search the Spotify catalog for matching audiobook criteria. * Added service `search_episodes` to search the Spotify catalog for matching episode criteria. * Added service `search_shows` to search the Spotify catalog for matching show (aka podcast) criteria. * Added service `search_tracks` to search the Spotify catalog for matching track criteria. * Updated underlying `spotifywebapiPython` package requirement to version 1.0.32. --- .github/workflows/validate.yml | 4 +- CHANGELOG.md | 10 + custom_components/spotifyplus/__init__.py | 221 ++++++- custom_components/spotifyplus/manifest.json | 4 +- custom_components/spotifyplus/media_player.py | 594 +++++++++++++++++- custom_components/spotifyplus/services.yaml | 381 ++++++++++- custom_components/spotifyplus/strings.json | 158 ++++- .../spotifyplus/translations/en.json | 158 ++++- requirements.txt | 2 +- 9 files changed, 1501 insertions(+), 31 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 59614e8..a35c6cb 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -23,8 +23,8 @@ jobs: uses: "hacs/action@main" with: category: "integration" - # Remove this 'ignore' key when you have added brand images for your integration to https://github.com/home-assistant/brands - #ignore: "brands" + # Comment the following 'ignore' key when you have added brand images for your integration to https://github.com/home-assistant/brands + ignore: "brands" validate-hassfest: name: "HASSFest Validation" diff --git a/CHANGELOG.md b/CHANGELOG.md index e0d3e02..1217e8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ Change are listed in reverse chronological order (newest to oldest). +###### [ 1.0.4 ] - 2024/03/01 + + * Added service `search_albums` to search the Spotify catalog for matching album criteria. + * Added service `search_artists` to search the Spotify catalog for matching artist criteria. + * Added service `search_audiobooks` to search the Spotify catalog for matching audiobook criteria. + * Added service `search_episodes` to search the Spotify catalog for matching episode criteria. + * Added service `search_shows` to search the Spotify catalog for matching show (aka podcast) criteria. + * Added service `search_tracks` to search the Spotify catalog for matching track criteria. + * Updated underlying `spotifywebapiPython` package requirement to version 1.0.32. + ###### [ 1.0.3 ] - 2024/02/28 * Updated service `get_show_episodes` to include the `limit_total` argument. diff --git a/custom_components/spotifyplus/__init__.py b/custom_components/spotifyplus/__init__.py index f3528c6..59f8559 100644 --- a/custom_components/spotifyplus/__init__.py +++ b/custom_components/spotifyplus/__init__.py @@ -98,7 +98,13 @@ SERVICE_SPOTIFY_GET_TRACK_FAVORITES:str = 'get_track_favorites' SERVICE_SPOTIFY_GET_USERS_TOP_ARTISTS:str = 'get_users_top_artists' SERVICE_SPOTIFY_GET_USERS_TOP_TRACKS:str = 'get_users_top_tracks' +SERVICE_SPOTIFY_SEARCH_ALBUMS:str = 'search_albums' +SERVICE_SPOTIFY_SEARCH_ARTISTS:str = 'search_artists' +SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS:str = 'search_audiobooks' +SERVICE_SPOTIFY_SEARCH_EPISODES:str = 'search_episodes' SERVICE_SPOTIFY_SEARCH_PLAYLISTS:str = 'search_playlists' +SERVICE_SPOTIFY_SEARCH_SHOWS:str = 'search_shows' +SERVICE_SPOTIFY_SEARCH_TRACKS:str = 'search_tracks' SERVICE_SPOTIFY_GET_ALBUM_SCHEMA = vol.Schema( @@ -289,6 +295,54 @@ } ) +SERVICE_SPOTIFY_SEARCH_ALBUMS_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), + } +) + +SERVICE_SPOTIFY_SEARCH_ARTISTS_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), + } +) + +SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), + } +) + +SERVICE_SPOTIFY_SEARCH_EPISODES_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), + } +) + SERVICE_SPOTIFY_SEARCH_PLAYLISTS_SCHEMA = vol.Schema( { vol.Required("entity_id"): cv.entity_id, @@ -298,7 +352,30 @@ vol.Optional("market"): cv.string, vol.Optional("include_external"): cv.string, vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), - vol.Optional("spotify_owned_only"): cv.boolean, + } +) + +SERVICE_SPOTIFY_SEARCH_SHOWS_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), + } +) + +SERVICE_SPOTIFY_SEARCH_TRACKS_SCHEMA = vol.Schema( + { + vol.Required("entity_id"): cv.entity_id, + vol.Required("criteria"): cv.string, + vol.Optional("limit", default=50): vol.All(vol.Range(min=1,max=50)), + vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)), + vol.Optional("market"): cv.string, + vol.Optional("include_external"): cv.string, + vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)), } ) @@ -570,6 +647,54 @@ async def service_handle_spotify_serviceresponse(service: ServiceCall) -> Servic _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) response = await hass.async_add_executor_job(entity.service_spotify_get_users_top_tracks, time_range, limit, offset, limit_total) + elif service.service == SERVICE_SPOTIFY_SEARCH_ALBUMS: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_albums, criteria, limit, offset, market, include_external, limit_total) + + elif service.service == SERVICE_SPOTIFY_SEARCH_ARTISTS: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_artists, criteria, limit, offset, market, include_external, limit_total) + + elif service.service == SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_audiobooks, criteria, limit, offset, market, include_external, limit_total) + + elif service.service == SERVICE_SPOTIFY_SEARCH_EPISODES: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_episodes, criteria, limit, offset, market, include_external, limit_total) + elif service.service == SERVICE_SPOTIFY_SEARCH_PLAYLISTS: # search Spotify for specified criteria. @@ -579,18 +704,47 @@ async def service_handle_spotify_serviceresponse(service: ServiceCall) -> Servic market = service.data.get("market") include_external = service.data.get("include_external") limit_total = service.data.get("limit_total") - spotify_owned_only = service.data.get("spotify_owned_only") _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) - response = await hass.async_add_executor_job(entity.service_spotify_search_playlists, criteria, limit, offset, market, include_external, limit_total, spotify_owned_only) + response = await hass.async_add_executor_job(entity.service_spotify_search_playlists, criteria, limit, offset, market, include_external, limit_total) + + elif service.service == SERVICE_SPOTIFY_SEARCH_SHOWS: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_shows, criteria, limit, offset, market, include_external, limit_total) + + elif service.service == SERVICE_SPOTIFY_SEARCH_TRACKS: + + # search Spotify for specified criteria. + criteria = service.data.get("criteria") + limit = service.data.get("limit") + offset = service.data.get("offset") + market = service.data.get("market") + include_external = service.data.get("include_external") + limit_total = service.data.get("limit_total") + _logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name)) + response = await hass.async_add_executor_job(entity.service_spotify_search_tracks, criteria, limit, offset, market, include_external, limit_total) else: - raise ValueError("Unrecognized service identifier '%s' in method service_handle_spotify_serviceresponse" % service.service) + + raise HomeAssistantError("Unrecognized service identifier '%s' in method service_handle_spotify_serviceresponse" % service.service) # return the response. _logsi.LogDictionary(SILevel.Verbose, "Service Response data: '%s'" % (service.service), response, prettyPrint=True) return response - except HomeAssistantError: raise # pass handled exception on through. + except HomeAssistantError as ex: + + # log error, but not to system logger as HA will take care of it. + _logsi.LogError(str(ex), logToSystemLogger=False) + raise + except Exception as ex: # log exception, but not to system logger as HA will take care of it. @@ -642,8 +796,7 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id: # did we resolve it? if not, then log a message. if player is None: - _logsi.LogError("Entity id value of '%s' could not be resolved to a MediaPlayerEntity instance for the '%s' method call" % (str(entity_id), service.service)) - return None + raise HomeAssistantError("Entity id value of '%s' could not be resolved to a MediaPlayerEntity instance for the '%s' method call" % (str(entity_id), service.service)) # return the MediaPlayerEntity instance. _logsi.LogVerbose("Entity id value of '%s' was resolved to MediaPlayerEntity instance for the '%s' method call" % (str(entity_id), service.service)) @@ -831,6 +984,42 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id: supports_response=SupportsResponse.ONLY, ) + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_ALBUMS, SERVICE_SPOTIFY_SEARCH_ALBUMS_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_ALBUMS, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_ALBUMS_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_ARTISTS, SERVICE_SPOTIFY_SEARCH_ARTISTS_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_ARTISTS, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_ARTISTS_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS, SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_AUDIOBOOKS_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_EPISODES, SERVICE_SPOTIFY_SEARCH_EPISODES_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_EPISODES, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_EPISODES_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_PLAYLISTS, SERVICE_SPOTIFY_SEARCH_PLAYLISTS_SCHEMA) hass.services.async_register( DOMAIN, @@ -840,6 +1029,24 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id: supports_response=SupportsResponse.ONLY, ) + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_SHOWS, SERVICE_SPOTIFY_SEARCH_SHOWS_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_SHOWS, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_SHOWS_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + + _logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_SEARCH_TRACKS, SERVICE_SPOTIFY_SEARCH_TRACKS_SCHEMA) + hass.services.async_register( + DOMAIN, + SERVICE_SPOTIFY_SEARCH_TRACKS, + service_handle_spotify_serviceresponse, + schema=SERVICE_SPOTIFY_SEARCH_TRACKS_SCHEMA, + supports_response=SupportsResponse.ONLY, + ) + # indicate success. _logsi.LogVerbose("Component async_setup complete") return True diff --git a/custom_components/spotifyplus/manifest.json b/custom_components/spotifyplus/manifest.json index 8e1cb3b..97a81c5 100644 --- a/custom_components/spotifyplus/manifest.json +++ b/custom_components/spotifyplus/manifest.json @@ -10,9 +10,9 @@ "issue_tracker": "https://github.com/thlucas1/homeassistantcomponent_spotifyplus/issues", "requirements": [ "smartinspectPython==3.0.33", - "spotifywebapiPython==1.0.31", + "spotifywebapiPython==1.0.32", "urllib3>=1.21.1,<1.27" ], - "version": "1.0.3", + "version": "1.0.4", "zeroconf": [ "_spotify-connect._tcp.local." ] } diff --git a/custom_components/spotifyplus/media_player.py b/custom_components/spotifyplus/media_player.py index 3cb1e7e..b80d046 100644 --- a/custom_components/spotifyplus/media_player.py +++ b/custom_components/spotifyplus/media_player.py @@ -2103,6 +2103,390 @@ def service_spotify_get_users_top_tracks(self, _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + def service_spotify_search_albums(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about albums that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: An `AlbumPageSimplified` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_albums' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Albums Service", apiMethodParms) + + # get Spotify catalog information about Albums that match a keyword string. + _logsi.LogVerbose("Searching Spotify Albums for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchAlbums(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Albums.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + + def service_spotify_search_artists(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about artists that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: An `ArtistPage` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_artists' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Artists Service", apiMethodParms) + + # get Spotify catalog information about Artists that match a keyword string. + _logsi.LogVerbose("Searching Spotify Artists for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchArtists(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Artists.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + + def service_spotify_search_audiobooks(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about audiobooks that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: An `AudiobookPageSimplified` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_audiobooks' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Audiobooks Service", apiMethodParms) + + # get Spotify catalog information about Audiobooks that match a keyword string. + _logsi.LogVerbose("Searching Spotify Audiobooks for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchAudiobooks(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Audiobooks.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + + def service_spotify_search_episodes(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about episodes that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: An `EpisodePageSimplified` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_episodes' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Episodes Service", apiMethodParms) + + # get Spotify catalog information about Episodes that match a keyword string. + _logsi.LogVerbose("Searching Spotify Episodes for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchEpisodes(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Episodes.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + def service_spotify_search_playlists(self, criteria:str, limit:int, @@ -2110,12 +2494,9 @@ def service_spotify_search_playlists(self, market:str, includeExternal:str, limitTotal:int, - spotifyOwnedOnly:bool ) -> dict: """ - Get Spotify catalog information about albums, artists, playlists, tracks, shows, episodes - or audiobooks that match a keyword string. Audiobooks are only available within the US, UK, - Canada, Ireland, New Zealand and Australia markets. + Get Spotify catalog information about playlists that match a keyword string. Args: criteria (str): @@ -2157,10 +2538,6 @@ def service_spotify_search_playlists(self, and paging is automatically used to retrieve all available items up to the maximum number specified. Default: None (disabled) - spotifyOwnedOnly (bool): - True to return only found items that are owned by spotify (e.g. content generated for you by the spotify AI engine); - otherwise, False to return all found items. - Default is False. Returns: A dictionary that contains the following keys: @@ -2181,16 +2558,11 @@ def service_spotify_search_playlists(self, apiMethodParms.AppendKeyValue("market", market) apiMethodParms.AppendKeyValue("includeExternal", includeExternal) apiMethodParms.AppendKeyValue("limitTotal", limitTotal) - apiMethodParms.AppendKeyValue("spotifyOwnedOnly", spotifyOwnedOnly) - _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Service", apiMethodParms) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Playlists Service", apiMethodParms) # get Spotify catalog information about Playlists that match a keyword string. _logsi.LogVerbose("Searching Spotify Playlists for criteria") - searchResponse:SearchResponse = self.data.spotifyClient.SearchPlaylists(criteria, limit, offset, market, includeExternal, limitTotal, spotifyOwnedOnly) - - # # sort items on Name property, ascending order. - # if len(searchResponse.Playlists.Items) > 0: - # searchResponse.Playlists.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False) + searchResponse:SearchResponse = self.data.spotifyClient.SearchPlaylists(criteria, limit, offset, market, includeExternal, limitTotal) # return the (partial) user profile that retrieved the result, as well as the result itself. return { @@ -2211,6 +2583,198 @@ def service_spotify_search_playlists(self, _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + def service_spotify_search_shows(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about shows (aka. podcasts) that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: An `ShowPageSimplified` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_shows' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Shows Service", apiMethodParms) + + # get Spotify catalog information about Episodes that match a keyword string. + _logsi.LogVerbose("Searching Spotify Shows for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchShows(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Shows.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + + def service_spotify_search_tracks(self, + criteria:str, + limit:int, + offset:int, + market:str, + includeExternal:str, + limitTotal:int, + ) -> dict: + """ + Get Spotify catalog information about tracks that match a keyword string. + + Args: + criteria (str): + Your search query. + You can narrow down your search using field filters. + The available filters are album, artist, track, year, upc, tag:hipster, tag:new, + isrc, and genre. Each field filter only applies to certain result types. + The artist and year filters can be used while searching albums, artists and tracks. + You can filter on a single year or a range (e.g. 1955-1960). + The album filter can be used while searching albums and tracks. + The genre filter can be used while searching artists and tracks. + The isrc and track filters can be used while searching tracks. + The upc, tag:new and tag:hipster filters can only be used while searching albums. + The tag:new filter will return albums released in the past two weeks and tag:hipster + can be used to return only albums with the lowest 10% popularity. + limit (int): + The maximum number of items to return in a page of items. + Default: 20, Range: 1 to 50. + offset (int): + The page index offset of the first item to return. + Use with limit to get the next set of items. + Default: 0 (the first item). Range: 0 to 1000. + market (str): + An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that + is available in that market will be returned. If a valid user access token is specified + in the request header, the country associated with the user account will take priority over + this parameter. + Note: If neither market or user country are provided, the content is considered unavailable for the client. + Users can view the country that is associated with their account in the account settings. + Example: `ES` + includeExternal (str): + If "audio" is specified it signals that the client can play externally hosted audio content, and + marks the content as playable in the response. By default externally hosted audio content is marked + as unplayable in the response. + Allowed values: "audio" + limitTotal (int): + The maximum number of items to return for the request. + If specified, this argument overrides the limit and offset argument values + and paging is automatically used to retrieve all available items up to the + maximum number specified. + Default: None (disabled) + + Returns: + A dictionary that contains the following keys: + - user_profile: A (partial) user profile that retrieved the result. + - result: A `TrackPage` object of matching results. + """ + apiMethodName:str = 'service_spotify_search_tracks' + apiMethodParms:SIMethodParmListContext = None + result:SearchResponse = None + + try: + + # trace. + apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName) + apiMethodParms.AppendKeyValue("criteria", criteria) + apiMethodParms.AppendKeyValue("limit", limit) + apiMethodParms.AppendKeyValue("offset", offset) + apiMethodParms.AppendKeyValue("market", market) + apiMethodParms.AppendKeyValue("includeExternal", includeExternal) + apiMethodParms.AppendKeyValue("limitTotal", limitTotal) + _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Search Tracks Service", apiMethodParms) + + # get Spotify catalog information about Playlists that match a keyword string. + _logsi.LogVerbose("Searching Spotify Tracks for criteria") + searchResponse:SearchResponse = self.data.spotifyClient.SearchTracks(criteria, limit, offset, market, includeExternal, limitTotal) + + # return the (partial) user profile that retrieved the result, as well as the result itself. + return { + "user_profile": self._GetUserProfilePartialDictionary(self.data.spotifyClient.UserProfile), + "result": searchResponse.Tracks.ToDictionary() + } + + # the following exceptions have already been logged, so we just need to + # pass them back to HA for display in the log (or service UI). + except SpotifyApiError as ex: + raise HomeAssistantError(ex.Message) + except SpotifyWebApiError as ex: + raise HomeAssistantError(ex.Message) + + finally: + + # trace. + _logsi.LeaveMethod(SILevel.Debug, apiMethodName) + + def _GetUserProfilePartialDictionary(self, userProfile:UserProfile) -> dict: """ Returns a dictionary of a partial UserProfile object that can be returned with diff --git a/custom_components/spotifyplus/services.yaml b/custom_components/spotifyplus/services.yaml index c8aeb9c..50c5071 100644 --- a/custom_components/spotifyplus/services.yaml +++ b/custom_components/spotifyplus/services.yaml @@ -847,6 +847,258 @@ get_users_top_tracks: number: mode: box +search_albums: + name: Search Albums + description: Get Spotify catalog information about Albums that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "Welcome to the New" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box + +search_artists: + name: Search Artists + description: Get Spotify catalog information about Artists that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "MercyMe" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box + +search_audiobooks: + name: Search Audiobooks + description: Get Spotify catalog information about Audiobooks that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "The Elfstones of Shannara" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box + +search_episodes: + name: Search Episodes + description: Get Spotify catalog information about Episodes that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "Armchair Anonymous" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box + search_playlists: name: Search Playlists description: Get Spotify catalog information about Playlists that match a keyword string. @@ -862,7 +1114,7 @@ search_playlists: domain: media_player criteria: name: Search Criteria - description: The criteria to search for (e.g. "Daily Mix"). + description: The criteria to search for. example: "Daily Mix" required: true selector: @@ -916,4 +1168,129 @@ search_playlists: required: false selector: boolean: - \ No newline at end of file + +search_shows: + name: Search Shows (aka Podcasts) + description: Get Spotify catalog information about Show (aka Podcasts) that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "Dax Shepard" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box + +search_tracks: + name: Search Tracks + description: Get Spotify catalog information about Tracks that match a keyword string. + fields: + entity_id: + name: Entity ID + description: Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. + example: "media_player.spotifyplus_username" + required: true + selector: + entity: + integration: spotifyplus + domain: media_player + criteria: + name: Search Criteria + description: The criteria to search for. + example: "Dear Younger Me" + required: true + selector: + text: + limit: + name: Limit + description: The maximum number of items to return. + example: 20 + required: false + selector: + number: + min: 1 + max: 50 + step: 1 + mode: slider + offset: + name: Offset + description: The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). + example: 20 + required: false + selector: + number: + min: 1 + max: 500 + market: + name: Market / Country Code + description: An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. + example: "ES" + required: false + selector: + text: + include_external: + name: Include External + description: If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. + example: "audio" + required: false + selector: + text: + limit_total: + name: Limit Total + description: The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. + example: 20 + required: false + selector: + number: + mode: box diff --git a/custom_components/spotifyplus/strings.json b/custom_components/spotifyplus/strings.json index d80de1c..9289306 100644 --- a/custom_components/spotifyplus/strings.json +++ b/custom_components/spotifyplus/strings.json @@ -501,6 +501,110 @@ } } }, + "search_albums": { + "name": "Search Albums", + "description": "Get Spotify catalog information about Albums that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_artists": { + "name": "Search Artists", + "description": "Get Spotify catalog information about Artists that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_ausiobooks": { + "name": "Search Audiobooks", + "description": "Get Spotify catalog information about Audiobooks that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_episodes": { + "name": "Search Episodes", + "description": "Get Spotify catalog information about Episodes that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, "search_playlists": { "name": "Search Playlists", "description": "Get Spotify catalog information about Playlists that match a keyword string.", @@ -511,7 +615,7 @@ }, "criteria": { "name": "Search Criteria", - "description": "The criteria to search for (e.g. \"Daily Mix\")." + "description": "The criteria to search for." }, "limit": { "name": "Limit", @@ -530,6 +634,58 @@ "description": "True to return only found items that are owned by spotify (e.g. content generated for you by the spotify AI engine); otherwise, False to return all found items. Default is False." } } + }, + "search_shows": { + "name": "Search Shows", + "description": "Get Spotify catalog information about Shows that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_tracks": { + "name": "Search Tracks", + "description": "Get Spotify catalog information about Tracks that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } } } } diff --git a/custom_components/spotifyplus/translations/en.json b/custom_components/spotifyplus/translations/en.json index d80de1c..9289306 100644 --- a/custom_components/spotifyplus/translations/en.json +++ b/custom_components/spotifyplus/translations/en.json @@ -501,6 +501,110 @@ } } }, + "search_albums": { + "name": "Search Albums", + "description": "Get Spotify catalog information about Albums that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_artists": { + "name": "Search Artists", + "description": "Get Spotify catalog information about Artists that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_ausiobooks": { + "name": "Search Audiobooks", + "description": "Get Spotify catalog information about Audiobooks that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_episodes": { + "name": "Search Episodes", + "description": "Get Spotify catalog information about Episodes that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, "search_playlists": { "name": "Search Playlists", "description": "Get Spotify catalog information about Playlists that match a keyword string.", @@ -511,7 +615,7 @@ }, "criteria": { "name": "Search Criteria", - "description": "The criteria to search for (e.g. \"Daily Mix\")." + "description": "The criteria to search for." }, "limit": { "name": "Limit", @@ -530,6 +634,58 @@ "description": "True to return only found items that are owned by spotify (e.g. content generated for you by the spotify AI engine); otherwise, False to return all found items. Default is False." } } + }, + "search_shows": { + "name": "Search Shows", + "description": "Get Spotify catalog information about Shows that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } + }, + "search_tracks": { + "name": "Search Tracks", + "description": "Get Spotify catalog information about Tracks that match a keyword string.", + "fields": { + "entity_id": { + "name": "Entity ID", + "description": "Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API." + }, + "criteria": { + "name": "Search Criteria", + "description": "The criteria to search for." + }, + "limit": { + "name": "Limit", + "description": "The maximum number of items to return in a page of items. Default is 20, Range is 1 to 50." + }, + "market": { + "name": "Market / Country Code", + "description": "An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter." + }, + "limit_total": { + "name": "Limit Total", + "description": "The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total." + } + } } } } diff --git a/requirements.txt b/requirements.txt index 9182a5c..6b4e3c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ colorlog==6.7.0 homeassistant==2023.10.5 ruff==0.1.3 smartinspectPython>=3.0.33 -spotifywebapiPython==1.0.31 +spotifywebapiPython==1.0.32