Jump to content

kleemajo

Members
  • Posts

    2
  • Joined

  • Last visited

Posts posted by kleemajo

  1. I came across this semi-accidentally and I think that it is a really cool project. I can't wait to see what else you have going! In the meantime, the script on the front page doesn't work, so here is a modified version that goes through the new grooveshark api calls that a few people were discussing above. I switched the functions around a bit so it won't work with the gui or command line and it won't actually play, but you can at least see how the api works from a python shell and get an mp3 file spewed out in hex. Just open a shell and type in the commands listed in Usage.

    '''
    Main class for handling of grooveshark
    
    one grooveshark instance represents one session (so usually one per application instance)
    '''
    import time
    import sys
    import uuid
    import hashlib
    import urllib
    import os
    import random
    import subprocess
    from mutagen.mp3 import MP3
    try:
        import json
    except ImportError:
        import simplejson as json#If this also errors allows the gui/user/whatever to handle the failed import
    #Third Pary Libaries
    import httplib2#Need version 5 or higher for python 2.6 compatability  - No version info in httplib2 so I can not check this :(
    
    #This is a default header that can be used if you just need a user agent change (this way not every function/method has to define this)
    header = {}
    header['user-agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)'
    
    '''
    Intialize Grooveshark
    -- Get Session Data No Return
    -- set ID3 tags No Return
    -- Work methods
        - search, return json search results
        - songKeyfromID return songKey
        - Download - return song
    
    
    
    Usage:
    from Grooveshark import Grooveshark
    g = Grooveshark()
    g.sessionData()
    -Searching
    g.search('some search string')
    -Get Song Key and Stream server
    g.songKeyfromID(songID)
    -Download
    g.download(songKey, streamServer)
    -Popular Songs
    g.Popular()
    
    '''
    class Grooveshark(object):
        def __init__(self):
            self.search_url = 'http://cowbell.grooveshark.com/more.php?getSearchResults'
            self.count = 0
        def save(self, content, path):
            file_ = open(path, 'wb')
            file_.write(content)
            file_.close()
        def sessionData(self):
            self.session = self.getSessionID()
            self.uuid = self.getUID()
            self.token = self.getToken()
        def getToken(self):
            http = httplib2.Http()
            url = 'https://cowbell.grooveshark.com/service.php'
            self.secretKey = hashlib.md5(self.session).hexdigest()
            tokenPOSTdata = ('''{"header":{"session":"%s","uuid":"%s","client":"gslite","clientRevision":"20100211.13"},'''
            '''"parameters":{"secretKey":"%s"},"method":"getCommunicationToken"}''' % (self.session, self.uuid, self.secretKey))
            request, reply = http.request(url, 'POST', headers = header, body = tokenPOSTdata)
            return json.loads(reply)['result']
        def getUID(self):
            return uuid.uuid4()
        def getSessionID(self):
            http = httplib2.Http()
            url = 'http://listen.grooveshark.com'
            response, src = http.request(url, 'GET', headers = header)
            src = src.lower().replace(' ', '')
            start = src.find('session')
            end = src[start:].find("',")
            startSession =  src[start:end+start].find("'") +1
            return src[startSession+start:end+start]
        def getRequestToken(self, method):
            randomStr = ''.join([random.choice('0123456789abcdef') for x in xrange(6)])
            return randomStr + hashlib.sha1(method + ":" + self.token + ":theColorIsRed:" + randomStr).hexdigest()
    #work Methods
        def search(self, search_string):
            http = httplib2.Http()
            data = ('''{"header":{"session":"%s","uuid":"%s","client":"gslite","clientRevision":"20100211.13","token":"%s"},'''
            '''"parameters":{"type":"Songs","query":"%s"},"method":"getSearchResults"}''' % (self.session, self.uuid, self.getRequestToken("getSearchResults"), search_string.lower()))
            self.response, self.result = http.request(self.search_url, 'POST', headers = header, body = data)
            self.result = self.result
            self.searchResults = json.loads(self.result)['result']
            return self.searchResults
        def songKeyfromID(self, id):
            http = httplib2.Http()
            self.songID = id
            songKeyURL = '  http://cowbell.grooveshark.com/more.php?ge...FromSongID'
            songKeyPOSTdata = ('''{"header":{"token":"%s","session":"%s","uuid":"%s","client":"gslite","clientRevision":"20100211.13"},'''
            '''"parameters":{"songID":%s,"prefetch":false},"method":"getStreamKeyFromSongID"}''') % (self.getRequestToken("getStreamKeyFromSongID"), self.session, self.uuid, self.songID)
            request, reply = http.request(songKeyURL, 'POST', headers = header, body = songKeyPOSTdata)
            self.reply = json.loads(reply)['result']
            self.songKey = self.reply['result']['streamKey']
            return (self.songKey, self.reply['result']['streamServer'])
        def download(self, songKey, streamServer):
            http = httplib2.Http()
            self.mp3URL = 'http://'+streamServer+'/stream.php'#use self. so that any outer program can access it (not local)
            data = {}
            data['streamKey'] = songKey
            songHeader = dict(header)
            songHeader['content-length'] = str(len(urllib.urlencode(data)))
            songHeader['content-type'] = 'application/x-www-form-urlencoded'
            self.response, self.song = http.request(self.mp3URL, 'POST', headers = songHeader, body = urllib.urlencode(data))
            if self.response['status'] == '302':
                self.response, self.song = http.request(self.response['location'], 'GET', headers = header)
            if self.response['status'] == '400':
                return '400 Error'
            return self.song
    
        def stream(self, streamKeys, songServers, file):
            '''A list of streamkeys and base file'''
            self.stream_process = subprocess.Popen('python stream.py %s %s %s' % (json.dumps(songServers), json.dumps(streamKeys), file))
        def popular(self):
            http = httplib2.Http()
            url = 'http://cowbell.grooveshark.com/more.php?popularGetSongs'
            popularPOSTdata = ('''{"header":{"token":"%s","session":"%s","uuid":"%s","client":"gslite","clientRevision":"20100211.13"},'''
            '''"parameters":{},"method":"popularGetSongs"}''' % (self.getRequestToken("popularGetSongs"), self.session, self.uuid))
            self.request, self.reply = http.request(url, 'POST', headers = header, body = popularPOSTdata)
            return json.loads(self.reply)['result']['Songs']
    
        # def favorites(self):
            # http = httplib2.Http()
            # url = 'http://cowbell.grooveshark.com/more.php?getFavorites'
            # songKeyPOSTdata = ('''{"header":{"token":"%s","session":"%s","uuid":"%s","client":"gslite","clientRevision":"20091027.09"},'''
            # '''"parameters":{"prefetch":false},"method":"getFavorites"}''' % (self.token, self.session, self.uuid))
            # request, reply = http.request(url, 'POST', headers = header, body = songKeyPOSTdata)
            # print request
        # def playlist(self):
            # http = httplib2.Http()
            # url = 'http://cowbell.grooveshark.com/more.php?playlistGetSongs'
            # songKeyPOSTdata = ('''{"header":{"token":"%s","session":"%s","uuid":"%s","client":"gslite","clientRevision":"20091027.09"},'''
            # '''"parameters":{"prefetch":false},"method":"getPaylist"}''' % (self.token, self.session, self.uuid))
            # request, reply = http.request(url, 'POST', headers = header, body = songKeyPOSTdata)
            # print request
    
        def setID3tags(self, file, title = None, artist = None, album = None, albumArt = None, genre = None, composer = None):
            '''Does NOT WORK DUE TO UNKOWN UNICODE PROBLEM when saving'''
            if not os.path.exists(file):
                raise IOError('MP3 File does not exist.')
            print file
            tag_lookup = {'album':'TALB', 'comment':"COMM::'eng'", 'description':'TIT3', 'artist':'TPE1', 'title':'TIT2', 'track':'TRCK', 'composer':'TCOM', 'genre':'TCON'}
            http = httplib2.Http()
            request, albumArt = http.request('http://beta.grooveshark.com/static/amazonart/'+albumArt)
            if request['status'] == '404':
                albumArt = u''
            tag_lookup['album_art'] = 'TART'
            tags = {}
            #tags['title'] = title
            #tags['artist'] = artist
            #tags['album'] = album
            #tags['album_art'] = albumArt
            tags['genre'] = genre
            #tags['composer'] = composer
            #if tags['composer'] == None:
            #    tags['composer'] = tags['artist']
            for i in tags:
                if tags[i] == None:
                    tags[i] = ''
            audio = MP3(file)
            #Delete Existing Songs
            audio.delete()
            #Set the tags
            #Iterate through tags
            for i in tags:
                print i
                print type(tags[i])
                print tags[i]
                audio[tag_lookup[i]] = tags[i]
            print audio[tag_lookup[i]]
            audio.tags.save()
    
    
    #This is for streaming support
    class Stream(urllib.FancyURLopener):
        version = header['user-agent']
    

    Great project!

    Also, I have a semi-working obj-c/iPhone port if anyone is interested.

×
×
  • Create New...