[RELEASE] LastFM Playlist Maker - external Python Script
#1
Music 
Hey,

in the course of making a little home automation system, i stumbled upon
ErlendSB's great LastFM PlaylistGenerator which is awesome as an addon;
But didn't quite suite my needs. So is decided to make my own little Python
Script that runs seperately and populates (on request) the Playlist. This is just
a quick and dirty script, and is heavily based on ErlendSB's addon. So all credit
to him.

PHP Code:
import os
import json
import socket
import re
import urllib

#for debug
from pprint import pprint

class LastFMPlaylist():
    
    
def __init__ (self):
        
self.delay 5
        self
.add_limit 10
        self
.search_limit 240
        self
.api "http://ws.audioscrobbler.com/2.0/?api_key=3ae834eee073c460a250ee08979184ec"
        
self.allAddedSongs = []
        
self.timer None
        self
.artist "Not working"
        
self.title "Hallo"
        
self.newSongs = []
        
    
def startTitleSearch(self):
        
'''Gets currently Played Song from XBMC'''
        
        
jdata ='{"jsonrpc": "2.0", "method": "Player.GetItem", "params": { "properties": ["title","artist"], "playerid": 0 }, "id": "AudioGetItem"}'
        
decoded self.getJson(jdata)
        print 
"Currently Playing Song is " decoded['result']['item']['artist'][0] + ' - ' decoded['result']['item']['title']
        
self.artist decoded['result']['item']['artist'][0]
        
self.title decoded['result']['item']['title']
        
        
answer self.dumbUnavailable(self.fetchSimilarTracks(self.artist,self.title))
        
self.allAddedSongs += answer
        
print len(self.allAddedSongs)

    
def fetchSimilarTracks(selfartist,title):
        
'''Gets similar Artists Song'''
        
        
apiMethod "&method=track.getsimilar&limit=" str(self.search_limit)
        
        
urla urllib.quote_plus(artist)
        
urlt urllib.quote_plus(title)
        
        
# The url in which to use
        
apiurl self.api apiMethod "&artist=" urla "&track=" urlt
        
print "Search on " apiurl
        
# Gets Info from LASTFM
        
WebSock urllib.urlopen(apiurl)  # Opens a 'Socket' to URL
        
WebHTML WebSock.read()            # Reads Contents of URL and saves to Variable
        
WebSock.close()                     # Closes connection to url
        
        
print "Search Done"
        
        
# Gets Array with [ TRACK, MATCHVALUE, ARTIST]
        
similarTracks re.findall("<track>.+?<name>(.+?)</name>.+?<match>(.+?)</match>.+?<artist>.+?<name>(.+?)</name>.+?</artist>.+?</track>"WebHTMLre.DOTALL )
        
        return 
similarTracks
        
    def checkWanted
(selfartisttitle,matchValue,album,duration):
        
'''Check for Wanted Status SHOULD RETURN FALSE IF NOT MET '''
        
# CAN BE PRETTY MUCH ANY CRITERIA YOU WANT
        
        
if matchValue <= 0.00005
            return 
False
            
        
# CHECKS AGAINST ALREADY ADDED SONGS
        
for item in self.allAddedSongs:
            if 
item[0] == artist and item[1] == title# IS EQUAL TO NOT THE SAME SONG AGAIN
                
return False
        
return True
        
    def printPlaylist
(self):
        print 
"Added Songs: "
        
for item in self.allAddedSongs:
            print 
item[0] + " - " item[1]
        print 
" "
        
print "Total Songs Added: " str(len(self.allAddedSongs))
            
    
def addToPlaylist(self):
        for 
item in self.newSongs :
            
addRequest '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "' item[3] + '"}, "playlistid": 0 }, "id": 1}'
            
#addRequest = '{ "jsonrpc": "2.0", "method": "JSONRPC.Introspect", "params": { "filter": { "id": "Playlist.Add", "type": "method" } }, "id": 1 }'
            
self.getJson(addRequest)
        
    
def getJson(self,string):
    
        
gsocket socket.socket(socket.AF_INETsocket.SOCK_STREAM)
        
gsocket.connect(("localhost"9090))
        
# Whatever structure you need to send goes here:
        #jdata = json.dumps({"username":"...", "password":"..."})
        
gsocket.send(string)
        
response gsocket.recv(2048)
                
        
json_query unicode(response'utf-8'errors='ignore')
        
json_response json.loads(json_query)
        return 
json_response
        
        
    def dumbUnavailable 
(selfsimilarTracks):
    
        
songsAdded 0
        songsToAdd 
= []
        
# Shuffles the Result
        
random.shuffle(similarTracks)
        for 
trackmatchValueartist in similarTracks:
        
            
track track.replace("+"," ").replace("("," ").replace(")"," ").replace("&quot","''").replace("'","''").replace("&amp;","and")
            
artist artist.replace("+"," ").replace("("," ").replace(")"," ").replace("&quot","''").replace("'","''").replace("&amp;","and")
            
#Query LastFM for TRACK
            
            
            
json_response self.getJson('{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "properties": ["title", "artist", "album", "file", "thumbnail", "duration", "fanart"], "limits": {"end":1}, "sort": {"method":"random"}, "filter": { "and":[{"field":"title","operator":"contains","value":"%s"},{"field":"artist","operator":"contains","value":"%s"}] } }, "id": 1}' % (trackartist)) 
            
            
            
# separate the records
            
if json_response.has_key('result') and json_response['result'] != None and json_response['result'].has_key('songs'):
                
nur 0
                
for item in json_response['result']['songs']:
                
                    
artist item["artist"][0]
                    
trackTitle item["title"]
                    
album item["album"]
                    
trackPath item["file"]
                    
thumb item["thumbnail"]
                    
duration int(item["duration"])
                    
fanart item["fanart"]
                
                    if (
self.checkWanted(artist,trackTitle,matchValue,album,duration) != False or nur != 0):
                        
songsToAdd.append([artist,trackTitle,album,trackPath,thumb,duration,fanart]) #if file is wanted add to list
                        
songsAdded += 1
                        nur 
+= 1
                    
                    
            
if (songsAdded >= self.add_limit):
                break
                    
        
self.newSongs songsToAdd
        
return songsToAdd
        
        
        
        
LastFMPlaylist()
p.startTitleSearch()
p.printPlaylist()
p.addToPlaylist() 

Should be pretty much self explaining and functioning (IF control from remotes is
enabled in XBMC.

Hope I have not made any mistakes and/or offended someone Big Grin

Cheers
Reply

Logout Mark Read Team Forum Stats Members Help
[RELEASE] LastFM Playlist Maker - external Python Script0