From 3d1a7a95b6a9328bd0ff9a5e4269900b761d8d46 Mon Sep 17 00:00:00 2001 From: Fred Shih Date: Thu, 28 Jun 2012 22:54:38 -0700 Subject: [PATCH] - Restructuring classes to be more suited for server use - Decoupling user account with general pandora connection - Modified all getters to require user information - Fixed test runs --- pandora/connection.py | 66 +++++++++++++++++++++++++------------------ pandora/pandora.py | 50 ++++++++++++++------------------ 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/pandora/connection.py b/pandora/connection.py index 33e7f85..40b8e07 100644 --- a/pandora/connection.py +++ b/pandora/connection.py @@ -13,9 +13,6 @@ class PandoraConnection(object): partner_id = None partner_auth_token = None - user_id = None - user_auth_token = None - time_offset = None PROTOCOL_VERSION = '5' @@ -29,52 +26,60 @@ class PandoraConnection(object): def __init__(self): self.rid = "%07i" % (time.time() % 1e7) self.timedelta = 0 + self.authenticate_connection() - def authenticate(self, user, pwd): + def authenticate_connection(self): try: # partner login - partner = self.do_request('auth.partnerLogin', True, False, deviceModel=self.DEVICE_MODEL, username=self.PARTNER_USERNAME, password=self.PARTNER_PASSWORD, version=self.PROTOCOL_VERSION) + partner = self.do_request('auth.partnerLogin', True, False, None, deviceModel=self.DEVICE_MODEL, username=self.PARTNER_USERNAME, password=self.PARTNER_PASSWORD, version=self.PROTOCOL_VERSION) self.partner_id = partner['partnerId'] self.partner_auth_token = partner['partnerAuthToken'] # sync pandora_time = int(crypt.pandora_decrypt(partner['syncTime'])[4:14]) self.time_offset = pandora_time - time.time() - - # user login - user = self.do_request('auth.userLogin', True, True, username=user, password=pwd, loginType="user") - self.user_id = user['userId'] - self.user_auth_token = user['userAuthToken'] + # + ## user login + #user = self.do_request('auth.userLogin', True, True, username=user, password=pwd, loginType="user") + #self.user_id = user['userId'] + #self.user_auth_token = user['userAuthToken'] return True except: self.partner_id = None self.partner_auth_token = None - self.user_id = None - self.user_auth_token = None - self.time_offset = None + #self.user_id = None + #self.user_auth_token = None + #self.time_offset = None return False + + def get_user_authentication(self, user, password): + try: + user = self.do_request('auth.userLogin', True, True, None, username = user, password = password, loginType = "user") + return {'userId': user['userId'], 'userAuthToken': user['userAuthToken']} + except: + return None + + def get_stations(self, user): + return self.do_request('user.getStationList', False, True, user)['stations'] - def get_stations(self): - return self.do_request('user.getStationList', False, True)['stations'] - - def get_fragment(self, stationId=None, additional_format="mp3"): - songlist = self.do_request('station.getPlaylist', True, True, stationToken=stationId, additionalAudioUrl=self.AUDIO_FORMAT_MAP[additional_format])['items'] + def get_fragment(self, user, stationId=None, additional_format="mp3"): + songlist = self.do_request('station.getPlaylist', True, True, user, stationToken=stationId, additionalAudioUrl=self.AUDIO_FORMAT_MAP[additional_format])['items'] self.curStation = stationId self.curFormat = format return songlist - def do_request(self, method, secure, crypted, **kwargs): + def do_request(self, method, secure, crypted, user, **kwargs): url_arg_strings = [] if self.partner_id: url_arg_strings.append('partner_id=%s' % self.partner_id) - if self.user_id: - url_arg_strings.append('user_id=%s' % self.user_id) - if self.user_auth_token: - url_arg_strings.append('auth_token=%s'%urllib.quote_plus(self.user_auth_token)) + if user: + url_arg_strings.append('user_id=%s' % user['userId']) + if user: + url_arg_strings.append('auth_token=%s'%urllib.quote_plus(user['userAuthToken'])) elif self.partner_auth_token: url_arg_strings.append('auth_token=%s' % urllib.quote_plus(self.partner_auth_token)) @@ -83,8 +88,8 @@ def do_request(self, method, secure, crypted, **kwargs): if self.time_offset: kwargs['syncTime'] = int(time.time()+self.time_offset) - if self.user_auth_token: - kwargs['userAuthToken'] = self.user_auth_token + if user: + kwargs['userAuthToken'] = user['userAuthToken'] elif self.partner_auth_token: kwargs['partnerAuthToken'] = self.partner_auth_token data = json.dumps(kwargs) @@ -99,6 +104,7 @@ def do_request(self, method, secure, crypted, **kwargs): # parse result tree = json.loads(text) + print tree if tree['stat'] == 'fail': code = tree['code'] msg = tree['message'] @@ -122,11 +128,15 @@ def do_request(self, method, secure, crypted, **kwargs): password = raw_input() # authenticate - print "Authenthicated: " + str(pandora.authenticate(username, password)) + pandora.authenticate_connection + user = pandora.get_user_authentication(username, password) + print "Authenthicated: " + str(user) + if not user: + raise Exception("Not authenticated") # output stations (without QuickMix) print "users stations:" - for station in pandora.getStations(): + for station in pandora.get_stations(user): if station['isQuickMix']: quickmix = station print "\t" + station['stationName'] + "*" @@ -144,4 +154,4 @@ def do_request(self, method, secure, crypted, **kwargs): #f = open('test.mp3', 'wb') #f.write(u.read()) #f.close() - #u.close() \ No newline at end of file + #u.close() diff --git a/pandora/pandora.py b/pandora/pandora.py index eab4c9e..13438c3 100644 --- a/pandora/pandora.py +++ b/pandora/pandora.py @@ -3,44 +3,33 @@ from connection import PandoraConnection class Pandora(object): - station_id = None - authenticated = False backlog = [] - def __init__(self): - self.connection = PandoraConnection() + def __init__(self, connection): + self.connection = connection def authenticate(self, username, password): - self.authenticated = self.connection.authenticate(username, password) - return self.authenticated + return self.connection.get_user_authentication(username, password) - def get_station_list(self): - return self.connection.get_stations() + def get_station_list(self, user): + return self.connection.get_stations(user) - def switch_station(self, station_id): - if type(station_id) is dict: - station_id = station_id['stationId'] - - if not self.authenticated: raise ValueError("User not yet authenticated") - + def switch_station(self, user, station_id): self.backlog = [] - self.station_id = station_id - self.backlog = self.connection.get_fragment(station_id) + self.backlog + self.backlog = self.connection.get_fragment(user, station_id) + self.backlog - def get_next_song(self): - if not self.authenticated: raise ValueError("User not yet authenticated") - if not self.station_id: raise ValueError("No station selected") - + def get_next_song(self, user, stationId): # get more songs if len(self.backlog) < 2: - self.backlog = self.connection.get_fragment(self.station_id) + self.backlog + self.backlog = self.connection.get_fragment(user, station_id) + self.backlog # get next song return self.backlog.pop() if __name__ == "__main__": - pandora = Pandora() + connection = PandoraConnection() + pandora = Pandora(connection) # read username print "Username: " @@ -59,29 +48,32 @@ def get_next_song(self): urllib2.install_opener(opener) # authenticate - print "Authenthicated: " + str(pandora.authenticate(username, password)) + user = pandora.authenticate(username, password) + print "Authenthicated: " + str(user) # output stations (without QuickMix) print "users stations:" - for station in pandora.getStationList(): + for station in pandora.get_station_list(user): if station['isQuickMix']: quickmix = station print "\t" + station['stationName'] + "*" else: print "\t" + station['stationName'] + print "\n\n\n" + quickmix = quickmix['stationId'] if type(quickmix) is dict else quickmix # switch to quickmix station - pandora.switchStation(quickmix) + pandora.switch_station(user, quickmix) # get one song from quickmix print "next song from quickmix:" - next = pandora.getNextSong() - print next['artistName'] + ': ' + next['songName'] - print next['audioUrlMap']['highQuality']['audioUrl'] + n = pandora.get_next_song(user, quickmix) + print n['artistName'] + ': ' + n['songName'] + print n['audioUrlMap']['highQuality']['audioUrl'] # download it #u = urllib2.urlopen(next['audioUrlMap']['highQuality']['audioUrl']) #f = open('test.mp3', 'wb') #f.write(u.read()) #f.close() - #u.close() \ No newline at end of file + #u.close()