First attempt at new API.
[clinton/xbmc-groove.git] / resources / lib / GrooveAPIWP.py
1 import socket, hmac, urllib, urllib2, pprint, md5, os, pickle
2 from operator import itemgetter
3
4 THUMB_URL = 'http://beta.grooveshark.com/static/amazonart/'
5 THUMB_URL_DEFAULT = 'http://grooveshark.com/webincludes/logo/Grooveshark_Logo_No-Text.png'
6 SONG_LIMIT = 25
7 ALBUM_LIMIT = 15
8 ARTIST_LIMIT = 15
9
10
11 class GrooveAPI:
12
13 sessionID = ''
14 userID = 0
15 host = 'api.grooveshark.com'
16
17 # Constructor
18 def __init__(self, sessionID = ''):
19 import simplejson
20 self.simplejson = simplejson
21 socket.setdefaulttimeout(40)
22 if sessionID == '':
23 self.sessionID = self._getSessionID()
24 else:
25 self.sessionID = sessionID
26
27 def _keySort(self, d):
28 return [(k,d[k]) for k in sorted(d.keys())]
29
30 # Make a message sig
31 def _createMessageSig(self, method, params, secret):
32 args = self._keySort(params);
33 data = '';
34 for arg in args:
35 data += str(arg[0])
36 data += str(arg[1])
37 data = method + data
38
39 h = hmac.new(secret, data)
40 return h.hexdigest()
41
42 # The actual call to the API
43 def _callRemote(self, method, params = {}):
44 url = 'http://%s/ws/2.1/?method=%s&%s&wsKey=wordpress&sig=%s&format=json' % (self.host, method, urllib.urlencode(params), self._createMessageSig(method, params, 'd6c59291620c6eaa5bf94da08fae0ecc'))
45 print url
46 req = urllib2.Request(url)
47 response = urllib2.urlopen(req)
48 result = response.read()
49 pprint.pprint(result)
50 response.close()
51 try:
52 result = self.simplejson.loads(result)
53 return result
54 except:
55 return []
56
57 def getUserID(self):
58 return self.userID
59
60 def getSessionID(self):
61 return self.sessionID
62
63 def _getSessionID(self):
64 params = {}
65 result = self._callRemote('startSession', params)
66 return result['result']['sessionID']
67
68 # Make user authentication token
69 def _getUserToken(self, username, password):
70 return md5.new(username.lower() + md5.new(password).hexdigest()).hexdigest()
71
72 # Authenticates the user for current API session
73 def _authenticateUser(self, username, token):
74 params = {'sessionID': self.sessionID, 'username': username, 'token': token}
75 result = self._callRemote('authenticateUser', params)
76 return result['result']['UserID']
77
78 # Login
79 def login(self, username, password):
80 token = self._getUserToken(username, password)
81 self.userID = self._authenticateUser(username, token)
82 return self.userID
83
84 # Logs the user out
85 def logout(self):
86 self._callRemote('logout', {'sessionID' : self.sessionID})
87
88 # Search for albums
89 def getArtistSearchResults(self, query, limit=ARTIST_LIMIT):
90 result = self._callRemote('getArtistSearchResults', {'query' : query,'limit' : limit})
91 if 'result' in result:
92 return self._parseArtists(result)
93 else:
94 return []
95
96 # Search for albums
97 def getAlbumSearchResults(self, query, limit=ALBUM_LIMIT):
98 result = self._callRemote('getAlbumSearchResults', {'query' : query,'limit' : limit})
99 if 'result' in result:
100 return self._parseAlbums(result)
101 else:
102 return []
103
104 # Search for songs
105 def getSongSearchResults(self, query, limit=SONG_LIMIT):
106 result = self._callRemote('getSongSearchResultsEx', {'query' : query, 'limit' : limit})
107 if 'result' in result:
108 return self._parseSongs(result)
109 else:
110 return []
111
112 # Gets the popular songs
113 def getPopularSongsToday(self, limit=SONG_LIMIT):
114 result = self._callRemote('getPopularSongsToday', {'limit' : limit})
115 if 'result' in result:
116 return self._parseSongs(result)
117 else:
118 return []
119
120 # Gets the favorite songs of the logged-in user
121 def getUserFavoriteSongs(self):
122 if (self.userID == 0):
123 return [];
124 result = self._callRemote('getUserFavoriteSongs', {'sessionID' : self.sessionID})
125 if 'result' in result:
126 return self._parseSongs(result)
127 else:
128 return []
129
130 # Get the url to link to a song on Grooveshark
131 def getSongURLFromSongID(self, songID):
132 result = self._callRemote('getSongURLFromSongID', {'songID' : songID})
133 if 'result' in result:
134 url = result['result']['url']
135 return url.encode('ascii', 'ignore')
136 else:
137 return ''
138
139 # Get the url to link to a song on Grooveshark
140 def getSongInfo(self, songID):
141 result = self._callRemote('getSongInfoEx', {'songID' : songID})
142 if 'result' in result and 'SongID' in result['result']:
143 info = result['result']
144 if 'CoverArtFilename' in info and info['CoverArtFilename'] != None:
145 info['CoverArtFilename'] = THUMB_URL+info['CoverArtFilename'].encode('ascii', 'ignore')
146 else:
147 info['CoverArtFilename'] = THUMB_URL_DEFAULT
148 return info
149 else:
150 return ''
151
152 # Gets the playlists of the logged-in user
153 def getUserPlaylists(self):
154 if (self.userID == 0):
155 return [];
156 result = self._callRemote('getUserPlaylists', {'sessionID' : self.sessionID})
157 if 'result' in result:
158 return self._parsePlaylists(result)
159 else:
160 return []
161
162 # Creates a playlist with songs
163 def createPlaylist(self, name, songIDs):
164 result = self._callRemote('createPlaylist', {'name' : name, 'songIDs' : songIDs, 'sessionID' : self.sessionID})
165 if 'result' in result and result['result']['success'] == 'true':
166 return result['result']['PlaylistID']
167 elif 'errors' in result:
168 for error in result['errors']:
169 if (error['code'] == 800):
170 return -1
171 else:
172 return 0
173 else:
174 return 0
175
176 # Sets the songs for a playlist
177 def setPlaylistSongs(self, playlistID, songIDs):
178 result = self._callRemote('setPlaylistSongs', {'playlistID' : playlistID, 'songIDs' : songIDs, 'sessionID' : self.sessionID})
179 if 'result' in result and result['result']['success'] == 'true':
180 return True;
181 else:
182 return False;
183
184 # Gets the songs of a playlist
185 def getPlaylistSongs(self, playlistID):
186 result = self._callRemote('getPlaylistSongs', {'playlistID' : playlistID});
187 if 'result' in result:
188 return self._parseSongs(result)
189 else:
190 return []
191
192 # Extract song data
193 def _parseSongs(self, items):
194 if 'result' in items:
195 i = 0
196 list = []
197 if 'songs' in items['result']:
198 l = len(items['result']['songs'])
199 index = 'songs'
200 elif 'song' in items['result']:
201 l = 1
202 index = 'song'
203 else:
204 l = len(items['result'])
205 index = ''
206 while(i < l):
207 if index == 'songs':
208 s = items['result'][index][i]
209 elif index == 'song':
210 s = items['result'][index]
211 else:
212 s = items['result'][i]
213 if 'CoverArtFilename' not in s:
214 info = self.getSongInfo(s['SongID'])
215 coverart = info['CoverArtFilename']
216 elif s['CoverArtFilename'] != None:
217 coverart = THUMB_URL+s['CoverArtFilename'].encode('ascii', 'ignore')
218 else:
219 coverart = THUMB_URL_DEFAULT
220 list.append([s['SongName'].encode('ascii', 'ignore'),\
221 s['SongID'],\
222 s['AlbumName'].encode('ascii', 'ignore'),\
223 s['AlbumID'],\
224 s['ArtistName'].encode('ascii', 'ignore'),\
225 s['ArtistID'],\
226 coverart])
227 i = i + 1
228 return list
229 else:
230 return []
231
232 # Extract artist data
233 def _parseArtists(self, items):
234 if 'result' in items:
235 i = 0
236 list = []
237 artists = items['result']['artists']
238 while(i < len(artists)):
239 s = artists[i]
240 list.append([s['ArtistName'].encode('ascii', 'ignore'),\
241 s['ArtistID']])
242 i = i + 1
243 return list
244 else:
245 return []
246
247 # Extract album data
248 def _parseAlbums(self, items):
249 if 'result' in items:
250 i = 0
251 list = []
252 albums = items['result']['albums']
253 while(i < len(albums)):
254 s = albums[i]
255 if 'CoverArtFilename' in s and s['CoverArtFilename'] != None:
256 coverart = THUMB_URL+s['CoverArtFilename'].encode('ascii', 'ignore')
257 else:
258 coverart = THUMB_URL_DEFAULT
259 list.append([s['ArtistName'].encode('ascii', 'ignore'),\
260 s['ArtistID'],\
261 s['AlbumName'].encode('ascii', 'ignore'),\
262 s['AlbumID'],\
263 coverart])
264 i = i + 1
265 return list
266 else:
267 return []
268
269 def _parsePlaylists(self, items):
270 if 'result' in items:
271 i = 0
272 list = []
273 playlists = items['result']
274 while(i < len(playlists)):
275 s = playlists[i]
276 list.append([s['PlaylistID'],\
277 s['Name'].encode('ascii', 'ignore')])
278 i = i + 1
279 return list
280 else:
281 return []
282
283
284 groovesharkApi = GrooveAPI('c4285d93d556349d284704100eb557d7')
285 print "SessionID: " + groovesharkApi.getSessionID()
286 print "UserID: " + str(groovesharkApi.login('stephendenham', 'lond0n'))
287
288 #res = groovesharkApi.getSongSearchResults('jimmy jazz', 3)
289 #res = groovesharkApi.getPopularSongsToday()
290 #res = groovesharkApi.getSongURLFromSongID('27425375')
291 #res = groovesharkApi.getAlbumSearchResults('london calling', 3)
292 #res = groovesharkApi.getArtistSearchResults('the clash', 3)
293 #res = groovesharkApi.getUserFavoriteSongs()
294 #res = groovesharkApi.getUserPlaylists()
295 #res = groovesharkApi.getSongInfo('27425375')
296
297 res = groovesharkApi.getPlaylistSongs(40902662)
298
299 pprint.pprint(res)
300
301
302