diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index afee183f..559d39b7 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -99,8 +99,6 @@ class LibrarySync(): for view in views: - updateNeeded = False - #process new movies allMB3Movies = ReadEmbyDB().getMovies(view.get('id'), True, fullsync) allKodiIds = set(ReadKodiDB().getKodiMoviesIds(True)) @@ -126,7 +124,6 @@ class LibrarySync(): if item["Id"] not in allKodiIds: WriteKodiDB().addMovieToKodiLibrary(item) - updateNeeded = True totalItemsAdded += 1 if(self.ShouldStop(pDialog)): @@ -138,19 +135,6 @@ class LibrarySync(): pDialog.update(percentage, progressTitle, "Adding Movie: " + str(count)) 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)): return False @@ -228,8 +212,6 @@ class LibrarySync(): if(self.ShouldStop(pDialog)): return False - cleanNeeded = False - # process any deletes only at fullsync if fullsync: allKodiIds = ReadKodiDB().getKodiMoviesIds(True) @@ -238,16 +220,11 @@ class LibrarySync(): if not kodiId in allEmbyMovieIds: WINDOW.setProperty(kodiId,"deleted") WriteKodiDB().deleteMovieFromKodiLibrary(kodiId) - cleanNeeded = True totalItemsDeleted += 1 if(self.ShouldStop(pDialog)): return False - #initiate library clean and wait for finish before processing any updates - if cleanNeeded: - self.doKodiLibraryUpdate(True, pDialog) - # display notification if set up notificationString = "" if(totalItemsAdded > 0): @@ -308,8 +285,6 @@ class LibrarySync(): if latestMBEpisodes != None: allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True)) - updateNeeded = False - if(pDialog != None): pDialog.update(0, progressTitle) total = len(latestMBEpisodes) + 1 @@ -339,7 +314,6 @@ class LibrarySync(): #no match so we have to create it print "creating episode in incremental sync!" WriteKodiDB().addEpisodeToKodiLibrary(episode) - updateNeeded = True progressAction = "Adding" totalItemsAdded += 1 @@ -352,11 +326,6 @@ class LibrarySync(): pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count)) count += 1 - #initiate library update and wait for finish before processing any updates - if updateNeeded: - self.doKodiLibraryUpdate(False, pDialog) - updateNeeded = False - #process updates if(pDialog != None): progressTitle = "Sync DB : Processing Episodes" @@ -400,7 +369,6 @@ class LibrarySync(): tvShowData = ReadEmbyDB().getTVShows(True,True) allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True)) - updateNeeded = False if(self.ShouldStop(pDialog)): return False @@ -420,7 +388,6 @@ class LibrarySync(): progMessage = "Processing" if item["Id"] not in allKodiIds: WriteKodiDB().addTVShowToKodiLibrary(item) - updateNeeded = True totalItemsAdded += 1 if(self.ShouldStop(pDialog)): @@ -479,7 +446,6 @@ class LibrarySync(): if ReadKodiDB().getKodiEpisodeByMbItem(item["Id"],tvshow) == None: #no match so we have to create it WriteKodiDB().addEpisodeToKodiLibrary(item) - updateNeeded = True progressAction = "Adding" totalItemsAdded += 1 @@ -493,20 +459,7 @@ class LibrarySync(): count += 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): progressTitle = "Sync DB : Processing TV Shows" @@ -602,8 +555,6 @@ class LibrarySync(): if(self.ShouldStop(pDialog)): return False - cleanNeeded = False - # DELETES -- EPISODES # process any deletes only at fullsync allMB3EpisodeIds = set(allMB3EpisodeIds) @@ -611,25 +562,19 @@ class LibrarySync(): if episode.get('episodeid') not in allMB3EpisodeIds: WINDOW.setProperty("embyid" + str(episode.get('episodeid')),"deleted") WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid')) - cleanneeded = True totalItemsDeleted += 1 # DELETES -- TV SHOWS if fullsync: - allLocaldirs, filesTVShows = xbmcvfs.listdir(tvLibrary) + allKodiShows = ReadKodiDB().getKodiTvShowsIds(True) allMB3TVShows = set(allTVShows) - for dir in allLocaldirs: - if not dir in allMB3TVShows: + for show in allKodiShows: + if not show in allMB3TVShows: WriteKodiDB().deleteTVShowFromKodiLibrary(dir) - cleanneeded = True totalItemsDeleted += 1 if(self.ShouldStop(pDialog)): return False - - #initiate library clean and wait for finish before processing any updates - if cleanNeeded: - self.doKodiLibraryUpdate(True, pDialog) # display notification if set up notificationString = "" @@ -680,8 +625,6 @@ class LibrarySync(): progressTitle = "" - updateNeeded = False - #process new musicvideos allMB3MusicVideos = ReadEmbyDB().getMusicVideos(True, fullsync) allKodiIds = set(ReadKodiDB().getKodiMusicVideoIds(True)) @@ -705,7 +648,6 @@ class LibrarySync(): if item["Id"] not in allKodiIds: WriteKodiDB().addMusicVideoToKodiLibrary(item) - updateNeeded = True if(self.ShouldStop(pDialog)): return False @@ -716,19 +658,6 @@ class LibrarySync(): pDialog.update(percentage, progressTitle, "Adding Musicvideo: " + str(count)) 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)): return False @@ -750,7 +679,6 @@ class LibrarySync(): kodimusicvideo = None if(kodimusicvideo != None): - #WriteKodiDB().updateMusicVideoToKodiLibrary(item, kodimusicvideo) WriteKodiDB().updateMusicVideoToKodiLibrary_Batched(item, kodimusicvideo) if(self.ShouldStop(pDialog)): @@ -770,8 +698,6 @@ class LibrarySync(): if(self.ShouldStop(pDialog)): return False - cleanNeeded = False - # process any deletes only at fullsync if fullsync: allKodiIds = ReadKodiDB().getKodiMusicVideoIds(True) @@ -779,33 +705,16 @@ class LibrarySync(): for kodiId in allKodiIds: if not kodiId in allEmbyMusicVideoIds: WriteKodiDB().deleteMusicVideoFromKodiLibrary(kodiId) - cleanNeeded = True if(self.ShouldStop(pDialog)): return False - #initiate library clean and wait for finish before processing any updates - if cleanNeeded: - self.doKodiLibraryUpdate(True, pDialog) - finally: if(pDialog != None): pDialog.close() 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): #update all playcounts from MB3 to Kodi library diff --git a/resources/lib/PlayUtils.py b/resources/lib/PlayUtils.py index 8deff44b..facae3b4 100644 --- a/resources/lib/PlayUtils.py +++ b/resources/lib/PlayUtils.py @@ -76,8 +76,9 @@ class PlayUtils(): # Works out if we are direct playing or not 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)): - return True + return False else: return False diff --git a/resources/lib/ReadKodiDB.py b/resources/lib/ReadKodiDB.py index 4ed01d50..3efb4c6f 100644 --- a/resources/lib/ReadKodiDB.py +++ b/resources/lib/ReadKodiDB.py @@ -9,12 +9,8 @@ import xbmcaddon import json import os -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') +import Utils as utils + #sleepval is used to throttle the calls to the xbmc json API sleepVal = 15 @@ -44,11 +40,20 @@ class ReadKodiDB(): xbmc.sleep(sleepVal) embyId = None + json_response = None if type == "movie": json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": { "movieid": %d, "properties" : ["imdbnumber","file"] }, "id": "libMovies"}' %kodiid) if type == "episode": 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: jsonobject = json.loads(json_response.decode('utf-8','replace')) @@ -65,7 +70,7 @@ class ReadKodiDB(): if item['uniqueid'].has_key('unknown'): embyId = item["uniqueid"]["unknown"] - return embyId + return embyId def getKodiMovies(self,fullInfo = False): #returns all movies in Kodi db @@ -212,15 +217,25 @@ class ReadKodiDB(): def getKodiMusicVideo(self, id): #returns a single musicvideo from Kodi db selected on MB item ID 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"}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - musicvideo = None - - if(jsonobject.has_key('result')): - result = jsonobject['result'] - if(result.has_key('musicvideos')): - musicvideos = result['musicvideos'] - musicvideo = musicvideos[0] + #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')) + musicvideo = None + + if(jsonobject.has_key('result')): + result = jsonobject['result'] + if(result.has_key('musicvideodetails')): + musicvideo = result['musicvideodetails'] return musicvideo @@ -228,9 +243,9 @@ class ReadKodiDB(): #returns all musicvideos in Kodi db inserted by MB xbmc.sleep(sleepVal) 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: - 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')) musicvideos = None if(jsonobject.has_key('result')): @@ -241,10 +256,16 @@ class ReadKodiDB(): kodiMusicVideoMap = None if(musicvideos != None and len(musicvideos) > 0): kodiMusicVideoMap = {} + connection = utils.KodiSQL() + cursor = connection.cursor() for kodivideo in musicvideos: - key = kodivideo["file"][-37:-5] #extract the id from the file name - kodiMusicVideoMap[key] = kodivideo - + cursor.execute("SELECT c23 as MBid FROM musicvideo WHERE idMVideo = ?",(kodivideo["musicvideoid"],)) + result = cursor.fetchone() + if result != None: + key = result[0] + kodiMusicVideoMap[key] = kodivideo + + cursor.close() return kodiMusicVideoMap def getKodiMusicVideoIds(self,returnMB3Ids = False): diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index a39423f4..0ad9acad 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -49,44 +49,6 @@ def convertEncoding(data): except: 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(): if xbmc.getInfoLabel("System.BuildVersion").startswith("13"): #gotham @@ -103,81 +65,7 @@ def KodiSQL(): 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(): #check authentication if addonSettings.getSetting('username') != "" and addonSettings.getSetting('ipaddress') != "": diff --git a/resources/lib/WriteKodiDB.py b/resources/lib/WriteKodiDB.py index 905e10e7..4a70e09b 100644 --- a/resources/lib/WriteKodiDB.py +++ b/resources/lib/WriteKodiDB.py @@ -20,13 +20,6 @@ from ReadEmbyDB import ReadEmbyDB from API import API 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 class WriteKodiDB(): @@ -76,15 +69,11 @@ class WriteKodiDB(): #set Filename playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) - docleanup = self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie") - #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)) + self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie", MBitem["Id"]) #update common properties - duration = (int(timeInfo.get('Duration'))*60) - self.getPropertyParam_Batched(KodiItem, "runtime", duration, params) + if KodiItem["runtime"] == 0: + self.getPropertyParam_Batched(KodiItem, "runtime", (int(timeInfo.get('Duration'))*60), params) self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params) self.getPropertyParam_Batched(KodiItem, "mpaa", MBitem.get("OfficialRating"), params) self.getPropertyParam_Batched(KodiItem, "lastplayed", userData.get("LastPlayedDate"), params) @@ -126,7 +115,7 @@ class WriteKodiDB(): if(jsonData != ""): trailerItem = json.loads(jsonData) 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) @@ -151,14 +140,6 @@ class WriteKodiDB(): #add actors 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): 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) #update common properties - duration = (int(timeInfo.get('Duration'))*60) - self.getPropertyParam_Batched(KodiItem, "runtime", duration, params) + if KodiItem["runtime"] == None: + self.getPropertyParam_Batched(KodiItem, "runtime", (int(timeInfo.get('Duration'))*60), params) self.getPropertyParam_Batched(KodiItem, "year", MBitem.get("ProductionYear"), params) self.getPropertyParamArray_Batched(KodiItem, "director", people.get("Director"), params) self.getPropertyParamArray_Batched(KodiItem, "genre", MBitem.get("Genres"), params) @@ -218,9 +199,6 @@ class WriteKodiDB(): xbmc.sleep(sleepVal) result = xbmc.executeJSONRPC(jsoncommand.encode("utf-8")) - CreateFiles().createSTRM(MBitem) - CreateFiles().createNFO(MBitem) - if(changes): utils.logMsg("Updated musicvideo to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0) @@ -248,8 +226,6 @@ class WriteKodiDB(): changes |= self.updateArtWork(KodiItem,MBitem) #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,"mpaa",MBitem.get("OfficialRating"),"movie") changes |= self.updateProperty(KodiItem,"lastplayed",MBitem.get("LastPlayedDate"),"movie") @@ -289,7 +265,7 @@ class WriteKodiDB(): jsonData = downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=0 ) if(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") #add actors @@ -299,15 +275,6 @@ class WriteKodiDB(): playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) 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: utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"]) @@ -334,13 +301,8 @@ class WriteKodiDB(): playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) #make sure that the path always ends with a slash playurl = playurl + "/" - docleanup = self.setKodiFilename(KodiItem["tvshowid"], KodiItem["file"], playurl, "tvshow") - - #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) - + self.setKodiFilename(KodiItem["tvshowid"], KodiItem["file"], playurl, "tvshow", MBitem["Id"]) + #update/check all artwork changes |= self.updateArtWork(KodiItem,MBitem) @@ -375,18 +337,8 @@ class WriteKodiDB(): #add actors changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"),"tvshow") - #update season artwork - self.updateSeasonArtwork(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) + #update season details + self.updateSeasons(MBitem, KodiItem) if changes: utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"]) @@ -416,22 +368,13 @@ class WriteKodiDB(): #update/check all artwork 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) - docleanup = self.setKodiFilename(KodiItem["episodeid"], KodiItem["file"], playurl, "episode") - - #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)) + docleanup = self.setKodiFilename(KodiItem["episodeid"], KodiItem["file"], playurl, "episode", MBitem["Id"]) #update common properties - duration = (int(timeInfo.get('Duration'))*60) - changes |= self.updateProperty(KodiItem,"runtime",duration,"episode") + if KodiItem["runtime"] == 0: + changes |= self.updateProperty(KodiItem,"runtime",(int(timeInfo.get('Duration'))*60),"episode") changes |= self.updateProperty(KodiItem,"lastplayed",userData.get("LastPlayedDate"),"episode") if MBitem.get("PremiereDate") != None: @@ -696,80 +639,318 @@ class WriteKodiDB(): return pendingChanges - def addMovieToKodiLibrary( self, item ): - itemPath = os.path.join(movieLibrary,item["Id"]) - strmFile = os.path.join(itemPath,item["Id"] + ".strm") + def addMovieToKodiLibrary( self, MBitem ): + #adds a movie to Kodi by directly inserting it to the DB while there is no addmovie available on the json API + #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 - if not xbmcvfs.exists(itemPath + os.sep): - xbmcvfs.mkdir(itemPath) + timeInfo = API().getTimeInfo(MBitem) + userData=API().getUserData(MBitem) + people = API().getPeople(MBitem) + genre = API().getGenre(MBitem) + studios = API().getStudios(MBitem) + mediaStreams=API().getMediaStreams(MBitem) - #create nfo file - changes = CreateFiles().createNFO(item) + thumbPath = API().getArtwork(MBitem, "Primary") - # create strm file - changes |= CreateFiles().createSTRM(item) + playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) + playurl = utils.convertEncoding(playurl) - if changes: - utils.logMsg("MB3 Sync","Added movie to Kodi Library",item["Id"] + " - " + item["Name"]) + 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,"movies","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 = "" + API().getArtwork(MBitem, "Primary") + "" + fanart = "" + API().getArtwork(MBitem, "Backdrop") + "" + 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 + + 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]) + + #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)) + + try: + 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() - def addMusicVideoToKodiLibrary( self, item ): - itemPath = os.path.join(musicvideoLibrary,item["Id"]) - strmFile = os.path.join(itemPath,item["Id"] + ".strm") - - changes = False - - #create path if not exists - if not xbmcvfs.exists(itemPath + os.sep): - xbmcvfs.mkdir(itemPath) - - #create nfo file - changes = CreateFiles().createNFO(item) - - # create strm file - changes |= CreateFiles().createSTRM(item) - - if changes: - utils.logMsg("MB3 Sync","Added musicvideo to Kodi Library",item["Id"] + " - " + item["Name"]) - - def addEpisodeToKodiLibrary(self, item): - - changes = False + def addMusicVideoToKodiLibrary( self, MBitem ): - #create nfo file - changes = CreateFiles().createNFO(item) + #adds a musicvideo to Kodi by directly inserting it to the DB while there is no addMusicVideo available on the json API + #TODO: PR at Kodi team for a addMusicVideo endpoint on their API - # create strm file - changes |= CreateFiles().createSTRM(item) + addon = xbmcaddon.Addon(id='plugin.video.emby') + port = addon.getSetting('port') + host = addon.getSetting('ipaddress') + server = host + ":" + port + downloadUtils = DownloadUtils() + userid = downloadUtils.getUserId() - if changes: - utils.logMsg("MB3 Sync","Added episode to Kodi Library",item["Id"] + " - " + item["Name"]) + 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 = "" + API().getArtwork(MBitem, "Primary") + "" + 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 = "" + API().getArtwork(MBitem, "Primary") + "" + 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 ): kodiItem = ReadKodiDB().getKodiMovie(id) utils.logMsg("deleting movie from Kodi library",id) if kodiItem != None: 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 ): utils.logMsg("deleting musicvideo from Kodi library",id) kodiItem = ReadKodiDB().getKodiMusicVideo(id) if kodiItem != None: 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 ): utils.logMsg("deleting episode from Kodi library",episodeid) @@ -779,32 +960,82 @@ class WriteKodiDB(): WINDOW.setProperty("suspendDeletes", "True") 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": xbmc.sleep(100) utils.logMsg("episode deleted succesfully!",episodeid) else: utils.logMsg("episode not found in kodi DB",episodeid) - def addTVShowToKodiLibrary( self, item ): - itemPath = os.path.join(tvLibrary,item["Id"]) + def addTVShowToKodiLibrary( self, MBitem ): + #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 - if not xbmcvfs.exists(itemPath + os.sep): - xbmcvfs.mkdir(itemPath) + 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) + #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 = "" + API().getArtwork(MBitem, "Primary") + "" + fanart = "" + API().getArtwork(MBitem, "Backdrop") + "" + 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 nfo file - changes = CreateFiles().createNFO(item) + #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)) - if changes: - utils.logMsg("Added TV Show to Kodi Library ",item["Id"] + " - " + item["Name"]) + #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 ): xbmc.sleep(sleepVal) @@ -813,35 +1044,34 @@ class WriteKodiDB(): if kodiItem != None: xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveTVShow", "params": { "tvshowid": %i}, "id": 1 }' %(kodiItem["tvshowid"])) - - path = os.path.join(tvLibrary,id + os.sep) - utils.removeDirectory(path) - - 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 + def updateSeasons(self,MBitem, KodiItem): + #use sqlite to set the season details because no method in API available for this tvshowid = KodiItem["tvshowid"] connection = utils.KodiSQL() - cursor = connection.cursor( ) + cursor = connection.cursor() seasonData = ReadEmbyDB().getTVShowSeasons(MBitem["Id"]) if seasonData != None: for season in seasonData: 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"])) - 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: - sql="INSERT into art(media_id, media_type, type, url) values(?, ?, ?, ?)" - cursor.execute(sql, (seasonid,"season","landscape",MB3landscape)) + cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(tvshowid,season["IndexNumber"])) + result = cursor.fetchone() + if result == None: + #create the season + 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() cursor.close() @@ -873,7 +1103,7 @@ class WriteKodiDB(): connection.commit() 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 #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 @@ -889,7 +1119,7 @@ class WriteKodiDB(): xbmc.sleep(sleepVal) 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","old filename -->" + oldFileName) utils.logMsg("MB3 Sync","new filename -->" + newFileName) @@ -904,17 +1134,21 @@ class WriteKodiDB(): else: # we need to store both the path and the filename seperately in the kodi db so we split them up - if "\\" in newFileName: - filename = newFileName.rsplit("\\",1)[-1] - path = newFileName.replace(filename,"") - elif "/" in newFileName: - filename = newFileName.rsplit("/",1)[-1] - 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 + #transcoding or play from stream + path = "plugin://plugin.video.emby/" + filename = "?id=" + mbId + '&mode=play' + + else: + # direct play + if "\\" in newFileName: + filename = newFileName.rsplit("\\",1)[-1] + path = newFileName.replace(filename,"") + elif "/" in newFileName: + filename = newFileName.rsplit("/",1)[-1] + path = newFileName.replace(filename,"") + ######### PROCESS EPISODE ############ if fileType == "episode": @@ -963,7 +1197,6 @@ class WriteKodiDB(): cursor.close() return actionPerformed - def AddActorsToMedia(self, KodiItem, people, mediatype): #use sqlite to set add the actors while json api doesn't support this yet diff --git a/service.py b/service.py index 20975167..2fe56cd0 100644 --- a/service.py +++ b/service.py @@ -36,9 +36,6 @@ class Service(): ConnectionManager().checkServer() DownloadUtils().authenticate(retreive=True) - # check kodi library sources - mayRun = utils.checkKodiSources() - player = Player() lastProgressUpdate = datetime.today() @@ -48,86 +45,75 @@ class Service(): cur_seconds_fullsync = interval_FullSync cur_seconds_incrsync = interval_IncrementalSync - if mayRun: + ws = WebSocketThread() + + while not self.KodiMonitor.abortRequested(): - ws = WebSocketThread() + xbmc.sleep(1000) - while not self.KodiMonitor.abortRequested(): - - xbmc.sleep(1000) - - if xbmc.Player().isPlaying(): - try: - playTime = xbmc.Player().getTime() - currentFile = xbmc.Player().getPlayingFile() - - if(player.played_information.get(currentFile) != None): - player.played_information[currentFile]["currentPosition"] = playTime - - # send update - td = datetime.today() - lastProgressUpdate - secDiff = td.seconds - if(secDiff > 10): - try: - player.reportPlayback() - except Exception, msg: - xbmc.log("MB3 Sync Service -> Exception reporting progress : " + msg) - pass - lastProgressUpdate = datetime.today() - - except Exception, e: - xbmc.log("MB3 Sync Service -> Exception in Playback Monitor Service : " + str(e)) - pass - else: - # background worker for database sync - if DownloadUtils().authenticate(retreive=False) != "": - - # Correctly launch the websocket, if user manually launches the add-on - if (self.newWebSocketThread == None): - self.newWebSocketThread = "Started" - ws.start() - - #full sync - if(cur_seconds_fullsync >= interval_FullSync): - xbmc.log("Doing_Db_Sync: syncDatabase (Started)") - worked = librarySync.syncDatabase() - xbmc.log("Doing_Db_Sync: syncDatabase (Finished) " + str(worked)) - if(worked): - cur_seconds_fullsync = 0 - else: - cur_seconds_fullsync = interval_FullSync - 10 + if xbmc.Player().isPlaying(): + try: + playTime = xbmc.Player().getTime() + currentFile = xbmc.Player().getPlayingFile() + + if(player.played_information.get(currentFile) != None): + player.played_information[currentFile]["currentPosition"] = playTime + + # send update + td = datetime.today() - lastProgressUpdate + secDiff = td.seconds + if(secDiff > 10): + try: + player.reportPlayback() + except Exception, msg: + xbmc.log("MB3 Sync Service -> Exception reporting progress : " + msg) + pass + lastProgressUpdate = datetime.today() + + except Exception, e: + xbmc.log("MB3 Sync Service -> Exception in Playback Monitor Service : " + str(e)) + pass + else: + # background worker for database sync + if DownloadUtils().authenticate(retreive=False) != "": + + # Correctly launch the websocket, if user manually launches the add-on + if (self.newWebSocketThread == None): + self.newWebSocketThread = "Started" + ws.start() + + #full sync + if(cur_seconds_fullsync >= interval_FullSync): + xbmc.log("Doing_Db_Sync: syncDatabase (Started)") + worked = librarySync.syncDatabase() + xbmc.log("Doing_Db_Sync: syncDatabase (Finished) " + str(worked)) + if(worked): + cur_seconds_fullsync = 0 else: - cur_seconds_fullsync += 1 - - #incremental sync - if(cur_seconds_incrsync >= interval_IncrementalSync): - xbmc.log("Doing_Db_Sync: updatePlayCounts (Started)") - worked = librarySync.updatePlayCounts() - xbmc.log("Doing_Db_Sync: updatePlayCounts (Finished) " + str(worked)) - if(worked): - cur_seconds_incrsync = 0 - else: - cur_seconds_incrsync = interval_IncrementalSync - 10 - else: - 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") - + cur_seconds_fullsync = interval_FullSync - 10 else: - xbmc.log("Not authenticated yet") - - utils.logMsg("MB3 Sync Service", "stopping Service",0) - - if (self.newWebSocketThread != None): - ws.stopClient() + cur_seconds_fullsync += 1 + + #incremental sync + if(cur_seconds_incrsync >= interval_IncrementalSync): + xbmc.log("Doing_Db_Sync: updatePlayCounts (Started)") + worked = librarySync.updatePlayCounts() + xbmc.log("Doing_Db_Sync: updatePlayCounts (Finished) " + str(worked)) + if(worked): + cur_seconds_incrsync = 0 + else: + cur_seconds_incrsync = interval_IncrementalSync - 10 + else: + cur_seconds_incrsync += 1 + + + else: + xbmc.log("Not authenticated yet") + + utils.logMsg("MB3 Sync Service", "stopping Service",0) + + if (self.newWebSocketThread != None): + ws.stopClient() #start the service