Grooveshark internal methods
Publicado: 12 Oct 2014, 16:20
No comments, un script que usa los métodos internos de grooveshark para buscar canciones, artistas o álbunes y para descargar las canciones sin limite.
[Loving overxflow -> set_time_limit]
saludos
"""
A class implementing a internal API of Grooveshark.com
Ref: http://nettech.wikia.com/wiki/Grooveshark_Methods
Author: sanko
"""
import random, uuid, string, hashlib, httplib, json, gzip, StringIO, sys, urllib
class InternalGroove:
def __init__(self):
self.url = "grooveshark.com"
self.agent = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5", "Content-Type":"application/json", "Accept-Encoding":"gzip"}
#Neccessary headers to use InternalAPI methods
self.header = {}
self.header["country"] = {}
self.header["country"]["CC1"] = 72057594037927940
self.header["country"]["CC2"] = 0
self.header["country"]["CC3"] = 0
self.header["country"]["CC4"] = 0
self.header["country"]["ID"] = 57
self.header["country"]["IPR"] = 0
self.header["privacy"] = 0
self.header["session"] = (''.join(random.choice(string.digits + string.letters[:6]) for x in range(32))).lower()
self.header["uuid"] = str.upper(str(uuid.uuid4()))
def staticToken(self):
h = {}
h["parameters"] = {}
h["parameters"]["secretKey"] = hashlib.md5(self.header["session"]).hexdigest()
h["method"] = "getCommunicationToken"
h["header"] = self.header
h["header"]["client"] = "htmlshark"
h["header"]["clientRevision"] = "20130520"
conn = httplib.HTTPSConnection(self.url)
conn.request("POST", "/more.php", json.JSONEncoder().encode(h), self.agent)
self.genToken = json.JSONDecoder().decode(gzip.GzipFile(fileobj=(StringIO.StringIO(conn.getresponse().read()))).read())["result"]
return self.genToken
def methodToken(self, method, secret):
rnd = (''.join(random.choice(string.hexdigits) for x in range(6))).lower()
return rnd + hashlib.sha1('%s:%s:%s:%s' % (method, self.staticToken(), secret, rnd)).hexdigest()
def getResultsFromSearch(self,query, qType='Songs'):
h= {}
h["parameters"] = {}
h["parameters"]["type"] = qType
h["parameters"]["query"] = query
h["header"] = self.header
h["header"]["client"] = "htmlshark"
h["header"]["clientRevision"] = "20130520"
h["header"]["token"] = self.methodToken("getResultsFromSearch", 'nuggetsOfBaller')
h["method"] = "getResultsFromSearch"
conn = httplib.HTTPSConnection(self.url)
conn.request("POST", "/more.php", json.JSONEncoder().encode(h), self.agent)
self.result = json.JSONDecoder().decode(gzip.GzipFile(fileobj=(StringIO.StringIO(conn.getresponse().read()))).read())
return self.result
def getStreamKeyFromSongIDEx(self, songID):
h = {}
h["parameters"] = {}
#h["parameters"]["type"] = 8
h["parameters"]["mobile"] = False
h["parameters"]["prefetch"] = False
h["parameters"]["songIDs"] = songID
h["parameters"]["country"] = self.header["country"]
h["header"] = self.header
h["header"]["client"] = "jsqueue"
h["header"]["clientRevision"] = "20130520"
h["header"]["token"] = self.methodToken("getStreamKeysFromSongIDs", 'nuggetsOfBaller')
h["method"] = "getStreamKeysFromSongIDs"
conn = httplib.HTTPConnection(self.url)
conn.request("POST", "/more.php?" + h["method"], json.JSONEncoder().encode(h), {"User-Agent":self.agent, "Referer": 'http://%s/JSQueue.swf?%s' % (self.url, "20130520"), "Accept-Encoding":"gzip", "Content-Type":"application/json"})
return json.JSONDecoder().decode(gzip.GzipFile(fileobj=(StringIO.StringIO(conn.getresponse().read()))).read())
"""
Method to avoid be banned
"""
def markSongAsDownloaded(self, streamServer, songID, streamKey):
h = {}
h["parameters"] = {}
h["parameters"]["streamServerID"] = streamServer
h["parameters"]["songID"] = songID
h["parameters"]["streamKey"] = streamKey
h["header"] = self.header
h["header"]["client"] = "jsqueue"
h["header"]["clientRevision"] = "20130520"
h["header"]["token"] = self.methodToken("markSongDownloadedEx", "nuggetsOfBaller")
h["method"] = "markSongDownloadedEx"
conn = httplib.HTTPConnection(self.url)
conn.request("POST", "/more.php?" + h["method"], json.JSONEncoder().encode(h), {"User-Agent":self.agent, "Referer": 'http://%s/JSQueue.swf?%s' % (self.url, "20130520"), "Accept-Encoding":"gzip", "Content-Type":"application/json"})
return json.JSONDecoder().decode(gzip.GzipFile(fileobj=(StringIO.StringIO(conn.getresponse().read()))).read())
def tinyShorter(self, url):
tinyUrl = "http://tinyurl.com/api-create.php?url=%s" % url
return urllib.urlopen(tinyUrl).read()
if __name__ == "__main__":
options = ['-searchSong']
if sys.argv[1] == options[0] and len(sys.argv) == 3:
total = InternalGroove().getResultsFromSearch(sys.argv[2])["result"]
final = []
for i in total["result"]:
final.append({"Titulo":i["AlbumName"],
"Artista":i["ArtistName"],
"ID":i["SongID"],
"URL":InternalGroove().tinyShorter("http://%s/stream.php?streamKey=%s" % (InternalGroove().getStreamKeyFromSongIDEx(i["SongID"])["result"][i["SongID"]]["ip"],
InternalGroove().getStreamKeyFromSongIDEx(i["SongID"])["result"][i["SongID"]]["streamKey"]))})
#avoiding be banned
InternalGroove().markSongAsDownloaded(InternalGroove().getStreamKeyFromSongIDEx(i["SongID"])["result"][i["SongID"]]["ip"],
InternalGroove().getStreamKeyFromSongIDEx(i["SongID"]), InternalGroove().getStreamKeyFromSongIDEx(i["SongID"])["result"][i["SongID"]]["streamKey"])
print final
y un php para aquellos que quieren hacer una implementación cutre en su servidor:[Loving overxflow -> set_time_limit]
<?php
if(isset($_GET["q"]) && !empty($_GET["q"])){
set_time_limit(2000);
echo exec('python2 internalGroove.py -searchSong '.$_GET["q"]);
}
?>
y otro extra, un pequeño y cutre script que usa sfwdump para sacar el secretKey actual para el cliente JSQueue:"""
Author: sanko
Script to generate a new secret key to use it in interGroove script
secretKey for client: JSQueue
url to down: "http://grooveshark.com/JSQueue.swf"
"""
import urllib, os
def downSWF(url, path, sFilename):
urllib.urlretrieve(url, path+sFilename+".swf")
def dumpAndSearch(swf):
"""SWF file path"""
print os.system('swfdump -D %s | grep "secretKey"' % swf)
dumpAndSearch('JSQueue.swf')
saludos