#!/usr/bin/env python
# devloop.lyua.org 08/2008
# Trying to communicate with Anywhere.fm directly (whithout using the browser)
# Current problems for decoding AMF responses
# Code for developers only
import urllib, urllib2, cookielib, random
import sys, socket, os
# >> Please modify account information <<
account={'login':'toto','password':'toto'}
cj = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)
# Get our PHPSESSID
#agent = {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
req=urllib2.Request("http://www.anywhere.fm/")
socket.setdefaulttimeout(6)
try:
fd=urllib2.urlopen(req)
except IOError:
print "Error getting url"
sys.exit(1)
# >> Used only for tracking, commented <<
# Get our __qca and generate __qcb cookies
#req=urllib2.Request("http://edge.quantserve.com/quant.js")
#try:
# fd=urllib2.urlopen(req)
# htmlSource=fd.read()
# dc=htmlSource.split("var dc=\"")[1].split('"')[0]
#except IOError:
# print "Error getting url"
# sys.exit(1)
#except socket.timeout:
# print "timeout error"
# sys.exit(1)
#
#exp=cj._cookies['.quantserve.com']['/']['uid'].expires
#print "__qca =",dc,"- expires =",exp
#cj.set_cookie(cookielib.Cookie(version=0, name='__qca', value=dc, port=None, port_specified=False, domain='.anywhere.fm', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=exp, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False))
#
#qcb=str(int(random.random()*2147483647))
#print "__qcb =",qcb
#cj.set_cookie(cookielib.Cookie(version=0, name='__qcb', value=qcb, port=None, port_specified=False, domain='.anywhere.fm', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=exp, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False))
# Hardcoded initial Unique Request ID : works! :)
urid=1218964000
# Open a session with account information
req = urllib2.Request("http://music.anywhere.fm/account/login?_unique_request_id_="+str(urid),urllib.urlencode(account))
try:
fd=urllib2.urlopen(req)
htmlSource=fd.read()
except IOError:
print "Error getting url"
sys.exit(1)
except socket.timeout:
print "timeout error"
sys.exit(1)
if htmlSource.strip()!="<success>true</success>":
print "Warning: Connexion error! Check the credentials!"
print "Using default user_id (demo)"
else:
print "Connexion successfull"
urid+=1
# Get our user_id
req=urllib2.Request("http://music.anywhere.fm/account/get_current_user?_unique_request_id_="+str(urid))
try:
fd=urllib2.urlopen(req)
htmlSource=fd.read()
except IOError:
print "Error getting url"
sys.exit(1)
except socket.timeout:
print "timeout error"
sys.exit(1)
user_id=[q.strip() for q in htmlSource.split("\n") if q.find("user_id")>=0][0].split('>')[1].split('<')[0]
print "user_id =",user_id
# ! required for AMF queries, don't remove !
session_id=cj._cookies['music.anywhere.fm']['/']['auth_session_id'].value
# >> tracker_id is defined but not used, commented <<
#urid+=1
# Get our tracker_id
#tab={'session_id':session_id,'user_id':user_id}
#req = urllib2.Request("http://music.anywhere.fm/account/create_login_tracker?_unique_request_id_="+str(urid),urllib.urlencode(tab))
#try:
# fd=urllib2.urlopen(req)
# htmlSource=fd.read()
#except IOError:
# print "Error getting url"
# sys.exit(1)
#except socket.timeout:
# print "timeout error"
# sys.exit(1)
#
#tracker_id=htmlSource.split(">")[1].split("<")[0]
#print "tracker_id =",tracker_id
# Now let's go AMF :p
# feel free to modify user_id here for study, for example to 46 (=free music)
#user_id=46
import pyamf
from pyamf.remoting import client
from pyamf.flex import messaging
from pyamf import remoting
from pyamf import util
import uuid
urid+=1
# Get a list of playlists + informations about account, friends etc
# This is not necessary as we know the "Entire Playlist" is type 200 and id=user_id
# but it can be useful for customisation
url='http://www.anywhere.fm/amfphp/gateway.php?_unique_request_id_='+str(urid)
gw = client.RemotingService(url,pyamf.AMF0,pyamf.ClientTypes.Flash9)
message = messaging.RemotingMessage(operation=u'get_complete_profiles',
source=u'BlazingFast.DBQueries',
timestamp=0,
destination=u'amf',
clientId=None,
headers={u'DSEndpoint':None,u'DSId': u'nil'},
timeToLive=0,
messageId=unicode(uuid.uuid4()),
messageRefType=u'flex.messaging.messages.RemotingMessage',
body=[unicode(session_id),[user_id]])
gw.addRequest('null', message)
# Encode and inject
print "Getting the user profile..."
x=remoting.encode(gw.getAMFRequest(gw.requests)).getvalue()
xamf = {'Content-Type' : 'application/x-amf'}
req=urllib2.Request(url,data=x,headers=xamf)
socket.setdefaulttimeout(6)
try:
fd=urllib2.urlopen(req)
htmlSource=fd.read()
except IOError:
print "Error getting url"
sys.exit(1)
#doesn't work for the moment, unicode error :(
#liste=remoting.decode(htmlSource)
urid+=1
# Get the entire playlist of the user
url='http://www.anywhere.fm/amfphp/gateway.php?_unique_request_id_='+str(urid)
gw = client.RemotingService(url,pyamf.AMF0,pyamf.ClientTypes.Flash9)
message = messaging.RemotingMessage(operation=u'get_songs_for_user_playlists',
source=u'BlazingFast.DBQueries',
timestamp=0,
destination=u'amf',
clientId=None,
headers={u'DSEndpoint':None,u'DSId': u'nil'},
timeToLive=0,
messageId=unicode(uuid.uuid4()),
messageRefType=u'flex.messaging.messages.RemotingMessage',
body=[unicode(session_id),user_id,True,[user_id],[200],[u'0']])
gw.addRequest('null', message)
# Encode and inject
print "Getting the Entire Library playlist..."
x=remoting.encode(gw.getAMFRequest(gw.requests)).getvalue()
xamf = {'Content-Type' : 'application/x-amf'}
req=urllib2.Request(url,data=x,headers=xamf)
socket.setdefaulttimeout(6)
try:
fd=urllib2.urlopen(req)
htmlSource=fd.read()
except IOError:
print "Error getting url"
sys.exit(1)
#doesn't work for the moment, unicode error :(
#liste=remoting.decode(htmlSource)
urid+=1
# Get a valid url for an mp3 file (thumbs up lol)
user_id=5418
url='http://www.anywhere.fm/amfphp/gateway.php?_unique_request_id_='+str(urid)
gw = client.RemotingService(url,pyamf.AMF0,pyamf.ClientTypes.Flash9)
message = messaging.RemotingMessage(operation=u'get_song_url',
source=u'BlazingFast.DBQueries',
timestamp=0,
destination=u'amf',
clientId=None,
headers={u'DSEndpoint':None,u'DSId': u'nil'},
timeToLive=0,
messageId=unicode(uuid.uuid4()),
messageRefType=u'flex.messaging.messages.RemotingMessage',
body=[unicode(session_id),user_id,u'4722110-184833-204-44100-452',u'8113427'])
gw.addRequest('null', message)
# Encode and inject
print "Getting a valid music url..."
x=remoting.encode(gw.getAMFRequest(gw.requests)).getvalue()
xamf = {'Content-Type' : 'application/x-amf'}
req=urllib2.Request(url,data=x,headers=xamf)
socket.setdefaulttimeout(6)
try:
fd=urllib2.urlopen(req)
htmlSource=fd.read()
except IOError:
print "Error getting url"
sys.exit(1)
# This one works (the payload is very small, url in "standard" ascii)
liste=remoting.decode(htmlSource)
sesame=liste['/1'].body.body['url']
print "Reading url",sesame
# Let's play music hax0rz !!
os.system("mplayer '"+sesame+"'")
#####can be useful for debugging#####
#for index, cookie in enumerate(cj):
# print index,':',cookie