diff --git a/contextmenu.py b/contextmenu.py
index e7bee464..ab557b9f 100644
--- a/contextmenu.py
+++ b/contextmenu.py
@@ -112,9 +112,11 @@ if __name__ == '__main__':
if newvalue:
newvalue = int(newvalue)
if newvalue > 5: newvalue = "5"
- musicutils.updateRatingToFile(newvalue, API.getFilePath())
- like, favourite, deletelike = musicutils.getEmbyRatingFromKodiRating(newvalue)
- API.updateUserRating(embyid, like, favourite, deletelike)
+ if utils.settings('enableUpdateSongRating') == "true":
+ musicutils.updateRatingToFile(newvalue, API.getFilePath())
+ if utils.settings('enableExportSongRating') == "true":
+ like, favourite, deletelike = musicutils.getEmbyRatingFromKodiRating(newvalue)
+ API.updateUserRating(embyid, like, favourite, deletelike)
query = ' '.join(( "UPDATE song","SET rating = ?", "WHERE idSong = ?" ))
kodicursor.execute(query, (newvalue,itemid,))
kodiconn.commit()
diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py
index 1c244e74..578c932c 100644
--- a/resources/lib/downloadutils.py
+++ b/resources/lib/downloadutils.py
@@ -274,6 +274,7 @@ class DownloadUtils():
verify=verifyssl)
elif type == "POST":
+ print url
r = requests.post(url,
json=postBody,
headers=header,
diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py
index 6bcdc2b2..7397b9f6 100644
--- a/resources/lib/itemtypes.py
+++ b/resources/lib/itemtypes.py
@@ -38,7 +38,7 @@ class Items(object):
self.directpath = utils.settings('useDirectPaths') == "1"
self.music_enabled = utils.settings('enableMusic') == "true"
self.contentmsg = utils.settings('newContent') == "true"
-
+
self.artwork = artwork.Artwork()
self.emby = embyserver.Read_EmbyServer()
self.emby_db = embydb.Embydb_Functions(embycursor)
@@ -1613,6 +1613,9 @@ class Music(Items):
Items.__init__(self, embycursor, musiccursor)
self.directstream = utils.settings('streamMusic') == "true"
+ self.enableimportsongrating = utils.settings('enableImportSongRating') == "true"
+ self.enableexportsongrating = utils.settings('enableExportSongRating') == "true"
+ self.enableupdatesongrating = utils.settings('enableUpdateSongRating') == "true"
self.userid = utils.window('emby_currUser')
self.server = utils.window('emby_server%s' % self.userid)
@@ -1952,9 +1955,9 @@ class Music(Items):
#the server doesn't support comment on songs so this will always be empty
comment = API.getOverview()
- #if enabled, try to get the rating and comment value from the file itself
+ #if enabled, try to get the rating from file and/or emby
if not self.directstream:
- rating, comment, hasEmbeddedCover = self.getSongTagsFromFile(itemid, rating, API)
+ rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating)
##### GET THE FILE AND PATH #####
if self.directstream:
@@ -2191,7 +2194,7 @@ class Music(Items):
# Process playstates
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
- rating, comment, hasEmbeddedCover = self.getSongTagsFromFile(itemid, rating, API)
+ rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating)
query = "UPDATE song SET iTimesPlayed = ?, lastplayed = ?, rating = ? WHERE idSong = ?"
kodicursor.execute(query, (playcount, dateplayed, rating, kodiid))
@@ -2203,89 +2206,6 @@ class Music(Items):
emby_db.updateReference(itemid, checksum)
- def getSongTagsFromFile(self, embyid, emby_rating, API):
-
- kodicursor = self.kodicursor
-
- previous_values = None
- filename = API.getFilePath()
- rating = 0
- emby_rating = int(round(emby_rating, 0))
-
- #get file rating and comment tag from file itself.
- #TODO: should we make this an optional setting if it impacts sync speed too much ?
- file_rating, comment, hasEmbeddedCover = musicutils.getSongTags(filename)
-
- emby_dbitem = self.emby_db.getItem_byId(embyid)
- try:
- kodiid = emby_dbitem[0]
- except TypeError:
- # Item is not in database.
- currentvalue = None
- else:
- query = "SELECT rating FROM song WHERE idSong = ?"
- kodicursor.execute(query, (kodiid,))
- try:
- currentvalue = int(round(float(kodicursor.fetchone()[0]),0))
- except: currentvalue = None
-
- # Only proceed if we actually have a rating from the file
- if file_rating is None and currentvalue:
- return (currentvalue, comment, False)
- elif file_rating is None and not currentvalue:
- return (emby_rating, comment, False)
-
- self.logMsg("getSongTagsFromFile --> embyid: %s - emby_rating: %s - file_rating: %s - current rating in kodidb: %s" %(embyid, emby_rating, file_rating, currentvalue))
-
- updateFileRating = False
- updateEmbyRating = False
-
- if currentvalue != None:
- # we need to translate the emby values...
- if emby_rating == 1 and currentvalue == 2:
- emby_rating = 2
- if emby_rating == 3 and currentvalue == 4:
- emby_rating = 4
-
- if (emby_rating == file_rating) and (file_rating != currentvalue):
- #the rating has been updated from kodi itself, update change to both emby ands file
- rating = currentvalue
- updateFileRating = True
- updateEmbyRating = True
- elif (emby_rating != currentvalue) and (file_rating == currentvalue):
- #emby rating changed - update the file
- rating = emby_rating
- updateFileRating = True
- elif (file_rating != currentvalue) and (emby_rating == currentvalue):
- #file rating was updated, sync change to emby
- rating = file_rating
- updateEmbyRating = True
- elif (emby_rating != currentvalue) and (file_rating != currentvalue):
- #both ratings have changed (corner case) - the highest rating wins...
- if emby_rating > file_rating:
- rating = emby_rating
- updateFileRating = True
- else:
- rating = file_rating
- updateEmbyRating = True
- else:
- #nothing has changed, just return the current value
- rating = currentvalue
- else:
- # no rating yet in DB, always prefer file details...
- rating = file_rating
- updateEmbyRating = True
-
- if updateFileRating:
- musicutils.updateRatingToFile(rating, filename)
-
- if updateEmbyRating:
- # sync details to emby server. Translation needed between ID3 rating and emby likes/favourites:
- like, favourite, deletelike = musicutils.getEmbyRatingFromKodiRating(rating)
- API.updateUserRating(embyid, like, favourite, deletelike)
-
- return (rating, comment, hasEmbeddedCover)
-
def remove(self, itemid):
# Remove kodiid, fileid, pathid, emby reference
emby_db = self.emby_db
diff --git a/resources/lib/musicutils.py b/resources/lib/musicutils.py
index 2625cc7f..915714ec 100644
--- a/resources/lib/musicutils.py
+++ b/resources/lib/musicutils.py
@@ -17,9 +17,9 @@ import base64
def logMsg(msg, lvl=1):
utils.logMsg("%s %s" % ("Emby", "musictools"), msg, lvl)
-def getRealFileName(filename):
+def getRealFileName(filename,useTemp = False):
#get the filename path accessible by python if possible...
- isTemp = False
+ useTemp = False
if not xbmcvfs.exists(filename):
logMsg( "File does not exist! %s" %(filename), 0)
@@ -38,14 +38,16 @@ def getRealFileName(filename):
filename = filename.replace("smb://","\\\\").replace("/","\\")
else:
#file can not be accessed by python directly, we copy it for processing...
- isTemp = True
+ useTemp = True
+
+ if useTemp:
if "/" in filename: filepart = filename.split("/")[-1]
else: filepart = filename.split("\\")[-1]
tempfile = "special://temp/"+filepart
xbmcvfs.copy(filename, tempfile)
filename = xbmc.translatePath(tempfile).decode("utf-8")
- return (isTemp,filename)
+ return (useTemp,filename)
def getEmbyRatingFromKodiRating(rating):
# Translation needed between Kodi/ID3 rating and emby likes/favourites:
@@ -61,7 +63,112 @@ def getEmbyRatingFromKodiRating(rating):
if (rating == 1 or rating == 2): deletelike = True
if (rating >= 5): favourite = True
return(like, favourite, deletelike)
+
+def getAdditionalSongTags(embyid, emby_rating, API, kodicursor, emby_db, enableimportsongrating, enableexportsongrating, enableupdatesongrating):
+ previous_values = None
+ filename = API.getFilePath()
+ rating = 0
+ emby_rating = int(round(emby_rating, 0))
+ #get file rating and comment tag from file itself.
+ if enableimportsongrating:
+ file_rating, comment, hasEmbeddedCover = getSongTags(filename)
+ else:
+ file_rating = 0
+ comment = ""
+ hasEmbeddedCover = False
+
+
+ emby_dbitem = emby_db.getItem_byId(embyid)
+ try:
+ kodiid = emby_dbitem[0]
+ except TypeError:
+ # Item is not in database.
+ currentvalue = None
+ else:
+ query = "SELECT rating FROM song WHERE idSong = ?"
+ kodicursor.execute(query, (kodiid,))
+ try:
+ currentvalue = int(round(float(kodicursor.fetchone()[0]),0))
+ except: currentvalue = None
+
+ # Only proceed if we actually have a rating from the file
+ if file_rating is None and currentvalue:
+ return (currentvalue, comment, False)
+ elif file_rating is None and not currentvalue:
+ return (emby_rating, comment, False)
+
+ logMsg("getAdditionalSongTags --> embyid: %s - emby_rating: %s - file_rating: %s - current rating in kodidb: %s" %(embyid, emby_rating, file_rating, currentvalue))
+
+ updateFileRating = False
+ updateEmbyRating = False
+
+ if currentvalue != None:
+ # we need to translate the emby values...
+ if emby_rating == 1 and currentvalue == 2:
+ emby_rating = 2
+ if emby_rating == 3 and currentvalue == 4:
+ emby_rating = 4
+
+ #if updating rating into file is disabled, we ignore the rating in the file...
+ if not enableupdatesongrating:
+ file_rating = currentvalue
+ #if convert emby likes/favourites convert to song rating is disabled, we ignore the emby rating...
+ if not enableexportsongrating:
+ emby_rating = currentvalue
+
+ if (emby_rating == file_rating) and (file_rating != currentvalue):
+ #the rating has been updated from kodi itself, update change to both emby ands file
+ rating = currentvalue
+ updateFileRating = True
+ updateEmbyRating = True
+ elif (emby_rating != currentvalue) and (file_rating == currentvalue):
+ #emby rating changed - update the file
+ rating = emby_rating
+ updateFileRating = True
+ elif (file_rating != currentvalue) and (emby_rating == currentvalue):
+ #file rating was updated, sync change to emby
+ rating = file_rating
+ updateEmbyRating = True
+ elif (emby_rating != currentvalue) and (file_rating != currentvalue):
+ #both ratings have changed (corner case) - the highest rating wins...
+ if emby_rating > file_rating:
+ rating = emby_rating
+ updateFileRating = True
+ else:
+ rating = file_rating
+ updateEmbyRating = True
+ else:
+ #nothing has changed, just return the current value
+ rating = currentvalue
+ else:
+ # no rating yet in DB
+ if enableimportsongrating:
+ #prefer the file rating
+ rating = file_rating
+ #determine if we should also send the rating to emby server
+ if enableexportsongrating:
+ if emby_rating == 1 and file_rating == 2:
+ emby_rating = 2
+ if emby_rating == 3 and file_rating == 4:
+ emby_rating = 4
+ if emby_rating != file_rating:
+ updateEmbyRating = True
+
+ elif enableexportsongrating:
+ #set the initial rating to emby value
+ rating = emby_rating
+
+ if updateFileRating and enableupdatesongrating:
+ updateRatingToFile(rating, filename)
+
+ if updateEmbyRating and enableexportsongrating:
+ # sync details to emby server. Translation needed between ID3 rating and emby likes/favourites:
+ like, favourite, deletelike = getEmbyRatingFromKodiRating(rating)
+ API.updateUserRating(embyid, like, favourite, deletelike)
+
+ return (rating, comment, hasEmbeddedCover)
+
def getSongTags(file):
# Get the actual ID3 tags for music songs as the server is lacking that info
rating = 0
@@ -120,31 +227,33 @@ def getSongTags(file):
def updateRatingToFile(rating, file):
#update the rating from Emby to the file
- isTemp,filename = getRealFileName(file)
- logMsg( "setting song rating: %s for filename: %s" %(rating,filename))
+ isTemp,tempfile = getRealFileName(file,True)
+ logMsg( "setting song rating: %s for filename: %s" %(rating,tempfile))
- if not filename:
+ if not tempfile:
return
try:
- if filename.lower().endswith(".flac"):
- audio = FLAC(filename)
+ if tempfile.lower().endswith(".flac"):
+ audio = FLAC(tempfile)
calcrating = int(round((float(rating) / 5) * 100, 0))
audio["rating"] = str(calcrating)
audio.save()
- elif filename.lower().endswith(".mp3"):
- audio = ID3(filename)
+ elif tempfile.lower().endswith(".mp3"):
+ audio = ID3(tempfile)
calcrating = int(round((float(rating) / 5) * 255, 0))
audio.add(id3.POPM(email="Windows Media Player 9 Series", rating=calcrating, count=1))
audio.save()
else:
- logMsg( "Not supported fileformat: %s" %(filename))
+ logMsg( "Not supported fileformat: %s" %(tempfile))
- #remove tempfile if needed....
- if isTemp:
+ #once we have succesfully written the flags we move the temp file to destination, otherwise not proceeding and just delete the temp
+ #safety check: we check if we can read the new tags successfully from the tempfile before deleting anything
+ checksum_rating, checksum_comment, checksum_hasEmbeddedCover = getSongTags(tempfile)
+ if checksum_rating == rating:
xbmcvfs.delete(file)
- xbmcvfs.copy(filename,file)
- xbmcvfs.delete(filename)
+ xbmcvfs.copy(tempfile,file)
+ xbmcvfs.delete(tempfile)
except Exception as e:
#file in use ?
diff --git a/resources/settings.xml b/resources/settings.xml
index e26d4564..6191e1db 100644
--- a/resources/settings.xml
+++ b/resources/settings.xml
@@ -60,6 +60,10 @@
+
+
+
+