Skip to content

Commit b7d083a

Browse files
committed
Add helper method to add current playing track to favorites
1 parent 187f803 commit b7d083a

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

music_assistant_client/players.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
from typing import TYPE_CHECKING
66

7-
from music_assistant_models.enums import EventType
7+
from music_assistant_models.enums import EventType, MediaType
8+
from music_assistant_models.errors import PlayerCommandFailed, PlayerUnavailableError
9+
from music_assistant_models.helpers import create_sort_name
10+
from music_assistant_models.media_items import Track
811
from music_assistant_models.player import Player
912

1013
if TYPE_CHECKING:
@@ -192,6 +195,55 @@ async def player_command_group_volume_down(self, player_id: str) -> None:
192195
"""Send VOLUME_DOWN command to given playergroup."""
193196
await self.client.send_command("players/cmd/group_volume_down", player_id=player_id)
194197

198+
async def add_currently_playing_to_favorites(self, player_id: str) -> None:
199+
"""
200+
Add the currently playing item/track on given player to the favorites.
201+
202+
This tries to resolve the currently playing media to an actual media item
203+
and add that to the favorites in the library.
204+
205+
Will raise an error if the player is not currently playing anything
206+
or if the currently playing media can not be resolved to a media item.
207+
"""
208+
if not (player := self._players.get(player_id)):
209+
raise PlayerUnavailableError(f"Player {player_id} not found")
210+
if not player.active_source:
211+
raise PlayerCommandFailed("Player has no active source")
212+
if mass_queue := self.client.player_queues.get(player.active_source):
213+
if not (current_item := mass_queue.current_item) or not current_item.media_item:
214+
raise PlayerCommandFailed("No current item to add to favorites")
215+
# if we're playing a radio station, try to resolve the currently playing track
216+
if (
217+
current_item.media_item.media_type == MediaType.RADIO
218+
and (streamdetails := mass_queue.current_item.streamdetails)
219+
and (stream_title := streamdetails.stream_title)
220+
and " - " in stream_title
221+
):
222+
search_result = await self.client.music.search(
223+
search_query=stream_title,
224+
media_types=[MediaType.TRACK],
225+
)
226+
for search_track in search_result.tracks:
227+
if not isinstance(search_track, Track):
228+
continue
229+
# check if the artist and title match
230+
# for now we only allow a strict match on the artist and title
231+
artist, title = stream_title.split(" - ", 1)
232+
if create_sort_name(artist) != create_sort_name(search_track.artist_str):
233+
continue
234+
if create_sort_name(title) != create_sort_name(search_track.name):
235+
continue
236+
# we found a match, add it to the favorites
237+
await self.client.music.add_item_to_favorites(search_track)
238+
return
239+
# any other media item, just add it to the favorites
240+
await self.client.music.add_item_to_favorites(current_item.media_item)
241+
return
242+
# handle other source active using the current_media
243+
if not (current_media := player.current_media) or not current_media.uri:
244+
raise PlayerCommandFailed("No current item to add to favorites")
245+
await self.client.music.add_item_to_favorites(current_media.uri)
246+
195247
# Other endpoints/commands
196248

197249
async def _get_players(self) -> list[Player]:

0 commit comments

Comments
 (0)