Página 1 de 1

Grooveshark internal methods

Publicado: 12 Oct 2014, 16:20
por sanko
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.
"""
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

Re: Grooveshark internal methods

Publicado: 12 Oct 2014, 17:07
por Blau
Buen trabajo