jellyfin-kodi/resources/lib/LibrarySync.py
2015-03-26 16:33:31 +00:00

1039 lines
No EOL
47 KiB
Python

#################################################################################################
# LibrarySync
#################################################################################################
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import json
import sqlite3
import inspect
import threading
import urllib
from datetime import datetime, timedelta, time
import urllib2
import os
from API import API
import Utils as utils
from DownloadUtils import DownloadUtils
from ReadEmbyDB import ReadEmbyDB
from ReadKodiDB import ReadKodiDB
from WriteKodiDB import WriteKodiDB
from CreateFiles import CreateFiles
addondir = xbmc.translatePath(xbmcaddon.Addon(id='plugin.video.emby').getAddonInfo('profile'))
dataPath = os.path.join(addondir,"library")
movieLibrary = os.path.join(dataPath,'movies')
tvLibrary = os.path.join(dataPath,'tvshows')
class LibrarySync():
def syncDatabase(self):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window( 10000 )
pDialog = None
#set some variable to check if this is the first run
startupDone = False
startupStr = WINDOW.getProperty("startup")
if startupStr == "done":
startupDone = True
#are we running startup sync or background sync ?
#if not startupDone:
# syncOption = addon.getSetting("syncSettingStartup")
#else:
# syncOption = addon.getSetting("syncSettingBackground")
#what sync method to perform ?
#if syncOption == "Full Sync":
#pr = utils.startProfiling()
# self.MoviesSync(True)
#utils.stopProfiling(pr, "MoviesSync(True)")
#pr = utils.startProfiling()
# self.TvShowsSync(True)
#utils.stopProfiling(pr, "TvShowsSync(True)")
#pr = utils.startProfiling()
# self.MusicVideosSync(True)
#utils.stopProfiling(pr, "MusicVideosSync(True)")
#if syncOption == "Incremental Sync":
# self.MoviesSync(False)
# self.TvShowsSync(False)
# self.MusicVideosSync(False)
# Do incremental sync followed by full sync
if not startupDone:
self.MoviesSync(True)
self.TvShowsSync(True)
self.MusicVideosSync(True)
else:
self.MoviesSync(False)
self.TvShowsSync(False)
self.MusicVideosSync(False)
self.MoviesSync(True)
self.TvShowsSync(True)
self.MusicVideosSync(True)
WINDOW.setProperty("startup", "done")
return True
def MoviesSync(self, fullsync=True):
WINDOW = xbmcgui.Window( 10000 )
pDialog = None
startedSync = datetime.today()
try:
addon = xbmcaddon.Addon(id='plugin.video.emby')
dbSyncIndication = addon.getSetting("dbSyncIndication")
dbSyncFirstRun = addon.getSetting("SyncFirstMovieRunDone")
if(dbSyncFirstRun != "true" 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:
updateNeeded = False
#process new movies
allMB3Movies = ReadEmbyDB().getMovies(view.get('id'), True, fullsync)
allKodiIds = set(ReadKodiDB().getKodiMoviesIds(True))
if(self.ShouldStop(pDialog)):
return True
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)
updateNeeded = True
totalItemsAdded += 1
if(self.ShouldStop(pDialog)):
return True
# update progress bar
if(pDialog != None):
percentage = int(((float(count) / float(total)) * 100))
pDialog.update(percentage, progressTitle, "Adding Movie: " + str(count))
count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(self.ShouldStop(pDialog)):
return True
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'))
kodimovie = allKodiMovies.get(item["Id"], None)
if(kodimovie != None):
#WriteKodiDB().updateMovieToKodiLibrary(item, kodimovie)
updated = WriteKodiDB().updateMovieToKodiLibrary_Batched(item, kodimovie)
if(updated):
totalItemsUpdated += 1
if(self.ShouldStop(pDialog)):
return True
# 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 and addon.getSetting("syncMovieBoxSets") == "true":
utils.logMsg("Sync Movies", "BoxSet Sync Started", 1)
boxsets = ReadEmbyDB().getBoxSets()
for boxset in boxsets:
if(self.ShouldStop(pDialog)):
return True
boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"])
WriteKodiDB().addBoxsetToKodiLibrary(boxset)
for boxsetMovie in boxsetMovies:
if(self.ShouldStop(pDialog)):
return True
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 True
cleanNeeded = 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)
cleanNeeded = True
totalItemsDeleted += 1
if(self.ShouldStop(pDialog)):
return True
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
if(dbSyncFirstRun != "true"):
addon = xbmcaddon.Addon(id='plugin.video.emby') #force a new instance of the addon
addon.setSetting("SyncFirstMovieRunDone", "true")
# 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()
return True
def TvShowsSync(self, fullsync=True):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window( 10000 )
pDialog = None
startedSync = datetime.today()
try:
dbSyncIndication = addon.getSetting("dbSyncIndication")
dbSyncFirstRun = addon.getSetting("SyncFirstTVRunDone")
if(dbSyncFirstRun != "true" 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
progressTitle = "Sync DB : Processing Episodes"
# incremental sync --> new episodes only
if not fullsync:
latestMBEpisodes = ReadEmbyDB().getLatestEpisodes(True)
if latestMBEpisodes != None:
allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True))
updateNeeded = False
if(pDialog != None):
pDialog.update(0, progressTitle)
total = len(latestMBEpisodes) + 1
count = 1
# process new episodes
for episode in latestMBEpisodes:
if episode["SeriesId"] in allKodiTvShowsIds:
#only process tvshows that already exist in the db at incremental updates
kodiEpisodes = ReadKodiDB().getKodiEpisodes(episode["SeriesId"],True,True)
if(self.ShouldStop(pDialog)):
return True
#we have to compare the lists somehow
comparestring1 = str(episode.get("ParentIndexNumber")) + "-" + str(episode.get("IndexNumber"))
matchFound = False
if kodiEpisodes != None:
KodiItem = kodiEpisodes.get(comparestring1, None)
if(KodiItem != None):
matchFound = True
progressAction = "Checking"
if not matchFound:
#no match so we have to create it
WriteKodiDB().addEpisodeToKodiLibrary(episode)
updateNeeded = True
progressAction = "Adding"
totalItemsAdded += 1
if(self.ShouldStop(pDialog)):
return True
# update progress bar
if(pDialog != None):
percentage = int(((float(count) / float(total)) * 100))
pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count))
count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
self.doKodiLibraryUpdate(False, pDialog)
updateNeeded = False
#process updates
if(pDialog != None):
progressTitle = "Sync DB : Processing Episodes"
pDialog.update(0, progressTitle)
total = len(latestMBEpisodes) + 1
count = 1
for episode in latestMBEpisodes:
if episode["SeriesId"] in allKodiTvShowsIds:
#only process tvshows that already exist in the db at incremental updates
kodiEpisodes = ReadKodiDB().getKodiEpisodes(episode["SeriesId"],True,True)
if(self.ShouldStop(pDialog)):
return True
#we have to compare the lists somehow
comparestring1 = str(episode.get("ParentIndexNumber")) + "-" + str(episode.get("IndexNumber"))
if kodiEpisodes != None:
KodiItem = kodiEpisodes.get(comparestring1, None)
if(KodiItem != None):
WriteKodiDB().updateEpisodeToKodiLibrary(episode, KodiItem)
if(self.ShouldStop(pDialog)):
return True
# 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:
allTVShows = list()
allMB3EpisodeIds = list() #for use with deletions
allKodiEpisodeIds = [] # for use with deletions
tvShowData = ReadEmbyDB().getTVShows(True,True)
allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True))
updateNeeded = False
if(self.ShouldStop(pDialog)):
return True
if (tvShowData == None):
return
if(pDialog != None):
progressTitle = "Sync DB : Processing TV Shows"
pDialog.update(0, progressTitle)
total = len(tvShowData) + 1
count = 1
for item in tvShowData:
if item.get('IsFolder'):
allTVShows.append(item["Id"])
progMessage = "Processing"
if item["Id"] not in allKodiIds:
WriteKodiDB().addTVShowToKodiLibrary(item)
updateNeeded = True
totalItemsAdded += 1
if(self.ShouldStop(pDialog)):
return True
# update progress bar
if(pDialog != None):
percentage = int(((float(count) / float(total)) * 100))
pDialog.update(percentage, progressTitle, "Adding Tv Show: " + str(count))
count += 1
#process episodes first before updating tvshows
allEpisodes = list()
showTotal = len(allTVShows)
showCurrent = 1
# do episode adds
for tvshow in allTVShows:
episodeData = ReadEmbyDB().getEpisodes(tvshow,True)
kodiEpisodes = ReadKodiDB().getKodiEpisodes(tvshow,True,True)
if episodeData != None:
if(self.ShouldStop(pDialog)):
return True
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:
comparestring1 = str(item.get("ParentIndexNumber")) + "-" + str(item.get("IndexNumber"))
matchFound = False
if kodiEpisodes != None:
KodiItem = kodiEpisodes.get(comparestring1, None)
if(KodiItem != None):
matchFound = True
progressAction = "Checking"
if not matchFound:
#no match so we have to create it
WriteKodiDB().addEpisodeToKodiLibrary(item)
updateNeeded = True
progressAction = "Adding"
totalItemsAdded += 1
if(self.ShouldStop(pDialog)):
return True
# 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
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
updateNeeded = False
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(pDialog != None):
progressTitle = "Sync DB : Processing TV Shows"
pDialog.update(0, progressTitle, "")
total = len(allTVShows) + 1
count = 1
#process updates at TV Show level
allKodiTVShows = ReadKodiDB().getKodiTvShows(True)
for item in tvShowData:
if item.get('IsFolder'):
kodishow = allKodiTVShows.get(item["Id"],None)
if(kodishow != None):
updated = WriteKodiDB().updateTVShowToKodiLibrary(item,kodishow)
if(updated):
totalItemsUpdated += 1
if(self.ShouldStop(pDialog)):
return True
# 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 updates
showCurrent = 1
for tvshow in allTVShows:
episodeData = ReadEmbyDB().getEpisodes(tvshow,True)
kodiEpisodes = ReadKodiDB().getKodiEpisodes(tvshow,True,True)
if(self.ShouldStop(pDialog)):
return True
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"])
comparestring1 = str(item.get("ParentIndexNumber")) + "-" + str(item.get("IndexNumber"))
matchFound = False
if kodiEpisodes != None:
KodiItem = kodiEpisodes.get(comparestring1, None)
if(KodiItem != None):
updated = WriteKodiDB().updateEpisodeToKodiLibrary(item, KodiItem)
if(updated):
totalItemsUpdated += 1
if(self.ShouldStop(pDialog)):
return True
# 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
show = ReadKodiDB().getKodiEpisodes(tvshow,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 True
cleanNeeded = False
# DELETES -- EPISODES
# process any deletes only at fullsync
allMB3EpisodeIds = set(allMB3EpisodeIds)
for episode in allKodiEpisodeIds:
if episode.get('episodeid') not in allMB3EpisodeIds:
WINDOW.setProperty(episode.get('episodeid'),"deleted")
WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid'))
cleanneeded = True
totalItemsDeleted += 1
# DELETES -- TV SHOWS
if fullsync:
allLocaldirs, filesTVShows = xbmcvfs.listdir(tvLibrary)
allMB3TVShows = set(allTVShows)
for dir in allLocaldirs:
if not dir in allMB3TVShows:
WriteKodiDB().deleteTVShowFromKodiLibrary(dir)
cleanneeded = True
totalItemsDeleted += 1
if(self.ShouldStop(pDialog)):
return True
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
if(dbSyncFirstRun != "true"):
addon = xbmcaddon.Addon(id='plugin.video.emby') #force a new instance of the addon
addon.setSetting("SyncFirstTVRunDone", "true")
# 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=True):
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window( 10000 )
pDialog = None
try:
dbSyncIndication = addon.getSetting("dbSyncIndication")
dbSyncFirstRun = addon.getSetting("SyncFirstMusicVideoRunDone")
if(dbSyncFirstRun != "true" or dbSyncIndication == "Dialog Progress"):
pDialog = xbmcgui.DialogProgress()
elif(dbSyncIndication == "BG Progress"):
pDialog = xbmcgui.DialogProgressBG()
if(pDialog != None):
pDialog.create('Sync DB', 'Sync DB')
allEmbyMusicVideoIds = list()
progressTitle = ""
updateNeeded = False
#process new musicvideos
allMB3MusicVideos = ReadEmbyDB().getMusicVideos(True, fullsync)
allKodiIds = set(ReadKodiDB().getKodiMusicVideoIds(True))
if(self.ShouldStop(pDialog)):
return True
if(allMB3MusicVideos == None):
return False
if(pDialog != None):
progressTitle = "Sync DB : Processing Musicvideos"
pDialog.update(0, progressTitle)
total = len(allMB3MusicVideos) + 1
count = 1
for item in allMB3MusicVideos:
if not item.get('IsFolder'):
allEmbyMusicVideoIds.append(item["Id"])
if item["Id"] not in allKodiIds:
WriteKodiDB().addMusicVideoToKodiLibrary(item)
updateNeeded = True
if(self.ShouldStop(pDialog)):
return True
# update progress bar
if(pDialog != None):
percentage = int(((float(count) / float(total)) * 100))
pDialog.update(percentage, progressTitle, "Adding Musicvideo: " + str(count))
count += 1
#initiate library update and wait for finish before processing any updates
if updateNeeded:
if(pDialog != None):
pDialog.update(0, "Processing New Items", "Importing STRM Files")
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.close()
self.doKodiLibraryUpdate(False, pDialog)
if(pDialog != None and type(pDialog) == xbmcgui.DialogProgressBG):
pDialog.create('Sync DB', 'Sync DB')
if(self.ShouldStop(pDialog)):
return True
if(pDialog != None):
progressTitle = "Sync DB : Processing musicvideos"
pDialog.update(0, progressTitle, "")
total = len(allMB3MusicVideos) + 1
count = 1
#process updates
allKodiMusicVideos = ReadKodiDB().getKodiMusicVideos(True)
for item in allMB3MusicVideos:
if not item.get('IsFolder'):
kodimusicvideo = allKodiMusicVideos.get(item["Id"], None)
if(kodimusicvideo != None):
#WriteKodiDB().updateMusicVideoToKodiLibrary(item, kodimusicvideo)
WriteKodiDB().updateMusicVideoToKodiLibrary_Batched(item, kodimusicvideo)
if(self.ShouldStop(pDialog)):
return True
# update progress bar
if(pDialog != None):
percentage = int(((float(count) / float(total)) * 100))
pDialog.update(percentage, progressTitle, "Updating MusicVideo: " + str(count))
count += 1
if(pDialog != None):
progressTitle = "Removing Deleted Items"
pDialog.update(0, progressTitle, "")
if(self.ShouldStop(pDialog)):
return True
cleanNeeded = False
# process any deletes only at fullsync
if fullsync:
allKodiIds = ReadKodiDB().getKodiMusicVideoIds(True)
allEmbyMusicVideoIds = set(allEmbyMusicVideoIds)
for kodiId in allKodiIds:
if not kodiId in allEmbyMusicVideoIds:
WriteKodiDB().deleteMusicVideoFromKodiLibrary(kodiId)
cleanNeeded = True
if(self.ShouldStop(pDialog)):
return True
#initiate library clean and wait for finish before processing any updates
if cleanNeeded:
self.doKodiLibraryUpdate(True, pDialog)
if(dbSyncFirstRun != "true"):
addon = xbmcaddon.Addon(id='plugin.video.emby')
addon.setSetting("SyncFirstMusicVideoRunDone", "true")
finally:
if(pDialog != None):
pDialog.close()
return True
def doKodiLibraryUpdate(self, clean, prog):
#initiate library update and wait for finish before processing any updates
if clean:
xbmc.executebuiltin("CleanLibrary(video)")
else:
xbmc.executebuiltin("UpdateLibrary(video)")
xbmc.sleep(1000)
while (xbmc.getCondVisibility("Library.IsScanningVideo")):
if(self.ShouldStop(prog)):
return True
xbmc.sleep(1000)
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
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 True
if(allMB3Movies == None):
return False
if(allKodiMovies == None):
return False
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 True
# 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", "")
tvshowData = ReadEmbyDB().getTVShows(fullinfo = False, fullSync = True)
if(self.ShouldStop(pDialog)):
return True
if (tvshowData == None):
return False
showTotal = len(tvshowData)
showCurrent = 1
for item in tvshowData:
episodeData = ReadEmbyDB().getEpisodes(item["Id"], False)
kodiEpisodes = ReadKodiDB().getKodiEpisodes(item["Id"],False,True)
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
comparestring1 = str(episode.get("ParentIndexNumber")) + "-" + str(episode.get("IndexNumber"))
matchFound = False
if kodiEpisodes != None:
kodiItem = kodiEpisodes.get(comparestring1, 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'))
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 True
# 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:
if(pDialog != None):
pDialog.close()
return True
def updatePlayCount(self,itemID,type):
#update playcount of the itemID from MB3 to Kodi library
addon = xbmcaddon.Addon(id='plugin.video.emby')
WINDOW = xbmcgui.Window( 10000 )
#process movie
if type=='Movie':
MB3Movie = ReadEmbyDB().getItem(itemID)
kodiItem = ReadKodiDB().getKodiMovie(itemID)
if(self.ShouldStop(None)):
return True
if(MB3Movie == None):
return False
if(kodiItem == None):
return False
userData=API().getUserData(MB3Movie)
timeInfo = API().getTimeInfo(MB3Movie)
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")
#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 True
#process episode
elif type=='Episode':
if(self.ShouldStop(None)):
return True
MB3Episode = ReadEmbyDB().getItem(itemID)
kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(MB3Episode["Id"], MB3Episode["SeriesId"])
if (MB3Episode != None):
userData=API().getUserData(MB3Episode)
timeInfo = API().getTimeInfo(MB3Episode)
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")
if(self.ShouldStop(None)):
return True
return True
def ShouldStop(self, prog):
if(prog != None and type(prog) == xbmcgui.DialogProgress):
if(prog.iscanceled() == True):
return True
if(xbmc.Player().isPlaying() or xbmc.abortRequested):
return True
else:
return False