New abstract function GetAndProcessXMLs() to be called by all itemtypes while syncing

This commit is contained in:
tomkat83 2016-01-07 20:31:25 +01:00
parent 8c18879271
commit 81f4b514fa

View file

@ -144,10 +144,11 @@ class ThreadedShowSyncInfo(threading.Thread):
total: Total number of items to get total: Total number of items to get
viewName: Name of library we're getting viewName: Name of library we're getting
""" """
def __init__(self, dialog, locks, total, viewName): def __init__(self, dialog, locks, total, viewName, userStop):
self.locks = locks self.locks = locks
self.total = total self.total = total
self.viewName = viewName self.viewName = viewName
self.userStop = userStop
self.addonName = clientinfo.ClientInfo().getAddonName() self.addonName = clientinfo.ClientInfo().getAddonName()
self._shouldstop = threading.Event() self._shouldstop = threading.Event()
self.dialog = dialog self.dialog = dialog
@ -158,7 +159,8 @@ class ThreadedShowSyncInfo(threading.Thread):
downloadLock = self.locks[0] downloadLock = self.locks[0]
processLock = self.locks[1] processLock = self.locks[1]
self.dialog.create( self.dialog.create(
self.addonName + ": Sync " + self.viewName, self.addonName + ": Sync " + self.viewName +
': ' + total + 'items',
"Starting" "Starting"
) )
global getMetadataCount global getMetadataCount
@ -171,7 +173,10 @@ class ThreadedShowSyncInfo(threading.Thread):
with processLock: with processLock:
processMetadataProgress = processMetadataCount processMetadataProgress = processMetadataCount
totalProgress = getMetadataProgress + processMetadataProgress totalProgress = getMetadataProgress + processMetadataProgress
percentage = int(float(totalProgress) / float(total)*100.0) try:
percentage = int(float(totalProgress) / float(total)*100.0)
except ZeroDivisionError:
percentage = 0
self.dialog.update( self.dialog.update(
percentage, percentage,
message="Downloaded: %s, Processed: %s" % message="Downloaded: %s, Processed: %s" %
@ -183,7 +188,7 @@ class ThreadedShowSyncInfo(threading.Thread):
self._shouldstop.set() self._shouldstop.set()
def stopped(self): def stopped(self):
return self._shouldstop.isSet() return self._shouldstop.isSet() or self.userStop()
class LibrarySync(threading.Thread): class LibrarySync(threading.Thread):
@ -236,57 +241,10 @@ class LibrarySync(threading.Thread):
return dialog return dialog
def startSync(self): def startSync(self):
# Run at start up - optional to use the server plugin # Always do a fullSync. It will be faster automatically.
if utils.settings('SyncInstallRunDone') == "true": completed = self.fullSync(manualrun=True)
# Validate views
# self.refreshViews()
completed = False
# Verify if server plugin is installed.
if utils.settings('serverSync') == "true":
# Try to use fast start up
completed = self.fastSync()
if not completed:
# Fast sync failed or server plugin is not found
completed = self.fullSync(manualrun=True)
else:
# Install sync is not completed
completed = self.fullSync()
return completed return completed
def fastSync(self):
lastSync = utils.settings('LastIncrementalSync')
if not lastSync:
lastSync = "2010-01-01T00:00:00Z"
self.logMsg("Last sync run: %s" % lastSync, 1)
url = "{server}/emby/Emby.Kodi.SyncQueue/{UserId}/GetItems?format=json"
params = {'LastUpdateDT': lastSync}
result = self.doUtils.downloadUrl(url, parameters=params)
try:
processlist = {
'added': result['ItemsAdded'],
'update': result['ItemsUpdated'],
'userdata': result['UserDataChanged'],
'remove': result['ItemsRemoved']
}
except (KeyError, TypeError):
self.logMsg("Failed to retrieve latest updates using fast sync.", 1)
return False
else:
self.logMsg("Fast sync changes: %s" % result, 1)
for action in processlist:
self.triage_items(action, processlist[action])
return True
def saveLastSync(self): def saveLastSync(self):
# Save last sync time # Save last sync time
overlap = 2 overlap = 2
@ -342,6 +300,9 @@ class LibrarySync(threading.Thread):
self.logMsg("Commit successful.", 1) self.logMsg("Commit successful.", 1)
def initializeDBs(self): def initializeDBs(self):
"""
Run once during startup to verify that emby db exists.
"""
embyconn = utils.kodiSQL('emby') embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor() embycursor = embyconn.cursor()
# Create the tables for the emby database # Create the tables for the emby database
@ -647,46 +608,19 @@ class LibrarySync(threading.Thread):
# Update the Kodi popup info # Update the Kodi popup info
return self.updatelist, self.allPlexElementsId return self.updatelist, self.allPlexElementsId
def PlexMovies(self): def GetAndProcessXMLs(self, itemType, viewName, viewId):
# Initialize """
plx = PlexAPI.PlexAPI() Downloads all XMLs for itemType (e.g. Movies, TV-Shows). Processes them
compare = self.compare by then calling itemtypes.<itemType>()
self.updatelist = []
self.allPlexElementsId = {}
# Initialze DBs
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
# Get movies from Plex server Input:
emby_db = embydb.Embydb_Functions(embycursor) itemType: to construct itemtypes.py function name: 'Movies'
viewName: Plex name of library, e.g. 'My Movies'
views = plx.GetPlexCollections('movie') viewId: Plex Id for that library
self.logMsg("Media folders: %s" % views, 1)
if compare:
# Pull the list of movies and boxsets in Kodi
try:
self.allKodiElementsId = dict(emby_db.getChecksum('Movie'))
except ValueError:
self.allKodiElementsId = {}
else:
# Getting all metadata, hence set Kodi elements to {}
self.allKodiElementsId = {}
embyconn.close()
##### PROCESS MOVIES #####
for view in views:
self.updatelist = []
if self.shouldStop():
return False
# Get items per view
viewId = view['id']
viewName = view['name']
all_plexmovies = plx.GetPlexSectionResults(viewId)
# Populate self.updatelist and self.allPlexElementsId
self.GetUpdatelist(all_plexmovies)
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
Returns True if/when done
"""
# Some logging, just in case.
self.logMsg("self.updatelist: %s" % self.updatelist, 2) self.logMsg("self.updatelist: %s" % self.updatelist, 2)
self.logMsg("self.allPlexElementsId: %s" % self.allPlexElementsId, 2) self.logMsg("self.allPlexElementsId: %s" % self.allPlexElementsId, 2)
self.logMsg("self.allKodiElementsId: %s" % self.allKodiElementsId, 2) self.logMsg("self.allKodiElementsId: %s" % self.allKodiElementsId, 2)
@ -724,7 +658,7 @@ class LibrarySync(threading.Thread):
self.logMsg("Queue populated", 1) self.logMsg("Queue populated", 1)
# Spawn one more thread to process Metadata, once downloaded # Spawn one more thread to process Metadata, once downloaded
data = { data = {
'itemType': 'Movies', 'itemType': itemType,
'viewName': viewName, 'viewName': viewName,
'viewId': viewId 'viewId': viewId
} }
@ -746,7 +680,8 @@ class LibrarySync(threading.Thread):
dialog, dialog,
[getMetadataLock, processMetadataLock], [getMetadataLock, processMetadataLock],
total, total,
viewName viewName,
self.shouldStop
) )
thread.setDaemon(True) thread.setDaemon(True)
thread.start() thread.start()
@ -767,19 +702,61 @@ class LibrarySync(threading.Thread):
self.logMsg("=====================", 1) self.logMsg("=====================", 1)
self.logMsg("Sync threads finished", 1) self.logMsg("Sync threads finished", 1)
self.logMsg("=====================", 1) self.logMsg("=====================", 1)
##### PROCESS DELETES ##### ##### PROCESS DELETES #####
if compare: if self.compare:
# Manual sync, process deletes # Manual sync, process deletes
itemFkt = getattr(itemtypes, 'Movies') itemFkt = getattr(itemtypes, itemType)
with itemFkt() as item: with itemFkt() as item:
for kodimovie in self.allKodiElementsId: for kodimovie in self.allKodiElementsId:
if kodimovie not in self.allPlexElementsId: if kodimovie not in self.allPlexElementsId:
item.remove(kodimovie) item.remove(kodimovie)
else: else:
self.logMsg("Movies compare finished.", 1) self.logMsg("%s compare finished." % itemType, 1)
return True return True
def PlexMovies(self):
# Initialize
plx = PlexAPI.PlexAPI()
self.updatelist = []
self.allPlexElementsId = {}
views = plx.GetPlexCollections('movie')
self.logMsg("Media folders: %s" % views, 1)
# Get movies from Plex server
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
if self.compare:
# Pull the list of movies and boxsets in Kodi
try:
self.allKodiElementsId = dict(emby_db.getChecksum('Movie'))
except ValueError:
self.allKodiElementsId = {}
else:
# Getting all metadata, hence set Kodi elements to {}
self.allKodiElementsId = {}
embyconn.close()
##### PROCESS MOVIES #####
for view in views:
self.updatelist = []
if self.shouldStop():
return False
# Get items per view
viewId = view['id']
viewName = view['name']
all_plexmovies = plx.GetPlexSectionResults(viewId)
# Populate self.updatelist and self.allPlexElementsId
self.GetUpdatelist(all_plexmovies)
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
# Returns True if successful
result = self.GetAndProcessXMLs('Movies', viewName, viewId)
return result
def movies(self, embycursor, kodicursor, pdialog, compare=False): def movies(self, embycursor, kodicursor, pdialog, compare=False):
# Get movies from emby # Get movies from emby
emby = self.emby emby = self.emby