Use Plex library for timesync
- No need for Kodi elements
This commit is contained in:
parent
159bec297e
commit
d3e27d9797
2 changed files with 65 additions and 72 deletions
|
@ -46,9 +46,6 @@ class ThreadedGetMetadata(Thread):
|
||||||
self.out_queue = out_queue
|
self.out_queue = out_queue
|
||||||
self.lock = lock
|
self.lock = lock
|
||||||
self.processlock = processlock
|
self.processlock = processlock
|
||||||
# Just in case a time sync goes wrong
|
|
||||||
utils.window('kodiplextimeoffset',
|
|
||||||
utils.settings('kodiplextimeoffset'))
|
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
|
||||||
def terminateNow(self):
|
def terminateNow(self):
|
||||||
|
@ -291,11 +288,9 @@ class LibrarySync(Thread):
|
||||||
if utils.settings('emby_pathverified') == 'true':
|
if utils.settings('emby_pathverified') == 'true':
|
||||||
utils.window('emby_pathverified', value='true')
|
utils.window('emby_pathverified', value='true')
|
||||||
|
|
||||||
# Time offset between Kodi and PMS in seconds (=Koditime - PMStime)
|
# Just in case a time sync goes wrong
|
||||||
self.timeoffset = 0
|
self.timeoffset = int(utils.settings('kodiplextimeoffset'))
|
||||||
self.lastSync = 0
|
utils.window('kodiplextimeoffset', value=str(self.timeoffset))
|
||||||
self.lastTimeSync = 0
|
|
||||||
|
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
|
||||||
def showKodiNote(self, message, forced=False, icon="plex"):
|
def showKodiNote(self, message, forced=False, icon="plex"):
|
||||||
|
@ -338,101 +333,98 @@ class LibrarySync(Thread):
|
||||||
self.logMsg('Synching time with PMS server', 0)
|
self.logMsg('Synching time with PMS server', 0)
|
||||||
# Find a PMS item where we can toggle the view state to enforce a
|
# Find a PMS item where we can toggle the view state to enforce a
|
||||||
# change in lastViewedAt
|
# change in lastViewedAt
|
||||||
with kodidb.GetKodiDB('video') as kodi_db:
|
|
||||||
unplayedIds = kodi_db.getUnplayedItems()
|
|
||||||
resumeIds = kodi_db.getResumes()
|
|
||||||
self.logMsg('resumeIds: %s' % resumeIds, 1)
|
|
||||||
|
|
||||||
plexId = False
|
# Get all Plex libraries
|
||||||
for unplayedId in unplayedIds:
|
sections = downloadutils.DownloadUtils().downloadUrl(
|
||||||
if unplayedId not in resumeIds:
|
"{server}/library/sections")
|
||||||
if self.threadStopped():
|
try:
|
||||||
return
|
sections.attrib
|
||||||
# Found an item we can work with!
|
except AttributeError:
|
||||||
kodiId = unplayedId
|
self.logMsg("Error download PMS views, abort syncPMStime", -1)
|
||||||
self.logMsg('Found kodiId: %s' % kodiId, 1)
|
return False
|
||||||
# Get Plex ID using the Kodi ID
|
|
||||||
with embydb.GetEmbyDB() as emby_db:
|
|
||||||
plexId = emby_db.getItem_byFileId(kodiId, 'movie')
|
|
||||||
if plexId:
|
|
||||||
self.logMsg('Found movie plexId: %s' % plexId, 1)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
plexId = emby_db.getItem_byFileId(kodiId, 'episode')
|
|
||||||
if plexId:
|
|
||||||
self.logMsg('Found episode plexId: %s' % plexId, 1)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Try getting a music item if we did not find a video item
|
plexId = None
|
||||||
if not plexId:
|
for mediatype in ('movie', 'show', 'artist'):
|
||||||
self.logMsg("Could not find a video item to sync time with", 0)
|
if plexId is not None:
|
||||||
with kodidb.GetKodiDB('music') as kodi_db:
|
break
|
||||||
unplayedIds = kodi_db.getUnplayedMusicItems()
|
for view in sections:
|
||||||
# We don't care about resuming songs in the middle
|
if plexId is not None:
|
||||||
for unplayedId in unplayedIds:
|
|
||||||
if self.threadStopped():
|
|
||||||
return
|
|
||||||
# Found an item we can work with!
|
|
||||||
kodiId = unplayedId
|
|
||||||
self.logMsg('Found kodiId: %s' % kodiId, 1)
|
|
||||||
# Get Plex ID using the Kodi ID
|
|
||||||
with embydb.GetEmbyDB() as emby_db:
|
|
||||||
plexId = emby_db.getMusicItem_byFileId(kodiId, 'song')
|
|
||||||
if plexId:
|
|
||||||
self.logMsg('Found plexId: %s' % plexId, 1)
|
|
||||||
break
|
break
|
||||||
else:
|
if not view.attrib['type'] == mediatype:
|
||||||
self.logMsg("Could not find an item to sync time with", -1)
|
continue
|
||||||
self.logMsg("Aborting PMS-Kodi time sync", -1)
|
items = PF.GetAllPlexLeaves(view.attrib['key'],
|
||||||
return
|
containerSize=self.limitindex)
|
||||||
|
if items in (None, 401):
|
||||||
|
self.logMsg("Could not download section %s"
|
||||||
|
% view.attrib['key'], -1)
|
||||||
|
continue
|
||||||
|
for item in items:
|
||||||
|
if item.attrib.get('viewCount') is not None:
|
||||||
|
# Don't want to mess with items that have playcount>0
|
||||||
|
continue
|
||||||
|
if item.attrib.get('viewOffset') is not None:
|
||||||
|
# Don't mess with items with a resume point
|
||||||
|
continue
|
||||||
|
plexId = item.attrib.get('ratingKey')
|
||||||
|
self.logMsg('Found an item to sync with: %s' % plexId, 1)
|
||||||
|
break
|
||||||
|
|
||||||
|
if plexId is None:
|
||||||
|
self.logMsg("Could not find an item to sync time with", -1)
|
||||||
|
self.logMsg("Aborting PMS-Kodi time sync", -1)
|
||||||
|
return False
|
||||||
|
|
||||||
# Get the Plex item's metadata
|
# Get the Plex item's metadata
|
||||||
xml = PF.GetPlexMetadata(plexId)
|
xml = PF.GetPlexMetadata(plexId)
|
||||||
if xml is None or xml == 401:
|
if xml in (None, 401):
|
||||||
self.logMsg("Could not download metadata, aborting time sync", -1)
|
self.logMsg("Could not download metadata, aborting time sync", -1)
|
||||||
return
|
return False
|
||||||
|
|
||||||
libraryId = xml[0].attrib['librarySectionID']
|
libraryId = xml[0].attrib['librarySectionID']
|
||||||
# Get a PMS timestamp to start our question with
|
|
||||||
timestamp = xml[0].attrib.get('lastViewedAt')
|
timestamp = xml[0].attrib.get('lastViewedAt')
|
||||||
if not timestamp:
|
if timestamp is None:
|
||||||
timestamp = xml[0].attrib.get('updatedAt')
|
timestamp = xml[0].attrib.get('updatedAt')
|
||||||
self.logMsg('Using items updatedAt=%s' % timestamp, 1)
|
self.logMsg('Using items updatedAt=%s' % timestamp, 1)
|
||||||
if not timestamp:
|
if timestamp is None:
|
||||||
timestamp = xml[0].attrib.get('addedAt')
|
timestamp = xml[0].attrib.get('addedAt')
|
||||||
self.logMsg('Using items addedAt=%s' % timestamp, 1)
|
self.logMsg('Using items addedAt=%s' % timestamp, 1)
|
||||||
|
if timestamp is None:
|
||||||
|
timestamp = 0
|
||||||
|
self.logMsg('No timestamp; using 0', 1)
|
||||||
|
|
||||||
# Set the timer
|
# Set the timer
|
||||||
koditime = utils.getUnixTimestamp()
|
koditime = utils.getUnixTimestamp()
|
||||||
# Toggle watched state
|
# Toggle watched state
|
||||||
PF.scrobble(plexId, 'watched')
|
PF.scrobble(plexId, 'watched')
|
||||||
# Let the PMS process this first!
|
# Let the PMS process this first!
|
||||||
xbmc.sleep(2000)
|
xbmc.sleep(1000)
|
||||||
# Get all PMS items to find the item we just changed
|
# Get PMS items to find the item we just changed
|
||||||
items = PF.GetAllPlexLeaves(libraryId,
|
items = PF.GetAllPlexLeaves(libraryId,
|
||||||
lastViewedAt=timestamp,
|
lastViewedAt=timestamp,
|
||||||
containerSize=self.limitindex)
|
containerSize=self.limitindex)
|
||||||
# Toggle watched state back
|
# Toggle watched state back
|
||||||
PF.scrobble(plexId, 'unwatched')
|
PF.scrobble(plexId, 'unwatched')
|
||||||
if items in (None, 401):
|
if items in (None, 401):
|
||||||
self.logMsg('Could not download all Plex leaves for library %s '
|
self.logMsg("Could not download metadata, aborting time sync", -1)
|
||||||
'with lastViewedAt=%s and containerSize=%s'
|
return False
|
||||||
% (libraryId, timestamp, self.limitindex), -1)
|
|
||||||
return
|
|
||||||
# Get server timestamp for this change
|
|
||||||
plextime = None
|
plextime = None
|
||||||
for item in items:
|
for item in items:
|
||||||
if item.attrib['ratingKey'] == plexId:
|
if item.attrib['ratingKey'] == plexId:
|
||||||
plextime = item.attrib.get('lastViewedAt')
|
plextime = item.attrib.get('lastViewedAt')
|
||||||
break
|
break
|
||||||
|
|
||||||
if plextime is None:
|
if plextime is None:
|
||||||
self.logMsg("Could not set the items watched state, abort", -1)
|
self.logMsg('Could not get lastViewedAt - aborting', -1)
|
||||||
return
|
return False
|
||||||
|
|
||||||
# Calculate time offset Kodi-PMS
|
# Calculate time offset Kodi-PMS
|
||||||
timeoffset = int(koditime) - int(plextime)
|
self.timeoffset = int(koditime) - int(plextime)
|
||||||
utils.window('kodiplextimeoffset', value=str(timeoffset))
|
utils.window('kodiplextimeoffset', value=str(self.timeoffset))
|
||||||
utils.settings('kodiplextimeoffset', value=str(timeoffset))
|
utils.settings('kodiplextimeoffset', value=str(self.timeoffset))
|
||||||
self.logMsg("Time offset Koditime - Plextime in seconds: %s"
|
self.logMsg("Time offset Koditime - Plextime in seconds: %s"
|
||||||
% str(self.timeoffset), 0)
|
% str(self.timeoffset), 0)
|
||||||
|
return True
|
||||||
|
|
||||||
def initializeDBs(self):
|
def initializeDBs(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1530,8 +1522,8 @@ class LibrarySync(Thread):
|
||||||
processItems = self.processItems
|
processItems = self.processItems
|
||||||
string = self.__language__
|
string = self.__language__
|
||||||
fullSyncInterval = self.fullSyncInterval
|
fullSyncInterval = self.fullSyncInterval
|
||||||
lastSync = self.lastSync
|
lastSync = 0
|
||||||
lastTimeSync = self.lastTimeSync
|
lastTimeSync = 0
|
||||||
lastProcessing = 0
|
lastProcessing = 0
|
||||||
oneDay = 60*60*24
|
oneDay = 60*60*24
|
||||||
|
|
||||||
|
@ -1595,8 +1587,10 @@ class LibrarySync(Thread):
|
||||||
# Run start up sync
|
# Run start up sync
|
||||||
window('emby_dbScan', value="true")
|
window('emby_dbScan', value="true")
|
||||||
log("Db version: %s" % settings('dbCreatedWithVersion'), 0)
|
log("Db version: %s" % settings('dbCreatedWithVersion'), 0)
|
||||||
|
lastTimeSync = utils.getUnixTimestamp()
|
||||||
self.syncPMStime()
|
self.syncPMStime()
|
||||||
log("Initial start-up full sync starting", 0)
|
log("Initial start-up full sync starting", 0)
|
||||||
|
lastSync = utils.getUnixTimestamp()
|
||||||
librarySync = fullSync()
|
librarySync = fullSync()
|
||||||
# Initialize time offset Kodi - PMS
|
# Initialize time offset Kodi - PMS
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
|
|
|
@ -236,7 +236,6 @@ class plexgdm:
|
||||||
try:
|
try:
|
||||||
data, server = sock.recvfrom(1024)
|
data, server = sock.recvfrom(1024)
|
||||||
self.logMsg("Received data from %s, %s" % server, 2)
|
self.logMsg("Received data from %s, %s" % server, 2)
|
||||||
self.logMsg("Data received is:\r\n %s" % data, 2)
|
|
||||||
returnData.append({'from': server,
|
returnData.append({'from': server,
|
||||||
'data': data})
|
'data': data})
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
|
|
Loading…
Reference in a new issue