From b4dd9f58bd458d2ea1f465a912cf1c97556aa9c3 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sat, 2 May 2015 02:26:06 +0200 Subject: [PATCH] fixed the plugin path for playback --- resources/lib/API.py | 19 ++- resources/lib/LibrarySync.py | 271 +-------------------------------- resources/lib/PlaybackUtils.py | 24 +-- resources/lib/ReadKodiDB.py | 221 ++------------------------- resources/lib/WriteKodiDB.py | 166 +++++++++----------- 5 files changed, 119 insertions(+), 582 deletions(-) diff --git a/resources/lib/API.py b/resources/lib/API.py index 50e5587b..05fd237b 100644 --- a/resources/lib/API.py +++ b/resources/lib/API.py @@ -118,7 +118,24 @@ class API(): 'width' : width, 'aspectratio' : str(aspectfloat) } - + + def getChecksum(self, item): + #TODO --> use the etags or serverside checksum for this + # for now we just add some fields to a string + checksum = "" + userData = item.get("UserData") + if(userData != None): + checksum += str(userData.get("Played")) + checksum += str(userData.get("IsFavorite")) + if userData.get('UnplayedItemCount') != None: + checksum += str(userData.get("UnplayedItemCount")) + if userData.get('LastPlayedDate') != None: + checksum += str(userData.get("LastPlayedDate")) + if userData.get('PlaybackPositionTicks') != None: + checksum += str(userData.get("PlaybackPositionTicks")) + + return checksum + def getUserData(self, item): userData = item.get("UserData") resumeTime = 0 diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index a0363d02..114e00e2 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -51,10 +51,7 @@ class LibrarySync(): #TEMP --> add new columns try: - cursor.execute("alter table movie ADD COLUMN 'embyId' TEXT") - cursor.execute("alter table tvshow ADD COLUMN 'embyId' TEXT") - cursor.execute("alter table episode ADD COLUMN 'embyId' TEXT") - cursor.execute("alter table musicvideo ADD COLUMN 'embyId' TEXT") + cursor.execute("CREATE TABLE IF NOT EXISTS emby(emby_id TEXT, kodi_id INTEGER, media_type TEXT, checksum TEXT, parent_id INTEGER)") connection.commit() except: pass @@ -109,8 +106,7 @@ class LibrarySync(): allKodiMovieIds.append(item["Id"]) WriteKodiDB().addOrUpdateMovieToKodiLibrary(item["Id"],connection, cursor, view.get('title')) else: - # TODO --> compare with eTag - if kodiMovie[2] != item["Name"] or item["Id"] in itemList: + if kodiMovie[2] != API().getChecksum(item) or item["Id"] in itemList: WriteKodiDB().addOrUpdateMovieToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS DELETES ##### @@ -158,7 +154,7 @@ class LibrarySync(): else: kodiId = kodishow[0] # If there are changes to the item, perform a full sync of the item - if kodiShow[2] != item["Name"] or item["Id"] in itemList: + if kodiShow[2] != API().getChecksum(item) or item["Id"] in itemList: WriteKodiDB().addOrUpdateTvShowToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS EPISODES ###### @@ -203,18 +199,17 @@ class LibrarySync(): WriteKodiDB().addOrUpdateEpisodeToKodiLibrary(item["Id"], kodiShowId, connection, cursor) else: # If there are changes to the item, perform a full sync of the item - if kodiEpisode[2] != item["Name"] or item["Id"] in itemList: + if kodiEpisode[2] != API().getChecksum(item) or item["Id"] in itemList: WriteKodiDB().addOrUpdateEpisodeToKodiLibrary(item["Id"], kodiShowId, connection, cursor) #### EPISODES: PROCESS DELETES ##### allEmbyEpisodeIds = set(allEmbyEpisodeIds) print allEmbyEpisodeIds for kodiId in allKodiEpisodeIds: + print "kodiId-->" + kodiId if not kodiId in allEmbyEpisodeIds: WINDOW.setProperty(kodiId,"deleted") - print "deleting ???-->" + kodiId - #WriteKodiDB().deleteEpisodeFromKodiLibrary(kodiId, connection, cursor) - + WriteKodiDB().deleteEpisodeFromKodiLibrary(kodiId, connection, cursor) def MusicVideosSync(self, fullsync, installFirstRun,connection, cursor): @@ -328,260 +323,6 @@ class LibrarySync(): return True - def updatePlayCounts(self): - #update all playcounts from MB3 to Kodi library - - addon = xbmcaddon.Addon(id='plugin.video.emby') - WINDOW = xbmcgui.Window( 10000 ) - pDialog = None - startedSync = datetime.today() - processMovies = True - processTvShows = True - - if(WINDOW.getProperty("SyncDatabaseShouldStop") == "true"): - utils.logMsg("Sync PlayCount", "Can not start SyncDatabaseShouldStop=True", 0) - return True - - if(WINDOW.getProperty("updatePlayCounts_Running") == "true"): - utils.logMsg("Sync PlayCount", "updatePlayCounts Already Running", 0) - return False - - WINDOW.setProperty("updatePlayCounts_Running", "true") - - try: - playCountSyncIndication = addon.getSetting("playCountSyncIndication") - playCountSyncFirstRun = addon.getSetting("SyncFirstCountsRunDone") - - if(playCountSyncFirstRun != "true" or playCountSyncIndication == "Dialog Progress"): - pDialog = xbmcgui.DialogProgress() - elif(playCountSyncIndication == "BG Progress"): - pDialog = xbmcgui.DialogProgressBG() - - if(pDialog != None): - pDialog.create('Sync PlayCounts', 'Sync PlayCounts') - - totalCountsUpdated = 0 - totalPositionsUpdated = 0 - - #process movies - if processMovies: - if(pDialog != None): - pDialog.update(0, "Processing Movies", "") - - views = ReadEmbyDB().getCollections("movies") - viewCount = len(views) - viewCurrent = 1 - for view in views: - allMB3Movies = ReadEmbyDB().getMovies(view.get('id'), fullinfo = False, fullSync = True) - allKodiMovies = ReadKodiDB().getKodiMovies(False) - - if(self.ShouldStop(pDialog)): - return False - - if(allMB3Movies != None and allKodiMovies != None): - - if(pDialog != None): - progressTitle = "Sync PlayCounts: Processing " + view.get('title') + " " + str(viewCurrent) + " of " + str(viewCount) - pDialog.update(0, progressTitle) - totalCount = len(allMB3Movies) + 1 - count = 1 - - for item in allMB3Movies: - - if not item.get('IsFolder'): - kodiItem = allKodiMovies.get(item["Id"], None) - - userData = API().getUserData(item) - timeInfo = API().getTimeInfo(item) - - if kodiItem != None: - kodiresume = int(round(kodiItem['resume'].get("position"))) - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 - if kodiresume != resume: - WriteKodiDB().setKodiResumePoint(kodiItem['movieid'],resume,total,"movie") - totalPositionsUpdated += 1 - updated = WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")), "movie") - updated |= WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "movie") - if(updated): - totalCountsUpdated += 1 - - if(self.ShouldStop(pDialog)): - return False - - # update progress bar - if(pDialog != None): - percentage = int(((float(count) / float(totalCount)) * 100)) - pDialog.update(percentage, progressTitle, "Updating Movie: " + str(count)) - count += 1 - - viewCurrent += 1 - - #process Tv shows - if processTvShows: - if(pDialog != None): - pDialog.update(0, "Processing TV Episodes", "") - views = ReadEmbyDB().getCollections("tvshows") - viewCount = len(views) - viewCurrent = 1 - progressTitle = "" - for view in views: - - tvshowData = ReadEmbyDB().getTVShows(id = view.get('id'), fullinfo = False, fullSync = True) - - if(self.ShouldStop(pDialog)): - return False - - if (tvshowData != None): - - showTotal = len(tvshowData) - showCurrent = 1 - - for item in tvshowData: - - episodeData = ReadEmbyDB().getEpisodes(item["Id"], False) - allKodiTVShows = ReadKodiDB().getKodiTvShows(False) - kodishow = allKodiTVShows.get(item["Id"],None) - if kodishow != None: - kodiEpisodes = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],False,True) - else: - kodiEpisodes = None - - if (episodeData != None): - if(pDialog != None): - progressTitle = "Sync PlayCounts: Processing TV Show " + str(showCurrent) + " of " + str(showTotal) - pDialog.update(0, progressTitle) - totalCount = len(episodeData) + 1 - count = 1 - - for episode in episodeData: - - kodiItem = None - matchFound = False - if kodiEpisodes != None: - kodiItem = kodiEpisodes.get(episode.get("Id"), None) - - userData=API().getUserData(episode) - timeInfo = API().getTimeInfo(episode) - - - if kodiItem != None: - WINDOW = xbmcgui.Window( 10000 ) - WINDOW.setProperty("episodeid" + str(kodiItem['episodeid']), episode.get('Name') + ";;" + episode.get('Id')) - WINDOW.setProperty(episode.get('Id'), "episode;;" + str(kodishow["tvshowid"]) + ";;" +str(kodiItem['episodeid'])) - kodiresume = int(round(kodiItem['resume'].get("position"))) - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 - if kodiresume != resume: - WriteKodiDB().setKodiResumePoint(kodiItem['episodeid'],resume,total,"episode") - totalPositionsUpdated += 1 - - updated = WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode") - updated |= WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "episode") - if(updated): - totalCountsUpdated += 1 - - if(self.ShouldStop(pDialog)): - return False - - # update progress bar - if(pDialog != None): - percentage = int(((float(count) / float(totalCount)) * 100)) - pDialog.update(percentage, progressTitle, "Updating Episode: " + str(count)) - count += 1 - - showCurrent += 1 - - if(playCountSyncFirstRun != "true"): - addon = xbmcaddon.Addon(id='plugin.video.emby') - addon.setSetting("SyncFirstCountsRunDone", "true") - - # display notification if set up - notificationString = "" - if(totalPositionsUpdated > 0): - notificationString += "Pos:" + str(totalPositionsUpdated) + " " - if(totalCountsUpdated > 0): - notificationString += "Counts:" + str(totalCountsUpdated) + " " - - timeTaken = datetime.today() - startedSync - timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60) - utils.logMsg("Sync PlayCount", "Finished " + timeTakenString + " " + notificationString, 0) - - if(playCountSyncIndication == "Notify OnChange" and notificationString != ""): - notificationString = "(" + timeTakenString + ") " + notificationString - xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)") - elif(playCountSyncIndication == "Notify OnFinish"): - if(notificationString == ""): - notificationString = "Done" - notificationString = "(" + timeTakenString + ") " + notificationString - xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)") - - finally: - WINDOW.setProperty("updatePlayCounts_Running", "false") - if(pDialog != None): - pDialog.close() - - return True - - def updatePlayCount(self, itemID): - #update playcount of the itemID from MB3 to Kodi library - - addon = xbmcaddon.Addon(id='plugin.video.emby') - WINDOW = xbmcgui.Window( 10000 ) - - embyItem = ReadEmbyDB().getItem(itemID) - if(embyItem == None): - return False - - type = embyItem.get("Type") - - #process movie - if type == 'Movie': - kodiItem = ReadKodiDB().getKodiMovie(itemID) - - if(kodiItem == None): - return False - - if(self.ShouldStop(None)): - return False - - userData = API().getUserData(embyItem) - timeInfo = API().getTimeInfo(embyItem) - - kodiresume = int(round(kodiItem['resume'].get("position"))) - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 - if kodiresume != resume: - WriteKodiDB().setKodiResumePoint(kodiItem['movieid'],resume,total,"movie") - #write property forced will refresh the item in the list so playcount change is immediately visible - WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"movie",True) - WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "movie") - - if(self.ShouldStop(None)): - return False - - #process episode - elif type == 'Episode': - if(self.ShouldStop(None)): - return False - - kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(embyItem["Id"], embyItem["SeriesId"]) - - userData = API().getUserData(embyItem) - timeInfo = API().getTimeInfo(embyItem) - - if kodiItem != None: - kodiresume = int(round(kodiItem['resume'].get("position"))) - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 - if kodiresume != resume: - WriteKodiDB().setKodiResumePoint(kodiItem['episodeid'],resume,total,"episode") - #write property forced will refresh the item in the list so playcount change is immediately visible - WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode",True) - WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "episode") - - return True - def ShouldStop(self, prog): if(prog != None and type(prog) == xbmcgui.DialogProgress): diff --git a/resources/lib/PlaybackUtils.py b/resources/lib/PlaybackUtils.py index bad30609..0447c415 100644 --- a/resources/lib/PlaybackUtils.py +++ b/resources/lib/PlaybackUtils.py @@ -52,17 +52,17 @@ class PlaybackUtils(): seekTime = 0 #get the resume point from Kodi DB for a Movie - kodiItem = ReadKodiDB().getKodiMovie(id) - if kodiItem != None: - seekTime = int(round(kodiItem['resume'].get("position"))) - else: - #get the resume point from Kodi DB for an episode - episodeItem = ReadEmbyDB().getItem(id) - if episodeItem != None and str(episodeItem["Type"]) == "Episode": - kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(id,episodeItem["SeriesId"]) - if kodiItem != None: - seekTime = int(round(kodiItem['resume'].get("position"))) - + # kodiItem = ReadKodiDB().getKodiMovie(id) + # if kodiItem != None: + # seekTime = int(round(kodiItem['resume'].get("position"))) + # else: + # #get the resume point from Kodi DB for an episode + # episodeItem = ReadEmbyDB().getItem(id) + # if episodeItem != None and str(episodeItem["Type"]) == "Episode": + # kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(id,episodeItem["SeriesId"]) + # if kodiItem != None: + # seekTime = int(round(kodiItem['resume'].get("position"))) + playurl = PlayUtils().getPlayUrl(server, id, result) isStrmFile = False @@ -137,7 +137,7 @@ class PlaybackUtils(): if isStrmFile: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) else: - xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) + #xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) if(addon.getSetting("addExtraPlaybackArt") == "true"): utils.logMsg("PLAY", "Doing second xbmc.Player().play to add extra art") xbmc.Player().play(playurl,listItem) diff --git a/resources/lib/ReadKodiDB.py b/resources/lib/ReadKodiDB.py index 14b0872a..9909f4f9 100644 --- a/resources/lib/ReadKodiDB.py +++ b/resources/lib/ReadKodiDB.py @@ -16,229 +16,28 @@ import Utils as utils sleepVal = 15 class ReadKodiDB(): - - def getKodiMovie(self, id): - #returns a single movie from Kodi db selected on MB item ID - xbmc.sleep(sleepVal) - json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties" : ["art", "rating", "thumbnail", "fanart", "resume", "runtime", "year", "genre", "cast", "trailer", "country", "studio", "set", "imdbnumber", "mpaa", "tagline", "plotoutline","plot", "sorttitle", "director", "lastplayed", "writer", "playcount", "tag", "file"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libMovies"}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - movie = None - if(jsonobject.has_key('result')): - result = jsonobject['result'] - if(result.has_key('movies')): - movies = result['movies'] - movie = movies[0] - for item in movies: - if id in item["file"]: - movie = item - break - return movie - - def getEmbyIdByKodiId(self, kodiid, type): - embyId = None - connection = utils.KodiSQL() - cursor = connection.cursor() - - if type == "movie": - cursor.execute("SELECT embyId as embyId FROM movie WHERE idMovie = ?",(kodiid,)) - if type == "episode": - cursor.execute("SELECT embyId as embyId FROM episode WHERE idEpisode = ?",(kodiid,)) - if type == "musicvideo": - cursor.execute("SELECT embyId as embyId FROM musicvideo WHERE idMVideo = ?",(kodiid,)) - if type == "tvshow": - cursor.execute("SELECT embyId as embyId FROM tvshow WHERE idShow = ?",(kodiid,)) - - result = cursor.fetchone() - cursor.close() - if result != None: - embyId = result[0] - - return embyId - + def getKodiMovies(self, connection, cursor): #returns all movies in Kodi db - cursor.execute("SELECT idMovie, embyId, c00 FROM movie") + cursor.execute("SELECT kodi_id, emby_id, checksum FROM emby WHERE media_type='movie'") allmovies = cursor.fetchall() #this will return a list with tuples of all items returned from the database return allmovies - - def getKodiMoviesIds(self,returnMB3Ids = False): - # returns a list of movieIds or MB3 Id's from all movies currently in the Kodi library - allKodiMovies = self.getKodiMovies(False) - - if(allKodiMovies == None): - return list() - - if(returnMB3Ids): - allKodiMovieIds = list(allKodiMovies.keys()) - return allKodiMovieIds - else: - allKodiMovieIds = list() - for kodimovie in allKodiMovies.values(): - id = str(kodimovie["movieid"]) - allKodiMovieIds.append(id) - - return allKodiMovieIds - - def getKodiTvShowsIds(self,returnMB3Ids = False): - # returns a list of tvshowIds or MB3 Id's from all tvshows currently in the Kodi library - allKodiTvShows = self.getKodiTvShows(False) - - if allKodiTvShows == None: - return list() - - if(returnMB3Ids): - allKodiTvShowsIds = list(allKodiTvShows.keys()) - return allKodiTvShowsIds - else: - allKodiTvShowsIds = list() - for kodishow in allKodiTvShows.values(): - id = str(kodishow["tvshowid"]) - allKodiTvShowsIds.append(id) - - return allKodiTvShowsIds def getKodiTvShows(self, connection, cursor): - cursor.execute("SELECT idShow, embyId, c00 FROM tvshow") + cursor.execute("SELECT kodi_id, emby_id, checksum FROM emby WHERE media_type='tvshow'") allshows = cursor.fetchall() #this will return a list with tuples of all items returned from the database return allshows - - def getKodiTVShow(self, id): - xbmc.sleep(sleepVal) - json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["art", "genre", "plot", "mpaa", "cast", "studio", "sorttitle", "title", "originaltitle", "imdbnumber", "year", "lastplayed", "premiered", "rating", "thumbnail", "playcount", "file", "fanart", "tag"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libTvShows"}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - tvshow = None - if(jsonobject.has_key('result')): - result = jsonobject['result'] - if(result.has_key('tvshows')): - tvshows = result['tvshows'] - for show in tvshows: - if show["imdbnumber"] == id: - tvshow = show - break - return tvshow - - def getKodiEpisodes(self, connection, cursor, showid): - cursor.execute("SELECT idEpisode, embyId, c00 FROM episode WHERE idShow = ?", (showid,)) + + def getKodiEpisodes(self, connection, cursor, showid=None): + + if showid == None: + cursor.execute("SELECT kodi_id, emby_id, checksum FROM emby WHERE media_type=?",("episode",)) + else: + cursor.execute("SELECT kodi_id, emby_id, checksum FROM emby WHERE media_type=? AND parent_id=?",("episode", showid)) allepisodes = cursor.fetchall() #this will return a list with tuples of all items returned from the database return allepisodes - def getKodiEpisodeByMbItem(self, episodeid, tvshowid): - episode = None - tvshow = self.getKodiTVShow(tvshowid) - - if tvshow != None: - json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": ' + str(tvshow['tvshowid']) + ', "properties": ["playcount","season", "resume", "episode", "lastplayed", "uniqueid", "file"], "sort": {"method": "episode"}}, "id": 1}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - if(jsonobject.has_key('result')): - result = jsonobject['result'] - if(result.has_key('episodes')): - episodes = result['episodes'] - for ep in episodes: - if ep["uniqueid"]["unknown"] == episodeid: - episode = ep - break - - return episode - - def getKodiEpisodeByMbItemEx(self, id): - connection = utils.KodiSQL() - cursor = connection.cursor() - cursor.execute("SELECT idEpisode FROM episode WHERE c20 = ?", (id,)) - result = cursor.fetchone() - kodiId = None - if result != None: - kodiId = result[0] - cursor.close() - - episode = None - if(kodiId != None): - print "Kodi Episode ID : " + str(kodiId) - json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodeDetails", "params": {"episodeid": %d, "properties": ["playcount", "season", "resume", "episode", "lastplayed", "uniqueid", "file"]}, "id": 1}' %kodiId) - #json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodeDetails", "params": {"episodeid": ' + str(kodiId) + ', "properties": ["playcount", "season", "resume", "episode", "lastplayed", "uniqueid", "file"], "sort": {"method": "episode"}}, "id": 1}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - print "Kodi_Item: " + str(jsonobject) - if(jsonobject.has_key("result")): - result = jsonobject["result"] - if(result.has_key("episodedetails")): - episode = result["episodedetails"] - - return episode - - def getKodiMusicVideo(self, id): - #returns a single musicvideo from Kodi db selected on MB item ID - xbmc.sleep(sleepVal) - #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() - - musicvideo = None - - if musicvideoid != None: - json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMusicVideosDetails", "params": { "musicvideoid": ' + musicvideoid + ', "properties" : ["art", "thumbnail", "fanart", "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 - - def getKodiMusicVideos(self,fullInfo = False): - #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": { "properties" : ["art", "thumbnail", "fanart", "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": { "properties" : ["resume", "playcount", "lastplayed", "file", "track"] }, "id": "libMusicVideos"}') - jsonobject = json.loads(json_response.decode('utf-8','replace')) - musicvideos = None - if(jsonobject.has_key('result')): - result = jsonobject['result'] - if(result.has_key('musicvideos')): - musicvideos = result['musicvideos'] - - kodiMusicVideoMap = None - if(musicvideos != None and len(musicvideos) > 0): - kodiMusicVideoMap = {} - connection = utils.KodiSQL() - cursor = connection.cursor() - for kodivideo in musicvideos: - 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): - # returns a list of movieIds or MB3 Id's from all movies currently in the Kodi library - allKodiMusicVideos = self.getKodiMusicVideos(False) - - if(allKodiMusicVideos == None): - return list() - - if(returnMB3Ids): - allKodiMusicVideoIds = list(allKodiMusicVideos.keys()) - return allKodiMusicVideoIds - else: - allKodiMusicVideoIds = list() - for kodivideo in allKodiMusicVideos.values(): - id = str(kodivideo["musicvideoid"]) - allKodiMusicVideoIds.append(id) - - return allKodiMusicVideoIds - \ No newline at end of file diff --git a/resources/lib/WriteKodiDB.py b/resources/lib/WriteKodiDB.py index ff4dc30e..fddc62e7 100644 --- a/resources/lib/WriteKodiDB.py +++ b/resources/lib/WriteKodiDB.py @@ -57,7 +57,7 @@ class WriteKodiDB(): # If the item already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - cursor.execute("SELECT idMovie FROM movie WHERE embyId = ?",(MBitem["Id"],)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) result = cursor.fetchone() if result != None: movieid = result[0] @@ -99,7 +99,7 @@ class WriteKodiDB(): jsonData = downloadUtils.downloadUrl(itemTrailerUrl) if(jsonData != ""): trailerItem = jsonData - trailerUrl = "plugin://plugin.video.emby/?id=%s&mode=play" % trailerItem[0][u'Id'] + trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] if MBitem.get("DateCreated") != None: dateadded = MBitem["DateCreated"].replace("T"," ") @@ -113,21 +113,9 @@ class WriteKodiDB(): #### ADD OR UPDATE THE FILE AND PATH ########### #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY - path = "plugin://plugin.video.emby/?id=%s&mode=play" % MBitem["Id"] - filename = "plugin://plugin.video.emby/?id=%s&mode=play" % MBitem["Id"] + path = "plugin://plugin.video.emby/movies/" + filename = "plugin://plugin.video.emby/movies/?id=%s&mode=play" % MBitem["Id"] - playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) - playurl = utils.convertEncoding(playurl) - - # 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 idPath as pathid FROM path WHERE strPath = ?",(path,)) result = cursor.fetchone() @@ -159,16 +147,23 @@ class WriteKodiDB(): 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, c05, c06, c07, c09, c10, c11, c12, c14, c15, c16, c18, c19, embyId) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, MBitem["Id"])) + pathsql="insert into movie(idMovie, idFile, c00, c01, c02, c05, c06, c07, c09, c10, c11, c12, c14, c15, c16, c18, c19) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl)) #add the viewtag self.AddTagToMedia(movieid, viewTag, "movie", cursor) + #create the reference in emby table + pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" + cursor.execute(pathsql, (MBitem["Id"], movieid, "movie", API().getChecksum(MBitem))) + #### UPDATE THE MOVIE ##### else: - pathsql="update movie SET c00 = ?, c01 = ?, c02 = ?, c05 = ?, c06 = ?, c07 = ?, c09 = ? c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?, c16 = ?, c18 = ?, c19 = ?, embyId= ? WHERE idMovie = ?" - cursor.execute(pathsql, (title, plot, shortplot, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, MBitem["Id"], movieid)) + pathsql="update movie SET c00 = ?, c01 = ?, c02 = ?, c05 = ?, c06 = ?, c07 = ?, c09 = ? c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?, c16 = ?, c18 = ?, c19 = ? WHERE idMovie = ?" + cursor.execute(pathsql, (title, plot, shortplot, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, movieid)) + + #update the checksum in emby table + cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"])) #update or insert actors self.AddPeopleToMedia(movieid,MBitem.get("People"),"movie", connection, cursor) @@ -185,10 +180,15 @@ class WriteKodiDB(): #update genres self.AddGenresToMedia(movieid, genres, "movie", cursor) - + #update studios self.AddStudiosToMedia(movieid, studios, "movie", cursor) + #set resume point + resume = int(round(float(timeInfo.get("ResumeTime"))))*60 + total = int(round(float(timeInfo.get("TotalTime"))))*60 + self.setKodiResumePoint(fileid, resume, total, cursor) + #commit changes and return the id connection.commit() return movieid @@ -210,7 +210,7 @@ class WriteKodiDB(): # If the item already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - cursor.execute("SELECT idMovie FROM movie WHERE embyId = ?",(MBitem["Id"],)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) result = cursor.fetchone() if result != None: showid = result[0] @@ -237,12 +237,7 @@ class WriteKodiDB(): else: premieredate = None - path = "plugin://plugin.video.emby/tvshows/" + MBitem["Id"] + "/" - - playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) - #make sure that the path always ends with a slash - path = utils.convertEncoding(playurl + "/") - + path = "plugin://plugin.video.emby/tvshows/" + MBitem["Id"] + "/" #### ADD THE TV SHOW TO KODI ############## if showid == None: @@ -255,12 +250,7 @@ class WriteKodiDB(): cursor.execute(pathsql, (pathid,path,None,None,1)) #create toplevel path as monitored source - needed for things like actors and stuff to work (no clue why) - if "\\" in path: - toplevelpathstr = path.rsplit("\\",2)[1] - toplevelpath = path.replace(toplevelpathstr + "\\","") - elif "/" in path: - toplevelpathstr = path.rsplit("/",2)[1] - toplevelpath = path.replace(toplevelpathstr + "/","") + toplevelpath = "plugin://plugin.video.emby/" cursor.execute("SELECT idPath as tlpathid FROM path WHERE strPath = ?",(toplevelpath,)) result = cursor.fetchone() if result == None: @@ -281,8 +271,12 @@ class WriteKodiDB(): cursor.execute("select coalesce(max(idShow),0) as showid from tvshow") showid = cursor.fetchone()[0] showid = showid + 1 - pathsql="insert into tvshow(idShow, c00, c01, c04, c05, c08, c09, c13, c14, c15, embyId) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (showid, title, plot, rating, premieredate, genre, title, mpaa, studio, sorttitle, MBitem["Id"])) + pathsql="insert into tvshow(idShow, c00, c01, c04, c05, c08, c09, c13, c14, c15) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(pathsql, (showid, title, plot, rating, premieredate, genre, title, mpaa, studio, sorttitle)) + + #create the reference in emby table + pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" + cursor.execute(pathsql, (MBitem["Id"], showid, "tvshow", API().getChecksum(MBitem))) #link the path pathsql="insert into tvshowlinkpath(idShow,idPath) values(?, ?)" @@ -293,8 +287,11 @@ class WriteKodiDB(): #### UPDATE THE TV SHOW ############# else: - pathsql="UPDATE tvshow SET (c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c13 = ?, c14 = ?, c15 = ?, embyId = ? WHERE idShow = ?" - cursor.execute(pathsql, title, plot, rating, premieredate, title, genre, mpaa, studio, sorttitle, MBitem["Id"], showid) + pathsql="UPDATE tvshow SET (c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c13 = ?, c14 = ?, c15 = ? WHERE idShow = ?" + cursor.execute(pathsql, title, plot, rating, premieredate, title, genre, mpaa, studio, sorttitle, showid) + + #update the checksum in emby table + cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem), MBitem["Id"])) #update or insert people self.AddPeopleToMedia(showid,MBitem.get("People"),"tvshow", connection, cursor) @@ -304,7 +301,7 @@ class WriteKodiDB(): #update studios self.AddStudiosToMedia(showid, studios, "tvshow", cursor) - + #update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), showid, "tvshow", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), showid, "tvshow", "poster", cursor) @@ -399,11 +396,9 @@ class WriteKodiDB(): # If the item doesn't exist, we'll add it to the database MBitem = ReadEmbyDB().getFullItem(embyId) - - cursor.execute("SELECT idEpisode FROM episode WHERE embyId = ?",(MBitem["Id"],)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) result = cursor.fetchone() if result != None: - utils.logMsg("Emby", "Episode already exists in DB : " + MBitem["Id"] + " - " + MBitem["Name"], 2) episodeid = result[0] else: episodeid = None @@ -455,18 +450,6 @@ class WriteKodiDB(): path = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/" filename = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/?id=" + MBitem["Id"] + "&mode=play" - playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem) - playurl = utils.convertEncoding(playurl) - - # 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() @@ -512,30 +495,40 @@ class WriteKodiDB(): 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, c04, c05, c09, c10, c12, c13, c14, idShow, c15, c16, embyId) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, writer, premieredate, runtime, director, season, episode, title, showid, "-1", "-1", MBitem["Id"])) + pathsql = "INSERT into episode(idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14, idShow, c15, c16) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, writer, premieredate, runtime, director, season, episode, title, showid, "-1", "-1")) + + #create the reference in emby table + pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum, parent_id) values(?, ?, ?, ?, ?)" + cursor.execute(pathsql, (MBitem["Id"], episodeid, "episode", API().getChecksum(MBitem), showid)) # UPDATE THE EPISODE IN KODI (for now, we just send in all data) else: - pathsql = "UPDATE episode SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, embyId = ? WHERE idEpisode = ?" - cursor.execute(pathsql, (title, plot, rating, writer, premieredate, runtime, director, season, episode, title, "-1", "-1", MBitem["Id"], episodeid)) + pathsql = "UPDATE episode SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ? WHERE idEpisode = ?" + cursor.execute(pathsql, (title, plot, rating, writer, premieredate, runtime, director, season, episode, title, "-1", "-1", episodeid)) + + #update the checksum in emby table + cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem), MBitem["Id"])) #update or insert actors self.AddPeopleToMedia(episodeid,MBitem.get("People"),"episode", connection, cursor) + #set resume point + resume = int(round(float(timeInfo.get("ResumeTime"))))*60 + total = int(round(float(timeInfo.get("TotalTime"))))*60 + self.setKodiResumePoint(fileid, resume, total, cursor) + #update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary"), episodeid, "episode", "thumb", cursor) - try: - connection.commit() - utils.logMsg("Emby","Added or updated episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"]) - except: - utils.logMsg("Emby","Error adding/updating episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"]) - actionPerformed = False - + #commit changes + connection.commit() + def deleteMovieFromKodiLibrary(self, id, connection, cursor ): utils.logMsg("deleting movie from Kodi library --> ",id) - cursor.execute("DELETE FROM movie WHERE embyId = ?", (id,)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id=?", (id,)) + kodi_id = cursor.fetchone()[0] + cursor.execute("DELETE FROM movie WHERE idMovie = ?", (kodi_id,)) connection.commit() def deleteMusicVideoFromKodiLibrary(self, id ): @@ -546,12 +539,16 @@ class WriteKodiDB(): def deleteEpisodeFromKodiLibrary(self, id, connection, cursor ): utils.logMsg("deleting episode from Kodi library --> ",id) - cursor.execute("DELETE FROM episode WHERE embyId = ?", (id,)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id=?", (id,)) + kodi_id = cursor.fetchone()[0] + cursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodi_id,)) connection.commit() def deleteTVShowFromKodiLibrary(self, id, connection, cursor): utils.logMsg("deleting tvshow from Kodi library --> ",id) - cursor.execute("DELETE FROM tvshow WHERE embyId = ?", (id,)) + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id=?", (id,)) + kodi_id = cursor.fetchone()[0] + cursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodi_id,)) connection.commit() def updateSeasons(self,embyTvShowId, kodiTvShowId, connection, cursor): @@ -596,33 +593,16 @@ class WriteKodiDB(): utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")") cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType)) - def setKodiResumePoint(self, id, resume_seconds, total_seconds, fileType): - #use sqlite to set the resume point while json api doesn't support this yet - #todo --> submit PR to kodi team to get this added to the jsonrpc api - - utils.logMsg("Emby","setting resume point in kodi db..." + fileType + ": " + str(id)) - xbmc.sleep(sleepVal) - connection = utils.KodiSQL() - cursor = connection.cursor( ) - - if fileType == "episode": - cursor.execute("SELECT idFile as fileidid FROM episode WHERE idEpisode = ?",(id,)) - result = cursor.fetchone() - fileid = result[0] - if fileType == "movie": - cursor.execute("SELECT idFile as fileidid FROM movie WHERE idMovie = ?",(id,)) - result = cursor.fetchone() - fileid = result[0] + def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor): cursor.execute("delete FROM bookmark WHERE idFile = ?", (fileid,)) - cursor.execute("select coalesce(max(idBookmark),0) as bookmarkId from bookmark") - bookmarkId = cursor.fetchone()[0] - bookmarkId = bookmarkId + 1 - bookmarksql="insert into bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, thumbNailImage, player, playerState, type) values(?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(bookmarksql, (bookmarkId,fileid,resume_seconds,total_seconds,None,"DVDPlayer",None,1)) - connection.commit() - cursor.close() - + if resume_seconds != 0: + cursor.execute("select coalesce(max(idBookmark),0) as bookmarkId from bookmark") + bookmarkId = cursor.fetchone()[0] + bookmarkId = bookmarkId + 1 + bookmarksql="insert into bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, thumbNailImage, player, playerState, type) values(?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(bookmarksql, (bookmarkId,fileid,resume_seconds,total_seconds,None,"DVDPlayer",None,1)) + def AddPeopleToMedia(self, id, people, mediatype, connection, cursor): downloadUtils = DownloadUtils()