From 44dcc6f4add9cc470a9ee4a82db321ccb257b8be Mon Sep 17 00:00:00 2001 From: stephendenham Date: Thu, 13 Jan 2011 10:48:26 +0000 Subject: [PATCH] Session caching. git-svn-id: svn://svn.code.sf.net/p/xbmc-groove/code@31 2dec19e3-eb1d-4749-8193-008c8bba0994 --- resources/lib/GroovesharkAPI.py | 113 ++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 29 deletions(-) diff --git a/resources/lib/GroovesharkAPI.py b/resources/lib/GroovesharkAPI.py index 85a1ad1..fbc0389 100644 --- a/resources/lib/GroovesharkAPI.py +++ b/resources/lib/GroovesharkAPI.py @@ -1,5 +1,7 @@ import socket, hmac, urllib, urllib2, pprint, md5, uuid, re, hashlib, time, random, os, pickle +SESSION_EXPIRY = 518400 # 6 days in seconds + # GrooveAPI constants THUMB_URL = 'http://beta.grooveshark.com/static/amazonart/' THUMB_URL_DEFAULT = 'http://grooveshark.com/webincludes/logo/Grooveshark_Logo_No-Text.png' @@ -10,17 +12,18 @@ ARTIST_LIMIT = 15 # GrooveSong constants DOMAIN = "grooveshark.com" HOME_URL = "http://listen." + DOMAIN -TOKEN_URL = "http://cowbell." + DOMAIN + "/more.php" API_URL = "http://cowbell." + DOMAIN + "/more.php" SERVICE_URL = "http://cowbell." + DOMAIN + "/service.php" +TOKEN_URL = "http://cowbell." + DOMAIN + "/more.php" +TOKEN_EXPIRY = 1000 -CLIENT_NAME = "gslite" #htmlshark #jsqueue -CLIENT_VERSION = "20101012.37" #"20100831.25" +CLIENT_NAME = "gslite" +CLIENT_VERSION = "20101012.37" HEADERS = {"Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 3.5.30729)", "Referer": "http://listen.grooveshark.com/main.swf?cowbell=fe87233106a6cef919a1294fb2c3c05f"} -RE_SESSION = re.compile('"sessionID":"\s*?([A-z0-9]+)"') #re.compile('sessionID:\s*?\'([A-z0-9]+)\',') +RE_SESSION = re.compile('"sessionID":"\s*?([A-z0-9]+)"') RANDOM_CHARS = "1234567890abcdef" # Get a song @@ -33,10 +36,18 @@ class GrooveSong: self.cacheDir = cacheDir self._lastTokenTime = 0 + self._lastSessionTime = 0 self.uuid = self._getUUID() - self.sessionID = self._getSession(HOME_URL) - if self.sessionID == None: - raise StandardError("Cannot get session id") + + self._getSavedSession() + # session ids last 1 week + if self.sessionID == '' or time.time() - self._lastSessionTime >= SESSION_EXPIRY: + self.sessionID = self._getSession(HOME_URL) + if self.sessionID == '': + raise StandardError('Failed to get session id') + else: + print "New GrooveSong session id: " + self.sessionID + self._setSavedSession() # The actual call to the API def _callRemote(self, method, params, type="default"): @@ -85,11 +96,12 @@ class GrooveSong: # Make a token ready for a request header def _getMethodToken(self, method): - if (time.time() - self._lastTokenTime) >= 1000: + if (time.time() - self._lastTokenTime) >= TOKEN_EXPIRY: self._token = self._getCommunicationToken() if self._token == None: return None self._lastTokenTime = time.time() + self._setSavedSession() randomChars = "" while 6 > len(randomChars): @@ -135,9 +147,41 @@ class GrooveSong: html = urllib2.urlopen(HOME_URL).read() session = RE_SESSION.search(html) if session: + self._lastSessionTime = time.time() return session.group(1) else: return None + + def _getSavedSession(self): + path = os.path.join(self.cacheDir, 'session.dmp') + try: + f = open(path, 'rb') + session = pickle.load(f) + self.sessionID = session['sessionID'] + self._lastSessionTime = session['lastSessionTime'] + self._token = session['token'] + self._lastTokenTime = session['lastTokenTime'] + f.close() + except: + self.sessionID = '' + self._lastSessionTime = 0 + self._token = '' + self._lastTokenTime = 0 + pass + + def _setSavedSession(self): + try: + # Create the 'data' directory if it doesn't exist. + if not os.path.exists(self.cacheDir): + os.makedirs(self.cacheDir) + path = os.path.join(self.cacheDir, 'session.dmp') + f = open(path, 'wb') + session = {'sessionID' : self.sessionID, 'lastSessionTime' : self._lastSessionTime, 'token' : self._token, 'lastTokenTime' : self._lastTokenTime} + pickle.dump(session, f, protocol=pickle.HIGHEST_PROTOCOL) + f.close() + except: + print "An error occurred during save session" + pass # Gets a stream key and host to get song content def _getStreamDetails(self, songID): @@ -186,15 +230,15 @@ class GrooveAPI: self.simplejson = simplejson socket.setdefaulttimeout(40) self.cacheDir = cacheDir - self._getSavedSessionID() + self._getSavedSession() # session ids last 1 week - if self.sessionID == '' or time.time()- self.lastSessionTime >= 6*86400: + if self.sessionID == '' or time.time()- self.lastSessionTime >= SESSION_EXPIRY: self.sessionID = self._getSessionID() if self.sessionID == '': raise StandardError('Failed to get session id') else: - print "New session id: " + self.sessionID - self._setSavedSessionID() + print "New GrooveAPI session id: " + self.sessionID + self._setSavedSession() # Sort keys def _keySort(self, d): @@ -234,32 +278,34 @@ class GrooveAPI: self.lastSessionTime = time.time() return result['result']['sessionID'] - def _getSavedSessionID(self): - path = os.path.join(self.cacheDir, 'session', 'session.dmp') + def _getSavedSession(self): + path = os.path.join(self.cacheDir, 'grooveapi', 'session.dmp') try: f = open(path, 'rb') session = pickle.load(f) self.sessionID = session['sessionID'] self.lastSessionTime = session['lastSessionTime'] + self.userID = session['userID'] f.close() except: self.sessionID = '' self.lastSessionTime = 0 + self.userID = 0 pass - def _setSavedSessionID(self): + def _setSavedSession(self): try: - dir = os.path.join(self.cacheDir, 'session') + dir = os.path.join(self.cacheDir, 'grooveapi') # Create the 'data' directory if it doesn't exist. if not os.path.exists(dir): os.makedirs(dir) path = os.path.join(dir, 'session.dmp') f = open(path, 'wb') - session = { 'sessionID' : self.sessionID, 'lastSessionTime' : self.lastSessionTime} + session = { 'sessionID' : self.sessionID, 'lastSessionTime' : self.lastSessionTime, 'userID': self.userID} pickle.dump(session, f, protocol=pickle.HIGHEST_PROTOCOL) f.close() except: - print "An error occured during save session" + print "An error occurred during save session" pass # Make user authentication token @@ -274,18 +320,25 @@ class GrooveAPI: # Login def login(self, username, password): - token = self._getUserToken(username, password) - self.userID = self._authenticateUser(username, token) + if self.userID <= 0: + # Check cache + self._getSavedSession() + if self.userID <= 0: + token = self._getUserToken(username, password) + self.userID = self._authenticateUser(username, token) + if self.userID > 0: + self._setSavedSession() return self.userID # Logs the user out def logout(self): - self._callRemote('logout', {'sessionID' : self.sessionID}) + result = self._callRemote('logout', {'sessionID' : self.sessionID}) + if 'result' in result and result['result']['success'] == True: + self.userID = 0 + self._setSavedSession() + return True + return False - # Return user id - def getUserID(self): - return self.userID - # Search for albums def getArtistSearchResults(self, query, limit=ARTIST_LIMIT): result = self._callRemote('getArtistSearchResults', {'query' : query,'limit' : limit}) @@ -337,7 +390,8 @@ class GrooveAPI: # Get the url to link to a song on Grooveshark def getSongURLFromSongID(self, songID): - song = GrooveSong(self.cacheDir) + cacheDir = os.path.join(self.cacheDir, 'groovesong') + song = GrooveSong(cacheDir) return song.getSongURL(songID) # Get the url to link to a song on Grooveshark @@ -484,17 +538,18 @@ class GrooveAPI: import sys res = [] groovesharkApi = GrooveAPI('/tmp') -res = groovesharkApi.login(sys.argv[1], sys.argv[2]) +#res = groovesharkApi.login(sys.argv[1], sys.argv[2]) #res = groovesharkApi.getSongSearchResults('jimmy jazz', 3) #res = groovesharkApi.getPopularSongsToday() -#res = groovesharkApi.getSongURLFromSongID('27425375') +res = groovesharkApi.getSongURLFromSongID('27425375') #res = groovesharkApi.getAlbumSearchResults('london calling', 3) #res = groovesharkApi.getArtistSearchResults('the clash', 3) #res = groovesharkApi.getUserFavoriteSongs() -res = groovesharkApi.getUserPlaylists() +#res = groovesharkApi.getUserPlaylists() #res = groovesharkApi.getSongInfo('27425375') #res = groovesharkApi.getPlaylistSongs(40902662) #res = groovesharkApi.addUserFavoriteSong('27425375') +#res = groovesharkApi.logout() pprint.pprint(res) -- 2.20.1