1 import socket
, hmac
, urllib
, urllib2
, pprint
, md5
, os
, pickle
2 from operator
import itemgetter
4 THUMB_URL
= 'http://beta.grooveshark.com/static/amazonart/'
5 THUMB_URL_DEFAULT
= 'http://grooveshark.com/webincludes/logo/Grooveshark_Logo_No-Text.png'
15 host
= 'api.grooveshark.com'
18 def __init__(self
, sessionID
= ''):
20 self
.simplejson
= simplejson
21 socket
.setdefaulttimeout(40)
23 self
.sessionID
= self
._getSessionID
()
25 self
.sessionID
= sessionID
27 def _keySort(self
, d
):
28 return [(k
,d
[k
]) for k
in sorted(d
.keys())]
31 def _createMessageSig(self
, method
, params
, secret
):
32 args
= self
._keySort
(params
);
39 h
= hmac
.new(secret
, data
)
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'))
46 req
= urllib2
.Request(url
)
47 response
= urllib2
.urlopen(req
)
48 result
= response
.read()
52 result
= self
.simplejson
.loads(result
)
60 def getSessionID(self
):
63 def _getSessionID(self
):
65 result
= self
._callRemote
('startSession', params
)
66 return result
['result']['sessionID']
68 # Make user authentication token
69 def _getUserToken(self
, username
, password
):
70 return md5
.new(username
.lower() + md5
.new(password
).hexdigest()).hexdigest()
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']
79 def login(self
, username
, password
):
80 token
= self
._getUserToken
(username
, password
)
81 self
.userID
= self
._authenticateUser
(username
, token
)
86 self
._callRemote
('logout', {'sessionID' : self
.sessionID
})
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
)
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
)
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
)
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
)
120 # Gets the favorite songs of the logged-in user
121 def getUserFavoriteSongs(self
):
122 if (self
.userID
== 0):
124 result
= self
._callRemote
('getUserFavoriteSongs', {'sessionID' : self
.sessionID
})
125 if 'result' in result
:
126 return self
._parseSongs
(result
)
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')
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')
147 info
['CoverArtFilename'] = THUMB_URL_DEFAULT
152 # Gets the playlists of the logged-in user
153 def getUserPlaylists(self
):
154 if (self
.userID
== 0):
156 result
= self
._callRemote
('getUserPlaylists', {'sessionID' : self
.sessionID
})
157 if 'result' in result
:
158 return self
._parsePlaylists
(result
)
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):
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':
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
)
193 def _parseSongs(self
, items
):
194 if 'result' in items
:
197 if 'songs' in items
['result']:
198 l
= len(items
['result']['songs'])
200 elif 'song' in items
['result']:
204 l
= len(items
['result'])
208 s
= items
['result'][index
][i
]
209 elif index
== 'song':
210 s
= items
['result'][index
]
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')
219 coverart
= THUMB_URL_DEFAULT
220 list.append([s
['SongName'].encode('ascii', 'ignore'),\
222 s
['AlbumName'].encode('ascii', 'ignore'),\
224 s
['ArtistName'].encode('ascii', 'ignore'),\
232 # Extract artist data
233 def _parseArtists(self
, items
):
234 if 'result' in items
:
237 artists
= items
['result']['artists']
238 while(i
< len(artists
)):
240 list.append([s
['ArtistName'].encode('ascii', 'ignore'),\
248 def _parseAlbums(self
, items
):
249 if 'result' in items
:
252 albums
= items
['result']['albums']
253 while(i
< len(albums
)):
255 if 'CoverArtFilename' in s
and s
['CoverArtFilename'] != None:
256 coverart
= THUMB_URL
+s
['CoverArtFilename'].encode('ascii', 'ignore')
258 coverart
= THUMB_URL_DEFAULT
259 list.append([s
['ArtistName'].encode('ascii', 'ignore'),\
261 s
['AlbumName'].encode('ascii', 'ignore'),\
269 def _parsePlaylists(self
, items
):
270 if 'result' in items
:
273 playlists
= items
['result']
274 while(i
< len(playlists
)):
276 list.append([s
['PlaylistID'],\
277 s
['Name'].encode('ascii', 'ignore')])
284 groovesharkApi
= GrooveAPI('c4285d93d556349d284704100eb557d7')
285 print "SessionID: " + groovesharkApi
.getSessionID()
286 print "UserID: " + str(groovesharkApi
.login('stephendenham', 'lond0n'))
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')
297 res
= groovesharkApi
.getPlaylistSongs(40902662)