/
/
/
1"""Recommendation logic for YouSee Musik."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING
6
7from music_assistant_models.enums import MediaType
8from music_assistant_models.media_items import (
9 RecommendationFolder,
10 UniqueList,
11)
12
13from music_assistant.providers.yousee.constants import IMAGE_SIZE, PAGE_SIZE
14from music_assistant.providers.yousee.parsers import parse_album, parse_track
15
16if TYPE_CHECKING:
17 from music_assistant.providers.yousee.provider import YouSeeMusikProvider
18
19
20class YouSeeRecommendationsManager:
21 """Manages YouSee Musik recommendations."""
22
23 def __init__(self, provider: YouSeeMusikProvider):
24 """Initialize recommendation manager."""
25 self.provider = provider
26 self.api = provider.api
27 self.auth = provider.auth
28 self.logger = provider.logger
29 self.mass = provider.mass
30
31 async def get_recommendations(self) -> list[RecommendationFolder]:
32 """Get recommendations from YouSee Musik."""
33 query = """
34 query Recommendations($imageSize: Int = 512, $first: Int = 50) {
35 me {
36 recommendations {
37 albumRecommendations: recommendation(id: "discoveralbums") {
38 id
39 title
40 subtitle
41 description
42 cover(size: $imageSize)
43 ... on AlbumsRecommendation {
44 albums(first: $first) {
45 items {
46 id
47 title
48 tracksCount
49 genre
50 label
51 releaseDate
52 available
53 upc
54 type
55 share
56 cover(size: $imageSize)
57 artist {
58 id
59 title
60 cover(size: $imageSize)
61 }
62 featuredArtists {
63 items {
64 id
65 title
66 cover(size: $imageSize)
67 }
68 }
69 }
70 }
71 }
72 }
73 trackRecommendations: recommendation(id: "discovertracks") {
74 ...RecommendationTracks
75 }
76 weeklyDiscoveries: recommendation(id: "weeklyDiscoveries") {
77 ...RecommendationTracks
78 }
79 trackRecommendationsFirstMostPlayed: recommendation(
80 id: "tracksbasedonfirstmostplayedartist"
81 ) {
82 ...RecommendationTracks
83 }
84 trackRecommendationsSecondMostPlayed: recommendation(
85 id: "tracksbasedonSecondmostplayedartist"
86 ) {
87 ...RecommendationTracks
88 }
89 historyTopTracks: recommendation(
90 id: "toptracks"
91 ) {
92 ...RecommendationTracks
93 }
94 historyRecentTracks: recommendation(
95 id: "recenttracks"
96 ) {
97 ...RecommendationTracks
98 }
99 yourmix1: recommendation(
100 id: "yourmix"
101 ) {
102 ...RecommendationTracks
103 }
104 yourmix2: recommendation(
105 id: "yourmix2"
106 ) {
107 ...RecommendationTracks
108 }
109 yourmix3: recommendation(
110 id: "yourmix3"
111 ) {
112 ...RecommendationTracks
113 }
114 }
115 }
116 }
117 fragment RecommendationTracks on Recommendation {
118 id
119 title
120 subtitle
121 description
122 cover(size: $imageSize)
123 ... on TracksRecommendation {
124 tracks(first: $first) {
125 items {
126 id
127 title
128 cover(size: $imageSize)
129 isrc
130 duration
131 label
132 artist {
133 id
134 title
135 cover(size: $imageSize)
136 }
137 featuredArtists {
138 items {
139 id
140 title
141 cover(size: $imageSize)
142 }
143 }
144 share
145 genre
146 }
147 }
148 }
149 }
150 """
151
152 variables = {
153 "imageSize": IMAGE_SIZE,
154 "first": PAGE_SIZE,
155 }
156
157 result = await self.api.post_graphql(query, variables)
158
159 if not result or not result.get("data", {}).get("me", {}).get("recommendations"):
160 return []
161
162 recommendations: list[RecommendationFolder] = []
163
164 album_keys = ["albumRecommendations"]
165 track_keys = [
166 "trackRecommendations",
167 "weeklyDiscoveries",
168 "trackRecommendationsFirstMostPlayed",
169 "trackRecommendationsSecondMostPlayed",
170 "historyTopTracks",
171 "historyRecentTracks",
172 "yourmix1",
173 "yourmix2",
174 "yourmix3",
175 ]
176
177 for key in album_keys:
178 rec_data = result["data"]["me"]["recommendations"].get(key)
179 if rec_data:
180 folder = RecommendationFolder(
181 name=rec_data.get("title"),
182 subtitle=rec_data.get("subtitle"),
183 provider=self.provider.instance_id,
184 item_id=rec_data["id"],
185 media_type=MediaType.ALBUM,
186 items=UniqueList(
187 [
188 await parse_album(self.provider, item)
189 for item in rec_data.get("albums", {}).get("items", [])
190 ]
191 ),
192 )
193 recommendations.append(folder)
194 for key in track_keys:
195 rec_data = result["data"]["me"]["recommendations"].get(key)
196 if rec_data:
197 folder = RecommendationFolder(
198 name=rec_data.get("title"),
199 subtitle=rec_data.get("subtitle"),
200 provider=self.provider.instance_id,
201 item_id=rec_data["id"],
202 media_type=MediaType.TRACK,
203 items=UniqueList(
204 [
205 await parse_track(self.provider, item)
206 for item in rec_data.get("tracks", {}).get("items", [])
207 ]
208 ),
209 )
210 recommendations.append(folder)
211
212 return recommendations
213