Added UpdateUserdata to Movies and TV Shows

This commit is contained in:
tomkat83 2016-01-14 16:17:24 +01:00
parent eddfa23a71
commit 40c02395a2
3 changed files with 108 additions and 121 deletions

View file

@ -1412,37 +1412,44 @@ class PlexAPI():
})
return collections
def GetPlexSectionResults(self, viewId):
def GetPlexSectionResults(self, viewId, headerOptions={}):
"""
Returns a list (raw JSON API dump) of all Plex items in the Plex
section with key = viewId.
"""
result = []
url = "{server}/library/sections/%s/all" % viewId
jsondata = self.doUtils.downloadUrl(url)
jsondata = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
try:
result = jsondata['_children']
except KeyError:
self.logMsg("Error retrieving all items for Plex section %s" % viewId, -1)
except TypeError:
# Received an XML
pass
except:
self.logMsg("Error retrieving all items for Plex section %s"
% viewId, -1)
return []
return result
def GetAllPlexLeaves(self, key):
def GetAllPlexLeaves(self, viewId, headerOptions={}):
"""
Returns a list (raw JSON API dump) of all Plex subitems for the key.
(e.g. /library/metadata/194853/allLeaves pointing to all episodes
of a TV show)
(e.g. /library/sections/2/allLeaves pointing to all TV shows)
Input:
key Key to a Plex item, e.g. 12345
viewId Id of Plex library, e.g. '2'
"""
result = []
url = "{server}/library/metadata/%s/allLeaves" % key
jsondata = self.doUtils.downloadUrl(url)
url = "{server}/library/sections/%s/allLeaves" % viewId
jsondata = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
try:
result = jsondata['_children']
except TypeError:
# received an XMl
pass
except KeyError:
self.logMsg("Error retrieving all children for Plex item %s" % key, -1)
self.logMsg("Error retrieving all children for Plex viewId %s"
% viewId, -1)
pass
return result
@ -1517,6 +1524,8 @@ class API():
self.server = utils.window('emby_server%s' % self.userId)
self.token = utils.window('emby_accessToken%s' % self.userId)
self.jumpback = int(utils.settings('resumeJumpBack'))
def logMsg(self, msg, lvl=1):
className = self.__class__.__name__
utils.logMsg("%s %s" % (self.addonName, className), msg, lvl)
@ -1643,6 +1652,7 @@ class API():
'Played': played, # True/False
'LastPlayedDate': lastPlayedDate,
'Resume': resume, # Resume time in seconds
'Runtime': runtime,
'Rating': rating
}
"""
@ -1670,17 +1680,14 @@ class API():
except KeyError:
lastPlayedDate = None
try:
resume = float(item['viewOffset']) * 1.0/1000.0
resume = round(resume, 6)
except KeyError:
resume = 0.0
resume, runtime = self.getRuntime()
return {
'Favorite': favorite,
'PlayCount': playcount,
'Played': played,
'LastPlayedDate': lastPlayedDate,
'Resume': resume,
'Runtime': runtime,
'Rating': rating
}
@ -1890,6 +1897,14 @@ class API():
resume = float(item['viewOffset'])
except KeyError:
resume = 0.0
# Adjust the resume point by x seconds as chosen by the user in the
# settings
if resume:
# To avoid negative bookmark
if resume > self.jumpback:
resume = resume - self.jumpback
runtime = runtime * time_factor
resume = resume * time_factor
resume = round(resume, 6)
@ -2465,16 +2480,6 @@ class API():
urlencode(args)
return url
def adjustResume(self, resume_seconds):
resume = 0
if resume_seconds:
resume = round(float(resume_seconds), 6)
jumpback = int(utils.settings('resumeJumpBack'))
if resume > jumpback:
# To avoid negative bookmark
resume = resume - jumpback
return resume
def externalSubs(self, playurl):
externalsubs = []
mapping = {}

View file

@ -281,6 +281,26 @@ class Movies(Items):
count += 1
self.add_updateBoxset(boxset)
def updateUserdata(self, itemList):
"""
Updates the Kodi watched state of the item from PMS. Also retrieves
Plex resume points for movies in progress.
"""
API = PlexAPI.API(itemList)
for itemNumber in range(0, len(itemList)):
API.setChildNumber(itemNumber)
itemid = API.getKey()
# Get key and db entry on the Kodi db side
fileid = self.emby_db.getItem_byId(itemid)[1]
# Grab the user's viewcount, resume points etc. from PMS' answer
userdata = API.getUserData()
# Write to Kodi DB
self.kodi_db.addPlaystate(fileid,
userdata['Resume'],
userdata['Runtime'],
userdata['PlayCount'],
userdata['LastPlayedDate'])
def add_update(self, item, viewtag=None, viewid=None):
# Process single movie
kodicursor = self.kodicursor
@ -485,48 +505,8 @@ class Movies(Items):
# tags.append("Favorite movies")
kodi_db.addTags(movieid, tags, "movie")
# Process playstates
resume = API.adjustResume(userdata['Resume'])
kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed)
def updateUserdata(self, item):
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
# Poster with progress bar
emby_db = self.emby_db
kodi_db = self.kodi_db
API = api.API(item)
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
# Get Kodi information
emby_dbitem = emby_db.getItem_byId(itemid)
try:
movieid = emby_dbitem[0]
fileid = emby_dbitem[1]
self.logMsg(
"Update playstate for movie: %s fileid: %s"
% (item['Name'], fileid), 1)
except TypeError:
return
# Process favorite tags
if userdata['Favorite']:
kodi_db.addTag(movieid, "Favorite movies", "movie")
else:
kodi_db.removeTag(movieid, "Favorite movies", "movie")
# Process playstates
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
resume = API.adjustResume(userdata['Resume'])
total = round(float(runtime), 6)
kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
emby_db.updateReference(itemid, checksum)
def remove(self, itemid):
# Remove movieid, fileid, emby reference
emby_db = self.emby_db
@ -1171,6 +1151,26 @@ class TVShows(Items):
if not pdialog and self.contentmsg:
self.contentPop(title)
def updateUserdata(self, itemList):
"""
Updates the Kodi watched state of the item from PMS. Also retrieves
Plex resume points for movies in progress.
"""
API = PlexAPI.API(itemList)
for itemNumber in range(0, len(itemList)):
API.setChildNumber(itemNumber)
itemid = API.getKey()
# Get key and db entry on the Kodi db side
fileid = self.emby_db.getItem_byId(itemid)[1]
# Grab the user's viewcount, resume points etc. from PMS' answer
userdata = API.getUserData()
# Write to Kodi DB
self.kodi_db.addPlaystate(fileid,
userdata['Resume'],
userdata['Runtime'],
userdata['PlayCount'],
userdata['LastPlayedDate'])
def add_update(self, item, viewtag=None, viewid=None):
# Process single tvshow
kodicursor = self.kodicursor
@ -1611,9 +1611,7 @@ class TVShows(Items):
streams = API.getMediaStreams()
kodi_db.addStreams(fileid, streams, runtime)
# Process playstates
resume = API.adjustResume(userdata['Resume'])
total = round(float(runtime), 6)
kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
kodi_db.addPlaystate(fileid, resume, runtime, playcount, dateplayed)
if not self.directpath and resume:
# Create additional entry for widgets. This is only required for plugin/episode.
temppathid = kodi_db.getPath("plugin://plugin.video.plexkodiconnect.tvshows/")
@ -1625,53 +1623,7 @@ class TVShows(Items):
"WHERE idFile = ?"
))
kodicursor.execute(query, (temppathid, filename, dateadded, tempfileid))
kodi_db.addPlaystate(tempfileid, resume, total, playcount, dateplayed)
def updateUserdata(self, item):
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
# Poster with progress bar
emby_db = self.emby_db
kodi_db = self.kodi_db
API = api.API(item)
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
# Get Kodi information
emby_dbitem = emby_db.getItem_byId(itemid)
try:
kodiid = emby_dbitem[0]
fileid = emby_dbitem[1]
mediatype = emby_dbitem[4]
self.logMsg(
"Update playstate for %s: %s fileid: %s"
% (mediatype, item['Name'], fileid), 1)
except TypeError:
return
# Process favorite tags
if mediatype == "tvshow":
if userdata['Favorite']:
kodi_db.addTag(kodiid, "Favorite tvshows", "tvshow")
else:
kodi_db.removeTag(kodiid, "Favorite tvshows", "tvshow")
# Process playstates
if mediatype == "episode":
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
resume = API.adjustResume(userdata['Resume'])
total = round(float(runtime), 6)
kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
if not self.directpath and not resume:
# Make sure there's no other bookmarks created by widget.
filename = kodi_db.getFile(fileid)
kodi_db.removeFile("plugin://plugin.video.plexkodiconnect.tvshows/", filename)
emby_db.updateReference(itemid, checksum)
kodi_db.addPlaystate(tempfileid, resume, runtime, playcount, dateplayed)
def remove(self, itemid):
# Remove showid, fileid, pathid, emby reference

View file

@ -302,7 +302,6 @@ class LibrarySync(threading.Thread):
# Save last sync time
overlap = 2
self.logMsg("An exception occurred: %s" % e, 1)
time_now = datetime.utcnow()-timedelta(minutes=overlap)
lastSync = time_now.strftime('%Y-%m-%dT%H:%M:%SZ')
self.logMsg("New sync time: client time -%s min: %s"
@ -755,6 +754,10 @@ class LibrarySync(threading.Thread):
viewId)
self.GetAndProcessXMLs(itemType)
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
# Update viewstate
for view in views:
self.PlexUpdateWatched(view['id'], itemType)
##### PROCESS DELETES #####
if self.compare:
# Manual sync, process deletes
@ -765,6 +768,27 @@ class LibrarySync(threading.Thread):
self.logMsg("%s sync is finished." % itemType, 1)
return True
def PlexUpdateWatched(self, viewId, itemType):
"""
Updates ALL plex elements' view status ('watched' or 'unwatched') and
also updates resume times.
This is done by downloading one XML for ALL elements with viewId
"""
starttotal = datetime.now()
plx = PlexAPI.PlexAPI()
# Download XML, not JSON
headerOptions = {'Accept': 'application/xml'}
plexItems = plx.GetAllPlexLeaves(viewId,
headerOptions=headerOptions)
itemMth = getattr(itemtypes, itemType)
with itemMth() as method:
method.UpdateWatched(plexItems)
elapsedtotal = datetime.now() - starttotal
self.logMsg("Syncing userdata for itemtype %s and viewid %s took "
"%s seconds" % (itemType, viewId, elapsedtotal), 0)
def musicvideos(self, embycursor, kodicursor, pdialog, compare=False):
# Get musicvideos from emby
emby = self.emby
@ -1022,22 +1046,24 @@ class LibrarySync(threading.Thread):
'add_updateSeason',
None,
tvShowId) # send showId instead of viewid
self.logMsg("Analyzed all seasons of TV show with Plex Id %s" % tvShowId, 1)
self.logMsg("Analyzed all seasons of TV show with Plex Id %s"
% tvShowId, 1)
##### PROCESS TV Episodes #####
# Cycle through tv shows
for tvShowId in allPlexTvShowsId:
for view in views:
if self.shouldStop():
return False
# Grab all episodes to tvshow from PMS
episodes = plx.GetAllPlexLeaves(tvShowId)
episodes = plx.GetAllPlexLeaves(view['id'])
# Populate self.updatelist and self.allPlexElementsId
self.GetUpdatelist(episodes,
itemType,
'add_updateEpisode',
None,
None)
self.logMsg("Analyzed all episodes of TV show with Plex Id %s" % tvShowId, 1)
self.logMsg("Analyzed all episodes of TV show with Plex Id %s"
% tvShowId, 1)
# Process self.updatelist
self.GetAndProcessXMLs(itemType)
@ -1050,6 +1076,10 @@ class LibrarySync(threading.Thread):
TVshow.refreshSeasonEntry(XMLtvshow, tvShowId)
self.logMsg("Season info refreshed", 1)
# Update viewstate:
for view in views:
self.PlexUpdateWatched(view['id'], itemType)
##### PROCESS DELETES #####
if self.compare:
# Manual sync, process deletes