I'v been very busy lately and couldn't get back to you on the Hebrew search issue.
i have checked the script with a friend and we managed to figure out the problem.
it seems that last.fm api cant query for tracks in hebrew, only artists.
we have add another loop to the script that checks for similar artists if similar tracks are return count=0:
PHP Code:
"""
Script for generating smart playlists based on a seeding track and last.fm api
Created by: ErlendSB
"""
import os
import random
import httplib, urllib, urllib2
import sys, time
import threading, thread
import xbmc, xbmcgui, xbmcaddon
from urllib import quote_plus, unquote_plus
import re
from os.path import exists
from os import remove
if sys.version_info < (2, 7):
import simplejson
else:
import json as simplejson
__settings__ = xbmcaddon.Addon(id='script.lastfmplaylistgeneratorPM')
__addonversion__ = __settings__.getAddonInfo('version')
__cwd__ = __settings__.getAddonInfo('path')
def log(message):
xbmc.log(msg=message)
class MyPlayer( xbmc.Player ) :
countFoundTracks = 0
addedTracks = []
currentSeedingTrack = 0
firstRun = 0
dbtype = 'sqlite3'
timeStarted = time.time()
SCRIPT_NAME = "LAST.FM Playlist Generator"
allowtrackrepeat = __settings__.getSetting( "allowtrackrepeat" )
preferdifferentartist = __settings__.getSetting( "preferdifferentartist" )
numberoftrackstoadd = ( 1, 3, 5, 10, )[ int( __settings__.getSetting( "numberoftrackstoadd" ) ) ]
delaybeforesearching= ( 2, 10, 30, )[ int( __settings__.getSetting( "delaybeforesearching" ) ) ]
limitlastfmresult= ( 50, 100, 250, )[ int( __settings__.getSetting( "limitlastfmresult" ) ) ]
timer = None
#apiPath = "http://ws.audioscrobbler.com/2.0/?api_key=71e468a84c1f40d4991ddccc46e40f1b"
apiPath = "http://ws.audioscrobbler.com/2.0/?api_key=3ae834eee073c460a250ee08979184ec"
def __init__ ( self ):
if not os.path.exists(xbmc.translatePath("special://userdata/advancedsettings.xml")):
self.dbtype = 'sqlite3'
else:
from xml.etree.ElementTree import ElementTree
advancedsettings = ElementTree()
advancedsettings.parse(xbmc.translatePath("special://userdata/advancedsettings.xml"))
settings = advancedsettings.getroot().find("musicdatabase")
if settings is not None:
for setting in settings:
if setting.tag == 'type':
self.dbtype = setting.text
else:
self.dbtype = 'sqlite3'
xbmc.Player.__init__( self )
xbmc.PlayList(0).clear()
self.firstRun = 1
BASE_RESOURCE_PATH = os.path.join( __cwd__, "resources" )
process = os.path.join( BASE_RESOURCE_PATH , "pm.pid")
removeauto('lastfmplaylistgeneratorpm')
addauto("if os.path.exists('" + os.path.normpath(process).replace('\\','\\\\') + "'):#lastfmplaylistgeneratorpm\n\tos.remove('" + os.path.normpath(process).replace('\\','\\\\') + "')","lastfmplaylistgeneratorpm")
xbmc.executebuiltin("Notification(" + self.SCRIPT_NAME+",Start by playing a song)")
def startPlayBack(self):
print "[LFM PLG(PM)] onPlayBackStarted started"
if xbmc.Player().isPlayingAudio() == True:
currentlyPlayingTitle = xbmc.Player().getMusicInfoTag().getTitle()
print "[LFM PLG(PM)] " + currentlyPlayingTitle + " started playing"
currentlyPlayingArtist = xbmc.Player().getMusicInfoTag().getArtist()
self.countFoundTracks = 0
if (self.firstRun == 1):
self.firstRun = 0
#print "firstRun - clearing playlist"
album = xbmc.Player().getMusicInfoTag().getAlbum()
cache_name = xbmc.getCacheThumbName(os.path.dirname(xbmc.Player().getMusicInfoTag().getURL()))
print "[LFM PLG(PM)] Playing file: %s" % xbmc.Player().getMusicInfoTag().getURL()
thumb = "special://profile/Thumbnails/Music/%s/%s" % ( cache_name[:1], cache_name, )
duration = xbmc.Player().getMusicInfoTag().getDuration()
fanart = ""
listitem = self.getListItem(currentlyPlayingTitle,currentlyPlayingArtist,album,thumb,fanart,duration)
xbmc.PlayList(0).clear()
#xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": 0 }, "id": 1}')
xbmc.executebuiltin('XBMC.ActivateWindow(10500)')
xbmc.PlayList(0).add(url= xbmc.Player().getMusicInfoTag().getURL(), listitem = listitem)
#trackPath = xbmc.Player().getMusicInfoTag().getURL()
#xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "%s"}, "playlistid": 0 }, "id": 1}' % trackPath)
self.addedTracks += [xbmc.Player().getMusicInfoTag().getURL()]
#print "Start looking for similar tracks"
self.fetch_similarTracks(currentlyPlayingTitle,currentlyPlayingArtist)
def onPlayBackStarted(self):
print "[LFM PLG(PM)] onPlayBackStarted waiting: " + str(self.delaybeforesearching) +" seconds"
if (self.timer is not None and self.timer.isAlive()):
self.timer.cancel()
self.timer = threading.Timer(self.delaybeforesearching,self.startPlayBack)
self.timer.start()
def fetch_similarTracks( self, currentlyPlayingTitle, currentlyPlayingArtist ):
apiMethod = "&method=track.getsimilar&limit=" + str(self.limitlastfmresult)
# The url in which to use
Base_URL = self.apiPath + apiMethod + "&artist=" + urllib.quote_plus(currentlyPlayingArtist) + "&track=" + urllib.quote_plus(currentlyPlayingTitle)
print Base_URL
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#xbmc.executehttpapi("setresponseformat(openRecordSet;<recordset>;closeRecordSet;</recordset>;openRecord;<record>;closeRecord;</record>;openField;<field>;closeField;</field>)");
#print WebHTML
similarTracks = re.findall("<track>.+?<name>(.+?)</name>.+?<match>(.+?)</match>.+?<artist>.+?<name>(.+?)</name>.+?</artist>.+?</track>", WebHTML, re.DOTALL )
random.shuffle(similarTracks)
foundArtists = []
countTracks = len(similarTracks)
print "[LFM PLG(PM)] Count: " + str(countTracks)
if countTracks==0:
apiMethod = "&method=artist.getsimilar&limit=" + str(self.limitlastfmresult)
Base_URL = self.apiPath + apiMethod + "&artist=" + urllib.quote_plus(currentlyPlayingArtist)
print Base_URL
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close()
similarArtists = re.findall("<artist>.+?<name>(.+?)</name>.+?</artist>", WebHTML, re.DOTALL)
#random.shuffle(similarArtists)
countArtists = len(similarArtists)
print "[LFM PLG(PM)] Artists Count: " + str(countArtists)
for artist in similarArtists:
json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "properties": ["title", "artist", "album", "file", "thumbnail", "duration", "fanart"], "limits": {"end":1}, "sort": {"method":"random"}, "filter": {"field":"artist","operator":"contains","value":"%s"} } , "id": 1}' % (artist))
json_query = unicode(json_query, 'utf-8', errors='ignore')
json_response = simplejson.loads(json_query)
if json_response.has_key('result') and json_response['result'] != None and json_response['result'].has_key('songs'):
count = 0
for item in json_response['result']['songs']:
count += 1
artist = item["artist"]
trackTitle = item["title"]
album = item["album"]
trackPath = item["file"]
thumb = item["thumbnail"]
duration = int(item["duration"])
fanart = item["fanart"]
#log("[LFM PLG(PM)] Found: " + str(trackTitle) + " by: " + str(artist))
if ((self.allowtrackrepeat == "true" or self.allowtrackrepeat == 1) or (trackPath not in self.addedTracks)):
if ((self.preferdifferentartist != "true" and self.preferdifferentartist != 1) or (eval(matchValue) < 0.2 and similarArtistName not in foundArtists)):
listitem = self.getListItem(trackTitle,artist,album,thumb,fanart,duration)
xbmc.PlayList(0).add(url=trackPath, listitem=listitem)
#xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "%s"}, "playlistid": 0 }, "id": 1}' % trackPath)
self.addedTracks += [trackPath]
xbmc.executebuiltin("Container.Refresh")
self.countFoundTracks += 1
if (artist not in foundArtists):
foundArtists += [artist]
if (self.countFoundTracks >= self.numberoftrackstoadd):
break
#for artist in similarArtists:
#print artist
for similarTrackName, matchValue, similarArtistName in similarTracks:
#print "Looking for: " + similarTrackName + " - " + similarArtistName + " - " + matchValue
similarTrackName = similarTrackName.replace("+"," ").replace("("," ").replace(")"," ").replace(""","''").replace("'","''").replace("&","and")
similarArtistName = similarArtistName.replace("+"," ").replace("("," ").replace(")"," ").replace(""","''").replace("'","''").replace("&","and")
json_query = xbmc.executeJSONRPC('{"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}' % (similarTrackName, similarArtistName))
json_query = unicode(json_query, 'utf-8', errors='ignore')
json_response = simplejson.loads(json_query)
# separate the records
if json_response.has_key('result') and json_response['result'] != None and json_response['result'].has_key('songs'):
count = 0
for item in json_response['result']['songs']:
count += 1
artist = item["artist"]
trackTitle = item["title"]
album = item["album"]
trackPath = item["file"]
thumb = item["thumbnail"]
duration = int(item["duration"])
fanart = item["fanart"]
log("[LFM PLG(PM)] Found: " + str(trackTitle) + " by: " + str(artist))
if ((self.allowtrackrepeat == "true" or self.allowtrackrepeat == 1) or (trackPath not in self.addedTracks)):
if ((self.preferdifferentartist != "true" and self.preferdifferentartist != 1) or (eval(matchValue) < 0.2 and similarArtistName not in foundArtists)):
listitem = self.getListItem(trackTitle,artist,album,thumb,fanart,duration)
xbmc.PlayList(0).add(url=trackPath, listitem=listitem)
#xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "%s"}, "playlistid": 0 }, "id": 1}' % trackPath)
self.addedTracks += [trackPath]
xbmc.executebuiltin("Container.Refresh")
self.countFoundTracks += 1
if (similarArtistName not in foundArtists):
foundArtists += [similarArtistName]
if (self.countFoundTracks >= self.numberoftrackstoadd):
break
if (self.countFoundTracks == 0):
time.sleep(3)
#self.firstRun = 1
log("[LFM PLG(PM)] None found")
xbmc.executebuiltin("Notification(" + self.SCRIPT_NAME+",No similar tracks were found)")
return False
xbmc.executebuiltin('SetCurrentPlaylist(0)')
def getListItem(self, trackTitle, artist, album, thumb, fanart,duration):
listitem = xbmcgui.ListItem(trackTitle)
if (fanart == ""):
cache_name = xbmc.getCacheThumbName( str(artist) )
fanart = "special://profile/Thumbnails/Music/%s/%s" % ( "Fanart", cache_name, )
listitem.setProperty('fanart_image',fanart)
listitem.setInfo('music', { 'title': trackTitle, 'artist': artist, 'album': album, 'duration': duration })
listitem.setThumbnailImage(thumb)
#log("[LFM PLG(PM)] Fanart:%s" % fanart)
return listitem
def addauto(newentry, scriptcode):
autoexecfile = xbmc.translatePath('special://home/userdata/autoexec.py')
#autoexecfile = "special://masterprofile/autoexec.py"
if exists(autoexecfile):
fh = open(autoexecfile)
lines = []
for line in fh.readlines():
lines.append(line)
lines.append("import time" + "#" + scriptcode + "\n")
lines.append("time.sleep(2)" + "#" + scriptcode + "\n")
lines.append(newentry + "#" + scriptcode + "\n")
fh.close()
f = open(autoexecfile, "w")
if not "import xbmc\n" in lines:
f.write("import xbmc" + "#" + scriptcode + "\n")
if not "import os\n" in lines:
f.write("import os" + "#" + scriptcode + "\n")
f.writelines(lines)
f.close()
else:
f = open(autoexecfile, "w")
f.write("import time" + "#" + scriptcode + "\n")
f.write("time.sleep(2)" + "#" + scriptcode + "\n")
f.write("import os" + "#" + scriptcode + "\n")
f.write("import xbmc" + "#" + scriptcode + "\n")
f.write(newentry + "#" + scriptcode + "\n")
f.close()
def removeauto(scriptcode):
autoexecfile = xbmc.translatePath('special://home/userdata/autoexec.py')
#autoexecfile = "special://masterprofile/autoexec.py"
if exists(autoexecfile):
fh = open(autoexecfile)
lines = [ line for line in fh if not line.strip().endswith("#" + scriptcode) ]
fh.close()
f = open(autoexecfile, "w")
f.writelines(lines)
f.close()
BASE_RESOURCE_PATH = os.path.join( __cwd__, "resources" )
process = os.path.join( BASE_RESOURCE_PATH , "pm.pid")
p=MyPlayer()
while(1):
if os.path.exists(process):
if (xbmc.abortRequested):
os.remove(process)
print "[LFM PLG(PM)] deleting pid"
xbmc.sleep(500)
else:
break

Search
Help