e278f474 |
1 | import urllib2, md5, os, traceback, sys, pickle, socket, xbmc |
2 | from operator import itemgetter |
8817bb2e |
3 | |
4 | class LoginTokensExceededError(Exception): |
5 | def __init__(self): |
6 | self.value = 'You have created to many tokens. Only 12 are allowed' |
7 | def __str__(self): |
8 | return repr(self.value) |
9 | |
10 | class LoginUnknownError(Exception): |
11 | def __init__(self): |
12 | self.value = 'Unable to get a new session ID. Wait a few minutes and try again' |
13 | def __str__(self): |
14 | return repr(self.value) |
15 | |
16 | class SessionIDTryAgainError(Exception): |
17 | def __init__(self): |
18 | self.value = 'Unable to get a new session ID. Wait a few minutes and try again' |
19 | def __str__(self): |
20 | return repr(self.value) |
21 | |
22 | class GrooveAPI: |
23 | def __init__(self, enableDebug = False, isXbox = False): |
b738088f |
24 | import simplejson |
25 | self.simplejson = simplejson |
8817bb2e |
26 | timeout = 40 |
27 | socket.setdefaulttimeout(timeout) |
28 | self.enableDebug = enableDebug |
29 | self.loggedIn = 0 |
8817bb2e |
30 | self.userId = 0 |
b738088f |
31 | self.removeDuplicates = False |
3fcef5ba |
32 | |
33 | self.radioRecentSongs = [] |
34 | self.radioRecentArtists = [] |
35 | self.radioEnabled = False |
36 | |
973b4c6c |
37 | self.dataDir = 'addon_data' |
b738088f |
38 | self.confDir = xbmc.translatePath(os.path.join('special://masterprofile/' + self.dataDir, os.path.basename(os.getcwd()))) |
8817bb2e |
39 | self.sessionID = self.getSavedSession() |
40 | self.debug('Saved sessionID: ' + self.sessionID) |
b738088f |
41 | #self.sessionID = self.getSessionFromAPI() |
42 | #self.debug('API sessionID: ' + self.sessionID) |
8817bb2e |
43 | if self.sessionID == '': |
44 | self.sessionID = self.startSession() |
45 | self.debug('Start() sessionID: ' + self.sessionID) |
46 | if self.sessionID == '': |
47 | self.debug('Could not get a sessionID. Try again in a few minutes') |
48 | raise SessionIDTryAgainError() |
49 | else: |
50 | self.saveSession() |
51 | |
52 | self.debug('sessionID: ' + self.sessionID) |
53 | |
54 | def __del__(self): |
55 | try: |
56 | if self.loggedIn == 1: |
57 | self.logout() |
58 | except: |
59 | pass |
60 | |
61 | def debug(self, msg): |
62 | if self.enableDebug == True: |
63 | print msg |
b738088f |
64 | |
65 | def setRemoveDuplicates(self, enable): |
66 | if enable == True or enable == 'true' or enable == 'True': |
67 | self.removeDuplicates = True |
68 | else: |
69 | self.removeDuplicates = False |
8817bb2e |
70 | |
71 | def getSavedSession(self): |
72 | sessionID = '' |
b738088f |
73 | path = os.path.join(self.confDir, 'session', 'session.txt') |
8817bb2e |
74 | |
75 | try: |
76 | f = open(path, 'rb') |
77 | sessionID = pickle.load(f) |
78 | f.close() |
79 | except: |
80 | sessionID = '' |
81 | pass |
82 | |
83 | return sessionID |
84 | |
85 | def saveSession(self): |
86 | try: |
b738088f |
87 | dir = os.path.join(self.confDir, 'session') |
8817bb2e |
88 | # Create the 'data' directory if it doesn't exist. |
89 | if not os.path.exists(dir): |
b738088f |
90 | os.makedirs(dir) |
8817bb2e |
91 | path = os.path.join(dir, 'session.txt') |
92 | f = open(path, 'wb') |
93 | pickle.dump(self.sessionID, f, protocol=pickle.HIGHEST_PROTOCOL) |
94 | f.close() |
95 | except IOError, e: |
96 | print 'There was an error while saving the session pickle (%s)' % e |
97 | pass |
98 | except: |
99 | print "An unknown error occured during save session: " + str(sys.exc_info()[0]) |
100 | pass |
101 | |
102 | def saveSettings(self): |
103 | try: |
b738088f |
104 | dir = os.path.join(self.confDir, 'data') |
8817bb2e |
105 | # Create the 'data' directory if it doesn't exist. |
106 | if not os.path.exists(dir): |
b738088f |
107 | os.makedirs(dir) |
8817bb2e |
108 | path = os.path.join(dir, 'settings1.txt') |
109 | f = open(path, 'wb') |
110 | pickle.dump(self.settings, f, protocol=pickle.HIGHEST_PROTOCOL) |
111 | f.close() |
112 | except IOError, e: |
113 | print 'There was an error while saving the settings pickle (%s)' % e |
114 | pass |
115 | except: |
116 | print "An unknown error occured during save settings\n" |
117 | pass |
118 | |
119 | def callRemote(self, method, params={}): |
120 | data = {'header': {'sessionID': self.sessionID}, 'method': method, 'parameters': params} |
8817bb2e |
121 | data = self.simplejson.dumps(data) |
8817bb2e |
122 | req = urllib2.Request("http://api.grooveshark.com/ws/1.0/?json") |
123 | req.add_header('Host', 'api.grooveshark.com') |
124 | req.add_header('Content-type', 'text/json') |
125 | req.add_header('Content-length', str(len(data))) |
126 | req.add_data(data) |
127 | response = urllib2.urlopen(req) |
128 | result = response.read() |
129 | response.close() |
130 | try: |
131 | result = self.simplejson.loads(result) |
132 | if 'fault' in result: |
133 | self.debug(result) |
b738088f |
134 | if result['fault']['code'] == 8: #Session ID has expired. Get a new and try again if possible. |
135 | self.debug(result['fault']['message']) |
136 | self.sessionID = self.startSession() |
137 | if self.sessionID != '': |
138 | self.saveSession() |
139 | return self.callRemote(method, params) |
140 | else: |
141 | self.debug('GrooveShark: SessionID expired, but unable to get new') |
142 | return [] |
8817bb2e |
143 | return result |
144 | except: |
145 | return [] |
146 | |
147 | def startSession(self): |
a3ad8f73 |
148 | try: |
149 | response = urllib2.urlopen("http://www.moovida.com/services/grooveshark/session_start") |
150 | result = response.read() |
151 | result = self.simplejson.loads(result) |
152 | response.close() |
153 | except: |
154 | return '' |
155 | |
8817bb2e |
156 | if 'fault' in result: |
157 | return '' |
158 | else: |
3fcef5ba |
159 | return result['result']['sessionID'] |
8817bb2e |
160 | |
161 | def sessionDestroy(self): |
162 | return self.callRemote("session.destroy") |
163 | |
164 | def getSessionFromAPI(self): |
165 | result = self.callRemote("session.get") |
166 | if 'fault' in result: |
167 | return '' |
168 | else: |
169 | return result['header']['sessionID'] |
170 | |
171 | def getStreamURL(self, songID): |
172 | result = self.callRemote("song.getStreamUrlEx", {"songID": songID}) |
173 | if 'result' in result: |
174 | return result['result']['url'] |
175 | else: |
176 | return '' |
177 | |
178 | def createUserAuthToken(self, username, password): |
179 | hashpass = md5.new(password).hexdigest() |
180 | hashpass = username + hashpass |
181 | hashpass = md5.new(hashpass).hexdigest() |
182 | result = self.callRemote("session.createUserAuthToken", {"username": username, "hashpass": hashpass}) |
183 | if 'result' in result: |
184 | return result['result']['token'], result['result']['userID'] |
185 | elif 'fault' in result: |
186 | if result['fault']['code'] == 256: |
187 | return -1 # Exceeded the number of allowed tokens. Should not happen |
188 | else: |
189 | return -2 # Unknown error |
190 | else: |
191 | return -2 # Unknown error |
192 | |
193 | def destroyUserAuthToken(self, token): |
194 | self.callRemote("session.destroyAuthToken", {"token": token}) |
195 | |
196 | def loginViaAuthToken(self, token): |
197 | result = self.callRemote("session.loginViaAuthToken", {"token": token}) |
198 | self.destroyUserAuthToken(token) |
199 | if 'result' in result: |
200 | self.userID = result['result']['userID'] |
201 | return result['result']['userID'] |
202 | else: |
203 | return 0 |
204 | |
205 | def login(self, username, password): |
206 | if self.loggedIn == 1: |
207 | return self.userId |
208 | result = self.createUserAuthToken(username, password) |
209 | if result == -1: |
210 | raise LoginTokensExceededError() |
211 | elif result == -2: |
212 | raise LoginUnknownError() |
213 | else: |
214 | self.token = result[0] |
215 | self.debug('Token:' + self.token) |
216 | self.userId = self.loginViaAuthToken(self.token) |
217 | if self.userId == 0: |
218 | raise LoginUnknownError() |
219 | else: |
220 | self.loggedIn = 1 |
221 | return self.userId |
b738088f |
222 | |
8817bb2e |
223 | |
224 | def loginExt(self, username, password): |
225 | if self.loggedIn == 1: |
226 | return self.userId |
227 | token = md5.new(username.lower() + md5.new(password).hexdigest()).hexdigest() |
228 | result = self.callRemote("session.loginExt", {"username": username, "token": token}) |
229 | if 'result' in result: |
230 | if 'userID' in result['result']: |
231 | self.loggedIn = 1 |
232 | self.userId = result['result']['userID'] |
233 | return result['result']['userID'] |
234 | else: |
235 | return 0 |
236 | |
237 | |
238 | def loginBasic(self, username, password): |
239 | if self.loggedIn == 1: |
240 | return self.userId |
241 | result = self.callRemote("session.login", {"username": username, "password": password}) |
242 | if 'result' in result: |
243 | if 'userID' in result['result']: |
244 | self.loggedIn = 1 |
245 | self.userId = result['result']['userID'] |
246 | return result['result']['userID'] |
247 | else: |
248 | return 0 |
249 | |
250 | def loggedInStatus(self): |
251 | return self.loggedIn |
252 | |
253 | def logout(self): |
254 | self.callRemote("session.logout", {}) |
255 | self.loggedIn = 0 |
256 | |
257 | def getSongInfo(self, songID): |
258 | return self.callRemote("song.about", {"songID": songID})['result']['song'] |
259 | |
260 | def userGetFavoriteSongs(self, userID): |
261 | result = self.callRemote("user.getFavoriteSongs", {"userID": userID}) |
262 | list = self.parseSongs(result) |
263 | return list |
264 | |
265 | def userGetPlaylists(self, limit=25): |
266 | if self.loggedIn == 1: |
267 | result = self.callRemote("user.getPlaylists", {"userID": self.userId, "limit": limit}) |
268 | if 'result' in result: |
269 | playlists = result['result']['playlists'] |
270 | else: |
271 | return [] |
272 | i = 0 |
273 | list = [] |
274 | while(i < len(playlists)): |
275 | p = playlists[i] |
276 | list.append([p['playlistName'].encode('ascii', 'ignore'), p['playlistID']]) |
277 | i = i + 1 |
278 | return sorted(list, key=itemgetter(0)) |
279 | else: |
280 | return [] |
281 | |
282 | def playlistCreate(self, name, about): |
283 | if self.loggedIn == 1: |
284 | result = self.callRemote("playlist.create", {"name": name, "about": about}) |
285 | if 'result' in result: |
286 | return result['result']['playlistID'] |
287 | else: |
288 | return 0 |
289 | else: |
290 | return 0 |
36cc00d7 |
291 | |
292 | def playlistCreateUnique(self, name, songIds): |
293 | if self.loggedIn == 1: |
294 | result = self.callRemote("playlist.createunique", {"name": name, "songIDs": songIds}) |
295 | if 'result' in result: |
296 | return result['result']['playlistID'] |
297 | else: |
298 | return 0 |
299 | else: |
300 | return 0 |
8817bb2e |
301 | |
302 | def playlistGetSongs(self, playlistId, limit=25): |
303 | result = self.callRemote("playlist.getSongs", {"playlistID": playlistId}) |
304 | list = self.parseSongs(result) |
305 | return list |
306 | |
307 | def playlistDelete(self, playlistId): |
308 | if self.loggedIn == 1: |
e278f474 |
309 | result = self.callRemote("playlist.delete", {"playlistID": playlistId}) |
310 | if 'fault' in result: |
311 | return 0 |
312 | else: |
313 | return 1 |
314 | else: |
315 | return 0 |
8817bb2e |
316 | |
317 | def playlistRename(self, playlistId, name): |
318 | if self.loggedIn == 1: |
319 | result = self.callRemote("playlist.rename", {"playlistID": playlistId, "name": name}) |
320 | if 'fault' in result: |
321 | return 0 |
322 | else: |
323 | return 1 |
324 | else: |
325 | return 0 |
326 | |
327 | def playlistClearSongs(self, playlistId): |
328 | if self.loggedIn == 1: |
329 | return self.callRemote("playlist.clearSongs", {"playlistID": playlistId}) |
330 | |
331 | def playlistAddSong(self, playlistId, songId, position): |
332 | if self.loggedIn == 1: |
333 | result = self.callRemote("playlist.addSong", {"playlistID": playlistId, "songID": songId, "position": position}) |
4be42357 |
334 | if 'fault' in result: |
335 | return 0 |
336 | else: |
337 | return 1 |
338 | else: |
339 | return 0 |
340 | |
341 | def playlistDeleteSong(self, playlistId, position): |
342 | if self.loggedIn == 1: |
343 | result = self.callRemote("playlist.removeSong", {"playlistID": playlistId, "position": position}) |
8817bb2e |
344 | if 'fault' in result: |
345 | return 0 |
346 | else: |
347 | return 1 |
348 | else: |
349 | return 0 |
350 | |
351 | def playlistReplace(self, playlistId, songIds): |
352 | if self.loggedIn == 1: |
353 | result = self.callRemote("playlist.replace", {"playlistID": playlistId, "songIDs": songIds}) |
354 | if 'fault' in result: |
355 | return 0 |
356 | else: |
357 | return 1 |
358 | else: |
359 | return 0 |
360 | |
3fcef5ba |
361 | def radioStartArtists(self): |
362 | radio = self.getSavedRadio() |
363 | if radio == None: |
364 | return False |
365 | result = self.callRemote("autoplay.startWithArtistIDs", {"artistIDs": radio['seedArtists']}) |
8817bb2e |
366 | if 'fault' in result: |
e6ccfeca |
367 | print "Cannot autoplay artists" |
3fcef5ba |
368 | self.radioEnabled = False |
8817bb2e |
369 | else: |
3fcef5ba |
370 | self.radioEnabled = True |
371 | return self.radioEnabled |
8817bb2e |
372 | |
3fcef5ba |
373 | def radioStartSongs(self): |
374 | radio = self.getSavedRadio() |
375 | if radio == None: |
376 | return False |
377 | result = self.callRemote("autoplay.start", {"songIDs": radio['seedSongs']}) |
8817bb2e |
378 | if 'fault' in result: |
e6ccfeca |
379 | print "Cannot autoplay songs" |
3fcef5ba |
380 | self.radioEnabled = False |
8817bb2e |
381 | else: |
3fcef5ba |
382 | self.radioEnabled = True |
383 | return self.radioEnabled |
8817bb2e |
384 | |
3fcef5ba |
385 | def radioNextSong(self): |
b738088f |
386 | radio = self.getSavedRadio() |
387 | if radio == None: |
388 | return None |
8817bb2e |
389 | else: |
3fcef5ba |
390 | result = self.callRemote("autoplay.getNextSongEx", {"seedArtists": radio['seedArtists'], "frowns": radio['frowns'], "songIDsAlreadySeen": self.radioRecentSongs, "recentArtists": self.radioRecentArtists}) |
8817bb2e |
391 | if 'fault' in result: |
392 | return [] |
393 | else: |
394 | song = self.parseSongs(result) |
3fcef5ba |
395 | self.radioRecentSongs.append(song[0][1]) |
396 | self.radioRecentArtists.append(song[0][7]) |
8817bb2e |
397 | return song |
398 | |
3fcef5ba |
399 | def radioFrown(self, songId = None): |
400 | radio = self.getSavedRadio() |
401 | if radio != None and songId != None: |
402 | try: |
403 | radio['frowns'].remove(songId) |
404 | except: pass |
405 | radio['frowns'].append(songId) |
b738088f |
406 | return self.saveRadio(radio = radio) |
407 | else: |
3fcef5ba |
408 | return False |
8817bb2e |
409 | |
3fcef5ba |
410 | def radioArtist(self, artistId = None): |
411 | radio = self.getSavedRadio() |
412 | if radio != None and artistId != None: |
413 | try: |
414 | radio['seedArtists'].remove(artistId) |
415 | except: pass |
416 | radio['seedArtists'].append(artistId) |
e6ccfeca |
417 | print "Saved radio" |
3fcef5ba |
418 | return self.saveRadio(radio = radio) |
8817bb2e |
419 | else: |
e6ccfeca |
420 | print "Failed to get radio" |
3fcef5ba |
421 | return False |
8817bb2e |
422 | |
3fcef5ba |
423 | def radioSong(self, songId = None): |
424 | radio = self.getSavedRadio() |
425 | if radio != None and songId != None: |
426 | try: |
427 | radio['seedSongs'].remove(songId) |
428 | except: pass |
429 | radio['seedSongs'].append(songId) |
e6ccfeca |
430 | print "Saved radio" |
3fcef5ba |
431 | return self.saveRadio(radio = radio) |
432 | else: |
e6ccfeca |
433 | print "Failed to get radio" |
3fcef5ba |
434 | return False |
8817bb2e |
435 | |
436 | def radioTurnedOn(self): |
437 | return self.radioEnabled |
438 | |
3fcef5ba |
439 | def getSavedRadio(self): |
440 | path = os.path.join(self.confDir, 'radio', 'radio.dmp') |
b738088f |
441 | try: |
442 | f = open(path, 'rb') |
443 | radio = pickle.load(f) |
444 | f.close() |
445 | except: |
e6ccfeca |
446 | print "Failed to open " + path |
3fcef5ba |
447 | radio = {} |
448 | radio['seedSongs'] = [] |
449 | radio['seedArtists'] = [] |
450 | radio['frowns'] = [] |
451 | if self.saveRadio(radio) == False: |
452 | return None |
b738088f |
453 | return radio |
454 | |
3fcef5ba |
455 | def saveRadio(self, radio): #blaher |
456 | if radio == {}: |
457 | print 'Invalid radio' |
458 | return False |
b738088f |
459 | try: |
460 | dir = os.path.join(self.confDir, 'radio') |
461 | # Create the 'data' directory if it doesn't exist. |
462 | if not os.path.exists(dir): |
463 | os.mkdir(dir) |
3fcef5ba |
464 | path = os.path.join(dir, 'radio.dmp') |
b738088f |
465 | f = open(path, 'wb') |
466 | pickle.dump(radio, f, protocol=pickle.HIGHEST_PROTOCOL) |
467 | f.close() |
3fcef5ba |
468 | return True |
b738088f |
469 | except IOError, e: |
470 | print 'There was an error while saving the radio pickle (%s)' % e |
3fcef5ba |
471 | return False |
b738088f |
472 | except: |
3fcef5ba |
473 | print "An unknown error occurred during save radio: " + str(sys.exc_info()[0]) |
474 | return False |
b738088f |
475 | |
8817bb2e |
476 | def favoriteSong(self, songID): |
477 | return self.callRemote("song.favorite", {"songID": songID}) |
478 | |
479 | def unfavoriteSong(self, songID): |
480 | return self.callRemote("song.unfavorite", {"songID": songID}) |
481 | |
482 | def getMethods(self): |
483 | return self.callRemote("service.getMethods") |
484 | |
485 | def searchSongsExactMatch(self, songName, artistName, albumName): |
486 | result = self.callRemote("search.songExactMatch", {"songName": songName, "artistName": artistName, "albumName": albumName}) |
487 | list = self.parseSongs(result) |
488 | return list |
489 | |
490 | def searchSongs(self, query, limit, page=0, sortKey=6): |
491 | result = self.callRemote("search.songs", {"query": query, "limit": limit, "page:": page, "streamableOnly": 1}) |
492 | list = self.parseSongs(result) |
493 | return list |
494 | #return sorted(list, key=itemgetter(sortKey)) |
495 | |
496 | def searchArtists(self, query, limit, sortKey=0): |
497 | result = self.callRemote("search.artists", {"query": query, "limit": limit, "streamableOnly": 1}) |
498 | list = self.parseArtists(result) |
499 | return list |
500 | #return sorted(list, key=itemgetter(sortKey)) |
501 | |
502 | def searchAlbums(self, query, limit, sortKey=2): |
503 | result = self.callRemote("search.albums", {"query": query, "limit": limit, "streamableOnly": 1}) |
504 | list = self.parseAlbums(result) |
505 | return list |
506 | #return sorted(list, key=itemgetter(sortKey)) |
507 | |
508 | def searchPlaylists(self, query, limit): |
509 | result = self.callRemote("search.playlists", {"query": query, "limit": limit, "streamableOnly": 1}) |
510 | list = self.parsePlaylists(result) |
511 | return list |
512 | |
513 | def popularGetSongs(self, limit): |
514 | result = self.callRemote("popular.getSongs", {"limit": limit}) |
515 | list = self.parseSongs(result) |
516 | return list |
517 | |
518 | def popularGetArtists(self, limit): |
519 | result = self.callRemote("popular.getArtists", {"limit": limit}) |
520 | list = self.parseArtists(result) |
521 | return list |
522 | |
523 | def popularGetAlbums(self, limit): |
524 | result = self.callRemote("popular.getAlbums", {"limit": limit}) |
525 | list = self.parseAlbums(result) |
526 | return list |
527 | |
b738088f |
528 | def artistAbout(self, artistId): |
529 | result = self.callRemote("artist.about", {"artistID": artistId}) |
530 | return result |
531 | |
8817bb2e |
532 | def artistGetAlbums(self, artistId, limit, sortKey=2): |
533 | result = self.callRemote("artist.getAlbums", {"artistID": artistId, "limit": limit}) |
534 | list = self.parseAlbums(result) |
535 | return list |
536 | #return sorted(list, key=itemgetter(sortKey)) |
537 | |
538 | def artistGetVerifiedAlbums(self, artistId, limit): |
539 | result = self.callRemote("artist.getVerifiedAlbums", {"artistID": artistId, "limit": limit}) |
540 | list = self.parseSongs(result) |
541 | return list |
542 | |
543 | def albumGetSongs(self, albumId, limit): |
544 | result = self.callRemote("album.getSongs", {"albumID": albumId, "limit": limit}) |
545 | list = self.parseSongs(result) |
546 | return list |
547 | |
548 | def songGetSimilar(self, songId, limit): |
549 | result = self.callRemote("song.getSimilar", {"songID": songId, "limit": limit}) |
550 | list = self.parseSongs(result) |
551 | return list |
552 | |
b738088f |
553 | def artistGetSimilar(self, artistId, limit): |
554 | result = self.callRemote("artist.getSimilar", {"artistID": artistId, "limit": limit}) |
555 | list = self.parseArtists(result) |
556 | return list |
557 | |
558 | def songAbout(self, songId): |
559 | result = self.callRemote("song.about", {"songID": songId}) |
560 | return result['result']['song'] |
561 | |
562 | def getVersion(self): |
563 | result = self.callRemote("service.getVersion", {}) |
564 | return result |
565 | |
8817bb2e |
566 | def parseSongs(self, items): |
567 | try: |
568 | if 'result' in items: |
569 | i = 0 |
570 | list = [] |
571 | if 'songs' in items['result']: |
572 | l = len(items['result']['songs']) |
573 | index = 'songs' |
574 | elif 'song' in items['result']: |
575 | l = 1 |
576 | index = 'song' |
577 | else: |
578 | l = 0 |
579 | index = '' |
580 | while(i < l): |
581 | if index == 'songs': |
582 | s = items['result'][index][i] |
583 | else: |
584 | s = items['result'][index] |
585 | if 'estDurationSecs' in s: |
586 | dur = s['estDurationSecs'] |
587 | else: |
588 | dur = 0 |
589 | try: |
590 | notIn = True |
591 | for entry in list: |
592 | songName = s['songName'].encode('ascii', 'ignore') |
593 | albumName = s['albumName'].encode('ascii', 'ignore') |
594 | artistName = s['artistName'].encode('ascii', 'ignore') |
b738088f |
595 | if self.removeDuplicates == True: |
596 | if (entry[0].lower() == songName.lower()) and (entry[3].lower() == albumName.lower()) and (entry[6].lower() == artistName.lower()): |
597 | notIn = False |
8817bb2e |
598 | if notIn == True: |
599 | list.append([s['songName'].encode('ascii', 'ignore'),\ |
600 | s['songID'],\ |
601 | dur,\ |
602 | s['albumName'].encode('ascii', 'ignore'),\ |
603 | s['albumID'],\ |
604 | s['image']['tiny'].encode('ascii', 'ignore'),\ |
605 | s['artistName'].encode('ascii', 'ignore'),\ |
606 | s['artistID'],\ |
607 | s['image']['small'].encode('ascii', 'ignore'),\ |
608 | s['image']['medium'].encode('ascii', 'ignore')]) |
609 | except: |
610 | print 'GrooveShark: Could not parse song number: ' + str(i) |
611 | traceback.print_exc() |
612 | i = i + 1 |
613 | return list |
614 | else: |
615 | return [] |
616 | pass |
617 | except: |
618 | print 'GrooveShark: Could not parse songs. Got this:' |
619 | traceback.print_exc() |
620 | return [] |
621 | |
622 | def parseArtists(self, items): |
b738088f |
623 | try: |
624 | if 'result' in items: |
625 | i = 0 |
626 | list = [] |
627 | artists = items['result']['artists'] |
628 | while(i < len(artists)): |
629 | s = artists[i] |
630 | try: |
631 | list.append([s['artistName'].encode('ascii', 'ignore'),\ |
632 | s['artistID']]) |
633 | except: |
634 | print 'GrooveShark: Could not parse album number: ' + str(i) |
635 | traceback.print_exc() |
636 | i = i + 1 |
637 | return list |
638 | else: |
639 | return [] |
640 | except: |
641 | print 'GrooveShark: Could not parse artists. Got this:' |
642 | traceback.print_exc() |
8817bb2e |
643 | return [] |
644 | |
645 | def parseAlbums(self, items): |
b738088f |
646 | try: |
647 | if 'result' in items: |
648 | i = 0 |
649 | list = [] |
650 | albums = items['result']['albums'] |
651 | while(i < len(albums)): |
652 | s = albums[i] |
653 | try: # Avoid ascii ancoding errors |
654 | list.append([s['artistName'].encode('ascii', 'ignore'),\ |
655 | s['artistID'],\ |
656 | s['albumName'].encode('ascii', 'ignore'),\ |
657 | s['albumID'],\ |
406ab447 |
658 | s['image']['medium'].encode('ascii', 'ignore')]) |
b738088f |
659 | except: |
660 | print 'GrooveShark: Could not parse album number: ' + str(i) |
661 | traceback.print_exc() |
662 | i = i + 1 |
663 | return list |
664 | else: |
665 | return [] |
666 | except: |
667 | print 'GrooveShark: Could not parse albums. Got this' |
668 | traceback.print_exc() |
8817bb2e |
669 | return [] |
670 | |
671 | def parsePlaylists(self, items): |
b738088f |
672 | try: |
673 | if 'result' in items: |
674 | i = 0 |
675 | list = [] |
676 | playlists = items['result']['playlists'] |
677 | while(i < len(playlists)): |
678 | s = playlists[i] |
679 | try: # Avoid ascii ancoding errors |
680 | list.append([s['playlistID'],\ |
681 | s['playlistName'].encode('ascii', 'ignore'),\ |
682 | s['username'].encode('ascii', 'ignore')]) |
683 | except: |
684 | print 'GrooveShark: Could not parse playlist number: ' + str(i) |
685 | traceback.print_exc() |
686 | i = i + 1 |
687 | return list |
688 | else: |
689 | return [] |
690 | except: |
691 | print 'GrooveShark: Could not parse playlists. Got this:' |
692 | print items |
8817bb2e |
693 | return [] |