diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py
index b6135af4..d95d2989 100644
--- a/resources/lib/LibrarySync.py
+++ b/resources/lib/LibrarySync.py
@@ -12,6 +12,7 @@ import inspect
import threading
import urllib
from datetime import datetime, timedelta, time
+from itertools import chain
import urllib2
import os
@@ -47,23 +48,21 @@ class LibrarySync():
completed = True
connection = utils.KodiSQL()
cursor = connection.cursor()
+
+ #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")
+ connection.commit()
+ except: pass
+
# sync movies
- if(syncInstallRunDone == False): # on first install run do a full sync with model progress dialog
- completed = completed and self.TvShowsSync(connection, cursor,True, True)
- completed = completed and self.MoviesSync(connection, cursor,True, True)
- completed = completed and self.MusicVideosSync(True, True,connection , cursor)
- elif(startupDone == False): # on first run after startup do a inc then a full sync
- self.TvShowsSync(connection, cursor,False, False)
- self.MoviesSync(connection, cursor,False, False)
- self.MusicVideosSync(False, False, connection,cursor)
- self.TvShowsSync(connection, cursor,True, False)
- self.MoviesSync(connection, cursor,True, False)
- self.MusicVideosSync(True, False,connection,cursor)
- else: # on scheduled sync do a full sync
- self.TvShowsSync(connection, cursor,True, False)
- self.MoviesSync(connection, cursor,True, False)
- self.MusicVideosSync(True, False,connection,cursor)
-
+ self.MoviesSync(connection,cursor,True)
+ #sync Tvshows and episodes
+ self.TvShowsSync(connection,cursor,True)
+
# set the install done setting
if(syncInstallRunDone == False and completed):
addon = xbmcaddon.Addon(id='plugin.video.emby') #force a new instance of the addon
@@ -78,540 +77,145 @@ class LibrarySync():
cursor.close()
return True
-
- def MoviesSync(self,connection, cursor, fullsync, installFirstRun,itemList = []):
+
+ def MoviesSync(self,connection,cursor,installFirstRun,itemList = []):
+
+ pDialog = xbmcgui.DialogProgressBG()
+ pDialog.create('Sync DB', 'Sync Movies')
+
+ views = ReadEmbyDB().getCollections("movies")
+
+ allKodiMovieIds = list()
+ allEmbyMovieIds = list()
+
+ for view in views:
+
+ allMB3Movies = ReadEmbyDB().getMovies(view.get('id'))
+ allKodiMovies = ReadKodiDB().getKodiMovies(connection, cursor)
+ #### PROCESS ADDS AND UPDATES ###
+ for item in allMB3Movies:
+
+ if not item.get('IsFolder'):
+ allEmbyMovieIds.append(item["Id"])
+
+ kodiMovie = None
+ for kodimovie in allKodiMovies:
+ allKodiMovieIds.append(kodimovie[1])
+ if kodimovie[1] == item["Id"]:
+ kodiMovie = kodimovie
+
+ if kodiMovie == None:
+ 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:
+ WriteKodiDB().addOrUpdateMovieToKodiLibrary(item["Id"],connection, cursor, view.get('title'))
+
+ #### PROCESS DELETES #####
+ allEmbyMovieIds = set(allEmbyMovieIds)
+ for kodiId in allKodiMovieIds:
+ if not kodiId in allEmbyMovieIds:
+ WINDOW.setProperty(kodiId,"deleted")
+ WriteKodiDB().deleteMovieFromKodiLibrary(kodiId, connection, cursor)
+
+ if(pDialog != None):
+ pDialog.close()
+
+ def TvShowsSync(self,connection,cursor,installFirstRun,itemList = []):
+
+ pDialog = xbmcgui.DialogProgressBG()
+ pDialog.create('Sync DB', 'Sync TV Shows')
+
+ views = ReadEmbyDB().getCollections("tvshows")
+
+ allKodiTvShowIds = list()
+ allEmbyTvShowIds = list()
+
+ for view in views:
+
+ allEmbyTvShows = ReadEmbyDB().getTvShows(view.get('id'))
+ allKodiTvShows = ReadKodiDB().getKodiTvShows(connection, cursor)
+
+ #### TVSHOW: PROCESS ADDS AND UPDATES ###
+ for item in allEmbyTvShows:
+
+ if item.get('IsFolder') and item.get('RecursiveItemCount') != 0:
+ allEmbyTvShowIds.append(item["Id"])
+
+ #build a list with all Id's and get the existing entry (if exists) in Kodi DB
+ kodiShow = None
+ for kodishow in allKodiTvShows:
+ allKodiTvShowIds.append(kodishow[1])
+ if kodishow[1] == item["Id"]:
+ kodiShow = kodishow
+
+ if kodiShow == None:
+ # Tv show doesn't exist in Kodi yet so proceed and add it
+ allKodiTvShowIds.append(item["Id"])
+ kodiId = WriteKodiDB().addOrUpdateTvShowToKodiLibrary(item["Id"],connection, cursor, view.get('title'))
+ 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:
+ WriteKodiDB().addOrUpdateTvShowToKodiLibrary(item["Id"],connection, cursor, view.get('title'))
+
+ #### PROCESS EPISODES ######
+ self.EpisodesSync(connection,cursor,installFirstRun, item["Id"], kodiId, itemList)
+
+ #### TVSHOW: PROCESS DELETES #####
+ allEmbyTvShowIds = set(allEmbyTvShowIds)
+ for kodiId in allKodiTvShowIds:
+ if not kodiId in allEmbyTvShowIds:
+ WINDOW.setProperty(kodiId,"deleted")
+ WriteKodiDB().deleteTvShowFromKodiLibrary(kodiId, connection, cursor)
+
+ if(pDialog != None):
+ pDialog.close()
+
+
+ def EpisodesSync(self,connection,cursor,installFirstRun, embyShowId, kodiShowId, itemList = []):
+
WINDOW = xbmcgui.Window( 10000 )
- pDialog = None
- startedSync = datetime.today()
- try:
- addon = xbmcaddon.Addon(id='plugin.video.emby')
- dbSyncIndication = addon.getSetting("dbSyncIndication")
-
- if(installFirstRun or dbSyncIndication == "Dialog Progress"):
- pDialog = xbmcgui.DialogProgress()
- elif(dbSyncIndication == "BG Progress"):
- pDialog = xbmcgui.DialogProgressBG()
-
- if(pDialog != None):
- pDialog.create('Sync DB', 'Sync DB')
-
- totalItemsAdded = 0
- totalItemsUpdated = 0
- totalItemsDeleted = 0
-
- allEmbyMovieIds = list()
-
- views = ReadEmbyDB().getCollections("movies")
- viewCount = len(views)
- viewCurrent = 1
- progressTitle = ""
-
- for view in views:
-
- #process new movies
- allMB3Movies = ReadEmbyDB().getMovies(id = view.get('id'), fullinfo=True, fullSync = fullsync, itemList = itemList)
- allKodiIds = set(ReadKodiDB().getKodiMoviesIds(True))
-
- if(self.ShouldStop(pDialog)):
- return False
-
- if(allMB3Movies == None):
- return False
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing " + view.get('title') + " " + str(viewCurrent) + " of " + str(viewCount)
- pDialog.update(0, progressTitle)
- total = len(allMB3Movies) + 1
- count = 1
-
- for item in allMB3Movies:
-
- if not item.get('IsFolder'):
- allEmbyMovieIds.append(item["Id"])
- item['Tag'] = []
- item['Tag'].append(view.get('title'))
-
- if item["Id"] not in allKodiIds:
- WriteKodiDB().addMovieToKodiLibrary(item,connection, cursor)
- totalItemsAdded += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Adding Movie: " + str(count))
- count += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing " + view.get('title') + " " + str(viewCurrent) + " of " + str(viewCount)
- pDialog.update(0, progressTitle, "")
- total = len(allMB3Movies) + 1
- count = 1
-
- #process updates
- allKodiMovies = ReadKodiDB().getKodiMovies(True)
- for item in allMB3Movies:
-
- if not item.get('IsFolder'):
- item['Tag'] = []
- item['Tag'].append(view.get('title'))
-
- if allKodiMovies != None:
- kodimovie = allKodiMovies.get(item["Id"], None)
- else:
- kodimovie = None
-
- userData = API().getUserData(item)
-
- if(kodimovie != None):
- updated = WriteKodiDB().updateMovieToKodiLibrary_Batched(item, kodimovie, connection, cursor)
- if(updated):
- totalItemsUpdated += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Updating Movie: " + str(count))
- count += 1
-
- viewCurrent += 1
-
- # process box sets - TODO cope with movies removed from a set
- if fullsync:
-
- if(pDialog != None):
- progressTitle = "Sync DB : BoxSets"
- pDialog.update(0, progressTitle, "Retrieving Boxset List")
-
- utils.logMsg("Sync Movies", "BoxSet Sync Started", 1)
- boxsets = ReadEmbyDB().getBoxSets()
-
- if(pDialog != None):
- total = len(boxsets) + 1
- count = 1
-
- for boxset in boxsets:
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Updating BoxSet: " + str(count) + " of " + str(total))
- count += 1
- if(self.ShouldStop(pDialog)):
- return False
- boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"])
- WriteKodiDB().addBoxsetToKodiLibrary(boxset,connection, cursor)
-
- for boxsetMovie in boxsetMovies:
- if(self.ShouldStop(pDialog)):
- return False
- WriteKodiDB().updateBoxsetToKodiLibrary(boxsetMovie,boxset)
-
- utils.logMsg("Sync Movies", "BoxSet Sync Finished", 1)
-
- if(pDialog != None):
- progressTitle = "Removing Deleted Items"
- pDialog.update(0, progressTitle, "")
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # process any deletes only at fullsync
- if fullsync:
- allKodiIds = ReadKodiDB().getKodiMoviesIds(True)
- allEmbyMovieIds = set(allEmbyMovieIds)
- for kodiId in allKodiIds:
- if not kodiId in allEmbyMovieIds:
- WINDOW.setProperty(kodiId,"deleted")
- WriteKodiDB().deleteMovieFromKodiLibrary(kodiId)
- totalItemsDeleted += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # display notification if set up
- notificationString = ""
- if(totalItemsAdded > 0):
- notificationString += "Added:" + str(totalItemsAdded) + " "
- if(totalItemsUpdated > 0):
- notificationString += "Updated:" + str(totalItemsUpdated) + " "
- if(totalItemsDeleted > 0):
- notificationString += "Deleted:" + str(totalItemsDeleted) + " "
-
- timeTaken = datetime.today() - startedSync
- timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60)
- utils.logMsg("Sync Movies", "Finished " + timeTakenString + " " + notificationString, 0)
-
- if(dbSyncIndication == "Notify OnChange" and notificationString != ""):
- notificationString = "(" + timeTakenString + ") " + notificationString
- xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)")
- elif(dbSyncIndication == "Notify OnFinish"):
- if(notificationString == ""):
- notificationString = "Done"
- notificationString = "(" + timeTakenString + ") " + notificationString
- xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)")
-
- finally:
- if(pDialog != None):
- pDialog.close()
+ allKodiEpisodeIds = list()
+ allEmbyEpisodeIds = list()
- return True
+ allEmbyEpisodes = ReadEmbyDB().getEpisodes(embyShowId)
+ allKodiEpisodes = ReadKodiDB().getKodiEpisodes(connection, cursor, kodiShowId)
+
+ #### EPISODES: PROCESS ADDS AND UPDATES ###
+ for item in allEmbyEpisodes:
+
+ allEmbyEpisodeIds.append(item["Id"])
+
+ #build a list with all Id's and get the existing entry (if exists) in Kodi DB
+ kodiEpisode = None
+ for kodiepisode in allKodiEpisodes:
+ allKodiEpisodeIds.append(kodiepisode[1])
+ if kodiepisode[1] == item["Id"]:
+ kodiEpisode = kodiepisode
+
+ if kodiEpisode == None:
+ # Episode doesn't exist in Kodi yet so proceed and add it
+ allKodiEpisodeIds.append(item["Id"])
+ 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:
+ WriteKodiDB().addOrUpdateTvShowToKodiLibrary(item["Id"], kodiShowId, connection, cursor)
- def TvShowsSync(self, connection, cursor ,fullsync, installFirstRun, itemList = []):
+ #### EPISODES: PROCESS DELETES #####
+ allEmbyEpisodeIds = set(allEmbyEpisodeIds)
+ print allEmbyEpisodeIds
+ for kodiId in allKodiEpisodeIds:
+ if not kodiId in allEmbyEpisodeIds:
+ WINDOW.setProperty(kodiId,"deleted")
+ print "deleting ???-->" + kodiId
+ #WriteKodiDB().deleteEpisodeFromKodiLibrary(kodiId, connection, cursor)
- addon = xbmcaddon.Addon(id='plugin.video.emby')
- WINDOW = xbmcgui.Window( 10000 )
- pDialog = None
- startedSync = datetime.today()
-
- try:
- dbSyncIndication = addon.getSetting("dbSyncIndication")
-
- if(installFirstRun or dbSyncIndication == "Dialog Progress"):
- pDialog = xbmcgui.DialogProgress()
- elif(dbSyncIndication == "BG Progress"):
- pDialog = xbmcgui.DialogProgressBG()
-
- if(pDialog != None):
- pDialog.create('Sync DB', 'Sync DB')
-
- totalItemsAdded = 0
- totalItemsUpdated = 0
- totalItemsDeleted = 0
- allTVShows = list()
- allMB3EpisodeIds = list() #for use with deletions
- allKodiEpisodeIds = [] # for use with deletions
-
- views = ReadEmbyDB().getCollections("tvshows")
- viewCount = len(views)
- viewCurrent = 1
- progressTitle = ""
- for view in views:
-
- progressTitle = "Sync DB : Processing " + view.get('title') + " " + str(viewCurrent) + " of " + str(viewCount)
-
- # incremental sync --> new episodes only
- if fullsync == False:
-
- latestMBEpisodes = ReadEmbyDB().getLatestEpisodes(fullinfo = True, itemList = itemList)
- utils.logMsg("Sync TV", "Inc Sync Started on : " + str(len(latestMBEpisodes)) + " : " + str(itemList), 1)
-
- if latestMBEpisodes != None:
- allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True))
-
- # get included TV Shows
- showList = []
- for episode in latestMBEpisodes:
- if(episode["SeriesId"] not in showList):
- showList.append(episode["SeriesId"])
-
- utils.logMsg("Incremental TV Sync", "Included TV Show List : " + str(showList), 0)
-
- if(pDialog != None):
- pDialog.update(0, progressTitle)
- total = len(showList) + 1
- count = 1
-
- # process included TV Shows
- for showID in showList:
-
- embyTvShow = ReadEmbyDB().getFullItem(showID)
-
- if(showID not in allKodiTvShowsIds):
- utils.logMsg("Incremental TV Sync", "Adding TV Show : " + embyTvShow.get("Name"), 1)
- WriteKodiDB().addTVShowToKodiLibrary(embyTvShow, connection, cursor)
-
- kodiTvShow = ReadKodiDB().getKodiTVShow(showID)
- utils.logMsg("Incremental TV Sync", "Updating TV Show : " + embyTvShow.get("Name"), 1)
- WriteKodiDB().updateTVShowToKodiLibrary(embyTvShow, kodiTvShow, connection, cursor)
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Processing TV Shows : " + str(count))
- count += 1
-
- if(pDialog != None):
- pDialog.update(0, progressTitle)
- total = len(latestMBEpisodes) + 1
- count = 1
-
- # process new episodes
- for episode in latestMBEpisodes:
- if(self.ShouldStop(pDialog)):
- return False
-
- WriteKodiDB().addEpisodeToKodiLibrary(episode, connection, cursor)
- progressAction = "Adding"
- totalItemsAdded += 1
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count))
- count += 1
-
- #process updates
- if(pDialog != None):
- progressTitle = "Sync DB : Processing Episodes"
- pDialog.update(0, progressTitle)
- total = len(latestMBEpisodes) + 1
- count = 1
-
- for episode in latestMBEpisodes:
- if(self.ShouldStop(pDialog)):
- return False
- allKodiTVShows = ReadKodiDB().getKodiTvShows(False)
- kodishow = allKodiTVShows.get(episode["SeriesId"],None)
- kodiEpisodes = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],True,True)
-
- if(self.ShouldStop(pDialog)):
- return False
-
- userData = API().getUserData(episode)
-
- if kodiEpisodes != None:
- KodiItem = kodiEpisodes.get(episode.get("Id"), None)
- if(KodiItem != None):
- WriteKodiDB().updateEpisodeToKodiLibrary(episode, KodiItem, connection, cursor)
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Updating Episode: " + str(count))
- count += 1
-
-
- # full sync --> Tv shows and Episodes
- if fullsync:
- viewTVShows = list()
- tvShowData = ReadEmbyDB().getTVShows(id = view.get('id') , fullinfo = True, fullSync = True)
- allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True))
-
- if(self.ShouldStop(pDialog)):
- return False
-
- if (tvShowData == None):
- return False
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing TV Shows"
- pDialog.update(0, progressTitle)
- total = len(tvShowData) + 1
- count = 1
-
- # add TV Shows
- for item in tvShowData:
- if item.get('IsFolder') and item.get('RecursiveItemCount') != 0:
- allTVShows.append(item["Id"])
- viewTVShows.append(item["Id"])
- item['Tag'] = []
- item['Tag'].append(view.get('title'))
- progMessage = "Processing"
- if item["Id"] not in allKodiIds:
- WriteKodiDB().addTVShowToKodiLibrary(item,connection, cursor)
- totalItemsAdded += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Adding Tv Show: " + str(count))
- count += 1
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing TV Shows"
- pDialog.update(0, progressTitle, "")
- total = len(viewTVShows) + 1
- count = 1
-
- # update TV Shows
- allKodiTVShows = ReadKodiDB().getKodiTvShows(True)
- for item in tvShowData:
- if item.get('IsFolder'):
- item['Tag'] = []
- item['Tag'].append(view.get('title'))
- if allKodiTVShows != None:
- kodishow = allKodiTVShows.get(item["Id"],None)
- else:
- kodishow = None
-
- if(kodishow != None):
- updated = WriteKodiDB().updateTVShowToKodiLibrary(item,kodishow,connection, cursor)
- if(updated):
- totalItemsUpdated += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Updating Tv Show: " + str(count))
- count += 1
-
-
- # do episode adds
- allEpisodes = list()
- showTotal = len(viewTVShows)
- showCurrent = 1
- for tvshow in viewTVShows:
-
- episodeData = ReadEmbyDB().getEpisodes(tvshow,True)
- if episodeData != None:
-
- if(self.ShouldStop(pDialog)):
- return False
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing Tv Show " + str(showCurrent) + " of " + str(showTotal)
- pDialog.update(0, progressTitle)
- total = len(episodeData) + 1
- count = 0
-
- for item in episodeData:
-
- if(self.ShouldStop(pDialog)):
- return False
-
- progressAction = "Adding"
- WriteKodiDB().addEpisodeToKodiLibrary(item, connection, cursor)
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count))
- count += 1
-
- showCurrent += 1
-
- # do episode updates
- showCurrent = 1
- for tvshow in viewTVShows:
- episodeData = ReadEmbyDB().getEpisodes(tvshow,True)
-
- kodiEpisodes = None
- allKodiTVShows = ReadKodiDB().getKodiTvShows(False)
- if allKodiTVShows != None:
- kodishow = allKodiTVShows.get(tvshow,None)
- if kodishow != None:
- kodiEpisodes = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],True,True)
-
- if(self.ShouldStop(pDialog)):
- return False
-
- if(pDialog != None):
- progressTitle = "Sync DB : Processing Tv Show " + str(showCurrent) + " of " + str(showTotal)
- pDialog.update(0, progressTitle)
- total = len(episodeData) + 1
- count = 0
-
- #we have to compare the lists somehow
- for item in episodeData:
- #add episodeId to the list of all episodes for use later on the deletes
- allMB3EpisodeIds.append(item["Id"])
-
- matchFound = False
-
- userData = API().getUserData(item)
-
- if kodiEpisodes != None:
- KodiItem = kodiEpisodes.get(item.get("Id"), None)
- if(KodiItem != None):
- updated = WriteKodiDB().updateEpisodeToKodiLibrary(item, KodiItem, connection, cursor)
- if(updated):
- totalItemsUpdated += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # update progress bar
- if(pDialog != None):
- percentage = int(((float(count) / float(total)) * 100))
- pDialog.update(percentage, progressTitle, "Updating Episode: " + str(count))
- count += 1
-
-
- #add all kodi episodes to a list with episodes for use later on to delete episodes
- #the mediabrowser ID is set as uniqueID in the NFO... for some reason this has key 'unknown' in the json response
- if kodishow != None:
- show = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],False,False)
- if show != None:
- for episode in show:
- dict = {'episodeid': str(episode["uniqueid"]["unknown"]),'tvshowid': tvshow}
- allKodiEpisodeIds.append(dict)
-
- showCurrent += 1
-
- if(pDialog != None):
- progressTitle = "Removing Deleted Items"
- pDialog.update(0, progressTitle)
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # DELETES -- EPISODES
- # process any deletes only at fullsync
- allMB3EpisodeIdsSet = set(allMB3EpisodeIds)
- for episode in allKodiEpisodeIds:
- if episode.get('episodeid') not in allMB3EpisodeIdsSet:
- WINDOW.setProperty("embyid" + str(episode.get('episodeid')),"deleted")
- WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid'))
- totalItemsDeleted += 1
-
- # DELETES -- TV SHOWS
- if fullsync:
- allKodiShows = ReadKodiDB().getKodiTvShowsIds(True)
- allMB3TVShows = set(allTVShows)
- for show in allKodiShows:
- if not show in allMB3TVShows:
- WriteKodiDB().deleteTVShowFromKodiLibrary(show)
- totalItemsDeleted += 1
-
- if(self.ShouldStop(pDialog)):
- return False
-
- # display notification if set up
- notificationString = ""
- if(totalItemsAdded > 0):
- notificationString += "Added:" + str(totalItemsAdded) + " "
- if(totalItemsUpdated > 0):
- notificationString += "Updated:" + str(totalItemsUpdated) + " "
- if(totalItemsDeleted > 0):
- notificationString += "Deleted:" + str(totalItemsDeleted) + " "
-
- timeTaken = datetime.today() - startedSync
- timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60)
- utils.logMsg("Sync Episodes", "Finished " + timeTakenString + " " + notificationString, 0)
-
- if(dbSyncIndication == "Notify OnChange" and notificationString != ""):
- notificationString = "(" + timeTakenString + ") " + notificationString
- xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)")
- elif(dbSyncIndication == "Notify OnFinish"):
- if(notificationString == ""):
- notificationString = "Done"
- notificationString = "(" + timeTakenString + ") " + notificationString
- xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)")
-
- finally:
- if(pDialog != None):
- pDialog.close()
-
- return True
def MusicVideosSync(self, fullsync, installFirstRun,connection, cursor):
diff --git a/resources/lib/ReadEmbyDB.py b/resources/lib/ReadEmbyDB.py
index 4d80455c..23773820 100644
--- a/resources/lib/ReadEmbyDB.py
+++ b/resources/lib/ReadEmbyDB.py
@@ -6,30 +6,22 @@ import xbmc
import xbmcgui
import xbmcaddon
+
+
from DownloadUtils import DownloadUtils
addon = xbmcaddon.Addon(id='plugin.video.emby')
class ReadEmbyDB():
- def getMovies(self, id, fullinfo = False, fullSync = True, itemList = []):
+ def getMovies(self, id):
result = None
doUtils = DownloadUtils()
-
- if fullSync:
- sortstring = "&SortBy=SortName"
- else:
- if(len(itemList) > 0): # if we want a certain list specify it
- #sortstring = "&Ids=" + ",".join(itemList)
- sortstring = "" # work around for now until ParetnId and Id work together
- else: # just get the last 20 created items
- sortstring = "&Limit=20&SortBy=DateCreated"
-
- if fullinfo:
- url = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s%s&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % (id, sortstring)
- else:
- url = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s%s&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % (id, sortstring)
+
+ #only get basic info for our sync-compares
+ sortstring = "&SortBy=SortName"
+ url = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s%s&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % (id, sortstring)
jsonData = doUtils.downloadUrl(url)
if (jsonData == ""):
@@ -37,14 +29,6 @@ class ReadEmbyDB():
if (jsonData[u'Items'] != ""):
result = jsonData[u'Items']
-
- # work around for now until ParetnId and Id work together
- if (result != None and len(result) > 0 and len(itemList) > 0):
- newResult = []
- for item in result:
- if (item[u'Id'] in itemList):
- newResult.append(item)
- result = newResult
return result
@@ -98,20 +82,14 @@ class ReadEmbyDB():
return result
- def getTVShows(self, id, fullinfo = False, fullSync = False):
+ def getTvShows(self, id):
result = None
doUtils = DownloadUtils()
-
- if not fullSync:
- sortstring = "&Limit=20&SortBy=DateCreated"
- else:
- sortstring = "&SortBy=SortName"
- if fullinfo:
- url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s%s&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=Series&format=json&ImageTypeLimit=1" % (id, sortstring)
- else:
- url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s%s&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Series&format=json&ImageTypeLimit=1" % (id, sortstring)
+ #only get basic info for our sync-compares
+ sortstring = "&SortBy=SortName"
+ url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s%s&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Series&format=json&ImageTypeLimit=1" % (id, sortstring)
jsonData = doUtils.downloadUrl(url)
if (jsonData == ""):
@@ -138,15 +116,12 @@ class ReadEmbyDB():
return result
- def getEpisodes(self, showId, fullinfo = False):
+ def getEpisodes(self, showId):
result = None
doUtils = DownloadUtils()
- if fullinfo:
- url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId
- else:
- url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId
+ url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId
jsonData = doUtils.downloadUrl(url)
if (jsonData == ""):
diff --git a/resources/lib/ReadKodiDB.py b/resources/lib/ReadKodiDB.py
index f5acdb26..14b0872a 100644
--- a/resources/lib/ReadKodiDB.py
+++ b/resources/lib/ReadKodiDB.py
@@ -30,71 +30,38 @@ class ReadKodiDB():
movies = result['movies']
movie = movies[0]
for item in movies:
- if item["imdbnumber"] == id:
+ if id in item["file"]:
movie = item
break
return movie
def getEmbyIdByKodiId(self, kodiid, type):
- #returns the emby id by search on kodi id
- xbmc.sleep(sleepVal)
-
embyId = None
- json_response = None
+ connection = utils.KodiSQL()
+ cursor = connection.cursor()
if type == "movie":
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": { "movieid": %d, "properties" : ["imdbnumber","file"] }, "id": "libMovies"}' %kodiid)
+ cursor.execute("SELECT embyId as embyId FROM movie WHERE idMovie = ?",(kodiid,))
if type == "episode":
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodeDetails", "params": {"episodeid": %d, "properties": ["file","uniqueid"]}, "id": 1}' %kodiid)
+ cursor.execute("SELECT embyId as embyId FROM episode WHERE idEpisode = ?",(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]
+ 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,))
- if json_response != None:
- jsonobject = json.loads(json_response.decode('utf-8','replace'))
- if(jsonobject.has_key('result')):
- result = jsonobject['result']
- resulttype = type + "details"
- if(result.has_key(resulttype)):
- item = result[resulttype]
- if type == "movie":
- if item.has_key('imdbnumber'):
- embyId = item['imdbnumber']
- if type == "episode":
- if item.has_key('uniqueid'):
- if item['uniqueid'].has_key('unknown'):
- embyId = item["uniqueid"]["unknown"]
+ result = cursor.fetchone()
+ cursor.close()
+ if result != None:
+ embyId = result[0]
return embyId
- def getKodiMovies(self,fullInfo = False):
+ def getKodiMovies(self, connection, cursor):
#returns all movies in Kodi db
- xbmc.sleep(sleepVal)
- if fullInfo:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties" : ["art", "rating", "thumbnail", "fanart", "resume", "runtime", "year", "genre", "cast", "trailer", "country", "lastplayed", "studio", "set", "imdbnumber", "mpaa", "tagline", "plotoutline","plot", "sorttitle", "director", "writer", "playcount", "tag", "file"] }, "id": "libMovies"}')
- else:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties" : ["resume", "playcount", "imdbnumber", "lastplayed", "file"] }, "id": "libMovies"}')
- jsonobject = json.loads(json_response.decode('utf-8','replace'))
- movies = None
-
- if(jsonobject.has_key('result')):
- result = jsonobject['result']
- if(result.has_key('movies')):
- movies = result['movies']
-
- kodiMovieMap = None
- if(movies != None and len(movies) > 0):
- kodiMovieMap = {}
- for kodimovie in movies:
- key = kodimovie["imdbnumber"] #extract the id from the imdbnumber
- kodiMovieMap[key] = kodimovie
-
- return kodiMovieMap
+ cursor.execute("SELECT idMovie, embyId, c00 FROM 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
@@ -132,29 +99,11 @@ class ReadKodiDB():
return allKodiTvShowsIds
- def getKodiTvShows(self,fullInfo = False):
- #returns all tvshows in Kodi db inserted by MB
- xbmc.sleep(sleepVal)
- if fullInfo:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["art", "genre", "plot", "mpaa", "cast", "studio", "sorttitle", "title", "originaltitle", "imdbnumber", "year", "premiered", "rating", "thumbnail", "playcount", "lastplayed", "file", "fanart", "tag"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libTvShows"}')
- else:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["sorttitle", "title", "playcount", "lastplayed", "imdbnumber", "file"], "sort": { "order": "ascending", "method": "label", "ignorearticle": true } }, "id": "libTvShows"}')
- jsonobject = json.loads(json_response.decode('utf-8','replace'))
- tvshows = None
-
- if(jsonobject.has_key('result')):
- result = jsonobject['result']
- if(result.has_key('tvshows')):
- tvshows = result['tvshows']
-
- kodiShowMap = None
- if(tvshows != None and len(tvshows) > 0):
- kodiShowMap = {}
- for kodishow in tvshows:
- key = kodishow["imdbnumber"] #extract the id from the imdb number
- kodiShowMap[key] = kodishow
-
- return kodiShowMap
+ def getKodiTvShows(self, connection, cursor):
+ cursor.execute("SELECT idShow, embyId, c00 FROM 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)
@@ -171,28 +120,11 @@ class ReadKodiDB():
break
return tvshow
- def getKodiEpisodes(self, KodiTvShowId, fullInfo = True, returnmap = True):
- xbmc.sleep(sleepVal)
- episodes = None
- if fullInfo:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": %d, "properties": ["title", "playcount", "plot", "season", "episode", "showtitle", "file", "lastplayed", "rating", "resume", "art", "streamdetails", "firstaired", "runtime", "writer", "cast", "director", "dateadded", "uniqueid", "thumbnail", "fanart"], "sort": {"method": "episode"}}, "id": 1}' %KodiTvShowId)
- else:
- json_response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": %d, "properties": ["title", "playcount", "season", "episode", "lastplayed", "resume","file","uniqueid"], "sort": {"method": "episode"}}, "id": 1}' %KodiTvShowId)
- jsonobject = json.loads(json_response.decode('utf-8','replace'))
- episodes = None
- if(jsonobject.has_key('result')):
- result = jsonobject['result']
- if(result.has_key('episodes')):
- episodes = result['episodes']
- if returnmap:
- episodeMap = None
- if(episodes != None):
- episodeMap = {}
- for KodiItem in episodes:
- episodeMap[KodiItem["uniqueid"]["unknown"]] = KodiItem
- return episodeMap
- else:
- return episodes
+ def getKodiEpisodes(self, connection, cursor, showid):
+ cursor.execute("SELECT idEpisode, embyId, c00 FROM episode WHERE idShow = ?", (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
diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py
index 4f47b77f..a9da6b5c 100644
--- a/resources/lib/Utils.py
+++ b/resources/lib/Utils.py
@@ -53,7 +53,7 @@ def convertEncoding(data):
def KodiSQL():
connection = sqlite3.connect(getKodiDBPath())
-
+
return connection
def getKodiDBPath():
diff --git a/resources/lib/WriteKodiDB.py b/resources/lib/WriteKodiDB.py
index b46ccb44..d2cf5421 100644
--- a/resources/lib/WriteKodiDB.py
+++ b/resources/lib/WriteKodiDB.py
@@ -43,107 +43,7 @@ class WriteKodiDB():
else:
downloadUtils.downloadUrl(watchedurl, type="DELETE")
- def updateMovieToKodiLibrary_Batched(self, MBitem, KodiItem,connection, cursor):
- addon = xbmcaddon.Addon(id='plugin.video.emby')
- WINDOW = xbmcgui.Window(10000)
- username = WINDOW.getProperty('currUser')
- server = WINDOW.getProperty('server%s' % username)
-
- downloadUtils = DownloadUtils()
-
- 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")
-
- params = list()
-
- self.getArtworkParam_Batched(KodiItem, MBitem, params)
-
- #set Filename
- playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
- self.setKodiFilename(KodiItem["movieid"], KodiItem["file"], playurl, "movie", MBitem["Id"], connection, cursor)
-
- #update common properties
- 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)
- self.getPropertyParamArray_Batched(KodiItem, "tag", MBitem.get("Tag"), params)
-
- if MBitem.get("CommunityRating") != None:
- self.getPropertyParam_Batched(KodiItem, "rating", Decimal(format(MBitem.get("CommunityRating"),'.1f')), params)
-
- self.getPropertyParam_Batched(KodiItem, "plot", MBitem.get("Overview"), params)
- self.getPropertyParam_Batched(KodiItem, "plotoutline", MBitem.get("ShortOverview"), params)
- self.getPropertyParam_Batched(KodiItem, "set", MBitem.get("TmdbCollectionName"), params)
- self.getPropertyParam_Batched(KodiItem, "sorttitle", MBitem.get("SortName"), params)
-
- if MBitem.get("ProviderIds") != None:
- if MBitem.get("ProviderIds").get("Imdb") != None:
- self.getPropertyParam_Batched(KodiItem, "imdbnumber", MBitem.get("ProviderIds").get("Imdb"), params)
-
- # FIXME --> Taglines not returned by MB3 server !?
- if MBitem.get("TagLines") != None:
- self.getPropertyParam_Batched(KodiItem, "tagline", MBitem.get("TagLines")[0], params)
-
- self.getPropertyParamArray_Batched(KodiItem, "writer", people.get("Writer"), params)
- self.getPropertyParamArray_Batched(KodiItem, "director", people.get("Director"), params)
- self.getPropertyParamArray_Batched(KodiItem, "genre", MBitem.get("Genres"), params)
-
- if(studios != None):
- for x in range(0, len(studios)):
- studios[x] = studios[x].replace("/", "&")
- self.getPropertyParamArray_Batched(KodiItem, "studio", studios, params)
-
- # FIXME --> ProductionLocations not returned by MB3 server !?
- self.getPropertyParamArray_Batched(KodiItem, "country", MBitem.get("ProductionLocations"), params)
-
- #trailer link
- trailerUrl = None
- if MBitem.get("LocalTrailerCount") != None and MBitem.get("LocalTrailerCount") > 0:
- itemTrailerUrl = "{server}/mediabrowser/Users/{UserId}/Items/%s/LocalTrailers?format=json" % MBitem.get("Id")
- jsonData = downloadUtils.downloadUrl(itemTrailerUrl)
- if (jsonData != ""):
- trailerItem = jsonData
- if trailerItem[0][u'LocationType'] == "FileSystem":
- trailerUrl = PlayUtils().getPlayUrl(server, trailerItem[0][u'Id'], trailerItem[0])
- trailerUrl = utils.convertEncoding(trailerUrl)
- self.getPropertyParam_Batched(KodiItem, "trailer", trailerUrl, params)
-
-
- changes = False
- # if there were movies changes then send the update via JSONRPC
- if(len(params) > 0):
- changes |= True
- utils.logMsg("UpdateMovieParams", str(params), level = 2)
- jsoncommand = '{"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": { "movieid": %i, %s}, "id": 1 }'
- paramString = ""
- paramLen = len(params)
- for x in range(0, paramLen):
- param = params[x]
- paramString += param
- if(x < paramLen-1):
- paramString += ", "
- jsoncommand = jsoncommand %(KodiItem['movieid'], paramString)
- utils.logMsg("executeJSONRPC : ", jsoncommand, level = 2)
- xbmc.sleep(sleepVal)
- result = xbmc.executeJSONRPC(jsoncommand.encode("utf-8"))
-
- #add actors
- changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"), "movie", connection, cursor)
-
- if(changes):
- utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0)
-
- return changes
-
def updateMusicVideoToKodiLibrary_Batched(self, MBitem, KodiItem):
addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
@@ -201,74 +101,6 @@ class WriteKodiDB():
if(changes):
utils.logMsg("Updated musicvideo to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"], level=0)
- def updateTVShowToKodiLibrary( self, MBitem, KodiItem,connection, cursor ):
-
- addon = xbmcaddon.Addon(id='plugin.video.emby')
- port = addon.getSetting('port')
- host = addon.getSetting('ipaddress')
- server = host + ":" + port
- downloadUtils = DownloadUtils()
-
- 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")
-
- changes = False
-
- #set Filename
- playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
- #make sure that the path always ends with a slash
- playurl = playurl + "/"
- self.setKodiFilename(KodiItem["tvshowid"], KodiItem["file"], playurl, "tvshow", MBitem["Id"], connection, cursor)
-
- #update/check all artwork
- changes |= self.updateArtWork(KodiItem,MBitem)
-
- #update common properties
- if MBitem.get("PremiereDate") != None:
- premieredatelist = (MBitem.get("PremiereDate")).split("T")
- premieredate = premieredatelist[0]
- changes |= self.updateProperty(KodiItem,"premiered",premieredate,"tvshow")
-
- changes |= self.updatePropertyArray(KodiItem,"tag",MBitem.get("Tag"),"tvshow")
- changes |= self.updateProperty(KodiItem,"mpaa",MBitem.get("OfficialRating"),"tvshow")
- changes |= self.updateProperty(KodiItem,"lastplayed",MBitem.get("LastPlayedDate"),"tvshow")
-
- if MBitem.get("CommunityRating") != None:
- changes |= self.updateProperty(KodiItem,"rating",Decimal(format(MBitem.get("CommunityRating"),'.1f')),"tvshow")
-
- changes |= self.updateProperty(KodiItem,"sorttitle",utils.convertEncoding(MBitem["SortName"]),"tvshow")
- changes |= self.updateProperty(KodiItem,"title",utils.convertEncoding(MBitem["Name"]),"tvshow")
- changes |= self.updateProperty(KodiItem,"plot",utils.convertEncoding(API().getOverview(MBitem)),"tvshow")
-
- # we use this to store the Emby ID so make sure we use that
- changes |= self.updateProperty(KodiItem, "imdbnumber", MBitem.get("Id"), "tvshow")
-
- changes |= self.updatePropertyArray(KodiItem,"genre",MBitem.get("Genres"),"tvshow")
-
- if(studios != None):
- for x in range(0, len(studios)):
- studios[x] = studios[x].replace("/", "&")
- changes |= self.updatePropertyArray(KodiItem,"studio",studios,"tvshow")
-
- # FIXME --> ProductionLocations not returned by MB3 server !?
- changes |= self.updatePropertyArray(KodiItem, "country", MBitem.get("ProductionLocations"), "tvshow")
-
- #add actors
- changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"),"tvshow", connection, cursor)
-
- #update season details
- self.updateSeasons(MBitem, KodiItem,connection, cursor)
-
- if changes:
- utils.logMsg("Updated item to Kodi Library", MBitem["Id"] + " - " + MBitem["Name"])
-
- return changes
def updateEpisodeToKodiLibrary( self, MBitem, KodiItem, connection, cursor ):
addon = xbmcaddon.Addon(id='plugin.video.emby')
@@ -288,48 +120,7 @@ class WriteKodiDB():
#update/check all artwork
changes |= self.updateArtWork(KodiItem,MBitem)
- #set Filename (will update the filename in db if changed)
- playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
- changes |= self.setKodiFilename(KodiItem["episodeid"], KodiItem["file"], playurl, "episode", MBitem["Id"], connection, cursor)
-
- #update common properties
- 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:
- premieredatelist = (MBitem.get("PremiereDate")).split("T")
- premieredate = premieredatelist[0]
- premieretime = premieredatelist[1].split(".")[0]
- firstaired = premieredate + " " + premieretime
- # for Helix we use the whole time string, for kodi 15 we have to change to only the datestring
- # see: http://forum.kodi.tv/showthread.php?tid=218743
- if KodiItem["firstaired"] != premieredate:
- changes |= self.updateProperty(KodiItem,"firstaired",firstaired,"episode")
-
- if MBitem.get("CommunityRating") != None:
- changes |= self.updateProperty(KodiItem,"rating",Decimal(format(MBitem.get("CommunityRating"),'.1f')),"episode")
-
- if MBitem.get("ParentIndexNumber") != None:
- season = int(MBitem.get("ParentIndexNumber"))
- changes |= self.updateProperty(KodiItem,"season",season,"episode")
- # removed for now as setting c15 and c16 to -1 just shows specials in the special folder only
- #if(season == 0):
- # changes |= self.setSpecialAirsDetails(MBitem, KodiItem, connection, cursor)
-
- if MBitem.get("IndexNumber") != None:
- episode = int(MBitem.get("IndexNumber"))
- changes |= self.updateProperty(KodiItem,"episode",episode,"episode")
-
- #plot = utils.convertEncoding(API().getOverview(MBitem))
- plot = MBitem.get("Overview")
- if(plot != None):
- changes |= self.updateProperty(KodiItem,"plot",plot,"episode")
-
- title = utils.convertEncoding(MBitem["Name"])
- changes |= self.updateProperty(KodiItem,"title",title,"episode")
- changes |= self.updatePropertyArray(KodiItem,"writer",people.get("Writer"),"episode")
- changes |= self.updatePropertyArray(KodiItem,"director",people.get("Director"),"episode")
+ addOrUpdateEpisodeToKodiLibrary(MBitem, connection, cursor)
#add actors
changes |= self.AddActorsToMedia(KodiItem,MBitem.get("People"),"episode", connection, cursor)
@@ -597,23 +388,50 @@ class WriteKodiDB():
return pendingChanges
- def addMovieToKodiLibrary( self, MBitem ,connection, cursor):
- #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
+ def addOrUpdateMovieToKodiLibrary( self, embyId ,connection, cursor, viewTag):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
userid = WINDOW.getProperty('userId%s' % username)
server = WINDOW.getProperty('server%s' % username)
-
downloadUtils = DownloadUtils()
+ MBitem = ReadEmbyDB().getFullItem(embyId)
+
+ # 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"],))
+ result = cursor.fetchone()
+ if result != None:
+ movieid = result[0]
+ else:
+ movieid = None
+
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
- playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
- playurl = utils.convertEncoding(playurl)
+ #### The movie details #########
+ runtime = int(timeInfo.get('Duration'))*60
+ plot = utils.convertEncoding(API().getOverview(MBitem))
+ title = utils.convertEncoding(MBitem["Name"])
+ sorttitle = utils.convertEncoding(MBitem["SortName"])
+ year = MBitem.get("ProductionYear")
+ rating = MBitem.get("CommunityRating")
+
+ 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 = "%s/mediabrowser/Users/%s/Items/%s/LocalTrailers?format=json" % (server, userid, MBitem.get("Id"))
+ jsonData = downloadUtils.downloadUrl(itemTrailerUrl)
+ if(jsonData != ""):
+ trailerItem = jsonData
+ trailerUrl = "plugin://plugin.video.emby/mode=play?id=" + trailerItem[0][u'Id']
if MBitem.get("DateCreated") != None:
dateadded = MBitem["DateCreated"].replace("T"," ")
@@ -621,14 +439,11 @@ class WriteKodiDB():
else:
dateadded = None
- # 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,"")
-
+ #### ADD OR UPDATE THE FILE AND PATH ###########
+ #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY
+ path = "plugin://plugin.video.emby/movies/"
+ filename = "plugin://plugin.video.emby/movies/?id=" MBitem["Id"] + "&mode=play"
+
#create the path
cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,))
result = cursor.fetchone()
@@ -656,44 +471,29 @@ class WriteKodiDB():
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))
- title = utils.convertEncoding(MBitem["Name"])
- sorttitle = utils.convertEncoding(MBitem["SortName"])
- year = MBitem.get("ProductionYear")
- rating = MBitem.get("CommunityRating")
- if MBitem.get("ShortOverview") != None:
- shortplot = utils.convertEncoding(MBitem.get("ShortOverview"))
+
+ ##### ADD THE MOVIE ############
+ if movieid == None:
+ #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, c05, c07, c10, c11, c16, c19, embyId) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+ cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, rating, year, sorttitle, runtime, title, trailerUrl, MBitem["Id"]))
+
+ #### UPDATE THE MOVIE #####
else:
- shortplot = None
+ pathsql="update movie SET c00 = ?, c01 = ?, c02 = ?, c05 = ?, c07 = ?, c10 = ?, c11 = ?, c16 = ?, c19 = ?, embyId= ? WHERE idMovie = ?"
+ cursor.execute(pathsql, (title, plot, shortplot, rating, year, sorttitle, runtime, title, trailerUrl, MBitem["Id"], movieid))
- trailerUrl = None
- if MBitem.get("LocalTrailerCount") != None and MBitem.get("LocalTrailerCount") > 0:
- itemTrailerUrl = "%s/mediabrowser/Users/%s/Items/%s/LocalTrailers?format=json" % (server, userid, MBitem.get("Id"))
- jsonData = downloadUtils.downloadUrl(itemTrailerUrl)
- if(jsonData != ""):
- trailerItem = jsonData
- if trailerItem[0][u'LocationType'] == "FileSystem":
- trailerUrl = PlayUtils().getPlayUrl(server, trailerItem[0][u'Id'], trailerItem[0])
- trailerUrl = utils.convertEncoding(trailerUrl)
+ #update or insert actors
+ self.AddActorsToMedia(movieid,MBitem.get("People"),"movie", connection, cursor)
- #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, c05, c07, c09, c10, c11, c16, c19) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
-
- cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, rating, year, MBitem["Id"], sorttitle, runtime, title, trailerUrl))
-
- try:
- connection.commit()
- utils.logMsg("Emby","Added movie to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
- except:
- utils.logMsg("Emby","Error adding movie to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
- actionPerformed = False
-
+ #commit changes and return the id
+ connection.commit()
+ return movieid
+
def addMusicVideoToKodiLibrary( self, MBitem, connection, cursor ):
#adds a musicvideo to Kodi by directly inserting it to connectionthe DB while there is no addMusicVideo available on the json API
@@ -716,13 +516,8 @@ class WriteKodiDB():
else:
dateadded = None
- # 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,"")
+ path = "plugin://plugin.video.emby/musicvideos/"
+ filename = "plugin://plugin.video.emby/musicvideos/?mode=play&id=" + MBitem["Id"]
#create the path
cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,))
@@ -770,17 +565,20 @@ class WriteKodiDB():
utils.logMsg("Emby","Error adding musicvideo to Kodi Library",MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
- def addEpisodeToKodiLibrary(self, MBitem, connection, cursor):
+ def addOrUpdateEpisodeToKodiLibrary(self, embyId, showid, connection, cursor):
- #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
+ # If the episode 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
- # first check the episode is not already in the DB using the Emby ID which is stored in c20
- cursor.execute("SELECT idEpisode FROM episode WHERE c20 = ?",(MBitem["Id"],))
+ MBitem = ReadEmbyDB().getFullItem(embyId)
+
+ cursor.execute("SELECT idEpisode FROM episode WHERE embyId = ?",(MBitem["Id"],))
result = cursor.fetchone()
if result != None:
utils.logMsg("Emby", "Episode already exists in DB : " + MBitem["Id"] + " - " + MBitem["Name"], 2)
- return
+ episodeid = result[0]
+ else:
+ episodeid = None
addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
@@ -790,83 +588,7 @@ class WriteKodiDB():
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
- 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
-
- # 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 = ? and idPath = ?",(filename,pathid,))
- 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"],))
- result = cursor.fetchone()
- showid = -1
- if(result == None):
- utils.logMsg("Emby","Error adding episode to Kodi Library, couldn't find show - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
- actionPerformed = False
- return False
- else:
- showid = result[0]
-
- # check season
- season = 0
- if MBitem.get("ParentIndexNumber") != None:
- season = int(MBitem.get("ParentIndexNumber"))
- else:
- utils.logMsg("Emby","Error adding episode to Kodi Library, no ParentIndexNumber - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
- return False
-
- cursor.execute("SELECT idSeason FROM seasons WHERE idShow = ? and season = ?",(showid, season))
- result = cursor.fetchone()
- if(result == None):
- utils.logMsg("Emby","Error adding episode to Kodi Library, season does not exist - ShowId: " + str(showid) + " SeasonNo: " + str(season) + " EmbyId: " + MBitem["Id"] + " Name: " + MBitem["Name"])
- actionPerformed = False
- return False
-
- # build info
+ ###### episode properties ################
episode = 0
if MBitem.get("IndexNumber") != None:
episode = int(MBitem.get("IndexNumber"))
@@ -881,25 +603,93 @@ class WriteKodiDB():
else:
premieredate = 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, c05, c09, c20, c12, c13, c14, idShow, c15, c16) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
- cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, premieredate, runtime, MBitem["Id"], season, episode, title, showid, "-1", "-1"))
+ 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
+
+ playcount = None
+ if userData.get("PlayCount") == "1":
+ playcount = 1
+
+ #### ADD OR UPDATE THE FILE AND PATH ###########
+ #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY
+ path = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/"
+ filename = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/?id=" MBitem["Id"] + "&mode=play"
+
+ #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))
+
+ #create the file if not exists
+ cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?",(filename,pathid,))
+ 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))
+
+ # safety check: check season first
+ season = 0
+ if MBitem.get("ParentIndexNumber") != None:
+ season = int(MBitem.get("ParentIndexNumber"))
+ else:
+ utils.logMsg("Emby","SKIP adding episode to Kodi Library, no ParentIndexNumber - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
+ return False
+
+ cursor.execute("SELECT idSeason FROM seasons WHERE idShow = ? and season = ?",(showid, season))
+ result = cursor.fetchone()
+ if(result == None):
+ #update seasons first
+ self.updateSeasons(MBitem["SeriesId"], showid, connection, cursor)
+
+ # ADD EPISODE TO KODI
+ if episodeid == 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, c05, c09, c12, c13, c14, idShow, c15, c16, embyId) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+ cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, premieredate, runtime, season, episode, title, showid, "-1", "-1", MBitem["Id"]))
+
+ # UPDATE THE EPISODE IN KODI (for now, we just send in all data)
+ else:
+ pathsql = "UPDATE episode SET c00 = ?, c01 = ?, c03 = ?, c05 = ?, c09 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, embyId = ? WHERE idEpisode = ?"
+ cursor.execute(pathsql, title, plot, rating, premieredate, runtime, season, episode, title, MBitem["Id"], episodeid)
+
+ #update or insert actors
+ self.AddActorsToMedia(episodeid,MBitem.get("People"),"episode", connection, cursor)
try:
connection.commit()
- utils.logMsg("Emby","Added episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
+ utils.logMsg("Emby","Added or updated episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
except:
- utils.logMsg("Emby","Error adding episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
+ utils.logMsg("Emby","Error adding/updating episode to Kodi Library - ID: " + MBitem["Id"] + " - " + MBitem["Name"])
actionPerformed = False
- 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"]))
+ def deleteMovieFromKodiLibrary(self, id, connection, cursor ):
+ utils.logMsg("deleting movie from Kodi library --> ",id)
+ cursor.execute("DELETE FROM movie WHERE embyId = ?", (id,))
+ connection.commit()
def deleteMusicVideoFromKodiLibrary(self, id ):
utils.logMsg("deleting musicvideo from Kodi library",id)
@@ -907,129 +697,120 @@ class WriteKodiDB():
if kodiItem != None:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMusicVideo", "params": { "musicvideoid": %i}, "id": 1 }' %(kodiItem["musicvideoid"]))
- def deleteEpisodeFromKodiLibrary(self, episodeid, tvshowid ):
- utils.logMsg("deleting episode from Kodi library",episodeid)
- episode = ReadKodiDB().getKodiEpisodeByMbItem(episodeid, tvshowid)
- if episode != None:
- WINDOW = xbmcgui.Window( 10000 )
- xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveEpisode", "params": { "episodeid": %i}, "id": 1 }' %(episode["episodeid"]))
-
- utils.logMsg("episode deleted succesfully!",episodeid)
- else:
- utils.logMsg("episode not found in kodi DB",episodeid)
-
- def deleteEpisodeFromKodiLibraryByMbId(self, id ):
- utils.logMsg("deleting episode from Kodi library", id)
- kodiItem = ReadKodiDB().getKodiEpisodeByMbItemEx(id)
- if kodiItem != None:
- xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveEpisode", "params": { "episodeid": %i}, "id": 1 }' %(kodiItem["episodeid"]))
- utils.logMsg("episode deleted succesfully!", id)
- else:
- utils.logMsg("episode not found in kodi DB", id)
-
- def addTVShowToKodiLibrary( self, MBitem, connection, cursor ):
- #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
+ def deleteEpisodeFromKodiLibrary(self, id, connection, cursor ):
+ utils.logMsg("deleting episode from Kodi library --> ",id)
+ cursor.execute("DELETE FROM episode WHERE embyId = ?", (id,))
+ connection.commit()
+
+ def addOrUpdateTvShowToKodiLibrary( self, embyId, connection, cursor, viewTag ):
addon = xbmcaddon.Addon(id='plugin.video.emby')
port = addon.getSetting('port')
host = addon.getSetting('ipaddress')
server = host + ":" + port
+ MBitem = ReadEmbyDB().getFullItem(embyId)
+
timeInfo = API().getTimeInfo(MBitem)
userData=API().getUserData(MBitem)
thumbPath = API().getArtwork(MBitem, "Primary")
- playurl = PlayUtils().getPlayUrl(server, MBitem["Id"], MBitem)
- #make sure that the path always ends with a slash
- path = utils.convertEncoding(playurl + "/")
+ # 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"],))
+ result = cursor.fetchone()
+ if result != None:
+ showid = result[0]
+ else:
+ showid = None
+
+ #### TV SHOW DETAILS #########
if MBitem.get("DateCreated") != None:
dateadded = MBitem["DateCreated"].replace("T"," ")
dateadded = dateadded.replace(".0000000Z","")
else:
dateadded = None
-
- #create the tv show 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))
- #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 + "/","")
- cursor.execute("SELECT idPath as tlpathid FROM path WHERE strPath = ?",(toplevelpath,))
- result = cursor.fetchone()
- if result == None:
- cursor.execute("select coalesce(max(idPath),0) as tlpathid from path")
- tlpathid = cursor.fetchone()[0]
- tlpathid = pathid + 1
- pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
- cursor.execute(pathsql, (tlpathid,toplevelpath,"tvshows","metadata.local",1))
+ path = "plugin://plugin.video.emby/tvshows/" + MBitem["Id"] + "/"
-
- runtime = int(timeInfo.get('Duration'))*60
- plot = utils.convertEncoding(API().getOverview(MBitem))
- title = utils.convertEncoding(MBitem["Name"])
- sorttitle = utils.convertEncoding(MBitem["SortName"])
- rating = MBitem.get("CommunityRating")
- #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, c09, c12, c15) values(?, ?, ?, ?, ?, ?, ?)"
- cursor.execute(pathsql, (showid, title, plot, rating, title, MBitem["Id"], sorttitle))
+ #### ADD THE TV SHOW TO KODI ##############
+ if showid == None:
+ #create toplevel path as monitored source - needed for things like actors and stuff to work (no clue why)
+ toplevelpath = "plugin://plugin.video.emby/tvshows/"
+ cursor.execute("SELECT idPath as tlpathid FROM path WHERE strPath = ?",(toplevelpath,))
+ result = cursor.fetchone()
+ if result == None:
+ cursor.execute("select coalesce(max(idPath),0) as tlpathid from path")
+ tlpathid = cursor.fetchone()[0]
+ tlpathid = tlpathid + 1
+ pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)"
+ cursor.execute(pathsql, (tlpathid,toplevelpath,"tvshows","metadata.local",1))
+ else:
+ tlpathid = result[0]
+
+ #create the tv show 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, idParentPath) values(?, ?, ?, ?, ?, ?)"
+ cursor.execute(pathsql, (pathid,path,None,None,1,tlpathid))
+
+ runtime = int(timeInfo.get('Duration'))*60
+ plot = utils.convertEncoding(API().getOverview(MBitem))
+ title = utils.convertEncoding(MBitem["Name"])
+ sorttitle = utils.convertEncoding(MBitem["SortName"])
+ rating = MBitem.get("CommunityRating")
+
+ #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, c09, c15, embyId) values(?, ?, ?, ?, ?, ?, ?)"
+ cursor.execute(pathsql, (showid, title, plot, rating, title, sorttitle, MBitem["Id"]))
+
+ #link the path
+ pathsql="insert into tvshowlinkpath(idShow,idPath) values(?, ?)"
+ cursor.execute(pathsql, (showid,pathid))
- #link the path
- pathsql="insert into tvshowlinkpath(idShow,idPath) values(?, ?)"
- cursor.execute(pathsql, (showid,pathid))
-
- try:
- connection.commit()
- utils.logMsg("Emby","Added TV Show to Kodi Library: " + MBitem["Id"] + " - " + MBitem["Name"])
- except:
- utils.logMsg("Emby","Error adding tvshow to Kodi Library: " + MBitem["Id"] + " - " + MBitem["Name"])
- actionPerformed = False
+ #### UPDATE THE TV SHOW #############
+ else:
+ pathsql="UPDATE tvshow SET (c00 = ?, c01 = ?, c04 = ?, c09 = ?, c15 = ?, embyId = ? WHERE idShow = ?"
+ cursor.execute(pathsql, title, plot, rating, title, sorttitle, MBitem["Id"], showid)
+
+ #update or insert actors
+ self.AddActorsToMedia(showid,MBitem.get("People"),"tvshow", connection, cursor)
- def deleteTVShowFromKodiLibrary(self, id):
- xbmc.sleep(sleepVal)
- kodiItem = ReadKodiDB().getKodiTVShow(id)
- utils.logMsg("deleting tvshow from Kodi library ", "Emby ID : " + id)
-
- if kodiItem != None:
- utils.logMsg("deleting tvshow from Kodi library ", str(kodiItem))
- kodiId = kodiItem["tvshowid"]
- utils.logMsg("deleting tvshow from Kodi library ", "Kodi ID : " + str(kodiId))
- xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.RemoveTVShow", "params": { "tvshowid": %i}, "id": 1 }' %(kodiId))
+ #update season details
+ self.updateSeasons(MBitem["Id"], showid, connection, cursor)
+
+ #commit changes and return the id
+ connection.commit()
+ return showid
+
+ def deleteTVShowFromKodiLibrary(self, id, connection, cursor):
+ utils.logMsg("deleting tvshow from Kodi library --> ",id)
+ cursor.execute("DELETE FROM tvshow WHERE embyId = ?", (id,))
+ connection.commit()
- def updateSeasons(self,MBitem, KodiItem, connection, cursor):
- #use sqlite to set the season details because no method in API available for this
- tvshowid = KodiItem["tvshowid"]
-
- #connection = utils.KodiSQL()
- #cursor = connection.cursor()
+ def updateSeasons(self,embyTvShowId, kodiTvShowId, connection, cursor):
- seasonData = ReadEmbyDB().getTVShowSeasons(MBitem["Id"])
+ seasonData = ReadEmbyDB().getTVShowSeasons(embyTvShowId)
if seasonData != None:
for season in seasonData:
seasonNum = season.get("IndexNumber")
if seasonNum != None and seasonNum >= 0 and seasonNum <= 1000:
- cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(tvshowid, seasonNum))
+ cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(kodiTvShowId, seasonNum))
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, seasonNum))
+ cursor.execute("INSERT into seasons(idSeason, idShow, season) values(?, ?, ?)", (seasonid, kodiTvShowId, seasonNum))
else:
seasonid = result[0]
@@ -1043,7 +824,6 @@ class WriteKodiDB():
imageUrl = API().getArtwork(season, "Banner")
self.updateSeasonArt(imageUrl, seasonid, "banner", cursor)
- connection.commit()
def updateSeasonArt(self, imageUrl, seasonid, imageType, cursor):
updateDone = False
@@ -1129,136 +909,9 @@ class WriteKodiDB():
return changes
'''
-
- def setKodiFilename(self, id, oldFileName, newFileName, fileType, mbId, connection, cursor):
- #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
- #todo --> extend support for musicvideos
-
- actionPerformed = False
-
- oldFileName = utils.convertEncoding(oldFileName)
- newFileName = utils.convertEncoding(newFileName)
-
- # this is required to make sure the paths match
- oldFileName = oldFileName.replace("\\", "/")
-
- # only perform changes if the path actually differs
- if oldFileName != newFileName:
-
- # xbmc.sleep(sleepVal)
- #connection = utils.KodiSQL()
- #cursor = connection.cursor()
- utils.logMsg("Emby","setting filename in kodi db..." + fileType + ": " + str(id))
- utils.logMsg("Emby","old filename -->" + oldFileName)
- utils.logMsg("Emby","new filename -->" + newFileName)
-
- ######### PROCESS TV SHOW ############
- if fileType == "tvshow":
-
- if newFileName.startswith("http"):
- newFileName = "plugin://plugin.video.emby/"
-
- #for tvshows we only store the path in DB
- cursor.execute("SELECT idPath as pathid FROM tvshowlinkpath WHERE idShow = ?",(id,))
- result = cursor.fetchone()
- pathid = result[0]
- cursor.execute("UPDATE path SET strPath = ?, noUpdate = ?, idParentPath = ? WHERE idPath = ?", (newFileName,1,None,pathid))
-
- else:
- # we need to store both the path and the filename seperately in the kodi db so we split them up
-
- if newFileName.startswith("http"):
- #transcoding or play from stream
- path = "plugin://plugin.video.emby/"
- filename = "plugin://plugin.video.emby/?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":
-
- #get the file and the current path id
- cursor.execute("SELECT idFile as fileid FROM episode WHERE idEpisode = ?",(id,))
- result = cursor.fetchone()
- fileid = result[0]
-
- #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))
-
- #set the new path and filename to the episode
- cursor.execute("UPDATE files SET idPath = ?, strFilename = ? WHERE idFile = ?", (pathid,filename,fileid))
-
- ######### PROCESS MOVIE ############
- if fileType == "movie":
- cursor.execute("SELECT idFile as fileid FROM movie WHERE idMovie = ?",(id,))
- result = cursor.fetchone()
- fileid = result[0]
- #write the new filename to the DB
- cursor.execute("UPDATE files SET strFilename = ? WHERE idFile = ?", (filename,fileid))
- #set the new path
- cursor.execute("SELECT idPath as pathid FROM files WHERE idFile = ?",(fileid,))
- result = cursor.fetchone()
- pathid = result[0]
- cursor.execute("UPDATE path SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?, idParentPath = ? WHERE idPath = ?", (path, "movies", "metadata.local", 1, None, pathid))
-
- try:
- connection.commit()
- actionPerformed = True
- except:
- utils.logMsg("Emby","Error setting filename in kodi db for: " + fileType + ": " + str(id))
- actionPerformed = False
-
- return actionPerformed
-
- def AddActorsToMedia(self, KodiItem, people, mediatype, connection, cursor):
- #use sqlite to set add the actors while json api doesn't support this yet
- #todo --> submit PR to kodi team to get this added to the jsonrpc api
-
+ def AddActorsToMedia(self, id, people, mediatype, connection, cursor):
downloadUtils = DownloadUtils()
- if mediatype == "movie":
- id = KodiItem["movieid"]
- if mediatype == "tvshow":
- id = KodiItem["tvshowid"]
- if mediatype == "episode":
- id = KodiItem["episodeid"]
-
- currentcast = list()
- if KodiItem["cast"] != None:
- for cast in KodiItem["cast"]:
- currentcast.append(cast["name"])
-
- needsUpdate = False
- if(people != None):
- for person in people:
- if(person.get("Type") == "Actor"):
- if person.get("Name") not in currentcast:
- needsUpdate = True
- break
-
- if(needsUpdate == False):
- return False
-
- utils.logMsg("AddActorsToMedia", "List needs updating")
kodiVersion = 14
if xbmc.getInfoLabel("System.BuildVersion").startswith("15"):
@@ -1267,61 +920,53 @@ class WriteKodiDB():
if(people != None):
for person in people:
if(person.get("Type") == "Actor"):
- if person.get("Name") not in currentcast:
- utils.logMsg("AddActorsToMedia", "Processing : " + person.get("Name"))
- Name = person.get("Name")
- Role = person.get("Role")
- actorid = None
- Thumb = downloadUtils.imageUrl(person.get("Id"), "Primary", 0, 400, 400)
+ utils.logMsg("AddActorsToMedia", "Processing : " + person.get("Name"))
+ Name = person.get("Name")
+ Role = person.get("Role")
+ actorid = None
+ Thumb = downloadUtils.imageUrl(person.get("Id"), "Primary", 0, 400, 400)
+ if kodiVersion == 15:
+ # Kodi Isengard database #
+ if Thumb != None:
+ Thumb = "" + Thumb + ""
+ cursor.execute("SELECT actor_id as actorid FROM actor WHERE name = ?",(Name,))
+ else:
+ # Kodi Gotham or Helix database #
+ cursor.execute("SELECT idActor as actorid FROM actors WHERE strActor = ?",(Name,))
+ result = cursor.fetchone()
+ if result != None:
+ actorid = result[0]
+ if actorid == None:
if kodiVersion == 15:
# Kodi Isengard database #
- if Thumb != None:
- Thumb = "" + Thumb + ""
- cursor.execute("SELECT actor_id as actorid FROM actor WHERE name = ?",(Name,))
+ cursor.execute("select coalesce(max(actor_id),0) as actorid from actor")
+ actorid = cursor.fetchone()[0]
+ actorid = actorid + 1
+ peoplesql="insert into actor(actor_id, name, art_urls) values(?, ?, ?)"
else:
# Kodi Gotham or Helix database #
- cursor.execute("SELECT idActor as actorid FROM actors WHERE strActor = ?",(Name,))
- result = cursor.fetchone()
- if result != None:
- actorid = result[0]
- if actorid == None:
- if kodiVersion == 15:
- # Kodi Isengard database #
- cursor.execute("select coalesce(max(actor_id),0) as actorid from actor")
- actorid = cursor.fetchone()[0]
- actorid = actorid + 1
- peoplesql="insert into actor(actor_id, name, art_urls) values(?, ?, ?)"
- else:
- # Kodi Gotham or Helix database #
- cursor.execute("select coalesce(max(idActor),0) as actorid from actors")
- actorid = cursor.fetchone()[0]
- actorid = actorid + 1
- peoplesql="insert into actors(idActor, strActor, strThumb) values(?, ?, ?)"
- cursor.execute(peoplesql, (actorid,Name,Thumb))
-
- if kodiVersion == 15:
- # Kodi Isengard database #
- peoplesql="INSERT OR REPLACE into actor_link(actor_id, media_id, media_type, role, cast_order) values(?, ?, ?, ?, ?)"
- cursor.execute(peoplesql, (actorid, id, mediatype, Role, None))
- else:
- # Kodi Gotham or Helix database #
- if mediatype == "movie":
- peoplesql="INSERT OR REPLACE into actorlinkmovie(idActor, idMovie, strRole, iOrder) values(?, ?, ?, ?)"
- if mediatype == "tvshow":
- peoplesql="INSERT OR REPLACE into actorlinktvshow(idActor, idShow, strRole, iOrder) values(?, ?, ?, ?)"
- if mediatype == "episode":
- peoplesql="INSERT OR REPLACE into actorlinkepisode(idActor, idEpisode, strRole, iOrder) values(?, ?, ?, ?)"
- cursor.execute(peoplesql, (actorid,id,Role,None))
-
- connection.commit()
- #cursor.close()
-
- return True
-
+ cursor.execute("select coalesce(max(idActor),0) as actorid from actors")
+ actorid = cursor.fetchone()[0]
+ actorid = actorid + 1
+ peoplesql="insert into actors(idActor, strActor, strThumb) values(?, ?, ?)"
+ cursor.execute(peoplesql, (actorid,Name,Thumb))
+
+ if kodiVersion == 15:
+ # Kodi Isengard database #
+ peoplesql="INSERT OR REPLACE into actor_link(actor_id, media_id, media_type, role, cast_order) values(?, ?, ?, ?, ?)"
+ cursor.execute(peoplesql, (actorid, id, mediatype, Role, None))
+ else:
+ # Kodi Gotham or Helix database #
+ if mediatype == "movie":
+ peoplesql="INSERT OR REPLACE into actorlinkmovie(idActor, idMovie, strRole, iOrder) values(?, ?, ?, ?)"
+ if mediatype == "tvshow":
+ peoplesql="INSERT OR REPLACE into actorlinktvshow(idActor, idShow, strRole, iOrder) values(?, ?, ?, ?)"
+ if mediatype == "episode":
+ peoplesql="INSERT OR REPLACE into actorlinkepisode(idActor, idEpisode, strRole, iOrder) values(?, ?, ?, ?)"
+ cursor.execute(peoplesql, (actorid,id,Role,None))
+
+
def addBoxsetToKodiLibrary(self, boxset, connection, cursor):
- #use sqlite to set add the set
- #connection = utils.KodiSQL()
- #cursor = connection.cursor()
strSet = boxset["Name"]
# check if exists
@@ -1365,7 +1010,7 @@ class WriteKodiDB():
if result != None:
setid = result[0]
connection.commit()
- #cursor.close()
+
return True
diff --git a/service.py b/service.py
index 55c8b664..72d4e045 100644
--- a/service.py
+++ b/service.py
@@ -115,12 +115,10 @@ class Service():
self.logMsg("Doing_Db_Sync: syncDatabase (Started)")
libSync = librarySync.syncDatabase()
self.logMsg("Doing_Db_Sync: syncDatabase (Finished) " + str(libSync))
- countSync = librarySync.updatePlayCounts()
- self.logMsg("Doing_Db_Sync: updatePlayCounts (Finished) " + str(countSync))
# Force refresh newly set thumbnails
xbmc.executebuiltin("UpdateLibrary(video)")
- if(libSync and countSync):
+ if(libSync):
startupComplete = True
else:
if self.KodiMonitor.waitForAbort(10):