changes to use native kodi db for inserts

This commit is contained in:
Marcel van der Veldt 2015-04-01 21:07:29 +02:00
parent 8ec2d7d33b
commit 5f8e5105bb
6 changed files with 520 additions and 482 deletions

View file

@ -99,8 +99,6 @@ class LibrarySync():
for view in views: for view in views:
updateNeeded = False
#process new movies #process new movies
allMB3Movies = ReadEmbyDB().getMovies(view.get('id'), True, fullsync) allMB3Movies = ReadEmbyDB().getMovies(view.get('id'), True, fullsync)
allKodiIds = set(ReadKodiDB().getKodiMoviesIds(True)) allKodiIds = set(ReadKodiDB().getKodiMoviesIds(True))
@ -126,7 +124,6 @@ class LibrarySync():
if item["Id"] not in allKodiIds: if item["Id"] not in allKodiIds:
WriteKodiDB().addMovieToKodiLibrary(item) WriteKodiDB().addMovieToKodiLibrary(item)
updateNeeded = True
totalItemsAdded += 1 totalItemsAdded += 1
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
@ -138,19 +135,6 @@ class LibrarySync():
pDialog.update(percentage, progressTitle, "Adding Movie: " + str(count)) pDialog.update(percentage, progressTitle, "Adding Movie: " + str(count))
count += 1 count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
@ -228,8 +212,6 @@ class LibrarySync():
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
cleanNeeded = False
# process any deletes only at fullsync # process any deletes only at fullsync
if fullsync: if fullsync:
allKodiIds = ReadKodiDB().getKodiMoviesIds(True) allKodiIds = ReadKodiDB().getKodiMoviesIds(True)
@ -238,16 +220,11 @@ class LibrarySync():
if not kodiId in allEmbyMovieIds: if not kodiId in allEmbyMovieIds:
WINDOW.setProperty(kodiId,"deleted") WINDOW.setProperty(kodiId,"deleted")
WriteKodiDB().deleteMovieFromKodiLibrary(kodiId) WriteKodiDB().deleteMovieFromKodiLibrary(kodiId)
cleanNeeded = True
totalItemsDeleted += 1 totalItemsDeleted += 1
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
# display notification if set up # display notification if set up
notificationString = "" notificationString = ""
if(totalItemsAdded > 0): if(totalItemsAdded > 0):
@ -308,8 +285,6 @@ class LibrarySync():
if latestMBEpisodes != None: if latestMBEpisodes != None:
allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True)) allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True))
updateNeeded = False
if(pDialog != None): if(pDialog != None):
pDialog.update(0, progressTitle) pDialog.update(0, progressTitle)
total = len(latestMBEpisodes) + 1 total = len(latestMBEpisodes) + 1
@ -339,7 +314,6 @@ class LibrarySync():
#no match so we have to create it #no match so we have to create it
print "creating episode in incremental sync!" print "creating episode in incremental sync!"
WriteKodiDB().addEpisodeToKodiLibrary(episode) WriteKodiDB().addEpisodeToKodiLibrary(episode)
updateNeeded = True
progressAction = "Adding" progressAction = "Adding"
totalItemsAdded += 1 totalItemsAdded += 1
@ -352,11 +326,6 @@ class LibrarySync():
pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count)) pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count))
count += 1 count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
self.doKodiLibraryUpdate(False, pDialog)
updateNeeded = False
#process updates #process updates
if(pDialog != None): if(pDialog != None):
progressTitle = "Sync DB : Processing Episodes" progressTitle = "Sync DB : Processing Episodes"
@ -400,7 +369,6 @@ class LibrarySync():
tvShowData = ReadEmbyDB().getTVShows(True,True) tvShowData = ReadEmbyDB().getTVShows(True,True)
allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True)) allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True))
updateNeeded = False
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
@ -420,7 +388,6 @@ class LibrarySync():
progMessage = "Processing" progMessage = "Processing"
if item["Id"] not in allKodiIds: if item["Id"] not in allKodiIds:
WriteKodiDB().addTVShowToKodiLibrary(item) WriteKodiDB().addTVShowToKodiLibrary(item)
updateNeeded = True
totalItemsAdded += 1 totalItemsAdded += 1
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
@ -479,7 +446,6 @@ class LibrarySync():
if ReadKodiDB().getKodiEpisodeByMbItem(item["Id"],tvshow) == None: if ReadKodiDB().getKodiEpisodeByMbItem(item["Id"],tvshow) == None:
#no match so we have to create it #no match so we have to create it
WriteKodiDB().addEpisodeToKodiLibrary(item) WriteKodiDB().addEpisodeToKodiLibrary(item)
updateNeeded = True
progressAction = "Adding" progressAction = "Adding"
totalItemsAdded += 1 totalItemsAdded += 1
@ -494,19 +460,6 @@ class LibrarySync():
showCurrent += 1 showCurrent += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
updateNeeded = False
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(pDialog != None): if(pDialog != None):
progressTitle = "Sync DB : Processing TV Shows" progressTitle = "Sync DB : Processing TV Shows"
@ -602,8 +555,6 @@ class LibrarySync():
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
cleanNeeded = False
# DELETES -- EPISODES # DELETES -- EPISODES
# process any deletes only at fullsync # process any deletes only at fullsync
allMB3EpisodeIds = set(allMB3EpisodeIds) allMB3EpisodeIds = set(allMB3EpisodeIds)
@ -611,26 +562,20 @@ class LibrarySync():
if episode.get('episodeid') not in allMB3EpisodeIds: if episode.get('episodeid') not in allMB3EpisodeIds:
WINDOW.setProperty("embyid" + str(episode.get('episodeid')),"deleted") WINDOW.setProperty("embyid" + str(episode.get('episodeid')),"deleted")
WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid')) WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid'))
cleanneeded = True
totalItemsDeleted += 1 totalItemsDeleted += 1
# DELETES -- TV SHOWS # DELETES -- TV SHOWS
if fullsync: if fullsync:
allLocaldirs, filesTVShows = xbmcvfs.listdir(tvLibrary) allKodiShows = ReadKodiDB().getKodiTvShowsIds(True)
allMB3TVShows = set(allTVShows) allMB3TVShows = set(allTVShows)
for dir in allLocaldirs: for show in allKodiShows:
if not dir in allMB3TVShows: if not show in allMB3TVShows:
WriteKodiDB().deleteTVShowFromKodiLibrary(dir) WriteKodiDB().deleteTVShowFromKodiLibrary(dir)
cleanneeded = True
totalItemsDeleted += 1 totalItemsDeleted += 1
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
# display notification if set up # display notification if set up
notificationString = "" notificationString = ""
if(totalItemsAdded > 0): if(totalItemsAdded > 0):
@ -680,8 +625,6 @@ class LibrarySync():
progressTitle = "" progressTitle = ""
updateNeeded = False
#process new musicvideos #process new musicvideos
allMB3MusicVideos = ReadEmbyDB().getMusicVideos(True, fullsync) allMB3MusicVideos = ReadEmbyDB().getMusicVideos(True, fullsync)
allKodiIds = set(ReadKodiDB().getKodiMusicVideoIds(True)) allKodiIds = set(ReadKodiDB().getKodiMusicVideoIds(True))
@ -705,7 +648,6 @@ class LibrarySync():
if item["Id"] not in allKodiIds: if item["Id"] not in allKodiIds:
WriteKodiDB().addMusicVideoToKodiLibrary(item) WriteKodiDB().addMusicVideoToKodiLibrary(item)
updateNeeded = True
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
@ -716,19 +658,6 @@ class LibrarySync():
pDialog.update(percentage, progressTitle, "Adding Musicvideo: " + str(count)) pDialog.update(percentage, progressTitle, "Adding Musicvideo: " + str(count))
count += 1 count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
@ -750,7 +679,6 @@ class LibrarySync():
kodimusicvideo = None kodimusicvideo = None
if(kodimusicvideo != None): if(kodimusicvideo != None):
#WriteKodiDB().updateMusicVideoToKodiLibrary(item, kodimusicvideo)
WriteKodiDB().updateMusicVideoToKodiLibrary_Batched(item, kodimusicvideo) WriteKodiDB().updateMusicVideoToKodiLibrary_Batched(item, kodimusicvideo)
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
@ -770,8 +698,6 @@ class LibrarySync():
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
cleanNeeded = False
# process any deletes only at fullsync # process any deletes only at fullsync
if fullsync: if fullsync:
allKodiIds = ReadKodiDB().getKodiMusicVideoIds(True) allKodiIds = ReadKodiDB().getKodiMusicVideoIds(True)
@ -779,33 +705,16 @@ class LibrarySync():
for kodiId in allKodiIds: for kodiId in allKodiIds:
if not kodiId in allEmbyMusicVideoIds: if not kodiId in allEmbyMusicVideoIds:
WriteKodiDB().deleteMusicVideoFromKodiLibrary(kodiId) WriteKodiDB().deleteMusicVideoFromKodiLibrary(kodiId)
cleanNeeded = True
if(self.ShouldStop(pDialog)): if(self.ShouldStop(pDialog)):
return False return False
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
finally: finally:
if(pDialog != None): if(pDialog != None):
pDialog.close() pDialog.close()
return True return True
def doKodiLibraryUpdate(self, clean, prog):
#initiate library update and wait for finish before processing any updates
if clean:
xbmc.executebuiltin("CleanLibrary(video)")
else:
xbmc.executebuiltin("UpdateLibrary(video)")
xbmc.sleep(1000)
while (xbmc.getCondVisibility("Library.IsScanningVideo")):
if(self.ShouldStop(prog)):
return False
xbmc.sleep(1000)
def updatePlayCounts(self): def updatePlayCounts(self):
#update all playcounts from MB3 to Kodi library #update all playcounts from MB3 to Kodi library

View file

@ -76,8 +76,9 @@ class PlayUtils():
# Works out if we are direct playing or not # Works out if we are direct playing or not
def isDirectPlay(self, result): def isDirectPlay(self, result):
return False
if (self.fileExists(result) or (result.get("LocationType") == "FileSystem" and self.isNetworkQualitySufficient(result) == True and self.isLocalPath(result) == False)): if (self.fileExists(result) or (result.get("LocationType") == "FileSystem" and self.isNetworkQualitySufficient(result) == True and self.isLocalPath(result) == False)):
return True return False
else: else:
return False return False

View file

@ -9,12 +9,8 @@ import xbmcaddon
import json import json
import os import os
addon = xbmcaddon.Addon(id='plugin.video.emby') import Utils as utils
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
musicvideoLibrary = os.path.join(dataPath,'musicvideos')
#sleepval is used to throttle the calls to the xbmc json API #sleepval is used to throttle the calls to the xbmc json API
sleepVal = 15 sleepVal = 15
@ -44,11 +40,20 @@ class ReadKodiDB():
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
embyId = None embyId = None
json_response = None
if type == "movie": if type == "movie":
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": { "movieid": %d, "properties" : ["imdbnumber","file"] }, "id": "libMovies"}' %kodiid) json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": { "movieid": %d, "properties" : ["imdbnumber","file"] }, "id": "libMovies"}' %kodiid)
if type == "episode": if type == "episode":
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodeDetails", "params": {"episodeid": %d, "properties": ["file","uniqueid"]}, "id": 1}' %kodiid) json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodeDetails", "params": {"episodeid": %d, "properties": ["file","uniqueid"]}, "id": 1}' %kodiid)
if type == "musicvideo":
connection = utils.KodiSQL()
cursor = connection.cursor()
cursor.execute("SELECT c23 as MBid FROM musicvideo WHERE idMVideo = ?",(kodiid,))
result = cursor.fetchone()
cursor.close()
if result != None:
embyId = result[0]
if json_response != None: if json_response != None:
jsonobject = json.loads(json_response.decode('utf-8','replace')) jsonobject = json.loads(json_response.decode('utf-8','replace'))
@ -212,15 +217,25 @@ class ReadKodiDB():
def getKodiMusicVideo(self, id): def getKodiMusicVideo(self, id):
#returns a single musicvideo from Kodi db selected on MB item ID #returns a single musicvideo from Kodi db selected on MB item ID
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideos", "params": { "filter": {"operator": "contains", "field": "path", "value": "' + id + '"}, "properties" : ["art", "thumbnail", "resume", "runtime", "year", "genre", "studio", "artist", "album", "track","plot", "director", "playcount", "lastplayed", "tag", "file"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libMusicVideos"}') #get the mediabrowser ID from DB
connection = utils.KodiSQL()
cursor = connection.cursor()
cursor.execute("SELECT idMVideo as musicvideoid FROM musicvideo WHERE c23 = ?",(id,))
result = cursor.fetchone()
musicvideoid = None
if result != None:
musicvideoid = result[0]
cursor.close()
if musicvideoid != None:
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideosDetails", "params": { "musicvideoid": ' + musicvideoid + ', "properties" : ["art", "thumbnail", "resume", "runtime", "year", "genre", "studio", "artist", "album", "track","plot", "director", "playcount", "lastplayed", "tag", "file"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libMusicVideos"}')
jsonobject = json.loads(json_response.decode('utf-8','replace')) jsonobject = json.loads(json_response.decode('utf-8','replace'))
musicvideo = None musicvideo = None
if(jsonobject.has_key('result')): if(jsonobject.has_key('result')):
result = jsonobject['result'] result = jsonobject['result']
if(result.has_key('musicvideos')): if(result.has_key('musicvideodetails')):
musicvideos = result['musicvideos'] musicvideo = result['musicvideodetails']
musicvideo = musicvideos[0]
return musicvideo return musicvideo
@ -228,9 +243,9 @@ class ReadKodiDB():
#returns all musicvideos in Kodi db inserted by MB #returns all musicvideos in Kodi db inserted by MB
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
if fullInfo: if fullInfo:
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideos", "params": { "filter": {"operator": "contains", "field": "path", "value": "plugin.video.emby"}, "properties" : ["art", "thumbnail", "resume", "runtime", "year", "genre", "studio", "artist", "album", "track", "lastplayed", "plot", "director", "playcount", "tag", "file"] }, "id": "libMusicVideos"}') json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideos", "params": { "properties" : ["art", "thumbnail", "resume", "runtime", "year", "genre", "studio", "artist", "album", "track", "lastplayed", "plot", "director", "playcount", "tag", "file"] }, "id": "libMusicVideos"}')
else: else:
json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideos", "params": { "filter": {"operator": "contains", "field": "path", "value": "plugin.video.emby"}, "properties" : ["resume", "playcount", "lastplayed", "file"] }, "id": "libMusicVideos"}') json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideos", "params": { "properties" : ["resume", "playcount", "lastplayed", "file", "track"] }, "id": "libMusicVideos"}')
jsonobject = json.loads(json_response.decode('utf-8','replace')) jsonobject = json.loads(json_response.decode('utf-8','replace'))
musicvideos = None musicvideos = None
if(jsonobject.has_key('result')): if(jsonobject.has_key('result')):
@ -241,10 +256,16 @@ class ReadKodiDB():
kodiMusicVideoMap = None kodiMusicVideoMap = None
if(musicvideos != None and len(musicvideos) > 0): if(musicvideos != None and len(musicvideos) > 0):
kodiMusicVideoMap = {} kodiMusicVideoMap = {}
connection = utils.KodiSQL()
cursor = connection.cursor()
for kodivideo in musicvideos: for kodivideo in musicvideos:
key = kodivideo["file"][-37:-5] #extract the id from the file name cursor.execute("SELECT c23 as MBid FROM musicvideo WHERE idMVideo = ?",(kodivideo["musicvideoid"],))
result = cursor.fetchone()
if result != None:
key = result[0]
kodiMusicVideoMap[key] = kodivideo kodiMusicVideoMap[key] = kodivideo
cursor.close()
return kodiMusicVideoMap return kodiMusicVideoMap
def getKodiMusicVideoIds(self,returnMB3Ids = False): def getKodiMusicVideoIds(self,returnMB3Ids = False):

View file

@ -49,44 +49,6 @@ def convertEncoding(data):
except: except:
return data return data
def checkKodiSources():
addon = xbmcaddon.Addon(id='plugin.video.emby')
addondir = xbmc.translatePath( addon.getAddonInfo('profile') )
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
musicvideoLibrary = os.path.join(dataPath,'musicvideos')
# If no folder exists at the time, create it.
if xbmcvfs.exists(addondir) == False:
xbmcvfs.mkdir(addondir)
xbmc.log("Manually created %s" % addondir)
if not xbmcvfs.exists(dataPath + os.sep):
xbmcvfs.mkdir(dataPath)
if not xbmcvfs.exists(movieLibrary + os.sep):
xbmcvfs.mkdir(movieLibrary)
addKodiSource("mediabrowser_movies",movieLibrary,"movies")
if not xbmcvfs.exists(tvLibrary + os.sep):
xbmcvfs.mkdir(tvLibrary)
addKodiSource("mediabrowser_tvshows",tvLibrary,"tvshows")
if not xbmcvfs.exists(musicvideoLibrary + os.sep):
xbmcvfs.mkdir(musicvideoLibrary)
addKodiSource("mediabrowser_musicvideos",musicvideoLibrary,"musicvideos")
rebootRequired = KodiAdvancedSettingsCheck()
if rebootRequired:
ret = xbmcgui.Dialog().yesno(heading="Emby Sync service", line1="A restart of Kodi is needed to apply changes.", line2="Synchronisation will not start before the restart.", line3="Do you want to restart now?")
if ret:
xbmc.executebuiltin("RestartApp")
else:
return False
return True
def KodiSQL(): def KodiSQL():
if xbmc.getInfoLabel("System.BuildVersion").startswith("13"): if xbmc.getInfoLabel("System.BuildVersion").startswith("13"):
#gotham #gotham
@ -104,80 +66,6 @@ def KodiSQL():
return connection return connection
def addKodiSource(name, path, type):
#add new source to database, common way is to add it directly to the Kodi DB. Fallback to adding it to the sources.xml
#return boolean wether a manual reboot is required.
#todo: Do feature request with Kodi team to get support for adding a source by the json API
error = False
try:
connection = KodiSQL()
cursor = connection.cursor( )
cursor.execute("select coalesce(max(idPath),0) as pathId from path")
pathId = cursor.fetchone()[0]
pathId = pathId + 1
pathsql="insert into path(idPath, strPath, strContent, strScraper, strHash, scanRecursive) values(?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (pathId,path + os.sep,type,"metadata.local",None,2147483647))
connection.commit()
cursor.close()
except:
error = True
# add it to sources.xml
sourcesFile = xbmc.translatePath( "special://profile/sources.xml" )
# add an empty sources file to work with
if xbmcvfs.exists(sourcesFile) == False:
sources = Element("sources")
video = SubElement(sources, "video")
ET.ElementTree(sources).write(sourcesFile)
if xbmcvfs.exists(sourcesFile):
tree = ET.ElementTree(file=sourcesFile)
root = tree.getroot()
videosources = root.find("video")
#remove any existing entries for this path
allsources = videosources.findall("source")
if allsources != None:
for source in allsources:
if source.find("name").text == name:
videosources.remove(source)
# add the new source
source = SubElement(videosources,'source')
SubElement(source, "name").text = name
SubElement(source, "path").text = path
tree.write(sourcesFile)
def KodiAdvancedSettingsCheck():
#setting that kodi should import watched state and resume points from the nfo files
settingsFile = xbmc.translatePath( "special://profile/advancedsettings.xml" )
# add an empty sources file to work with
if xbmcvfs.exists(settingsFile) == False:
sources = Element("advancedsettings")
video = SubElement(sources, "videolibrary")
ET.ElementTree(sources).write(settingsFile)
writeNeeded = False
if xbmcvfs.exists(settingsFile):
tree = ET.ElementTree(file=settingsFile)
root = tree.getroot()
video = root.find("videolibrary")
if video == None:
video = SubElement(root, "videolibrary")
# add the settings
if video.find("importwatchedstate") == None:
writeNeeded = True
SubElement(video, "importwatchedstate").text = "true"
if video.find("importresumepoint") == None:
writeNeeded = True
SubElement(video, "importresumepoint").text = "true"
if writeNeeded:
tree.write(settingsFile)
return True
else:
return False
def checkAuthentication(): def checkAuthentication():
#check authentication #check authentication
if addonSettings.getSetting('username') != "" and addonSettings.getSetting('ipaddress') != "": if addonSettings.getSetting('username') != "" and addonSettings.getSetting('ipaddress') != "":

View file

@ -20,13 +20,6 @@ from ReadEmbyDB import ReadEmbyDB
from API import API from API import API
import Utils as utils import Utils as utils
addon = xbmcaddon.Addon(id='plugin.video.emby')
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
musicvideoLibrary = os.path.join(dataPath,'musicvideos')
sleepVal = 20 sleepVal = 20
class WriteKodiDB(): class WriteKodiDB():
@ -76,15 +69,11 @@ class WriteKodiDB():
#set Filename #set Filename
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
docleanup = self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie") self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie", MBitem["Id"])
#if the path has been set directly in the DB, cleanup the locally created files to import the media-item into the Kodi DB to prevent Kodi from scanning it again.
if docleanup:
itemPath = os.path.join(movieLibrary,MBitem["Id"])
utils.removeDirectory(os.path.join(movieLibrary,MBitem["Id"] + os.sep))
#update common properties #update common properties
duration = (int(timeInfo.get('Duration'))*60) if KodiItem["runtime"] == 0:
self.getPropertyParam_Batched(KodiItem, "runtime", duration, params) self.getPropertyParam_Batched(KodiItem, "runtime", (int(timeInfo.get('Duration'))*60), params)
self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params) self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params)
self.getPropertyParam_Batched(KodiItem, "mpaa", MBitem.get("OfficialRating"), params) self.getPropertyParam_Batched(KodiItem, "mpaa", MBitem.get("OfficialRating"), params)
self.getPropertyParam_Batched(KodiItem, "lastplayed", userData.get("LastPlayedDate"), params) self.getPropertyParam_Batched(KodiItem, "lastplayed", userData.get("LastPlayedDate"), params)
@ -126,7 +115,7 @@ class WriteKodiDB():
if(jsonData != ""): if(jsonData != ""):
trailerItem = json.loads(jsonData) trailerItem = json.loads(jsonData)
if trailerItem[0].get("LocationType") == "FileSystem": if trailerItem[0].get("LocationType") == "FileSystem":
trailerUrl = "plugin://plugin.video.emby/?id=" + trailerItem[0].get("Id") + '&mode=play' trailerUrl = PlayUtils().getPlayUrl(server, trailerItem[0].get("Id"), trailerItem[0])
self.getPropertyParam_Batched(KodiItem, "trailer", trailerUrl, params) self.getPropertyParam_Batched(KodiItem, "trailer", trailerUrl, params)
@ -151,14 +140,6 @@ class WriteKodiDB():
#add actors #add actors
changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"), "movie") changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"), "movie")
#add theme music
if addon.getSetting("syncThemeMusic") == "true":
CreateFiles().copyThemeMusic(MBitem)
#add extra fanart
if addon.getSetting("syncExtraFanart") == "true":
CreateFiles().copyExtraFanart(MBitem)
if(changes): if(changes):
utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0) utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0)
@ -186,8 +167,8 @@ class WriteKodiDB():
self.getArtworkParam_Batched(KodiItem, MBitem, params) self.getArtworkParam_Batched(KodiItem, MBitem, params)
#update common properties #update common properties
duration = (int(timeInfo.get('Duration'))*60) if KodiItem["runtime"] == None:
self.getPropertyParam_Batched(KodiItem, "runtime", duration, params) self.getPropertyParam_Batched(KodiItem, "runtime", (int(timeInfo.get('Duration'))*60), params)
self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params) self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params)
self.getPropertyParamArray_Batched(KodiItem, "director", people.get("Director"), params) self.getPropertyParamArray_Batched(KodiItem, "director", people.get("Director"), params)
self.getPropertyParamArray_Batched(KodiItem, "genre", MBitem.get("Genres"), params) self.getPropertyParamArray_Batched(KodiItem, "genre", MBitem.get("Genres"), params)
@ -218,9 +199,6 @@ class WriteKodiDB():
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
result = xbmc.executeJSONRPC(jsoncommand.encode("utf-8")) result = xbmc.executeJSONRPC(jsoncommand.encode("utf-8"))
CreateFiles().createSTRM(MBitem)
CreateFiles().createNFO(MBitem)
if(changes): if(changes):
utils.logMsg("Updated musicvideo to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0) utils.logMsg("Updated musicvideo to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0)
@ -248,8 +226,6 @@ class WriteKodiDB():
changes |= self.updateArtWork(KodiItem,MBitem) changes |= self.updateArtWork(KodiItem,MBitem)
#update common properties #update common properties
duration = (int(timeInfo.get('Duration'))*60)
changes |= self.updateProperty(KodiItem,"runtime",duration,"movie")
changes |= self.updateProperty(KodiItem,"year",MBitem.get("ProductionYear"),"movie") changes |= self.updateProperty(KodiItem,"year",MBitem.get("ProductionYear"),"movie")
changes |= self.updateProperty(KodiItem,"mpaa",MBitem.get("OfficialRating"),"movie") changes |= self.updateProperty(KodiItem,"mpaa",MBitem.get("OfficialRating"),"movie")
changes |= self.updateProperty(KodiItem,"lastplayed",MBitem.get("LastPlayedDate"),"movie") changes |= self.updateProperty(KodiItem,"lastplayed",MBitem.get("LastPlayedDate"),"movie")
@ -289,7 +265,7 @@ class WriteKodiDB():
jsonData = downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=0 ) jsonData = downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=0 )
if(jsonData != ""): if(jsonData != ""):
trailerItem = json.loads(jsonData) trailerItem = json.loads(jsonData)
trailerUrl = "plugin://plugin.video.emby/?id=" + trailerItem[0].get("Id") + '&mode=play' trailerUrl = PlayUtils().getPlayUrl(server, trailerItem[0].get("Id"), MBitem)
changes |= self.updateProperty(KodiItem,"trailer",trailerUrl,"movie") changes |= self.updateProperty(KodiItem,"trailer",trailerUrl,"movie")
#add actors #add actors
@ -299,15 +275,6 @@ class WriteKodiDB():
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie") self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie")
#add theme music
if addon.getSetting("syncThemeMusic") == "true":
CreateFiles().copyThemeMusic(MBitem)
#add extra fanart
if addon.getSetting("syncExtraFanart") == "true":
CreateFiles().copyExtraFanart(MBitem)
if changes: if changes:
utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"]) utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"])
@ -334,12 +301,7 @@ class WriteKodiDB():
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
#make sure that the path always ends with a slash #make sure that the path always ends with a slash
playurl = playurl + "/" playurl = playurl + "/"
docleanup = self.setKodiFilename(KodiItem["tvshowid"], KodiItem["file"], playurl, "tvshow") self.setKodiFilename(KodiItem["tvshowid"], KodiItem["file"], playurl, "tvshow", MBitem["Id"])
#if the path has been set directly in the DB, cleanup the locally created nfo file to import the tvshow into the Kodi DB to prevent Kodi from scanning it again.
nfoPath = os.path.join(tvLibrary,MBitem["Id"],"tvshow.nfo")
if xbmcvfs.exists(nfoPath):
xbmcvfs.delete(nfoPath)
#update/check all artwork #update/check all artwork
changes |= self.updateArtWork(KodiItem,MBitem) changes |= self.updateArtWork(KodiItem,MBitem)
@ -375,18 +337,8 @@ class WriteKodiDB():
#add actors #add actors
changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"),"tvshow") changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"),"tvshow")
#update season artwork #update season details
self.updateSeasonArtwork(MBitem, KodiItem) self.updateSeasons(MBitem, KodiItem)
#CreateFiles().createNFO(MBitem)
#add theme music
if addon.getSetting("syncThemeMusic") == "true":
CreateFiles().copyThemeMusic(MBitem)
#add extra fanart
if addon.getSetting("syncExtraFanart") == "true":
CreateFiles().copyExtraFanart(MBitem)
if changes: if changes:
utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"]) utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"])
@ -416,22 +368,13 @@ class WriteKodiDB():
#update/check all artwork #update/check all artwork
changes |= self.updateArtWork(KodiItem,MBitem) changes |= self.updateArtWork(KodiItem,MBitem)
#set Filename (also submit strmfilepath to rename that if path has changed to original location) #set Filename (will update the filename in db if changed)
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
docleanup = self.setKodiFilename(KodiItem["episodeid"], KodiItem["file"], playurl, "episode") docleanup = self.setKodiFilename(KodiItem["episodeid"], KodiItem["file"], playurl, "episode", MBitem["Id"])
#if the path has been set directly in the DB, cleanup the locally created files to import the media-item into the Kodi DB to prevent Kodi from scanning it again.
if docleanup:
path = os.path.join(tvLibrary,MBitem["SeriesId"] + os.sep)
if xbmcvfs.exists(path):
allDirs, allFiles = xbmcvfs.listdir(path)
for file in allFiles:
if MBitem["Id"] in file:
xbmcvfs.delete(os.path.join(path,file))
#update common properties #update common properties
duration = (int(timeInfo.get('Duration'))*60) if KodiItem["runtime"] == 0:
changes |= self.updateProperty(KodiItem,"runtime",duration,"episode") changes |= self.updateProperty(KodiItem,"runtime",(int(timeInfo.get('Duration'))*60),"episode")
changes |= self.updateProperty(KodiItem,"lastplayed",userData.get("LastPlayedDate"),"episode") changes |= self.updateProperty(KodiItem,"lastplayed",userData.get("LastPlayedDate"),"episode")
if MBitem.get("PremiereDate") != None: if MBitem.get("PremiereDate") != None:
@ -696,56 +639,306 @@ class WriteKodiDB():
return pendingChanges return pendingChanges
def addMovieToKodiLibrary( self, item ): def addMovieToKodiLibrary( self, MBitem ):
itemPath = os.path.join(movieLibrary,item["Id"]) #adds a movie to Kodi by directly inserting it to the DB while there is no addmovie available on the json API
strmFile = os.path.join(itemPath,item["Id"] + ".strm") #TODO: PR at Kodi team for a addMovie endpoint on their API
changes = False addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
#create path if not exists timeInfo = API().getTimeInfo(MBitem)
if not xbmcvfs.exists(itemPath + os.sep): userData=API().getUserData(MBitem)
xbmcvfs.mkdir(itemPath) people = API().getPeople(MBitem)
genre = API().getGenre(MBitem)
studios = API().getStudios(MBitem)
mediaStreams=API().getMediaStreams(MBitem)
#create nfo file thumbPath = API().getArtwork(MBitem, "Primary")
changes = CreateFiles().createNFO(item)
# create strm file playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
changes |= CreateFiles().createSTRM(item) playurl = utils.convertEncoding(playurl)
if changes: if MBitem.get("DateCreated") != None:
utils.logMsg("MB3 Sync","Added movie to Kodi Library",item["Id"] + " - " + item["Name"]) dateadded = MBitem["DateCreated"].replace("T"," ")
dateadded = dateadded.replace(".0000000Z","")
else:
dateadded = None
def addMusicVideoToKodiLibrary( self, item ): connection = utils.KodiSQL()
itemPath = os.path.join(musicvideoLibrary,item["Id"]) cursor = connection.cursor()
strmFile = os.path.join(itemPath,item["Id"] + ".strm")
changes = False # we need to store both the path and the filename seperately in the kodi db so we split them up
if "\\" in playurl:
filename = playurl.rsplit("\\",1)[-1]
path = playurl.replace(filename,"")
elif "/" in playurl:
filename = playurl.rsplit("/",1)[-1]
path = playurl.replace(filename,"")
#create path if not exists #create the path
if not xbmcvfs.exists(itemPath + os.sep): cursor.execute("select coalesce(max(idPath),0) as pathid from path")
xbmcvfs.mkdir(itemPath) pathid = cursor.fetchone()[0]
pathid = pathid + 1
pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
cursor.execute(pathsql, (pathid,path,"movies","metadata.local",1))
#create nfo file playcount = None
changes = CreateFiles().createNFO(item) if userData.get("PlayCount") == "1":
playcount = 1
# create strm file #create the file if not exists
changes |= CreateFiles().createSTRM(item) cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ?",(filename,))
result = cursor.fetchone()
if result != None:
fileid = result[0]
if result == None:
cursor.execute("select coalesce(max(idFile),0) as fileid from files")
fileid = cursor.fetchone()[0]
fileid = fileid + 1
pathsql="insert into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (fileid,pathid,filename,playcount,userData.get("LastPlayedDate"),dateadded))
if changes: runtime = int(timeInfo.get('Duration'))*60
utils.logMsg("MB3 Sync","Added musicvideo to Kodi Library",item["Id"] + " - " + item["Name"]) plot = utils.convertEncoding(API().getOverview(MBitem))
thumb = "<thumb>" + API().getArtwork(MBitem, "Primary") + "</thumb>"
fanart = "<fanart>" + API().getArtwork(MBitem, "Backdrop") + "</fanart>"
title = utils.convertEncoding(MBitem["Name"])
sorttitle = utils.convertEncoding(MBitem["SortName"])
year = MBitem.get("ProductionYear")
if MBitem.get("CriticRating") != None:
rating = int(MBitem.get("CriticRating"))/10
else:
rating = None
if MBitem.get("ShortOverview") != None:
shortplot = utils.convertEncoding(MBitem.get("ShortOverview"))
else:
shortplot = None
def addEpisodeToKodiLibrary(self, item): trailerUrl = None
if MBitem.get("LocalTrailerCount") != None and MBitem.get("LocalTrailerCount") > 0:
itemTrailerUrl = "http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + MBitem.get("Id") + "/LocalTrailers?format=json"
jsonData = downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=0 )
if(jsonData != ""):
trailerItem = json.loads(jsonData)
if trailerItem[0].get("LocationType") == "FileSystem":
trailerUrl = PlayUtils().getPlayUrl(server, trailerItem[0].get("Id"), trailerItem[0])
changes = False #create the movie
cursor.execute("select coalesce(max(idMovie),0) as movieid from movie")
movieid = cursor.fetchone()[0]
movieid = movieid + 1
pathsql="insert into movie(idMovie, idFile, c00, c01, c02, c04, c07, c08, c09, c10, c11, c16, c19, c20) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, rating, year, thumb, MBitem["Id"], sorttitle, runtime, title, trailerUrl, fanart))
#create nfo file try:
changes = CreateFiles().createNFO(item) connection.commit()
utils.logMsg("MB3 Sync","Added movie to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
except:
utils.logMsg("MB3 Sync","Error adding movie to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
finally:
cursor.close()
# create strm file def addMusicVideoToKodiLibrary( self, MBitem ):
changes |= CreateFiles().createSTRM(item)
if changes: #adds a musicvideo to Kodi by directly inserting it to the DB while there is no addMusicVideo available on the json API
utils.logMsg("MB3 Sync","Added episode to Kodi Library",item["Id"] + " - " + item["Name"]) #TODO: PR at Kodi team for a addMusicVideo endpoint on their API
addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
people = API().getPeople(MBitem)
genre = API().getGenre(MBitem)
studios = API().getStudios(MBitem)
mediaStreams=API().getMediaStreams(MBitem)
thumbPath = API().getArtwork(MBitem, "Primary")
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
playurl = utils.convertEncoding(playurl)
if MBitem.get("DateCreated") != None:
dateadded = MBitem["DateCreated"].replace("T"," ")
dateadded = dateadded.replace(".0000000Z","")
else:
dateadded = None
connection = utils.KodiSQL()
cursor = connection.cursor()
# we need to store both the path and the filename seperately in the kodi db so we split them up
if "\\" in playurl:
filename = playurl.rsplit("\\",1)[-1]
path = playurl.replace(filename,"")
elif "/" in playurl:
filename = playurl.rsplit("/",1)[-1]
path = playurl.replace(filename,"")
#create the path
cursor.execute("select coalesce(max(idPath),0) as pathid from path")
pathid = cursor.fetchone()[0]
pathid = pathid + 1
pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
cursor.execute(pathsql, (pathid,path,"musicvideos","metadata.local",1))
playcount = None
if userData.get("PlayCount") == "1":
playcount = 1
#create the file if not exists
cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ?",(filename,))
result = cursor.fetchone()
if result != None:
fileid = result[0]
if result == None:
cursor.execute("select coalesce(max(idFile),0) as fileid from files")
fileid = cursor.fetchone()[0]
fileid = fileid + 1
pathsql="insert into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (fileid,pathid,filename,playcount,userData.get("LastPlayedDate"),dateadded))
runtime = int(timeInfo.get('Duration'))*60
plot = utils.convertEncoding(API().getOverview(MBitem))
thumb = "<thumb>" + API().getArtwork(MBitem, "Primary") + "</thumb>"
title = utils.convertEncoding(MBitem["Name"])
#create the musicvideo
cursor.execute("select coalesce(max(idMVideo),0) as musicvideoid from musicvideo")
musicvideoid = cursor.fetchone()[0]
musicvideoid = musicvideoid + 1
pathsql="insert into musicvideo(idMVideo, idFile, c00, c01, c04, c08, c23) values(?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (musicvideoid, fileid, title, thumb, runtime, plot, MBitem["Id"]))
try:
connection.commit()
utils.logMsg("MB3 Sync","Added musicvideo to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
except:
utils.logMsg("MB3 Sync","Error adding musicvideo to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
finally:
cursor.close()
def addEpisodeToKodiLibrary(self, MBitem):
#adds a Episode to Kodi by directly inserting it to the DB while there is no addEpisode available on the json API
#TODO: PR at Kodi team for a addEpisode endpoint on their API
addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
people = API().getPeople(MBitem)
genre = API().getGenre(MBitem)
studios = API().getStudios(MBitem)
mediaStreams=API().getMediaStreams(MBitem)
thumbPath = API().getArtwork(MBitem, "Primary")
playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
playurl = utils.convertEncoding(playurl)
if MBitem.get("DateCreated") != None:
dateadded = MBitem["DateCreated"].replace("T"," ")
dateadded = dateadded.split(".")[0]
else:
dateadded = None
if userData.get("LastPlayedDate") != None:
lastplayed = userData.get("LastPlayedDate")
else:
lastplayed = None
connection = utils.KodiSQL()
cursor = connection.cursor()
# we need to store both the path and the filename seperately in the kodi db so we split them up
if "\\" in playurl:
filename = playurl.rsplit("\\",1)[-1]
path = playurl.replace(filename,"")
elif "/" in playurl:
filename = playurl.rsplit("/",1)[-1]
path = playurl.replace(filename,"")
#create the new path - return id if already exists
cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,))
result = cursor.fetchone()
if result != None:
pathid = result[0]
if result == None:
cursor.execute("select coalesce(max(idPath),0) as pathid from path")
pathid = cursor.fetchone()[0]
pathid = pathid + 1
pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
cursor.execute(pathsql, (pathid,path,None,None,1))
playcount = None
if userData.get("PlayCount") == "1":
playcount = 1
#create the file if not exists
cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ?",(filename,))
result = cursor.fetchone()
if result != None:
fileid = result[0]
if result == None:
cursor.execute("select coalesce(max(idFile),0) as fileid from files")
fileid = cursor.fetchone()[0]
fileid = fileid + 1
sql="INSERT OR REPLACE into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)"
cursor.execute(sql, (fileid,pathid,filename,playcount,lastplayed,dateadded))
#get the showid
cursor.execute("SELECT idShow as showid FROM tvshow WHERE c12 = ?",(MBitem["SeriesId"],))
showid = cursor.fetchone()[0]
season = 0
if MBitem.get("ParentIndexNumber") != None:
season = int(MBitem.get("ParentIndexNumber"))
episode = 0
if MBitem.get("IndexNumber") != None:
episode = int(MBitem.get("IndexNumber"))
runtime = int(timeInfo.get('Duration'))*60
plot = utils.convertEncoding(API().getOverview(MBitem))
thumb = "<thumb>" + API().getArtwork(MBitem, "Primary") + "</thumb>"
title = utils.convertEncoding(MBitem["Name"])
if MBitem.get("CriticRating") != None:
rating = int(MBitem.get("CriticRating"))/10
else:
rating = None
#create the episode
cursor.execute("select coalesce(max(idEpisode),0) as episodeid from episode")
episodeid = cursor.fetchone()[0]
episodeid = episodeid + 1
pathsql="INSERT into episode(idEpisode, idFile, c00, c01, c03, c06, c09, c20, c12, c13, c14, idShow) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, thumb, runtime, MBitem["Id"], season, episode, title, showid))
try:
connection.commit()
utils.logMsg("MB3 Sync","Added TV Show to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
except:
utils.logMsg("MB3 Sync","Error adding tvshow to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
finally:
cursor.close()
def deleteMovieFromKodiLibrary(self, id ): def deleteMovieFromKodiLibrary(self, id ):
kodiItem = ReadKodiDB().getKodiMovie(id) kodiItem = ReadKodiDB().getKodiMovie(id)
@ -753,24 +946,12 @@ class WriteKodiDB():
if kodiItem != None: if kodiItem != None:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMovie", "params": { "movieid": %i}, "id": 1 }' %(kodiItem["movieid"])) xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMovie", "params": { "movieid": %i}, "id": 1 }' %(kodiItem["movieid"]))
path = os.path.join(movieLibrary,id + os.sep)
utils.removeDirectory(path)
def deleteMusicVideoFromKodiLibrary(self, id ): def deleteMusicVideoFromKodiLibrary(self, id ):
utils.logMsg("deleting musicvideo from Kodi library",id) utils.logMsg("deleting musicvideo from Kodi library",id)
kodiItem = ReadKodiDB().getKodiMusicVideo(id) kodiItem = ReadKodiDB().getKodiMusicVideo(id)
if kodiItem != None: if kodiItem != None:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMusicVideo", "params": { "musicvideoid": %i}, "id": 1 }' %(kodiItem["musicvideoid"])) xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMusicVideo", "params": { "musicvideoid": %i}, "id": 1 }' %(kodiItem["musicvideoid"]))
path = os.path.join(musicvideoLibrary,id)
allDirs, allFiles = xbmcvfs.listdir(path)
for dir in allDirs:
xbmcvfs.rmdir(os.path.join(path,dir))
for file in allFiles:
xbmcvfs.delete(os.path.join(path,file))
xbmcvfs.rmdir(path)
def deleteEpisodeFromKodiLibrary(self, episodeid, tvshowid ): def deleteEpisodeFromKodiLibrary(self, episodeid, tvshowid ):
utils.logMsg("deleting episode from Kodi library",episodeid) utils.logMsg("deleting episode from Kodi library",episodeid)
episode = ReadKodiDB().getKodiEpisodeByMbItem(episodeid, tvshowid) episode = ReadKodiDB().getKodiEpisodeByMbItem(episodeid, tvshowid)
@ -779,32 +960,82 @@ class WriteKodiDB():
WINDOW.setProperty("suspendDeletes", "True") WINDOW.setProperty("suspendDeletes", "True")
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveEpisode", "params": { "episodeid": %i}, "id": 1 }' %(episode["episodeid"])) xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveEpisode", "params": { "episodeid": %i}, "id": 1 }' %(episode["episodeid"]))
itemPath = os.path.join(tvLibrary,tvshowid)
allDirs, allFiles = xbmcvfs.listdir(itemPath)
for file in allFiles:
if episodeid in file:
xbmcvfs.delete(file)
while WINDOW.getProperty("suspendDeletes") == "True": while WINDOW.getProperty("suspendDeletes") == "True":
xbmc.sleep(100) xbmc.sleep(100)
utils.logMsg("episode deleted succesfully!",episodeid) utils.logMsg("episode deleted succesfully!",episodeid)
else: else:
utils.logMsg("episode not found in kodi DB",episodeid) utils.logMsg("episode not found in kodi DB",episodeid)
def addTVShowToKodiLibrary( self, item ): def addTVShowToKodiLibrary( self, MBitem ):
itemPath = os.path.join(tvLibrary,item["Id"]) #adds a Tvshow to Kodi by directly inserting it to the DB while there is no addTvShow available on the json API
#TODO: PR at Kodi team for a addTvShow endpoint on their API
changes = False addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
downloadUtils = DownloadUtils()
userid = downloadUtils.getUserId()
#create path if not exists timeInfo = API().getTimeInfo(MBitem)
if not xbmcvfs.exists(itemPath + os.sep): userData=API().getUserData(MBitem)
xbmcvfs.mkdir(itemPath) people = API().getPeople(MBitem)
genre = API().getGenre(MBitem)
studios = API().getStudios(MBitem)
mediaStreams=API().getMediaStreams(MBitem)
#create nfo file thumbPath = API().getArtwork(MBitem, "Primary")
changes = CreateFiles().createNFO(item)
if changes: playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
utils.logMsg("Added TV Show to Kodi Library ",item["Id"] + " - " + item["Name"]) #make sure that the path always ends with a slash
path = playurl + "/"
if MBitem.get("DateCreated") != None:
dateadded = MBitem["DateCreated"].replace("T"," ")
dateadded = dateadded.replace(".0000000Z","")
else:
dateadded = None
connection = utils.KodiSQL()
cursor = connection.cursor()
#create the path
cursor.execute("select coalesce(max(idPath),0) as pathid from path")
pathid = cursor.fetchone()[0]
pathid = pathid + 1
pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
cursor.execute(pathsql, (pathid,path,None,None,1))
runtime = int(timeInfo.get('Duration'))*60
plot = utils.convertEncoding(API().getOverview(MBitem))
thumb = "<thumb>" + API().getArtwork(MBitem, "Primary") + "</thumb>"
fanart = "<fanart>" + API().getArtwork(MBitem, "Backdrop") + "</fanart>"
title = utils.convertEncoding(MBitem["Name"])
sorttitle = utils.convertEncoding(MBitem["SortName"])
if MBitem.get("CriticRating") != None:
rating = int(MBitem.get("CriticRating"))/10
else:
rating = None
#create the tvshow
cursor.execute("select coalesce(max(idShow),0) as showid from tvshow")
showid = cursor.fetchone()[0]
showid = pathid + 1
pathsql="insert into tvshow(idShow, c00, c01, c04, c06, c09, c11, c12, c15) values(?, ?, ?, ?, ?, ?, ?, ?, ?)"
cursor.execute(pathsql, (showid, title, plot, rating, thumb, title, fanart, MBitem["Id"], sorttitle))
#link the path
pathsql="insert into tvshowlinkpath(idShow,idPath) values(?, ?)"
cursor.execute(pathsql, (showid,pathid))
try:
connection.commit()
utils.logMsg("MB3 Sync","Added TV Show to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
except:
utils.logMsg("MB3 Sync","Error adding tvshow to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
finally:
cursor.close()
def deleteTVShowFromKodiLibrary(self, id ): def deleteTVShowFromKodiLibrary(self, id ):
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
@ -814,34 +1045,33 @@ class WriteKodiDB():
if kodiItem != None: if kodiItem != None:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveTVShow", "params": { "tvshowid": %i}, "id": 1 }' %(kodiItem["tvshowid"])) xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveTVShow", "params": { "tvshowid": %i}, "id": 1 }' %(kodiItem["tvshowid"]))
path = os.path.join(tvLibrary,id + os.sep) def updateSeasons(self,MBitem, KodiItem):
utils.removeDirectory(path) #use sqlite to set the season details because no method in API available for this
def updateSeasonArtwork(self,MBitem, KodiItem):
#use sqlite to set the season artwork because no method in API available for this
#season poster and banner are set by the nfo. landscape image is filled by this method
#if wanted this feature can be extended to also update the other artwork
tvshowid = KodiItem["tvshowid"] tvshowid = KodiItem["tvshowid"]
connection = utils.KodiSQL() connection = utils.KodiSQL()
cursor = connection.cursor( ) cursor = connection.cursor()
seasonData = ReadEmbyDB().getTVShowSeasons(MBitem["Id"]) seasonData = ReadEmbyDB().getTVShowSeasons(MBitem["Id"])
if seasonData != None: if seasonData != None:
for season in seasonData: for season in seasonData:
if season.has_key("IndexNumber"): if season.has_key("IndexNumber"):
MB3landscape = API().getArtwork(season, "Thumb")
if MB3landscape != "":
cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(tvshowid,season["IndexNumber"])) cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(tvshowid,season["IndexNumber"]))
result = cursor.fetchone() result = cursor.fetchone()
if result != None:
seasonid = result[0]
cursor.execute("SELECT art_id as art_id FROM art WHERE media_id = ? and media_type = ? and type = ?",(seasonid,"season","landscape"))
result = cursor.fetchone()
if result == None: if result == None:
sql="INSERT into art(media_id, media_type, type, url) values(?, ?, ?, ?)" #create the season
cursor.execute(sql, (seasonid,"season","landscape",MB3landscape)) cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons")
seasonid = cursor.fetchone()[0]
seasonid = seasonid + 1
cursor.execute("INSERT into seasons(idSeason, idShow, season) values(?, ?, ?)", (seasonid, tvshowid, season["IndexNumber"]))
#insert artwork
if API().getArtwork(season, "Thumb") != "":
cursor.execute("INSERT into art(media_id, media_type, type, url) values(?, ?, ?, ?)", (seasonid,"season","landscape",API().getArtwork(season, "Thumb")))
if API().getArtwork(season, "Primary") != "":
cursor.execute("INSERT into art(media_id, media_type, type, url) values(?, ?, ?, ?)", (seasonid,"season","poster",API().getArtwork(season, "Primary")))
if API().getArtwork(season, "Banner") != "":
cursor.execute("INSERT into art(media_id, media_type, type, url) values(?, ?, ?, ?)", (seasonid,"season","banner",API().getArtwork(season, "Banner")))
connection.commit() connection.commit()
cursor.close() cursor.close()
@ -873,7 +1103,7 @@ class WriteKodiDB():
connection.commit() connection.commit()
cursor.close() cursor.close()
def setKodiFilename(self, id, oldFileName, newFileName, fileType): def setKodiFilename(self, id, oldFileName, newFileName, fileType, mbId):
#use sqlite to set the filename in DB -- needed to avoid problems with resumepoints etc #use sqlite to set the filename in DB -- needed to avoid problems with resumepoints etc
#return True if any action is performed, False if no action is performed #return True if any action is performed, False if no action is performed
#todo --> submit PR to kodi team to get this added to the jsonrpc api #todo --> submit PR to kodi team to get this added to the jsonrpc api
@ -889,7 +1119,7 @@ class WriteKodiDB():
xbmc.sleep(sleepVal) xbmc.sleep(sleepVal)
connection = utils.KodiSQL() connection = utils.KodiSQL()
cursor = connection.cursor( ) cursor = connection.cursor()
utils.logMsg("MB3 Sync","setting filename in kodi db..." + fileType + ": " + str(id)) utils.logMsg("MB3 Sync","setting filename in kodi db..." + fileType + ": " + str(id))
utils.logMsg("MB3 Sync","old filename -->" + oldFileName) utils.logMsg("MB3 Sync","old filename -->" + oldFileName)
utils.logMsg("MB3 Sync","new filename -->" + newFileName) utils.logMsg("MB3 Sync","new filename -->" + newFileName)
@ -904,6 +1134,14 @@ class WriteKodiDB():
else: else:
# we need to store both the path and the filename seperately in the kodi db so we split them up # we need to store both the path and the filename seperately in the kodi db so we split them up
if newFileName.startswith("http"):
#transcoding or play from stream
path = "plugin://plugin.video.emby/"
filename = "?id=" + mbId + '&mode=play'
else:
# direct play
if "\\" in newFileName: if "\\" in newFileName:
filename = newFileName.rsplit("\\",1)[-1] filename = newFileName.rsplit("\\",1)[-1]
path = newFileName.replace(filename,"") path = newFileName.replace(filename,"")
@ -911,10 +1149,6 @@ class WriteKodiDB():
filename = newFileName.rsplit("/",1)[-1] filename = newFileName.rsplit("/",1)[-1]
path = newFileName.replace(filename,"") path = newFileName.replace(filename,"")
#if we want to use transcoding/play from stream we pass on the complete http path
#in this case both the path and filename are set to the addonpath
if newFileName.startswith("http"):
path = newFileName
######### PROCESS EPISODE ############ ######### PROCESS EPISODE ############
if fileType == "episode": if fileType == "episode":
@ -964,7 +1198,6 @@ class WriteKodiDB():
return actionPerformed return actionPerformed
def AddActorsToMedia(self, KodiItem, people, mediatype): def AddActorsToMedia(self, KodiItem, people, mediatype):
#use sqlite to set add the actors while json api doesn't support this yet #use sqlite to set add the actors while json api doesn't support this yet
#todo --> submit PR to kodi team to get this added to the jsonrpc api #todo --> submit PR to kodi team to get this added to the jsonrpc api

View file

@ -36,9 +36,6 @@ class Service():
ConnectionManager().checkServer() ConnectionManager().checkServer()
DownloadUtils().authenticate(retreive=True) DownloadUtils().authenticate(retreive=True)
# check kodi library sources
mayRun = utils.checkKodiSources()
player = Player() player = Player()
lastProgressUpdate = datetime.today() lastProgressUpdate = datetime.today()
@ -48,8 +45,6 @@ class Service():
cur_seconds_fullsync = interval_FullSync cur_seconds_fullsync = interval_FullSync
cur_seconds_incrsync = interval_IncrementalSync cur_seconds_incrsync = interval_IncrementalSync
if mayRun:
ws = WebSocketThread() ws = WebSocketThread()
while not self.KodiMonitor.abortRequested(): while not self.KodiMonitor.abortRequested():
@ -111,15 +106,6 @@ class Service():
else: else:
cur_seconds_incrsync += 1 cur_seconds_incrsync += 1
# check if we need to run lib updates
WINDOW = xbmcgui.Window( 10000 )
if(WINDOW.getProperty("cleanNeeded") == "true"):
xbmc.executebuiltin("CleanLibrary(video)")
WINDOW.clearProperty("cleanNeeded")
if(WINDOW.getProperty("updateNeeded") == "true"):
xbmc.executebuiltin("UpdateLibrary(video)")
WINDOW.clearProperty("updateNeeded")
else: else:
xbmc.log("Not authenticated yet") xbmc.log("Not authenticated yet")