Movie sync working.
This commit is contained in:
parent
54a20f0b13
commit
25f5d65343
5 changed files with 65 additions and 70 deletions
|
@ -1281,15 +1281,23 @@ class PlexAPI():
|
||||||
try:
|
try:
|
||||||
result = jsondata['_children']
|
result = jsondata['_children']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
self.logMsg("Error retrieving all movies for section %s" % viewId, 1)
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def GetPlexMetadata(self, key):
|
def GetPlexMetadata(self, key):
|
||||||
"""
|
"""
|
||||||
Returns raw API metadata for 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 = []
|
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)
|
jsondata = self.doUtils.downloadUrl(url)
|
||||||
try:
|
try:
|
||||||
result = jsondata['_children'][0]
|
result = jsondata['_children'][0]
|
||||||
|
@ -1339,23 +1347,28 @@ class API():
|
||||||
|
|
||||||
def getChecksum(self):
|
def getChecksum(self):
|
||||||
"""
|
"""
|
||||||
|
Returns a string, not int!
|
||||||
Maybe get rid of viewOffset = (resume point)?!?
|
Maybe get rid of viewOffset = (resume point)?!?
|
||||||
"""
|
"""
|
||||||
item = self.item
|
item = self.item
|
||||||
checksum = "%s%s%s%s%s" % (
|
# Include a letter to prohibit saving as an int!
|
||||||
item['key'],
|
checksum = "K%s%s%s%s%s" % (
|
||||||
|
self.getKey(),
|
||||||
item['updatedAt'],
|
item['updatedAt'],
|
||||||
item.get('viewCount', ""),
|
item.get('viewCount', ""),
|
||||||
item.get('lastViewedAt', ""),
|
item.get('lastViewedAt', ""),
|
||||||
item.get('viewOffset', "")
|
item.get('viewOffset', "")
|
||||||
)
|
)
|
||||||
return checksum
|
return str(checksum)
|
||||||
|
|
||||||
def getKey(self):
|
def getKey(self):
|
||||||
|
"""
|
||||||
|
Returns the Plex unique movie id as a str, not int
|
||||||
|
"""
|
||||||
item = self.item
|
item = self.item
|
||||||
key_regex = re.compile(r'/(\d+)$')
|
key_regex = re.compile(r'/(\d+)$')
|
||||||
key = key_regex.findall(item['key'])[0]
|
key = key_regex.findall(item['key'])[0]
|
||||||
return int(key)
|
return str(key)
|
||||||
|
|
||||||
def getDateCreated(self):
|
def getDateCreated(self):
|
||||||
item = self.item
|
item = self.item
|
||||||
|
|
|
@ -313,7 +313,7 @@ class Movies(Items):
|
||||||
plot = item.get('summary', None)
|
plot = item.get('summary', None)
|
||||||
shortplot = None
|
shortplot = None
|
||||||
tagline = item.get('tagline', None)
|
tagline = item.get('tagline', None)
|
||||||
votecount = 0
|
votecount = None
|
||||||
rating = item.get('audienceRating', None)
|
rating = item.get('audienceRating', None)
|
||||||
year = item.get('year', None)
|
year = item.get('year', None)
|
||||||
imdb = API.getProvider('Imdb')
|
imdb = API.getProvider('Imdb')
|
||||||
|
|
|
@ -466,120 +466,102 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
def PlexMovies(self, embycursor, kodicursor, pdialog, compare=False):
|
def PlexMovies(self, embycursor, kodicursor, pdialog, compare=False):
|
||||||
# Get movies from emby
|
plx = PlexAPI.PlexAPI()
|
||||||
|
# Get movies from Plex server
|
||||||
emby = self.emby
|
emby = self.emby
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
emby_db = embydb.Embydb_Functions(embycursor)
|
||||||
movies = itemtypes.Movies(embycursor, kodicursor)
|
movies = itemtypes.Movies(embycursor, kodicursor)
|
||||||
|
|
||||||
views = self.plx.GetPlexCollections('movies')
|
views = plx.GetPlexCollections('movie')
|
||||||
self.logMsg("Media folders: %s" % views, 1)
|
self.logMsg("Movie folders found: %s" % views, 1)
|
||||||
|
|
||||||
if compare:
|
if compare:
|
||||||
# Pull the list of movies and boxsets in Kodi
|
# Pull the list of movies and boxsets in Kodi
|
||||||
try:
|
try:
|
||||||
all_kodimovies = dict(emby_db.getChecksum('Movie'))
|
all_kodimoviesId = dict(emby_db.getChecksum('Movie'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodimovies = {}
|
all_kodimoviesId = {}
|
||||||
|
self.logMsg("all_kodimoviesId: %s " % (all_kodimoviesId), 1)
|
||||||
try:
|
all_plexmoviesIds = []
|
||||||
all_kodisets = dict(emby_db.getChecksum('BoxSet'))
|
updatelist = []
|
||||||
except ValueError:
|
plexmovies = []
|
||||||
all_kodisets = {}
|
|
||||||
|
|
||||||
all_embymoviesIds = set()
|
|
||||||
all_embyboxsetsIds = set()
|
|
||||||
updatelist = []
|
|
||||||
|
|
||||||
##### PROCESS MOVIES #####
|
##### PROCESS MOVIES #####
|
||||||
for view in views:
|
for view in views:
|
||||||
|
|
||||||
if self.shouldStop():
|
if self.shouldStop():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
viewName = view['name']
|
viewName = view['name']
|
||||||
|
|
||||||
if pdialog:
|
if pdialog:
|
||||||
pdialog.update(
|
pdialog.update(
|
||||||
heading=self.addonName,
|
heading=self.addonName,
|
||||||
message="Gathering movies from view: %s..." % viewName)
|
message="Gathering movies from view: %s..." % viewName
|
||||||
|
)
|
||||||
|
all_plexmovies = plx.GetPlexSectionResults(viewId)
|
||||||
|
|
||||||
if compare:
|
if compare:
|
||||||
# Manual sync
|
# Manual sync
|
||||||
if pdialog:
|
if pdialog:
|
||||||
pdialog.update(
|
pdialog.update(
|
||||||
heading=self.addonName,
|
heading=self.addonName,
|
||||||
message="Comparing movies from view: %s..." % viewName)
|
message="Comparing movies from view: %s..." % viewName
|
||||||
|
)
|
||||||
all_embymovies = self.plx.GetPlexSectionResults(viewId)
|
for plexmovie in all_plexmovies[0:10]:
|
||||||
embymovies = []
|
|
||||||
for embymovie in all_embymovies:
|
|
||||||
|
|
||||||
if self.shouldStop():
|
if self.shouldStop():
|
||||||
return False
|
return False
|
||||||
|
API = PlexAPI.API(plexmovie)
|
||||||
API = PlexAPI.API(embymovie)
|
plex_checksum = API.getChecksum()
|
||||||
itemid = API.getKey()
|
itemid = API.getKey()
|
||||||
all_embymoviesIds.add(itemid)
|
kodi_checksum = all_kodimoviesId.get(itemid)
|
||||||
|
all_plexmoviesIds.append(plex_checksum)
|
||||||
if all_kodimovies.get(itemid) != API.getChecksum():
|
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
|
# Only update if movie is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
embymovies.append(embymovie)
|
|
||||||
|
|
||||||
self.logMsg("Movies to update for %s: %s" % (viewName, updatelist), 1)
|
|
||||||
total = len(updatelist)
|
|
||||||
del updatelist[:]
|
|
||||||
else:
|
else:
|
||||||
# Initial or repair sync
|
# Initial or repair sync: get all Plex movies
|
||||||
embymovies = self.plx.GetPlexSectionResults(viewId)
|
for plexmovie in all_plexmovies[0:10]:
|
||||||
total = len(embymovies)
|
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:
|
if pdialog:
|
||||||
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
|
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
# DELETE ME WHEN DONE TESTING!!
|
for plexmovie in plexmovies:
|
||||||
embymovies = embymovies[0:10]
|
|
||||||
for embymovie in embymovies:
|
|
||||||
# Process individual movies
|
# Process individual movies
|
||||||
if self.shouldStop():
|
if self.shouldStop():
|
||||||
return False
|
return False
|
||||||
|
title = plexmovie['title']
|
||||||
title = embymovie['title']
|
|
||||||
if pdialog:
|
if pdialog:
|
||||||
percentage = int((float(count) / float(total))*100)
|
percentage = int((float(count) / float(total))*100)
|
||||||
pdialog.update(percentage, message=title)
|
pdialog.update(percentage, message=title)
|
||||||
count += 1
|
count += 1
|
||||||
detailed = self.plx.GetPlexMetadata(embymovie['key'])
|
movies.add_update(plexmovie, viewName, viewId)
|
||||||
movies.add_update(detailed, viewName, viewId)
|
|
||||||
else:
|
else:
|
||||||
self.logMsg("Movies finished.", 2)
|
self.logMsg("Movies finished.", 2)
|
||||||
|
|
||||||
##### PROCESS DELETES #####
|
##### PROCESS DELETES #####
|
||||||
if compare:
|
if compare:
|
||||||
self.logMsg("all_kodimovies: %s" % all_kodimovies, 1)
|
|
||||||
self.logMsg("all_embymovies: %s" % all_embymoviesIds, 1)
|
|
||||||
# Manual sync, process deletes
|
# Manual sync, process deletes
|
||||||
for kodimovie in all_kodimovies:
|
for kodimovie, checksum in all_kodimoviesId.items():
|
||||||
if kodimovie not in all_embymoviesIds:
|
if checksum not in all_plexmoviesIds:
|
||||||
movies.remove(kodimovie)
|
movies.remove(kodimovie)
|
||||||
else:
|
else:
|
||||||
self.logMsg("Movies compare finished.", 1)
|
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -288,8 +288,8 @@ class WebSocket_Client(threading.Thread):
|
||||||
else:
|
else:
|
||||||
server = server.replace('http', "ws")
|
server = server.replace('http', "ws")
|
||||||
#EDIT: realized the ws url is at: ws://server.local:32400/:/websockets/notifications
|
#EDIT: realized the ws url is at: ws://server.local:32400/:/websockets/notifications
|
||||||
|
websocket_url = ""
|
||||||
websocket_url = "%s/:/websockets/notifications/?X-Plex-Token=%s" % (server, token)
|
# websocket_url = "%s/:/websockets/notifications/?X-Plex-Token=%s" % (server, token)
|
||||||
self.logMsg("websocket url: %s" % websocket_url, 1)
|
self.logMsg("websocket url: %s" % websocket_url, 1)
|
||||||
|
|
||||||
self.client = websocket.WebSocketApp(websocket_url,
|
self.client = websocket.WebSocketApp(websocket_url,
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
<category label="30022">
|
<category label="30022">
|
||||||
<setting id="logLevel" type="enum" label="30004" values="None|Info|Debug" default="1" />
|
<setting id="logLevel" type="enum" label="30004" values="None|Info|Debug" default="2" />
|
||||||
<setting id="connectMsg" type="bool" label="30249" default="true" />
|
<setting id="connectMsg" type="bool" label="30249" default="true" />
|
||||||
<setting id="restartMsg" type="bool" label="Enable server message when it's restarting" default="false" />
|
<setting id="restartMsg" type="bool" label="Enable server message when it's restarting" default="false" />
|
||||||
<setting id="newContent" type="bool" label="Enable new content notification" default="false" />
|
<setting id="newContent" type="bool" label="Enable new content notification" default="false" />
|
||||||
|
|
Loading…
Reference in a new issue