Skip to content

Commit

Permalink
[ 1.0.57 ] * Added service get_audiobook_favorites to get a list of…
Browse files Browse the repository at this point in the history
… the audiobooks saved in the current Spotify user's 'Your Library'.

  * Added service `get_episode_favorites` to get a list of the episodes saved in the current Spotify user's 'Your Library'.
  * Updated underlying `spotifywebapiPython` package requirement to version 1.0.97.
  • Loading branch information
thlucas1 committed Sep 20, 2024
1 parent 055e0f6 commit 8785192
Show file tree
Hide file tree
Showing 8 changed files with 432 additions and 22 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Change are listed in reverse chronological order (newest to oldest).

<span class="changelog">

###### [ 1.0.57 ] - 2024/09/20

* Added service `get_audiobook_favorites` to get a list of the audiobooks saved in the current Spotify user's 'Your Library'.
* Added service `get_episode_favorites` to get a list of the episodes saved in the current Spotify user's 'Your Library'.
* Updated underlying `spotifywebapiPython` package requirement to version 1.0.97.

###### [ 1.0.56 ] - 2024/09/19

* Updated underlying `spotifywebapiPython` package requirement to version 1.0.96.
Expand Down
60 changes: 60 additions & 0 deletions custom_components/spotifyplus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@
SERVICE_SPOTIFY_GET_ARTIST:str = 'get_artist'
SERVICE_SPOTIFY_GET_ARTIST_ALBUMS:str = 'get_artist_albums'
SERVICE_SPOTIFY_GET_ARTISTS_FOLLOWED:str = 'get_artists_followed'
SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES:str = 'get_audiobook_favorites'
SERVICE_SPOTIFY_GET_BROWSE_CATEGORYS_LIST:str = 'get_browse_categorys_list'
SERVICE_SPOTIFY_GET_CATEGORY_PLAYLISTS:str = 'get_category_playlists'
SERVICE_SPOTIFY_GET_EPISODE_FAVORITES:str = 'get_episode_favorites'
SERVICE_SPOTIFY_GET_FEATURED_PLAYLISTS:str = 'get_featured_playlists'
SERVICE_SPOTIFY_GET_PLAYER_DEVICES:str = 'get_player_devices'
SERVICE_SPOTIFY_GET_PLAYER_NOW_PLAYING:str = 'get_player_now_playing'
Expand Down Expand Up @@ -285,6 +287,16 @@
}
)

SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
vol.Optional("limit", default=50): vol.All(vol.Range(min=0,max=50)),
vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)),
vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)),
vol.Optional("sort_result"): cv.boolean,
}
)

SERVICE_SPOTIFY_GET_BROWSE_CATEGORYS_LIST_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
Expand All @@ -306,6 +318,16 @@
}
)

SERVICE_SPOTIFY_GET_EPISODE_FAVORITES_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
vol.Optional("limit", default=50): vol.All(vol.Range(min=0,max=50)),
vol.Optional("offset", default=0): vol.All(vol.Range(min=0,max=500)),
vol.Optional("limit_total", default=0): vol.All(vol.Range(min=0,max=9999)),
vol.Optional("sort_result"): cv.boolean,
}
)

SERVICE_SPOTIFY_GET_FEATURED_PLAYLISTS_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
Expand Down Expand Up @@ -1303,6 +1325,16 @@ 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_artists_followed, after, limit, limit_total, sort_result)

elif service.service == SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES:

# get spotify audiobook favorites.
limit = service.data.get("limit")
offset = service.data.get("offset")
limit_total = service.data.get("limit_total")
sort_result = service.data.get("sort_result")
_logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name))
response = await hass.async_add_executor_job(entity.service_spotify_get_audiobook_favorites, limit, offset, limit_total, sort_result)

elif service.service == SERVICE_SPOTIFY_GET_BROWSE_CATEGORYS_LIST:

# get spotify browse categorys.
Expand All @@ -1324,6 +1356,16 @@ 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_category_playlists, category_id, limit, offset, country, limit_total, sort_result)

elif service.service == SERVICE_SPOTIFY_GET_EPISODE_FAVORITES:

# get spotify episode (podcast) favorites.
limit = service.data.get("limit")
offset = service.data.get("offset")
limit_total = service.data.get("limit_total")
sort_result = service.data.get("sort_result")
_logsi.LogVerbose(STAppMessages.MSG_SERVICE_EXECUTE % (service.service, entity.name))
response = await hass.async_add_executor_job(entity.service_spotify_get_episode_favorites, limit, offset, limit_total, sort_result)

elif service.service == SERVICE_SPOTIFY_GET_FEATURED_PLAYLISTS:

# get spotify featured playlists.
Expand Down Expand Up @@ -1853,6 +1895,15 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id:
supports_response=SupportsResponse.ONLY,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES, SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES_SCHEMA)
hass.services.async_register(
DOMAIN,
SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES,
service_handle_spotify_serviceresponse,
schema=SERVICE_SPOTIFY_GET_AUDIOBOOK_FAVORITES_SCHEMA,
supports_response=SupportsResponse.ONLY,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_GET_BROWSE_CATEGORYS_LIST, SERVICE_SPOTIFY_GET_BROWSE_CATEGORYS_LIST_SCHEMA)
hass.services.async_register(
DOMAIN,
Expand All @@ -1871,6 +1922,15 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id:
supports_response=SupportsResponse.ONLY,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_GET_EPISODE_FAVORITES, SERVICE_SPOTIFY_GET_EPISODE_FAVORITES_SCHEMA)
hass.services.async_register(
DOMAIN,
SERVICE_SPOTIFY_GET_EPISODE_FAVORITES,
service_handle_spotify_serviceresponse,
schema=SERVICE_SPOTIFY_GET_EPISODE_FAVORITES_SCHEMA,
supports_response=SupportsResponse.ONLY,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_SPOTIFY_GET_FEATURED_PLAYLISTS, SERVICE_SPOTIFY_GET_FEATURED_PLAYLISTS_SCHEMA)
hass.services.async_register(
DOMAIN,
Expand Down
4 changes: 2 additions & 2 deletions custom_components/spotifyplus/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"requests>=2.31.0",
"requests_oauthlib>=1.3.1",
"smartinspectPython>=3.0.33",
"spotifywebapiPython>=1.0.96",
"spotifywebapiPython>=1.0.97",
"urllib3>=1.21.1,<1.27",
"zeroconf>=0.132.2"
],
"version": "1.0.56",
"version": "1.0.57",
"zeroconf": [ "_spotify-connect._tcp.local." ]
}
144 changes: 143 additions & 1 deletion custom_components/spotifyplus/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
AlbumSimplified,
Artist,
ArtistPage,
AudiobookPageSimplified,
AudioFeatures,
Category,
CategoryPage,
Context,
Device as PlayerDevice,
Episode,
EpisodePageSaved,
EpisodePageSimplified,
ImageObject,
PlayerPlayState,
Expand Down Expand Up @@ -2560,6 +2562,76 @@ def service_spotify_get_artists_followed(
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)


def service_spotify_get_audiobook_favorites(
self,
limit:int,
offset:int,
limitTotal:int=None,
sortResult:bool=True,
) -> dict:
"""
Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.
Args:
limit (int):
The maximum number of items to return in a page of items.
Default: 20, Range: 1 to 50.
offset (int):
The index of the first item to return.
Use with limit to get the next set of items.
Default: 0 (the first item).
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 count specified.
Default: None (disabled)
sortResult (bool):
True to sort the items by name; otherwise, False to leave the items in the same order they
were returned in by the Spotify Web API.
Default: True
Returns:
A dictionary that contains the following keys:
- user_profile: A (partial) user profile that retrieved the result.
- result: A `AudiobookPageSimplified` object that contains saved audiobook information.
"""
apiMethodName:str = 'service_spotify_get_audiobook_favorites'
apiMethodParms:SIMethodParmListContext = None

try:

# trace.
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
apiMethodParms.AppendKeyValue("limit", limit)
apiMethodParms.AppendKeyValue("offset", offset)
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
apiMethodParms.AppendKeyValue("sortResult", sortResult)
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Get Audiobook Favorites Service", apiMethodParms)

# request information from Spotify Web API.
_logsi.LogVerbose(STAppMessages.MSG_SERVICE_QUERY_WEB_API)
result:AudiobookPageSimplified = self.data.spotifyClient.GetAudiobookFavorites(limit, offset, limitTotal, sortResult)

# 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": result.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_get_browse_categorys_list(self,
country:str=None,
locale:str=None,
Expand Down Expand Up @@ -2724,6 +2796,76 @@ def service_spotify_get_category_playlists(
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)


def service_spotify_get_episode_favorites(
self,
limit:int,
offset:int,
limitTotal:int=None,
sortResult:bool=True,
) -> dict:
"""
Get a list of the episodes saved in the current Spotify user's 'Your Library'.
Args:
limit (int):
The maximum number of items to return in a page of items.
Default: 20, Range: 1 to 50.
offset (int):
The index of the first item to return.
Use with limit to get the next set of items.
Default: 0 (the first item).
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 count specified.
Default: None (disabled)
sortResult (bool):
True to sort the items by name; otherwise, False to leave the items in the same order they
were returned in by the Spotify Web API.
Default: True
Returns:
A dictionary that contains the following keys:
- user_profile: A (partial) user profile that retrieved the result.
- result: A `EpisodePageSaved` object that contains saved audiobook information.
"""
apiMethodName:str = 'service_spotify_get_episode_favorites'
apiMethodParms:SIMethodParmListContext = None

try:

# trace.
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
apiMethodParms.AppendKeyValue("limit", limit)
apiMethodParms.AppendKeyValue("offset", offset)
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
apiMethodParms.AppendKeyValue("sortResult", sortResult)
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Get Episode Favorites Service", apiMethodParms)

# request information from Spotify Web API.
_logsi.LogVerbose(STAppMessages.MSG_SERVICE_QUERY_WEB_API)
result:EpisodePageSaved = self.data.spotifyClient.GetEpisodeFavorites(limit, offset, limitTotal, sortResult)

# 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": result.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_get_featured_playlists(
self,
limit:int=20,
Expand Down Expand Up @@ -3761,7 +3903,7 @@ def service_spotify_get_tracks_audio_features(
- user_profile: A (partial) user profile that retrieved the result.
- result: A list of `AudioFeatures` objects that contain the audio feature details.
"""
apiMethodName:str = 'service_spotify_get_track_favorites'
apiMethodName:str = 'service_spotify_get_tracks_audio_features'
apiMethodParms:SIMethodParmListContext = None
result:TrackPageSaved = TrackPageSaved()

Expand Down
Loading

0 comments on commit 8785192

Please sign in to comment.