# pandora.com v15 xmlrpc encrypt/decrypt routines
# for data sent to /radio/xmlrpc/v15 in a POST
# usage:
# _xmlrpc_request_ = pandora_decrypt(_POST_data_)
# _POST_data_ = pandora_encrypt(_xmlrpc_request_)
def blowfish_round_function(XL):
F = S[0][XL>>24]
F += S[1][(XL>>16)&0xff]
F &= 0xffffffff
F ^= S[2][(XL>>8)&0xff]
F += S[3][XL&0xff]
F &= 0xffffffff
return F
def blowfish_intlist_decrypt(Li):
Lo = []
for i in xrange(0, len(Li), 2):
Lo.extend(blowfish_block_decrypt(Li[i], Li[i+1]))
return Lo
def blowfish_intlist_encrypt(Li):
Lo = []
for i in xrange(0, len(Li), 2):
Lo.extend(blowfish_block_encrypt(Li[i], Li[i+1]))
return Lo
def hexstr_to_intlist(H):
L = []
Hl = len(H)
Hm = Hl%8
for i in xrange(0, Hl-Hm, 8):
L.append(int(H[i:i+8],16))
if Hm > 0:
L.append(int(H[Hl-Hm:]+('0'*(8-Hm)),16))
return L
def intlist_to_hexstr(L):
H = ""
for I in L:
s = hex(I).replace('0x','').replace('L','')
H += ('0'*(8-len(s)))+s
return H
def str_to_intlist(S):
L = []
Sl = len(s)
Sm = Sl%4
if Sm > 0:
S += chr(0)*(4-Sm)
for i in xrange(0, len(S), 4):
L.append((ord(S[i])<<24)+(ord(S[i+1])<<16)+(ord(S[i+2])<<8)+ord(S[i+3]))
return L
def intlist_to_str(L):
S = ""
for I in L:
S += chr(I>>24&0xff)+chr(I>>16&0xff)+chr(I>>8&0xff)+chr(I&0xff)
return S
S[0] =(see post >>2)
S[1] =(see post >>3)
S[2] =(see post >>4)
S[3] =(see post >>5)
def blowfish_round_function(XL):
F = S[0][XL>>24]
F += S[1][(XL>>16)&0xff]
F &= 0xffffffff
F ^= S[2][(XL>>8)&0xff]
F += S[3][XL&0xff]
F &= 0xffffffff
return F
def blowfish_intlist_decrypt(Li):
Lo = []
for i in xrange(0, len(Li), 2):
Lo.extend(blowfish_block_decrypt(Li[i], Li[i+1]))
return Lo
def blowfish_intlist_encrypt(Li):
Lo = []
for i in xrange(0, len(Li), 2):
Lo.extend(blowfish_block_encrypt(Li[i], Li[i+1]))
return Lo
def hexstr_to_intlist(H):
L = []
Hl = len(H)
Hm = Hl%8
for i in xrange(0, Hl-Hm, 8):
L.append(int(H[i:i+8],16))
if Hm > 0:
L.append(int(H[Hl-Hm:]+('0'*(8-Hm)),16))
return L
def intlist_to_hexstr(L):
H = ""
for I in L:
s = hex(I).replace('0x','').replace('L','')
H += ('0'*(8-len(s)))+s
return H
def str_to_intlist(S):
L = []
Sm = len(S)%8
if Sm > 0:
S += chr(0)*(8-Sm)
for i in xrange(0, len(S), 4):
L.append((ord(S[i])<<24)+(ord(S[i+1])<<16)+(ord(S[i+2])<<8)+ord(S[i+3]))
return L
def intlist_to_str(L):
S = ""
for I in L:
S += chr(I>>24&0xff)+chr(I>>16&0xff)+chr(I>>8&0xff)+chr(I&0xff)
return S
def variable_to_xml(A):
X = "<value>"
tA = type(A)
if tA == list:
X += "<array><data>"
for B in A:
X += variable_to_xml(B)
X += "</data></array>"
elif tA == dict:
X += "<struct>"
for Ak in A:
X += "<member><name>"
X += Ak
X += "</name></member>"
X += variable_to_xml(A[Ak])
X += "</struct>"
elif tA == bool:
X += "<boolean>"
X += "1" if A else "0"
X += "</boolean>"
elif tA == int or tA == long:
X += "<int>"
X += str(A).replace('L','')
X += "</int>"
elif tA == str:
X += "<string>"
X += A
X += "</string>"
X += "</value>"
return X
def make_xmlrpc_content(method, params):
X = "<?xml version=\"1.0\"?><methodCall><methodName>"
X += method
X += "</methodName><params>"
for P in params:
X += "<param>"
X += variable_to_xml(P)
X += "</param>"
X += "</params></methodCall>"
return X
def pandora_make_url(method, args, ssl, rid, lid):
url = "http"
url += "s" if ssl else ""
url += "://www.pandora.com/radio/xmlrpc/v15?rid="
url += ('0'*6+str(rid))[-7:]
url += "P"
if lid != None:
url += "&lid="
url += str(lid)
url += "&method="
url += method.split(".")[-1]
for i in xrange(len(args)):
url += "&arg"
url += str(i+1)
url += "="
url += urllib.quote_plus(str(args[i]))
return url
def pandora_xmlrpc_call(method, args, ssl, rid, lid):
url = pandora_make_url(method, args, ssl, rid, lid)
data = pandora_encrypt(make_xmlrpc_content(method, args))
headers = {"User-Agent":"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)","Content-Type":"text/xml","Content-Length":str(len(data))}
req = urllib2.Request(url, data, headers)
res = urllib2.urlopen(req)
return res.read()
python -i post_22.py
>>> pandora_xmlrpc_call("misc.sync", [], False, 1234567, None)... xmlrpc response from server ...
>>> pandora_decrypt(data from Firefox's LiveHTTPHeaders, Wireshark etc)... decoded xmlrpc request ...
Parameters to pandora_xmlrpc_call:
1. method - string, method name
2. args - list of parameters
3. ssl - boolean indicating if https or http
4. rid - integer, route id (randomly generated for session)
5. lid - integer, listener id (returned from listener.getListenerResult method) or None if we don't have one yet
I get:
<?xml version="1.0" encoding="UTF-8"?><methodResponse><fault><value><struct><member><name>faultString</name><value>org.apache.xmlrpc.XmlRpcException: Illegal hex value AE at byte 1</value></member><member><name>faultCode</name><value><int>0</int></value></member></struct></value></fault></methodResponse>
>>29
wow, disputes over little implementation details. JUST ADD THE DAMN SWITCH STATEMENT AND BE DONE WITH IT, WE DONT GIVE A SHIT ABOUT HOW ITS IMPLEMENTED.
Python's community is a bit like that of the Macfags.
Name:
Anonymous2008-01-31 16:30
>>30
And it's a shame, 'cause Python is generally a damn good language.
Name:
Anonymous2008-01-31 16:31
>>31
ONE WORD. THE FORCED ASSIMILATION OF OPINION. NEWFAG OVER.
Name:
Anonymous2008-01-31 18:17
>>29 Unfortunately now we are forced to indent the case expressions
How fitting.
The only real use for switch statements is for forced loop unrolling without -funroll-loops. If you're in a situation where using a switchstatement is cleaner than using an if-elif chain (as the PyFags call it), then (in most cases) you've done something wrong with respect to the program structure.
>>37
Implementation details are besides the point.
Even if they were; I don't have any documents or evidence of this, but I'd assume that a jmp is more costly than a couple cmp's. I'm not going to even try to argue this; if someone claims that it's the opposite, then so be it.
The point is that a single syntactic construct suffices for both if clauses and switch statements. And, for the most part, if clauses are shorter to write (in C, at least) because of the explicit break which is required. Composited cases are shorter to write too - conditions can simply be chained with ||, which saves you 3 characters over case:.
Finally, unlike C-style switch statements, if-else blocks are unambiguous - their bounds are clearly delimited by brackets, whereas cases in a switch statement can run over into one another.
tl;dr - code clarity over premature optimizations.
Composited cases are shorter to write too
I just wanted to point out that, in some cases, using cases which flow into one another can shorten code length, but I maintain my argument that this method
* Reduces overall code clarity.
* Suggests a possible flaw in overall program flow.
* Could be refactored to minimize code duplication while still avoiding the switch block.
Switches are just a glorified, limited goto. Yes, they exist, and yes, they're useful in some situations. But you should still avoid them like the plague.
Name:
Anonymous2008-02-01 4:30
>>39
And loops are also ``just a glorified, limited goto''. Yes, they exist, and yes, they're useful in some situations. But you should still avoid them like the plague, since loops can always be replaced by recursion.