From 25f5d65343212137cefb5bb9a1f7c729f0896358 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Wed, 30 Dec 2015 13:25:37 +0100 Subject: [PATCH] Movie sync working. --- resources/lib/PlexAPI.py | 23 +++++-- resources/lib/itemtypes.py | 2 +- resources/lib/librarysync.py | 104 ++++++++++++------------------ resources/lib/websocket_client.py | 4 +- resources/settings.xml | 2 +- 5 files changed, 65 insertions(+), 70 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index f325e80b..df836f71 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -1281,15 +1281,23 @@ class PlexAPI(): try: result = jsondata['_children'] except KeyError: + self.logMsg("Error retrieving all movies for section %s" % viewId, 1) pass return result def GetPlexMetadata(self, key): """ Returns raw API metadata for key. + + Can be called with either Plex key '/library/metadata/xxxx'metadata + OR with the digits 'xxxx' only. """ result = [] - url = "{server}" + key + key = str(key) + if '/library/metadata/' in key: + url = "{server}" + key + else: + url = "{server}/library/metadata/" + key jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['_children'][0] @@ -1339,23 +1347,28 @@ class API(): def getChecksum(self): """ + Returns a string, not int! Maybe get rid of viewOffset = (resume point)?!? """ item = self.item - checksum = "%s%s%s%s%s" % ( - item['key'], + # Include a letter to prohibit saving as an int! + checksum = "K%s%s%s%s%s" % ( + self.getKey(), item['updatedAt'], item.get('viewCount', ""), item.get('lastViewedAt', ""), item.get('viewOffset', "") ) - return checksum + return str(checksum) def getKey(self): + """ + Returns the Plex unique movie id as a str, not int + """ item = self.item key_regex = re.compile(r'/(\d+)$') key = key_regex.findall(item['key'])[0] - return int(key) + return str(key) def getDateCreated(self): item = self.item diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 337b277e..f609cb83 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -313,7 +313,7 @@ class Movies(Items): plot = item.get('summary', None) shortplot = None tagline = item.get('tagline', None) - votecount = 0 + votecount = None rating = item.get('audienceRating', None) year = item.get('year', None) imdb = API.getProvider('Imdb') diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index f65679f1..8d02b493 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -466,120 +466,102 @@ class LibrarySync(threading.Thread): def PlexMovies(self, embycursor, kodicursor, pdialog, compare=False): - # Get movies from emby + plx = PlexAPI.PlexAPI() + # Get movies from Plex server emby = self.emby emby_db = embydb.Embydb_Functions(embycursor) movies = itemtypes.Movies(embycursor, kodicursor) - views = self.plx.GetPlexCollections('movies') - self.logMsg("Media folders: %s" % views, 1) + views = plx.GetPlexCollections('movie') + self.logMsg("Movie folders found: %s" % views, 1) if compare: # Pull the list of movies and boxsets in Kodi try: - all_kodimovies = dict(emby_db.getChecksum('Movie')) + all_kodimoviesId = dict(emby_db.getChecksum('Movie')) except ValueError: - all_kodimovies = {} - - try: - all_kodisets = dict(emby_db.getChecksum('BoxSet')) - except ValueError: - all_kodisets = {} - - all_embymoviesIds = set() - all_embyboxsetsIds = set() - updatelist = [] + all_kodimoviesId = {} + self.logMsg("all_kodimoviesId: %s " % (all_kodimoviesId), 1) + all_plexmoviesIds = [] + updatelist = [] + plexmovies = [] ##### PROCESS MOVIES ##### for view in views: - if self.shouldStop(): return False - # Get items per view viewId = view['id'] viewName = view['name'] - if pdialog: pdialog.update( - heading=self.addonName, - message="Gathering movies from view: %s..." % viewName) + heading=self.addonName, + message="Gathering movies from view: %s..." % viewName + ) + all_plexmovies = plx.GetPlexSectionResults(viewId) if compare: # Manual sync if pdialog: pdialog.update( - heading=self.addonName, - message="Comparing movies from view: %s..." % viewName) - - all_embymovies = self.plx.GetPlexSectionResults(viewId) - embymovies = [] - for embymovie in all_embymovies: - + heading=self.addonName, + message="Comparing movies from view: %s..." % viewName + ) + for plexmovie in all_plexmovies[0:10]: if self.shouldStop(): return False - - API = PlexAPI.API(embymovie) + API = PlexAPI.API(plexmovie) + plex_checksum = API.getChecksum() itemid = API.getKey() - all_embymoviesIds.add(itemid) - - if all_kodimovies.get(itemid) != API.getChecksum(): + kodi_checksum = all_kodimoviesId.get(itemid) + all_plexmoviesIds.append(plex_checksum) + if kodi_checksum != plex_checksum: + self.logMsg("Kodimovie unequal to Embymovie: %s %s" % (kodi_checksum, plex_checksum), 2) # Only update if movie is not in Kodi or checksum is different updatelist.append(itemid) - embymovies.append(embymovie) - - self.logMsg("Movies to update for %s: %s" % (viewName, updatelist), 1) - total = len(updatelist) - del updatelist[:] else: - # Initial or repair sync - embymovies = self.plx.GetPlexSectionResults(viewId) - total = len(embymovies) + # Initial or repair sync: get all Plex movies + for plexmovie in all_plexmovies[0:10]: + API = PlexAPI.API(plexmovie) + itemid = API.getKey() + plex_checksum = API.getChecksum() + all_plexmoviesIds.append(plex_checksum) + updatelist.append(itemid) + self.logMsg("Movies to update for %s: %s" % (viewName, updatelist), 1) + # Get individual metadata for all movies that we need to sync + # This is possibly a huge list! + for itemid in updatelist: + plexmovie = plx.GetPlexMetadata(itemid) + plexmovies.append(plexmovie) + total = len(plexmovies) if pdialog: pdialog.update(heading="Processing %s / %s items" % (viewName, total)) count = 0 - # DELETE ME WHEN DONE TESTING!! - embymovies = embymovies[0:10] - for embymovie in embymovies: + for plexmovie in plexmovies: # Process individual movies if self.shouldStop(): return False - - title = embymovie['title'] + title = plexmovie['title'] if pdialog: percentage = int((float(count) / float(total))*100) pdialog.update(percentage, message=title) count += 1 - detailed = self.plx.GetPlexMetadata(embymovie['key']) - movies.add_update(detailed, viewName, viewId) + movies.add_update(plexmovie, viewName, viewId) else: self.logMsg("Movies finished.", 2) ##### PROCESS DELETES ##### if compare: - self.logMsg("all_kodimovies: %s" % all_kodimovies, 1) - self.logMsg("all_embymovies: %s" % all_embymoviesIds, 1) # Manual sync, process deletes - for kodimovie in all_kodimovies: - if kodimovie not in all_embymoviesIds: + for kodimovie, checksum in all_kodimoviesId.items(): + if checksum not in all_plexmoviesIds: movies.remove(kodimovie) else: self.logMsg("Movies compare finished.", 1) - - for boxset in all_kodisets: - if boxset not in all_embyboxsetsIds: - movies.remove(boxset) - else: - self.logMsg("Boxsets compare finished.", 1) - return True - - - - def movies(self, embycursor, kodicursor, pdialog, compare=False): # Get movies from emby emby = self.emby diff --git a/resources/lib/websocket_client.py b/resources/lib/websocket_client.py index 3ba8849f..db7eca9d 100644 --- a/resources/lib/websocket_client.py +++ b/resources/lib/websocket_client.py @@ -288,8 +288,8 @@ class WebSocket_Client(threading.Thread): else: server = server.replace('http', "ws") #EDIT: realized the ws url is at: ws://server.local:32400/:/websockets/notifications - - websocket_url = "%s/:/websockets/notifications/?X-Plex-Token=%s" % (server, token) + websocket_url = "" + # websocket_url = "%s/:/websockets/notifications/?X-Plex-Token=%s" % (server, token) self.logMsg("websocket url: %s" % websocket_url, 1) self.client = websocket.WebSocketApp(websocket_url, diff --git a/resources/settings.xml b/resources/settings.xml index 27941ef4..2dc4b0c3 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -62,7 +62,7 @@ - +