2f8f3401e6e3833612b1469e01bdc11fe65c035e
1 import socket
, hmac
, urllib2
, pprint
, md5
, os
, pickle
, tempfile
, time
, re
, groovesharkAccess
3 SESSION_EXPIRY
= 1209600 # 2 weeks
6 THUMB_URL
= 'http://beta.grooveshark.com/static/amazonart/m'
21 _lastStreamServerID
= ''
27 self
.simplejson
= simplejson
28 socket
.setdefaulttimeout(40)
29 self
.cacheDir
= os
.path
.join(tempfile
.gettempdir(), 'groovesharkapi')
30 if os
.path
.isdir(self
.cacheDir
) == False:
31 os
.makedirs(self
.cacheDir
)
32 print "Made " + self
.cacheDir
33 self
._getSavedSession
()
34 # session ids last 2 weeks
35 if self
._sessionID
== '' or time
.time()- self
._lastSessionTime
>= SESSION_EXPIRY
:
36 self
._sessionID
= self
._getSessionID
()
37 self
._ip
= self
._getIP
()
38 self
._country
= self
._getCountry
()
39 if self
._sessionID
== '':
40 raise StandardError('Failed to get session id')
42 print "New GrooveAPI session id: " + self
._sessionID
43 self
._setSavedSession
()
46 def _callRemote(self
, method
, params
):
47 self
._setParams
(params
)
48 return groovesharkAccess
.callRemote(method
, self
._sessionID
)
51 def _getSessionID(self
):
53 result
= self
._callRemote
('startSession', params
)
54 self
._lastSessionTime
= time
.time()
55 if 'result' in result
:
56 return result
['result']['sessionID']
60 def _getSavedSession(self
):
61 path
= os
.path
.join(self
.cacheDir
, 'session.dmp')
64 session
= pickle
.load(f
)
65 self
._sessionID
= session
['sessionID']
66 self
._lastSessionTime
= session
['lastSessionTime']
67 self
._userID
= session
['userID']
68 self
._ip
= session
['ip']
69 self
._country
= session
['country']
73 self
._lastSessionTime
= 0
79 def _setSavedSession(self
):
81 # Create the directory if it doesn't exist.
82 if not os
.path
.exists(self
.cacheDir
):
83 os
.makedirs(self
.cacheDir
)
84 path
= os
.path
.join(self
.cacheDir
, 'session.dmp')
86 session
= { 'sessionID' : self
._sessionID
, 'lastSessionTime' : self
._lastSessionTime
, 'userID': self
._userID
, 'ip' : self
._ip
, 'country' : self
._country
}
87 pickle
.dump(session
, f
, protocol
=pickle
.HIGHEST_PROTOCOL
)
90 print "An error occurred during save session"
93 def _setParams(self
, params
):
95 # Create the directory if it doesn't exist.
96 if not os
.path
.exists(self
.cacheDir
):
97 os
.makedirs(self
.cacheDir
)
98 path
= os
.path
.join(self
.cacheDir
, 'params.dmp')
100 pickle
.dump(params
, f
, protocol
=pickle
.HIGHEST_PROTOCOL
)
103 print "An error occurred during save params"
109 myip
= urllib2
.urlopen('http://whatismyip.org').read()
110 if re
.match("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", myip
):
111 print "IP is " + myip
117 def _getCountry(self
):
118 params
= { 'ip' : self
._ip
}
119 response
= self
._callRemote
("getCountry", params
)
120 return response
['result']
122 # Get userid from name
123 def _getUserIDFromUsername(self
, username
):
124 result
= self
._callRemote
('getUserIDFromUsername', {'username' : username
})
125 if 'result' in result
and result
['result']['UserID'] > 0:
126 return result
['result']['UserID']
130 # Authenticates the user for current API session
131 def _authenticate(self
, login
, password
):
132 md5pwd
= md5
.new(password
).hexdigest()
133 params
= {'login': login
, 'password': md5pwd
}
135 result
= self
._callRemote
('authenticate', params
)
136 uid
= result
['result']['UserID']
143 def pingService(self
,):
144 result
= self
._callRemote
('pingService', {});
145 if 'result' in result
and result
['result'] != '':
151 def login(self
, username
, password
):
152 if self
._userID
<= 0:
154 self
._getSavedSession
()
155 if self
._userID
<= 0:
156 self
._userID
= self
._authenticate
(username
, password
)
158 self
._setSavedSession
()
163 result
= self
._callRemote
('logout', {'sessionID' : self
._sessionID
})
164 if 'result' in result
and result
['result']['success'] == True:
166 self
._setSavedSession
()
170 # Gets a stream key and host to get song content
171 def getSubscriberStreamKey(self
, songID
):
172 params
= { "songID": songID
, "country": self
._country
}
173 response
= self
._callRemote
("getSubscriberStreamKey", params
)
175 self
._lastStreamKey
= response
["result"]["StreamKey"]
176 self
._lastStreamServerID
= response
["result"]["StreamServerID"]
177 res
= response
["result"]
183 def getArtistSearchResults(self
, query
, limit
=ARTIST_LIMIT
):
184 result
= self
._callRemote
('getArtistSearchResults', {'query' : query
,'limit' : limit
})
185 if 'result' in result
:
186 return self
._parseArtists
(result
)
191 def getAlbumSearchResults(self
, query
, limit
=ALBUM_LIMIT
):
192 result
= self
._callRemote
('getAlbumSearchResults', {'query' : query
,'limit' : limit
})
193 if 'result' in result
:
194 return self
._parseAlbums
(result
)
199 def getSongSearchResults(self
, query
, limit
=SONG_LIMIT
):
200 result
= self
._callRemote
('getSongSearchResults', {'query' : query
, 'country' : self
._country
, 'limit' : limit
})
201 if 'result' in result
:
202 return self
._parseSongs
(result
)
207 def getArtistAlbums(self
, artistID
, limit
=ALBUM_LIMIT
):
208 result
= self
._callRemote
('getArtistAlbums', {'artistID' : artistID
})
209 if 'result' in result
:
210 return self
._parseAlbums
(result
, limit
)
215 def getAlbumSongs(self
, albumID
, limit
=SONG_LIMIT
):
216 result
= self
._callRemote
('getAlbumSongs', {'albumID' : albumID
, 'limit' : limit
})
217 if 'result' in result
:
218 return self
._parseSongs
(result
)
222 # Get artist's popular songs
223 def getArtistPopularSongs(self
, artistID
, limit
= SONG_LIMIT
):
224 result
= self
._callRemote
('getArtistPopularSongs', {'artistID' : artistID
})
225 if 'result' in result
:
226 return self
._parseSongs
(result
, limit
)
230 # Gets the popular songs
231 def getPopularSongsToday(self
, limit
=SONG_LIMIT
):
232 result
= self
._callRemote
('getPopularSongsToday', {'limit' : limit
})
233 if 'result' in result
:
234 # Note limit is broken in the Grooveshark getPopularSongsToday method
235 return self
._parseSongs
(result
, limit
)
239 # Gets the favorite songs of the logged-in user
240 def getUserFavoriteSongs(self
):
241 if (self
._userID
== 0):
243 result
= self
._callRemote
('getUserFavoriteSongs', {})
244 if 'result' in result
:
245 return self
._parseSongs
(result
)
250 def getSongsInfo(self
, songIDs
):
251 result
= self
._callRemote
('getSongsInfo', {'songIDs' : songIDs
})
252 if 'result' in result
and 'SongID' in result
['result']:
253 info
= result
['result']
254 if 'CoverArtFilename' in info
and info
['CoverArtFilename'] != None:
255 info
['CoverArtFilename'] = THUMB_URL
+info
['CoverArtFilename'].encode('ascii', 'ignore')
257 info
['CoverArtFilename'] = 'None'
262 # Add song to user favorites
263 def addUserFavoriteSong(self
, songID
):
264 if (self
._userID
== 0):
266 result
= self
._callRemote
('addUserFavoriteSong', {'songID' : songID
})
267 return result
['result']['success']
269 # Remove songs from user favorites
270 def removeUserFavoriteSongs(self
, songIDs
):
271 if (self
._userID
== 0):
273 result
= self
._callRemote
('removeUserFavoriteSongs', {'songIDs' : songIDs
})
274 return result
['result']['success']
276 # Gets the playlists of the logged-in user
277 def getUserPlaylists(self
):
278 if (self
._userID
== 0):
280 result
= self
._callRemote
('getUserPlaylists', {})
281 if 'result' in result
:
282 return self
._parsePlaylists
(result
)
286 # Gets the playlists of the logged-in user
287 def getUserPlaylistsByUsername(self
, username
):
288 userID
= self
._getUserIDFromUsername
(username
)
290 result
= self
._callRemote
('getUserPlaylistsByUserID', {'userID' : userID
})
291 if 'result' in result
and result
['result']['playlists'] != None:
292 playlists
= result
['result']['playlists']
293 return self
._parsePlaylists
(playlists
)
297 # Creates a playlist with songs
298 def createPlaylist(self
, name
, songIDs
):
299 result
= self
._callRemote
('createPlaylist', {'name' : name
, 'songIDs' : songIDs
})
300 if 'result' in result
and result
['result']['success'] == True:
301 return result
['result']['playlistID']
302 elif 'errors' in result
:
305 # Sets the songs for a playlist
306 def setPlaylistSongs(self
, playlistID
, songIDs
):
307 result
= self
._callRemote
('setPlaylistSongs', {'playlistID' : playlistID
, 'songIDs' : songIDs
})
308 if 'result' in result
and result
['result']['success'] == True:
313 # Gets the songs of a playlist
314 def getPlaylistSongs(self
, playlistID
):
315 result
= self
._callRemote
('getPlaylistSongs', {'playlistID' : playlistID
});
316 if 'result' in result
:
317 return self
._parseSongs
(result
)
322 def playlistDelete(self
, playlistId
):
323 result
= self
._callRemote
("deletePlaylist", {"playlistID": playlistId
})
324 if 'fault' in result
:
329 def playlistRename(self
, playlistId
, name
):
330 result
= self
._callRemote
("renamePlaylist", {"playlistID": playlistId
, "name": name
})
331 if 'fault' in result
:
336 def getSimilarArtists(self
, artistId
, limit
):
337 items
= self
._callRemote
("getSimilarArtists", {"artistID": artistId
, "limit": limit
})
338 if 'result' in items
:
341 artists
= items
['result']['artists']
342 while(i
< len(artists
)):
344 list.append([s
['artistName'].encode('ascii', 'ignore'),\
351 # After 30s play time
352 def markStreamKeyOver30Secs(self
):
353 params
= { "streamKey" : self
._lastStreamKey
, "streamServerID" : self
._lastStreamServerID
}
354 self
._callRemote
("markStreamKeyOver30Secs", params
)
357 def markSongComplete(self
, songid
):
358 params
= { "songID" : songid
, "streamKey" : self
._lastStreamKey
, "streamServerID" : self
._lastStreamServerID
}
359 self
._callRemote
("markSongComplete", params
)
362 def _parseSongs(self
, items
, limit
=0):
363 if 'result' in items
:
369 if 'songs' in items
['result'][0]:
370 l
= len(items
['result'][0]['songs'])
374 if l
< 0 and 'songs' in items
['result']:
375 l
= len(items
['result']['songs'])
379 if l
< 0 and 'song' in items
['result']:
385 l
= len(items
['result'])
388 if limit
> 0 and l
> limit
:
391 if index
== 'songs[]':
392 s
= items
['result'][0]['songs'][i
]
393 elif index
== 'songs':
394 s
= items
['result'][index
][i
]
395 elif index
== 'song':
396 s
= items
['result'][index
]
398 s
= items
['result'][i
]
399 if 'CoverArtFilename' not in s
:
400 info
= self
.getSongsInfo(s
['SongID'])
401 coverart
= info
['CoverArtFilename']
402 elif s
['CoverArtFilename'] != None:
403 coverart
= THUMB_URL
+s
['CoverArtFilename'].encode('ascii', 'ignore')
406 list.append([s
['SongName'].encode('ascii', 'ignore'),\
408 s
['AlbumName'].encode('ascii', 'ignore'),\
410 s
['ArtistName'].encode('ascii', 'ignore'),\
418 # Extract artist data
419 def _parseArtists(self
, items
):
420 if 'result' in items
:
423 artists
= items
['result']['artists']
424 while(i
< len(artists
)):
426 list.append([s
['ArtistName'].encode('ascii', 'ignore'),\
434 def _parseAlbums(self
, items
, limit
=0):
435 if 'result' in items
:
439 albums
= items
['result']['albums']
441 res
= items
['result'][0]
442 albums
= res
['albums']
444 if limit
> 0 and l
> limit
:
448 if 'CoverArtFilename' in s
and s
['CoverArtFilename'] != None:
449 coverart
= THUMB_URL
+s
['CoverArtFilename'].encode('ascii', 'ignore')
452 list.append([s
['ArtistName'].encode('ascii', 'ignore'),\
454 s
['AlbumName'].encode('ascii', 'ignore'),\
462 def _parsePlaylists(self
, items
):
465 if 'result' in items
:
466 playlists
= items
['result']['playlists']
472 while (i
< len(playlists
)):
474 list.append([str(s
['PlaylistName']).encode('ascii', 'ignore'), s
['PlaylistID']])
481 #groovesharkApi = GrooveAPI()
482 #res = groovesharkApi.pingService()
483 #res = groovesharkApi.login(sys.argv[1], sys.argv[2])
485 #songIds.append('28645456')
486 #songIds.append('26579347')
487 #res=groovesharkApi.playlistRename(58197714, 'renamed playlist2')
488 #res = groovesharkApi.createPlaylist("Test", songIDs)
489 #res = groovesharkApi.setPlaylistSongs('58197714',songIds)
491 #res = groovesharkApi.getPlaylistSongs('58197714')
492 #res = groovesharkApi.getSongSearchResults('jimmy jazz', 3)
493 #res = groovesharkApi.getPopularSongsToday(3)
494 #res = groovesharkApi.getSongURLFromSongID('26579347')
495 #res = groovesharkApi.getAlbumSearchResults('london calling', 3)
496 #res = groovesharkApi.getArtistAlbums('52283')
497 #res = groovesharkApi.getArtistSearchResults('the clash', 3)
498 #res = groovesharkApi.getUserFavoriteSongs()
499 #res = groovesharkApi.getUserPlaylists()
500 #res = groovesharkApi.getSongInfos('27425375')
501 #res = groovesharkApi.getPlaylistSongs(40902662)
502 #res = groovesharkApi.addUserFavoriteSong('27425375')
503 #res = groovesharkApi.logout()
504 #res = groovesharkApi.getUserPlaylistsByUsername('stephendenham')
505 #res = groovesharkApi.getArtistPopularSongs('3707')