aboutsummaryrefslogtreecommitdiff
path: root/pandora/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'pandora/client.py')
-rw-r--r--pandora/client.py215
1 files changed, 119 insertions, 96 deletions
diff --git a/pandora/client.py b/pandora/client.py
index e0d3da9..a98056c 100644
--- a/pandora/client.py
+++ b/pandora/client.py
@@ -29,8 +29,14 @@ class BaseAPIClient:
29 29
30 ALL_QUALITIES = [LOW_AUDIO_QUALITY, MED_AUDIO_QUALITY, HIGH_AUDIO_QUALITY] 30 ALL_QUALITIES = [LOW_AUDIO_QUALITY, MED_AUDIO_QUALITY, HIGH_AUDIO_QUALITY]
31 31
32 def __init__(self, transport, partner_user, partner_password, device, 32 def __init__(
33 default_audio_quality=MED_AUDIO_QUALITY): 33 self,
34 transport,
35 partner_user,
36 partner_password,
37 device,
38 default_audio_quality=MED_AUDIO_QUALITY,
39 ):
34 self.transport = transport 40 self.transport = transport
35 self.partner_user = partner_user 41 self.partner_user = partner_user
36 self.partner_password = partner_password 42 self.partner_password = partner_password
@@ -40,11 +46,13 @@ class BaseAPIClient:
40 self.password = None 46 self.password = None
41 47
42 def _partner_login(self): 48 def _partner_login(self):
43 partner = self.transport("auth.partnerLogin", 49 partner = self.transport(
44 username=self.partner_user, 50 "auth.partnerLogin",
45 password=self.partner_password, 51 username=self.partner_user,
46 deviceModel=self.device, 52 password=self.partner_password,
47 version=self.transport.API_VERSION) 53 deviceModel=self.device,
54 version=self.transport.API_VERSION,
55 )
48 56
49 self.transport.set_partner(partner) 57 self.transport.set_partner(partner)
50 58
@@ -59,16 +67,18 @@ class BaseAPIClient:
59 self._partner_login() 67 self._partner_login()
60 68
61 try: 69 try:
62 user = self.transport("auth.userLogin", 70 user = self.transport(
63 loginType="user", 71 "auth.userLogin",
64 username=self.username, 72 loginType="user",
65 password=self.password, 73 username=self.username,
66 includePandoraOneInfo=True, 74 password=self.password,
67 includeSubscriptionExpiration=True, 75 includePandoraOneInfo=True,
68 returnCapped=True, 76 includeSubscriptionExpiration=True,
69 includeAdAttributes=True, 77 returnCapped=True,
70 includeAdvertiserAttributes=True, 78 includeAdAttributes=True,
71 xplatformAdCapable=True) 79 includeAdvertiserAttributes=True,
80 xplatformAdCapable=True,
81 )
72 except errors.InvalidPartnerLogin: 82 except errors.InvalidPartnerLogin:
73 raise errors.InvalidUserLogin() 83 raise errors.InvalidUserLogin()
74 84
@@ -80,7 +90,7 @@ class BaseAPIClient:
80 def get_qualities(cls, start_at, return_all_if_invalid=True): 90 def get_qualities(cls, start_at, return_all_if_invalid=True):
81 try: 91 try:
82 idx = cls.ALL_QUALITIES.index(start_at) 92 idx = cls.ALL_QUALITIES.index(start_at)
83 return cls.ALL_QUALITIES[:idx + 1] 93 return cls.ALL_QUALITIES[: idx + 1]
84 except ValueError: 94 except ValueError:
85 if return_all_if_invalid: 95 if return_all_if_invalid:
86 return cls.ALL_QUALITIES[:] 96 return cls.ALL_QUALITIES[:]
@@ -105,9 +115,9 @@ class APIClient(BaseAPIClient):
105 def get_station_list(self): 115 def get_station_list(self):
106 from .models.station import StationList 116 from .models.station import StationList
107 117
108 return StationList.from_json(self, 118 return StationList.from_json(
109 self("user.getStationList", 119 self, self("user.getStationList", includeStationArtUrl=True)
110 includeStationArtUrl=True)) 120 )
111 121
112 def get_station_list_checksum(self): 122 def get_station_list_checksum(self):
113 return self("user.getStationListChecksum")["checksum"] 123 return self("user.getStationListChecksum")["checksum"]
@@ -119,19 +129,21 @@ class APIClient(BaseAPIClient):
119 additional_urls = [] 129 additional_urls = []
120 130
121 if isinstance(additional_urls, str): 131 if isinstance(additional_urls, str):
122 raise TypeError('Additional urls should be a list') 132 raise TypeError("Additional urls should be a list")
123 133
124 urls = [getattr(url, "value", url) for url in additional_urls] 134 urls = [getattr(url, "value", url) for url in additional_urls]
125 135
126 resp = self("station.getPlaylist", 136 resp = self(
127 stationToken=station_token, 137 "station.getPlaylist",
128 includeTrackLength=True, 138 stationToken=station_token,
129 xplatformAdCapable=True, 139 includeTrackLength=True,
130 audioAdPodCapable=True, 140 xplatformAdCapable=True,
131 additionalAudioUrl=','.join(urls)) 141 audioAdPodCapable=True,
142 additionalAudioUrl=",".join(urls),
143 )
132 144
133 for item in resp['items']: 145 for item in resp["items"]:
134 item['_paramAdditionalUrls'] = additional_urls 146 item["_paramAdditionalUrls"] = additional_urls
135 147
136 playlist = Playlist.from_json(self, resp) 148 playlist = Playlist.from_json(self, resp)
137 149
@@ -145,58 +157,69 @@ class APIClient(BaseAPIClient):
145 def get_bookmarks(self): 157 def get_bookmarks(self):
146 from .models.bookmark import BookmarkList 158 from .models.bookmark import BookmarkList
147 159
148 return BookmarkList.from_json(self, 160 return BookmarkList.from_json(self, self("user.getBookmarks"))
149 self("user.getBookmarks"))
150 161
151 def get_station(self, station_token): 162 def get_station(self, station_token):
152 from .models.station import Station 163 from .models.station import Station
153 164
154 return Station.from_json(self, 165 return Station.from_json(
155 self("station.getStation", 166 self,
156 stationToken=station_token, 167 self(
157 includeExtendedAttributes=True)) 168 "station.getStation",
169 stationToken=station_token,
170 includeExtendedAttributes=True,
171 ),
172 )
158 173
159 def add_artist_bookmark(self, track_token): 174 def add_artist_bookmark(self, track_token):
160 return self("bookmark.addArtistBookmark", 175 return self("bookmark.addArtistBookmark", trackToken=track_token)
161 trackToken=track_token)
162 176
163 def add_song_bookmark(self, track_token): 177 def add_song_bookmark(self, track_token):
164 return self("bookmark.addSongBookmark", 178 return self("bookmark.addSongBookmark", trackToken=track_token)
165 trackToken=track_token)
166 179
167 def delete_song_bookmark(self, bookmark_token): 180 def delete_song_bookmark(self, bookmark_token):
168 return self("bookmark.deleteSongBookmark", 181 return self(
169 bookmarkToken=bookmark_token) 182 "bookmark.deleteSongBookmark", bookmarkToken=bookmark_token
183 )
170 184
171 def delete_artist_bookmark(self, bookmark_token): 185 def delete_artist_bookmark(self, bookmark_token):
172 return self("bookmark.deleteArtistBookmark", 186 return self(
173 bookmarkToken=bookmark_token) 187 "bookmark.deleteArtistBookmark", bookmarkToken=bookmark_token
188 )
174 189
175 def search(self, search_text, 190 def search(
176 include_near_matches=False, 191 self,
177 include_genre_stations=False): 192 search_text,
193 include_near_matches=False,
194 include_genre_stations=False,
195 ):
178 from .models.search import SearchResult 196 from .models.search import SearchResult
179 197
180 return SearchResult.from_json( 198 return SearchResult.from_json(
181 self, 199 self,
182 self("music.search", 200 self(
183 searchText=search_text, 201 "music.search",
184 includeNearMatches=include_near_matches, 202 searchText=search_text,
185 includeGenreStations=include_genre_stations) 203 includeNearMatches=include_near_matches,
204 includeGenreStations=include_genre_stations,
205 ),
186 ) 206 )
187 207
188 def add_feedback(self, track_token, positive): 208 def add_feedback(self, track_token, positive):
189 return self("station.addFeedback", 209 return self(
190 trackToken=track_token, 210 "station.addFeedback", trackToken=track_token, isPositive=positive
191 isPositive=positive) 211 )
192 212
193 def add_music(self, music_token, station_token): 213 def add_music(self, music_token, station_token):
194 return self("station.addMusic", 214 return self(
195 musicToken=music_token, 215 "station.addMusic",
196 stationToken=station_token) 216 musicToken=music_token,
217 stationToken=station_token,
218 )
197 219
198 def create_station(self, search_token=None, artist_token=None, 220 def create_station(
199 track_token=None): 221 self, search_token=None, artist_token=None, track_token=None
222 ):
200 from .models.station import Station 223 from .models.station import Station
201 224
202 kwargs = {} 225 kwargs = {}
@@ -210,26 +233,23 @@ class APIClient(BaseAPIClient):
210 else: 233 else:
211 raise KeyError("Must pass a type of token") 234 raise KeyError("Must pass a type of token")
212 235
213 return Station.from_json(self, 236 return Station.from_json(self, self("station.createStation", **kwargs))
214 self("station.createStation", **kwargs))
215 237
216 def delete_feedback(self, feedback_id): 238 def delete_feedback(self, feedback_id):
217 return self("station.deleteFeedback", 239 return self("station.deleteFeedback", feedbackId=feedback_id)
218 feedbackId=feedback_id)
219 240
220 def delete_music(self, seed_id): 241 def delete_music(self, seed_id):
221 return self("station.deleteMusic", 242 return self("station.deleteMusic", seedId=seed_id)
222 seedId=seed_id)
223 243
224 def delete_station(self, station_token): 244 def delete_station(self, station_token):
225 return self("station.deleteStation", 245 return self("station.deleteStation", stationToken=station_token)
226 stationToken=station_token)
227 246
228 def get_genre_stations(self): 247 def get_genre_stations(self):
229 from .models.station import GenreStationList 248 from .models.station import GenreStationList
230 249
231 genre_stations = GenreStationList.from_json( 250 genre_stations = GenreStationList.from_json(
232 self, self("station.getGenreStations")) 251 self, self("station.getGenreStations")
252 )
233 genre_stations.checksum = self.get_genre_stations_checksum() 253 genre_stations.checksum = self.get_genre_stations_checksum()
234 254
235 return genre_stations 255 return genre_stations
@@ -238,44 +258,45 @@ class APIClient(BaseAPIClient):
238 return self("station.getGenreStationsChecksum")["checksum"] 258 return self("station.getGenreStationsChecksum")["checksum"]
239 259
240 def rename_station(self, station_token, name): 260 def rename_station(self, station_token, name):
241 return self("station.renameStation", 261 return self(
242 stationToken=station_token, 262 "station.renameStation",
243 stationName=name) 263 stationToken=station_token,
264 stationName=name,
265 )
244 266
245 def explain_track(self, track_token): 267 def explain_track(self, track_token):
246 return self("track.explainTrack", 268 return self("track.explainTrack", trackToken=track_token)
247 trackToken=track_token)
248 269
249 def set_quick_mix(self, *args): 270 def set_quick_mix(self, *args):
250 return self("user.setQuickMix", 271 return self("user.setQuickMix", quickMixStationIds=args)
251 quickMixStationIds=args)
252 272
253 def sleep_song(self, track_token): 273 def sleep_song(self, track_token):
254 return self("user.sleepSong", 274 return self("user.sleepSong", trackToken=track_token)
255 trackToken=track_token)
256 275
257 def share_station(self, station_id, station_token, *emails): 276 def share_station(self, station_id, station_token, *emails):
258 return self("station.shareStation", 277 return self(
259 stationId=station_id, 278 "station.shareStation",
260 stationToken=station_token, 279 stationId=station_id,
261 emails=emails) 280 stationToken=station_token,
281 emails=emails,
282 )
262 283
263 def transform_shared_station(self, station_token): 284 def transform_shared_station(self, station_token):
264 return self("station.transformSharedStation", 285 return self(
265 stationToken=station_token) 286 "station.transformSharedStation", stationToken=station_token
287 )
266 288
267 def share_music(self, music_token, *emails): 289 def share_music(self, music_token, *emails):
268 return self("music.shareMusic", 290 return self(
269 musicToken=music_token, 291 "music.shareMusic", musicToken=music_token, email=emails[0]
270 email=emails[0]) 292 )
271 293
272 def get_ad_item(self, station_id, ad_token): 294 def get_ad_item(self, station_id, ad_token):
273 from .models.ad import AdItem 295 from .models.ad import AdItem
274 296
275 if not station_id: 297 if not station_id:
276 raise errors.ParameterMissing("The 'station_id' param must be " 298 msg = "The 'station_id' param must be defined, got: '{}'"
277 "defined, got: '{}'" 299 raise errors.ParameterMissing(msg.format(station_id))
278 .format(station_id))
279 300
280 ad_item = AdItem.from_json(self, self.get_ad_metadata(ad_token)) 301 ad_item = AdItem.from_json(self, self.get_ad_metadata(ad_token))
281 ad_item.station_id = station_id 302 ad_item.station_id = station_id
@@ -283,12 +304,14 @@ class APIClient(BaseAPIClient):
283 return ad_item 304 return ad_item
284 305
285 def get_ad_metadata(self, ad_token): 306 def get_ad_metadata(self, ad_token):
286 return self("ad.getAdMetadata", 307 return self(
287 adToken=ad_token, 308 "ad.getAdMetadata",
288 returnAdTrackingTokens=True, 309 adToken=ad_token,
289 supportAudioAds=True) 310 returnAdTrackingTokens=True,
311 supportAudioAds=True,
312 )
290 313
291 def register_ad(self, station_id, tokens): 314 def register_ad(self, station_id, tokens):
292 return self("ad.registerAd", 315 return self(
293 stationId=station_id, 316 "ad.registerAd", stationId=station_id, adTrackingTokens=tokens
294 adTrackingTokens=tokens) 317 )