TV shows sync v0.1
This commit is contained in:
parent
b3f588fd71
commit
5da6b4153e
3 changed files with 271 additions and 466 deletions
|
@ -1232,16 +1232,46 @@ class PlexAPI():
|
||||||
try:
|
try:
|
||||||
result = jsondata['_children']
|
result = jsondata['_children']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.logMsg("Error retrieving all items for Plex section %s" % viewId, 1)
|
self.logMsg("Error retrieving all items for Plex section %s" % viewId, -1)
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def GetPlexSubitems(self, key):
|
def GetAllPlexLeaves(self, key):
|
||||||
"""
|
"""
|
||||||
Returns a list (raw JSON API dump) of all Plex subitems for the key.
|
Returns a list (raw JSON API dump) of all Plex subitems for the key.
|
||||||
(e.g. key=/library/metadata/194853/children pointing to a season)
|
(e.g. /library/metadata/194853/allLeaves pointing to all episodes
|
||||||
"""
|
of a TV show)
|
||||||
|
|
||||||
|
Input:
|
||||||
|
key Key to a Plex item, e.g. 12345
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
url = "{server}/library/metadata/%s/allLeaves" % key
|
||||||
|
jsondata = self.doUtils.downloadUrl(url)
|
||||||
|
try:
|
||||||
|
result = jsondata['_children']
|
||||||
|
except KeyError:
|
||||||
|
self.logMsg("Error retrieving all children for Plex item %s" % key, -1)
|
||||||
|
pass
|
||||||
|
return result
|
||||||
|
|
||||||
|
def GetAllPlexChildren(self, key):
|
||||||
|
"""
|
||||||
|
Returns a list (raw JSON API dump) of all Plex children for the key.
|
||||||
|
(e.g. /library/metadata/194853/children pointing to a season)
|
||||||
|
|
||||||
|
Input:
|
||||||
|
key Key to a Plex item, e.g. 12345
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
url = "{server}/library/metadata/%s/children" % key
|
||||||
|
jsondata = self.doUtils.downloadUrl(url)
|
||||||
|
try:
|
||||||
|
result = jsondata['_children']
|
||||||
|
except KeyError:
|
||||||
|
self.logMsg("Error retrieving all children for Plex item %s" % key, -1)
|
||||||
|
pass
|
||||||
|
return result
|
||||||
|
|
||||||
def GetPlexMetadata(self, key):
|
def GetPlexMetadata(self, key):
|
||||||
"""
|
"""
|
||||||
|
@ -1270,7 +1300,7 @@ class PlexAPI():
|
||||||
headerOptions = {'Accept': 'application/xml'}
|
headerOptions = {'Accept': 'application/xml'}
|
||||||
xml = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
|
xml = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
|
||||||
if not xml:
|
if not xml:
|
||||||
self.logMsg("Error retrieving metadata for %s" % url, 1)
|
self.logMsg("Error retrieving metadata for %s" % url, -1)
|
||||||
return xml
|
return xml
|
||||||
|
|
||||||
|
|
||||||
|
@ -1388,17 +1418,23 @@ class API():
|
||||||
Returns the Plex unique movie id as a str, not int
|
Returns the Plex unique movie id as a str, not int
|
||||||
"""
|
"""
|
||||||
item = self.item
|
item = self.item
|
||||||
key_regex = re.compile(r'/(\d+)$')
|
|
||||||
# XML
|
# XML
|
||||||
try:
|
try:
|
||||||
item = item[self.child].attrib
|
item = item[self.child].attrib
|
||||||
# JSON
|
# JSON
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
key = item['key']
|
key = item['ratingKey']
|
||||||
key = key_regex.findall(key)[0]
|
|
||||||
return str(key)
|
return str(key)
|
||||||
|
|
||||||
|
def getIndex(self):
|
||||||
|
"""
|
||||||
|
Returns the 'index' of an PMS XML reply. Depicts e.g. season number.
|
||||||
|
"""
|
||||||
|
item = self.item[self.child].attrib
|
||||||
|
index = item['index']
|
||||||
|
return str(index)
|
||||||
|
|
||||||
def getDateCreated(self):
|
def getDateCreated(self):
|
||||||
"""
|
"""
|
||||||
Returns the date when this library item was created
|
Returns the date when this library item was created
|
||||||
|
@ -1550,33 +1586,19 @@ class API():
|
||||||
genre.append(child.attrib['tag'])
|
genre.append(child.attrib['tag'])
|
||||||
return genre
|
return genre
|
||||||
|
|
||||||
def getProvider(self, providername):
|
def getProvider(self, providername=None):
|
||||||
"""
|
"""
|
||||||
providername: imdb, tvdb, musicBrainzArtist, musicBrainzAlbum,
|
providername: depricated
|
||||||
musicBrainzTrackId
|
|
||||||
|
|
||||||
Return IMDB: "tt1234567". Returns None if not found
|
Return IMDB, e.g. "imdb://tt0903624?lang=en". Returns None if not found
|
||||||
"""
|
"""
|
||||||
item = self.item
|
item = self.item
|
||||||
item = item[self.child].attrib
|
item = item[self.child].attrib
|
||||||
imdb_regex = re.compile(r'''(
|
regex = re.compile(r'''com.plexapp.agents.(.+)$''')
|
||||||
imdb:// # imdb tag, which will be followed be tt1234567
|
|
||||||
(tt\d{7}) # actual IMDB ID, e.g. tt1234567
|
provider = regex.findall(item['guid'])
|
||||||
\?? # zero or one ?
|
|
||||||
(.*) # rest, e.g. language setting
|
|
||||||
)''', re.VERBOSE)
|
|
||||||
try:
|
try:
|
||||||
if "Imdb" in providername:
|
provider = provider[0]
|
||||||
provider = imdb_regex.findall(item['guid'])
|
|
||||||
provider = provider[0][1]
|
|
||||||
elif "tvdb" in providername:
|
|
||||||
provider = item['ProviderIds']['Tvdb']
|
|
||||||
elif "musicBrainzArtist" in providername:
|
|
||||||
provider = item['ProviderIds']['MusicBrainzArtist']
|
|
||||||
elif "musicBrainzAlbum" in providername:
|
|
||||||
provider = item['ProviderIds']['MusicBrainzAlbum']
|
|
||||||
elif "musicBrainzTrackId" in providername:
|
|
||||||
provider = item['ProviderIds']['MusicBrainzTrackId']
|
|
||||||
except:
|
except:
|
||||||
provider = None
|
provider = None
|
||||||
return provider
|
return provider
|
||||||
|
@ -1752,6 +1774,25 @@ class API():
|
||||||
string = " / ".join(listobject)
|
string = " / ".join(listobject)
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
def getEpisodeDetails(self):
|
||||||
|
"""
|
||||||
|
Call on a single episode.
|
||||||
|
|
||||||
|
Output: for the corresponding the TV show and season:
|
||||||
|
[
|
||||||
|
TV show key, Plex: 'grandparentRatingKey'
|
||||||
|
TV show title, Plex: 'grandparentTitle'
|
||||||
|
TV show season, Plex: 'parentIndex'
|
||||||
|
Episode number, Plex: 'index'
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
item = self.item[self.child].attrib
|
||||||
|
key = item['grandparentRatingKey']
|
||||||
|
title = item['grandparentTitle']
|
||||||
|
season = item['parentIndex']
|
||||||
|
episode = item['index']
|
||||||
|
return key, title, season, episode
|
||||||
|
|
||||||
def getFilePath(self):
|
def getFilePath(self):
|
||||||
"""
|
"""
|
||||||
returns the path to the Plex object, e.g. "/library/metadata/221803"
|
returns the path to the Plex object, e.g. "/library/metadata/221803"
|
||||||
|
|
|
@ -1173,12 +1173,8 @@ class MusicVideos(Items):
|
||||||
|
|
||||||
self.logMsg("Deleted musicvideo %s from kodi database" % itemid, 1)
|
self.logMsg("Deleted musicvideo %s from kodi database" % itemid, 1)
|
||||||
|
|
||||||
|
|
||||||
class TVShows(Items):
|
class TVShows(Items):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, embycursor, kodicursor):
|
|
||||||
Items.__init__(self, embycursor, kodicursor)
|
|
||||||
|
|
||||||
def added(self, items, pdialog):
|
def added(self, items, pdialog):
|
||||||
|
|
||||||
total = len(items)
|
total = len(items)
|
||||||
|
@ -1233,15 +1229,18 @@ class TVShows(Items):
|
||||||
emby_db = self.emby_db
|
emby_db = self.emby_db
|
||||||
kodi_db = self.kodi_db
|
kodi_db = self.kodi_db
|
||||||
artwork = self.artwork
|
artwork = self.artwork
|
||||||
API = api.API(item)
|
API = PlexAPI.API(item)
|
||||||
|
|
||||||
if utils.settings('syncEmptyShows') == "false" and not item['RecursiveItemCount']:
|
# if utils.settings('syncEmptyShows') == "false" and not item['RecursiveItemCount']:
|
||||||
self.logMsg("Skipping empty show: %s" % item['Name'], 1)
|
# self.logMsg("Skipping empty show: %s" % item['Name'], 1)
|
||||||
return
|
# return
|
||||||
# If the item already exist in the local Kodi DB we'll perform a full item update
|
# If the item already exist in the local Kodi DB we'll perform a full item update
|
||||||
# If the item doesn't exist, we'll add it to the database
|
# If the item doesn't exist, we'll add it to the database
|
||||||
update_item = True
|
update_item = True
|
||||||
itemid = item['Id']
|
itemid = API.getKey()
|
||||||
|
if not itemid:
|
||||||
|
self.logMsg("Cannot parse XML data for TV show", -1)
|
||||||
|
return
|
||||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||||
try:
|
try:
|
||||||
showid = emby_dbitem[0]
|
showid = emby_dbitem[0]
|
||||||
|
@ -1252,32 +1251,29 @@ class TVShows(Items):
|
||||||
update_item = False
|
update_item = False
|
||||||
self.logMsg("showid: %s not found." % itemid, 2)
|
self.logMsg("showid: %s not found." % itemid, 2)
|
||||||
|
|
||||||
if viewtag is None or viewid is None:
|
# if viewtag is None or viewid is None:
|
||||||
# Get view tag from emby
|
# # Get view tag from emby
|
||||||
viewtag, viewid, mediatype = emby.getView_embyId(itemid)
|
# viewtag, viewid, mediatype = emby.getView_embyId(itemid)
|
||||||
self.logMsg("View tag found: %s" % viewtag, 2)
|
# self.logMsg("View tag found: %s" % viewtag, 2)
|
||||||
|
|
||||||
# fileId information
|
# fileId information
|
||||||
checksum = API.getChecksum()
|
checksum = API.getChecksum()
|
||||||
dateadded = API.getDateCreated()
|
|
||||||
userdata = API.getUserData()
|
|
||||||
playcount = userdata['PlayCount']
|
|
||||||
dateplayed = userdata['LastPlayedDate']
|
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
genres = item['Genres']
|
genres = API.getGenres()
|
||||||
title = item['Name']
|
title, sorttitle = API.getTitle()
|
||||||
plot = API.getOverview()
|
plot = API.getPlot()
|
||||||
rating = item.get('CommunityRating')
|
rating = API.getAudienceRating()
|
||||||
premieredate = API.getPremiereDate()
|
premieredate = API.getPremiereDate()
|
||||||
tvdb = API.getProvider('Tvdb')
|
tvdb = API.getProvider('Tvdb')
|
||||||
sorttitle = item['SortName']
|
|
||||||
mpaa = API.getMpaa()
|
mpaa = API.getMpaa()
|
||||||
genre = " / ".join(genres)
|
genre = API.joinList(genres)
|
||||||
studios = API.getStudios()
|
studios = API.getStudios()
|
||||||
studio = " / ".join(studios)
|
try:
|
||||||
|
studio = studios[0]
|
||||||
|
except IndexError:
|
||||||
|
studio = None
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
playurl = API.getFilePath()
|
playurl = API.getFilePath()
|
||||||
|
|
||||||
|
@ -1380,76 +1376,78 @@ class TVShows(Items):
|
||||||
kodicursor.execute(query, (path, None, None, 1, pathid))
|
kodicursor.execute(query, (path, None, None, 1, pathid))
|
||||||
|
|
||||||
# Process cast
|
# Process cast
|
||||||
people = artwork.getPeopleArtwork(item['People'])
|
people = API.getPeopleList()
|
||||||
kodi_db.addPeople(showid, people, "tvshow")
|
kodi_db.addPeople(showid, people, "tvshow")
|
||||||
# Process genres
|
# Process genres
|
||||||
kodi_db.addGenres(showid, genres, "tvshow")
|
kodi_db.addGenres(showid, genres, "tvshow")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), showid, "tvshow", kodicursor)
|
allartworks = API.getAllArtwork()
|
||||||
|
artwork.addArtwork(allartworks, showid, "tvshow", kodicursor)
|
||||||
# Process studios
|
# Process studios
|
||||||
kodi_db.addStudios(showid, studios, "tvshow")
|
kodi_db.addStudios(showid, studios, "tvshow")
|
||||||
# Process tags: view, emby tags
|
# Process tags: view, emby tags
|
||||||
tags = [viewtag]
|
# tags = [viewtag]
|
||||||
tags.extend(item['Tags'])
|
# tags.extend(item['Tags'])
|
||||||
if userdata['Favorite']:
|
# if userdata['Favorite']:
|
||||||
tags.append("Favorite tvshows")
|
# tags.append("Favorite tvshows")
|
||||||
kodi_db.addTags(showid, tags, "tvshow")
|
# kodi_db.addTags(showid, tags, "tvshow")
|
||||||
# Process seasons
|
# Process seasons
|
||||||
all_seasons = emby.getSeasons(itemid)
|
|
||||||
for season in all_seasons['Items']:
|
|
||||||
self.add_updateSeason(season, showid=showid)
|
|
||||||
else:
|
|
||||||
# Finally, refresh the all season entry
|
|
||||||
seasonid = kodi_db.addSeason(showid, -1)
|
|
||||||
# Process artwork
|
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor)
|
|
||||||
|
|
||||||
def add_updateSeason(self, item, showid=None):
|
def refreshSeasonEntry(self, item, showid):
|
||||||
|
API = PlexAPI.API(item)
|
||||||
|
kodicursor = self.kodicursor
|
||||||
|
kodi_db = self.kodi_db
|
||||||
|
# Finally, refresh the all season entry
|
||||||
|
seasonid = kodi_db.addSeason(showid, -1)
|
||||||
|
# Process artwork for season
|
||||||
|
allartworks = API.getAllArtwork()
|
||||||
|
artwork.addArtwork(allartworks, seasonid, "season", kodicursor)
|
||||||
|
|
||||||
|
def add_updateSeason(self, item, viewid=None, viewtag=None):
|
||||||
|
self.logMsg("add_updateSeason called with", 1)
|
||||||
|
self.logMsg("item: %s" % item, 1)
|
||||||
|
self.logMsg("viewid: %s" % viewid, 1)
|
||||||
|
self.logMsg("viewName: %s" % viewtag, 1)
|
||||||
|
showid = viewid
|
||||||
|
itemid = viewid
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
emby_db = self.emby_db
|
emby_db = self.emby_db
|
||||||
kodi_db = self.kodi_db
|
kodi_db = self.kodi_db
|
||||||
artwork = self.artwork
|
artwork = self.artwork
|
||||||
|
API = PlexAPI.API(item)
|
||||||
|
self.logMsg("add_updateSeason initialization done", 1)
|
||||||
|
|
||||||
if item['LocationType'] == "Virtual":
|
seasonnum = API.getIndex()
|
||||||
self.logMsg("Skipping virtual season.")
|
self.logMsg("seasonnum: %s" % seasonnum, 1)
|
||||||
return
|
|
||||||
|
|
||||||
seasonnum = item.get('IndexNumber', 1)
|
|
||||||
itemid = item['Id']
|
|
||||||
|
|
||||||
if showid is None:
|
|
||||||
try:
|
|
||||||
seriesId = item['SeriesId']
|
|
||||||
showid = emby_db.getItem_byId(seriesId)[0]
|
|
||||||
except KeyError:
|
|
||||||
return
|
|
||||||
except TypeError:
|
|
||||||
# Show is missing, update show instead.
|
|
||||||
show = self.emby.getItem(seriesId)
|
|
||||||
self.add_update(show)
|
|
||||||
return
|
|
||||||
|
|
||||||
seasonid = kodi_db.addSeason(showid, seasonnum)
|
seasonid = kodi_db.addSeason(showid, seasonnum)
|
||||||
|
self.logMsg("seasonid: %s" % seasonid, 1)
|
||||||
# Create the reference in emby table
|
# Create the reference in emby table
|
||||||
emby_db.addReference(itemid, seasonid, "Season", "season", parentid=showid)
|
emby_db.addReference(itemid, seasonid, "Season", "season", parentid=showid)
|
||||||
|
self.logMsg("Added db reference", 1)
|
||||||
|
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor)
|
allartworks = API.getAllArtwork()
|
||||||
|
self.logMsg("Gotten allartworks: %s" % allartworks, 1)
|
||||||
|
artwork.addArtwork(allartworks, seasonid, "season", kodicursor)
|
||||||
|
self.logMsg("Added Artwork reference", 1)
|
||||||
|
|
||||||
def add_updateEpisode(self, item):
|
def add_updateEpisode(self, item, viewtag=None, viewid=None):
|
||||||
|
"""
|
||||||
|
viewtag and viewid are irrelevant!
|
||||||
|
"""
|
||||||
# Process single episode
|
# Process single episode
|
||||||
kodiversion = self.kodiversion
|
kodiversion = self.kodiversion
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
emby_db = self.emby_db
|
emby_db = self.emby_db
|
||||||
kodi_db = self.kodi_db
|
kodi_db = self.kodi_db
|
||||||
artwork = self.artwork
|
artwork = self.artwork
|
||||||
API = api.API(item)
|
API = PlexAPI.API(item)
|
||||||
|
|
||||||
# If the item already exist in the local Kodi DB we'll perform a full item update
|
# If the item already exist in the local Kodi DB we'll perform a full item update
|
||||||
# If the item doesn't exist, we'll add it to the database
|
# If the item doesn't exist, we'll add it to the database
|
||||||
update_item = True
|
update_item = True
|
||||||
itemid = item['Id']
|
itemid = API.getKey()
|
||||||
|
self.logMsg("itemid: %s" % itemid, 2)
|
||||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||||
try:
|
try:
|
||||||
episodeid = emby_dbitem[0]
|
episodeid = emby_dbitem[0]
|
||||||
|
@ -1472,21 +1470,20 @@ class TVShows(Items):
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
people = API.getPeople()
|
director, writer, cast, producer = API.getPeople()
|
||||||
writer = " / ".join(people['Writer'])
|
director = API.joinList(director)
|
||||||
director = " / ".join(people['Director'])
|
writer = API.joinList(writer)
|
||||||
title = item['Name']
|
cast = API.joinList(cast)
|
||||||
plot = API.getOverview()
|
producer = API.joinList(producer)
|
||||||
rating = item.get('CommunityRating')
|
title, sorttitle = API.getTitle()
|
||||||
|
plot = API.getPlot()
|
||||||
|
rating = API.getAudienceRating()
|
||||||
runtime = API.getRuntime()
|
runtime = API.getRuntime()
|
||||||
premieredate = API.getPremiereDate()
|
premieredate = API.getPremiereDate()
|
||||||
|
|
||||||
# episode details
|
# episode details
|
||||||
seriesId = item['SeriesId']
|
seriesId, seriesName, season, episode = API.getEpisodeDetails()
|
||||||
seriesName = item['SeriesName']
|
|
||||||
season = item.get('ParentIndexNumber')
|
|
||||||
episode = item.get('IndexNumber', -1)
|
|
||||||
|
|
||||||
if season is None:
|
if season is None:
|
||||||
if item.get('AbsoluteEpisodeNumber'):
|
if item.get('AbsoluteEpisodeNumber'):
|
||||||
# Anime scenario
|
# Anime scenario
|
||||||
|
@ -1496,16 +1493,18 @@ class TVShows(Items):
|
||||||
season = -1
|
season = -1
|
||||||
|
|
||||||
# Specials ordering within season
|
# Specials ordering within season
|
||||||
if item.get('AirsAfterSeasonNumber'):
|
# if item.get('AirsAfterSeasonNumber'):
|
||||||
airsBeforeSeason = item['AirsAfterSeasonNumber']
|
# airsBeforeSeason = item['AirsAfterSeasonNumber']
|
||||||
airsBeforeEpisode = 4096 # Kodi default number for afterseason ordering
|
# airsBeforeEpisode = 4096 # Kodi default number for afterseason ordering
|
||||||
else:
|
# else:
|
||||||
airsBeforeSeason = item.get('AirsBeforeSeasonNumber', "-1")
|
# airsBeforeSeason = item.get('AirsBeforeSeasonNumber', "-1")
|
||||||
airsBeforeEpisode = item.get('AirsBeforeEpisodeNumber', "-1")
|
# airsBeforeEpisode = item.get('AirsBeforeEpisodeNumber', "-1")
|
||||||
|
|
||||||
|
airsBeforeSeason = "-1"
|
||||||
|
airsBeforeEpisode = "-1"
|
||||||
# Append multi episodes to title
|
# Append multi episodes to title
|
||||||
if item.get('IndexNumberEnd'):
|
# if item.get('IndexNumberEnd'):
|
||||||
title = "| %02d | %s" % (item['IndexNumberEnd'], title)
|
# title = "| %02d | %s" % (item['IndexNumberEnd'], title)
|
||||||
|
|
||||||
# Get season id
|
# Get season id
|
||||||
show = emby_db.getItem_byId(seriesId)
|
show = emby_db.getItem_byId(seriesId)
|
||||||
|
@ -1519,7 +1518,7 @@ class TVShows(Items):
|
||||||
try:
|
try:
|
||||||
showid = show[0]
|
showid = show[0]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.logMsg("Skipping: %s. Unable to add series: %s." % (itemid, seriesId))
|
self.logMsg("Skipping: %s. Unable to add series: %s." % (itemid, seriesId), -1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
seasonid = kodi_db.addSeason(showid, season)
|
seasonid = kodi_db.addSeason(showid, season)
|
||||||
|
@ -1658,12 +1657,13 @@ class TVShows(Items):
|
||||||
"WHERE idFile = ?"
|
"WHERE idFile = ?"
|
||||||
))
|
))
|
||||||
kodicursor.execute(query, (pathid, filename, dateadded, fileid))
|
kodicursor.execute(query, (pathid, filename, dateadded, fileid))
|
||||||
|
|
||||||
|
self.logMsg("Start processing getPeopleList", 1)
|
||||||
# Process cast
|
# Process cast
|
||||||
people = artwork.getPeopleArtwork(item['People'])
|
people = API.getPeopleList()
|
||||||
kodi_db.addPeople(episodeid, people, "episode")
|
kodi_db.addPeople(episodeid, people, "episode")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artworks = artwork.getAllArtwork(item)
|
artworks = API.getAllArtwork()
|
||||||
artwork.addOrUpdateArt(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
|
artwork.addOrUpdateArt(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
|
||||||
# Process stream details
|
# Process stream details
|
||||||
streams = API.getMediaStreams()
|
streams = API.getMediaStreams()
|
||||||
|
|
|
@ -87,6 +87,8 @@ class ThreadedProcessMetadata(threading.Thread):
|
||||||
data = {
|
data = {
|
||||||
'itemType': as used to call functions in itemtypes.py
|
'itemType': as used to call functions in itemtypes.py
|
||||||
e.g. 'Movies' => itemtypes.Movies()
|
e.g. 'Movies' => itemtypes.Movies()
|
||||||
|
'method' Name of method in itemtypes.py
|
||||||
|
e.g. 'add_updateSeason'
|
||||||
'viewName' Plex str for library view (e.g. 'Movies')
|
'viewName' Plex str for library view (e.g. 'Movies')
|
||||||
'viewId' Plex Id to identifiy the library view
|
'viewId' Plex Id to identifiy the library view
|
||||||
}
|
}
|
||||||
|
@ -108,6 +110,7 @@ class ThreadedProcessMetadata(threading.Thread):
|
||||||
viewId = self.data['viewId']
|
viewId = self.data['viewId']
|
||||||
global processMetadataCount
|
global processMetadataCount
|
||||||
with itemFkt() as item:
|
with itemFkt() as item:
|
||||||
|
itemSubFkt = getattr(item, self.data['method'])
|
||||||
while self.stopped() is False:
|
while self.stopped() is False:
|
||||||
# grabs item from queue
|
# grabs item from queue
|
||||||
try:
|
try:
|
||||||
|
@ -117,7 +120,7 @@ class ThreadedProcessMetadata(threading.Thread):
|
||||||
continue
|
continue
|
||||||
# Do the work; lock to be sure we've only got 1 Thread
|
# Do the work; lock to be sure we've only got 1 Thread
|
||||||
with self.lock:
|
with self.lock:
|
||||||
item.add_update(
|
itemSubFkt(
|
||||||
plexitem,
|
plexitem,
|
||||||
viewtag=viewName,
|
viewtag=viewName,
|
||||||
viewid=viewId
|
viewid=viewId
|
||||||
|
@ -159,19 +162,19 @@ 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 +
|
"%s: Sync %s: %s items" % (self.addonName,
|
||||||
': ' + str(total) + 'items',
|
self.viewName,
|
||||||
"Starting"
|
str(total)),
|
||||||
)
|
"Starting")
|
||||||
global getMetadataCount
|
global getMetadataCount
|
||||||
global processMetadataCount
|
global processMetadataCount
|
||||||
total = 2 * total
|
total = 2 * total
|
||||||
totalProgress = 0
|
totalProgress = 0
|
||||||
while self.stopped() is not True:
|
while self.stopped() is False:
|
||||||
with downloadLock:
|
with downloadLock:
|
||||||
getMetadataProgress = getMetadataCount
|
getMetadataProgress = getMetadataCount
|
||||||
with processLock:
|
#with processLock:
|
||||||
processMetadataProgress = processMetadataCount
|
processMetadataProgress = processMetadataCount
|
||||||
totalProgress = getMetadataProgress + processMetadataProgress
|
totalProgress = getMetadataProgress + processMetadataProgress
|
||||||
try:
|
try:
|
||||||
percentage = int(float(totalProgress) / float(total)*100.0)
|
percentage = int(float(totalProgress) / float(total)*100.0)
|
||||||
|
@ -182,7 +185,7 @@ class ThreadedShowSyncInfo(threading.Thread):
|
||||||
message="Downloaded: %s, Processed: %s" %
|
message="Downloaded: %s, Processed: %s" %
|
||||||
(getMetadataProgress, processMetadataProgress)
|
(getMetadataProgress, processMetadataProgress)
|
||||||
)
|
)
|
||||||
time.sleep(0.5)
|
time.sleep(1)
|
||||||
|
|
||||||
def stopThread(self):
|
def stopThread(self):
|
||||||
self._shouldstop.set()
|
self._shouldstop.set()
|
||||||
|
@ -345,16 +348,17 @@ class LibrarySync(threading.Thread):
|
||||||
# embyconn.commit()
|
# embyconn.commit()
|
||||||
self.initializeDBs()
|
self.initializeDBs()
|
||||||
# Sync video library
|
# Sync video library
|
||||||
process = {
|
# process = {
|
||||||
|
|
||||||
'movies': self.movies,
|
# 'movies': self.movies,
|
||||||
'musicvideos': self.musicvideos,
|
# 'musicvideos': self.musicvideos,
|
||||||
'tvshows': self.tvshows,
|
# 'tvshows': self.tvshows,
|
||||||
'homevideos': self.homevideos
|
# 'homevideos': self.homevideos
|
||||||
}
|
# }
|
||||||
|
|
||||||
process = {
|
process = {
|
||||||
'movies': self.PlexMovies
|
'movies': self.PlexMovies,
|
||||||
|
'tvshows': self.PlexTVShows
|
||||||
# 'tvshows': self.PlexTVShows
|
# 'tvshows': self.PlexTVShows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,30 +589,34 @@ class LibrarySync(threading.Thread):
|
||||||
"""
|
"""
|
||||||
if self.compare:
|
if self.compare:
|
||||||
# Manual sync
|
# Manual sync
|
||||||
for plexmovie in elementList:
|
for item in elementList:
|
||||||
if self.shouldStop():
|
# Only look at valid items = Plex library items
|
||||||
return False
|
if item.get('ratingKey', False):
|
||||||
API = PlexAPI.API(plexmovie)
|
if self.shouldStop():
|
||||||
plex_checksum = API.getChecksum()
|
return False
|
||||||
itemid = API.getKey()
|
API = PlexAPI.API(item)
|
||||||
self.allPlexElementsId[itemid] = plex_checksum
|
plex_checksum = API.getChecksum()
|
||||||
kodi_checksum = self.allKodiElementsId.get(itemid)
|
itemid = API.getKey()
|
||||||
if kodi_checksum != plex_checksum:
|
self.allPlexElementsId[itemid] = plex_checksum
|
||||||
# Only update if movie is not in Kodi or checksum is
|
kodi_checksum = self.allKodiElementsId.get(itemid)
|
||||||
# different
|
if kodi_checksum != plex_checksum:
|
||||||
self.updatelist.append(itemid)
|
# Only update if movie is not in Kodi or checksum is
|
||||||
|
# different
|
||||||
|
self.updatelist.append(itemid)
|
||||||
else:
|
else:
|
||||||
# Initial or repair sync: get all Plex movies
|
# Initial or repair sync: get all Plex movies
|
||||||
for plexmovie in elementList:
|
for item in elementList:
|
||||||
API = PlexAPI.API(plexmovie)
|
# Only look at valid items = Plex library items
|
||||||
itemid = API.getKey()
|
if item.get('ratingKey', False):
|
||||||
plex_checksum = API.getChecksum()
|
API = PlexAPI.API(item)
|
||||||
self.allPlexElementsId[itemid] = plex_checksum
|
itemid = API.getKey()
|
||||||
self.updatelist.append(itemid)
|
plex_checksum = API.getChecksum()
|
||||||
|
self.allPlexElementsId[itemid] = plex_checksum
|
||||||
|
self.updatelist.append(itemid)
|
||||||
# Update the Kodi popup info
|
# Update the Kodi popup info
|
||||||
return self.updatelist, self.allPlexElementsId
|
return self.updatelist, self.allPlexElementsId
|
||||||
|
|
||||||
def GetAndProcessXMLs(self, itemType, viewName, viewId):
|
def GetAndProcessXMLs(self, itemType, viewName, viewId, method):
|
||||||
"""
|
"""
|
||||||
Downloads all XMLs for itemType (e.g. Movies, TV-Shows). Processes them
|
Downloads all XMLs for itemType (e.g. Movies, TV-Shows). Processes them
|
||||||
by then calling itemtypes.<itemType>()
|
by then calling itemtypes.<itemType>()
|
||||||
|
@ -617,6 +625,8 @@ class LibrarySync(threading.Thread):
|
||||||
itemType: to construct itemtypes.py function name: 'Movies'
|
itemType: to construct itemtypes.py function name: 'Movies'
|
||||||
viewName: Plex name of library, e.g. 'My Movies'
|
viewName: Plex name of library, e.g. 'My Movies'
|
||||||
viewId: Plex Id for that library
|
viewId: Plex Id for that library
|
||||||
|
method: name of itemtypes.py method,
|
||||||
|
e.g. 'add_updateSeason'
|
||||||
|
|
||||||
Returns True if/when done
|
Returns True if/when done
|
||||||
"""
|
"""
|
||||||
|
@ -639,6 +649,9 @@ class LibrarySync(threading.Thread):
|
||||||
getMetadataCount = 0
|
getMetadataCount = 0
|
||||||
global processMetadataCount
|
global processMetadataCount
|
||||||
processMetadataCount = 0
|
processMetadataCount = 0
|
||||||
|
# Populate queue: GetMetadata
|
||||||
|
for itemId in self.updatelist:
|
||||||
|
getMetadataQueue.put(itemId)
|
||||||
# Spawn GetMetadata threads
|
# Spawn GetMetadata threads
|
||||||
threads = []
|
threads = []
|
||||||
for i in range(self.syncThreadNumber):
|
for i in range(self.syncThreadNumber):
|
||||||
|
@ -652,13 +665,11 @@ class LibrarySync(threading.Thread):
|
||||||
t.start()
|
t.start()
|
||||||
threads.append(t)
|
threads.append(t)
|
||||||
self.logMsg("%s download threads spawned" % self.syncThreadNumber, 1)
|
self.logMsg("%s download threads spawned" % self.syncThreadNumber, 1)
|
||||||
# Populate queue: GetMetadata
|
|
||||||
for itemId in self.updatelist:
|
|
||||||
getMetadataQueue.put(itemId)
|
|
||||||
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': itemType,
|
'itemType': itemType,
|
||||||
|
'method': method,
|
||||||
'viewName': viewName,
|
'viewName': viewName,
|
||||||
'viewId': viewId
|
'viewId': viewId
|
||||||
}
|
}
|
||||||
|
@ -714,7 +725,6 @@ class LibrarySync(threading.Thread):
|
||||||
self.logMsg("%s compare finished." % itemType, 1)
|
self.logMsg("%s compare finished." % itemType, 1)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def PlexMovies(self):
|
def PlexMovies(self):
|
||||||
# Initialize
|
# Initialize
|
||||||
plx = PlexAPI.PlexAPI()
|
plx = PlexAPI.PlexAPI()
|
||||||
|
@ -724,21 +734,20 @@ class LibrarySync(threading.Thread):
|
||||||
views = plx.GetPlexCollections('movie')
|
views = plx.GetPlexCollections('movie')
|
||||||
self.logMsg("Media folders: %s" % views, 1)
|
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:
|
if self.compare:
|
||||||
|
# Get movies from Plex server
|
||||||
|
embyconn = utils.kodiSQL('emby')
|
||||||
|
embycursor = embyconn.cursor()
|
||||||
|
emby_db = embydb.Embydb_Functions(embycursor)
|
||||||
# Pull the list of movies and boxsets in Kodi
|
# Pull the list of movies and boxsets in Kodi
|
||||||
try:
|
try:
|
||||||
self.allKodiElementsId = dict(emby_db.getChecksum('Movie'))
|
self.allKodiElementsId = dict(emby_db.getChecksum('Movie'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.allKodiElementsId = {}
|
self.allKodiElementsId = {}
|
||||||
|
embyconn.close()
|
||||||
else:
|
else:
|
||||||
# Getting all metadata, hence set Kodi elements to {}
|
# Getting all metadata, hence set Kodi elements to {}
|
||||||
self.allKodiElementsId = {}
|
self.allKodiElementsId = {}
|
||||||
embyconn.close()
|
|
||||||
|
|
||||||
##### PROCESS MOVIES #####
|
##### PROCESS MOVIES #####
|
||||||
for view in views:
|
for view in views:
|
||||||
|
@ -752,177 +761,14 @@ class LibrarySync(threading.Thread):
|
||||||
# Populate self.updatelist and self.allPlexElementsId
|
# Populate self.updatelist and self.allPlexElementsId
|
||||||
self.GetUpdatelist(all_plexmovies)
|
self.GetUpdatelist(all_plexmovies)
|
||||||
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
|
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
|
||||||
# Returns True if successful
|
result = self.GetAndProcessXMLs(
|
||||||
result = self.GetAndProcessXMLs('Movies', viewName, viewId)
|
'Movies',
|
||||||
|
viewName,
|
||||||
|
viewId,
|
||||||
|
'add_update'
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def movies(self, embycursor, kodicursor, pdialog, compare=False):
|
|
||||||
# Get movies from emby
|
|
||||||
emby = self.emby
|
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
|
||||||
movies = itemtypes.Movies(embycursor, kodicursor)
|
|
||||||
|
|
||||||
views = emby_db.getView_byType('movies')
|
|
||||||
views += emby_db.getView_byType('mixed')
|
|
||||||
self.logMsg("Media folders: %s" % views, 1)
|
|
||||||
|
|
||||||
if compare:
|
|
||||||
# Pull the list of movies and boxsets in Kodi
|
|
||||||
try:
|
|
||||||
all_kodimovies = 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 = []
|
|
||||||
|
|
||||||
##### 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="Emby for Kodi",
|
|
||||||
message="Gathering movies from view: %s..." % viewName)
|
|
||||||
|
|
||||||
if compare:
|
|
||||||
# Manual sync
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(
|
|
||||||
heading="Emby for Kodi",
|
|
||||||
message="Comparing movies from view: %s..." % viewName)
|
|
||||||
|
|
||||||
all_embymovies = emby.getMovies(viewId, basic=True)
|
|
||||||
for embymovie in all_embymovies['Items']:
|
|
||||||
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
API = api.API(embymovie)
|
|
||||||
itemid = embymovie['Id']
|
|
||||||
all_embymoviesIds.add(itemid)
|
|
||||||
|
|
||||||
|
|
||||||
if all_kodimovies.get(itemid) != API.getChecksum():
|
|
||||||
# Only update if movie is not in Kodi or checksum is different
|
|
||||||
updatelist.append(itemid)
|
|
||||||
|
|
||||||
self.logMsg("Movies to update for %s: %s" % (viewName, updatelist), 1)
|
|
||||||
embymovies = emby.getFullItems(updatelist)
|
|
||||||
total = len(updatelist)
|
|
||||||
del updatelist[:]
|
|
||||||
else:
|
|
||||||
# Initial or repair sync
|
|
||||||
all_embymovies = emby.getMovies(viewId)
|
|
||||||
total = all_embymovies['TotalRecordCount']
|
|
||||||
embymovies = all_embymovies['Items']
|
|
||||||
|
|
||||||
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
for embymovie in embymovies:
|
|
||||||
# Process individual movies
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
title = embymovie['Name']
|
|
||||||
if pdialog:
|
|
||||||
percentage = int((float(count) / float(total))*100)
|
|
||||||
pdialog.update(percentage, message=title)
|
|
||||||
count += 1
|
|
||||||
movies.add_update(embymovie, viewName, viewId)
|
|
||||||
else:
|
|
||||||
self.logMsg("Movies finished.", 2)
|
|
||||||
|
|
||||||
|
|
||||||
##### PROCESS BOXSETS #####
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(heading="Emby for Kodi", message="Gathering boxsets from server...")
|
|
||||||
|
|
||||||
boxsets = emby.getBoxset()
|
|
||||||
|
|
||||||
if compare:
|
|
||||||
# Manual sync
|
|
||||||
embyboxsets = []
|
|
||||||
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(
|
|
||||||
heading="Emby for Kodi",
|
|
||||||
message="Comparing boxsets...")
|
|
||||||
|
|
||||||
for boxset in boxsets['Items']:
|
|
||||||
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Boxset has no real userdata, so using etag to compare
|
|
||||||
checksum = boxset['Etag']
|
|
||||||
itemid = boxset['Id']
|
|
||||||
all_embyboxsetsIds.add(itemid)
|
|
||||||
|
|
||||||
if all_kodisets.get(itemid) != checksum:
|
|
||||||
# Only update if boxset is not in Kodi or checksum is different
|
|
||||||
updatelist.append(itemid)
|
|
||||||
embyboxsets.append(boxset)
|
|
||||||
|
|
||||||
self.logMsg("Boxsets to update: %s" % updatelist, 1)
|
|
||||||
total = len(updatelist)
|
|
||||||
else:
|
|
||||||
total = boxsets['TotalRecordCount']
|
|
||||||
embyboxsets = boxsets['Items']
|
|
||||||
|
|
||||||
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(heading="Processing Boxsets / %s items" % total)
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
for boxset in embyboxsets:
|
|
||||||
# Process individual boxset
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
title = boxset['Name']
|
|
||||||
if pdialog:
|
|
||||||
percentage = int((float(count) / float(total))*100)
|
|
||||||
pdialog.update(percentage, message=title)
|
|
||||||
count += 1
|
|
||||||
movies.add_updateBoxset(boxset)
|
|
||||||
else:
|
|
||||||
self.logMsg("Boxsets finished.", 2)
|
|
||||||
|
|
||||||
|
|
||||||
##### PROCESS DELETES #####
|
|
||||||
if compare:
|
|
||||||
# Manual sync, process deletes
|
|
||||||
for kodimovie in all_kodimovies:
|
|
||||||
if kodimovie not in all_embymoviesIds:
|
|
||||||
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 musicvideos(self, embycursor, kodicursor, pdialog, compare=False):
|
def musicvideos(self, embycursor, kodicursor, pdialog, compare=False):
|
||||||
# Get musicvideos from emby
|
# Get musicvideos from emby
|
||||||
emby = self.emby
|
emby = self.emby
|
||||||
|
@ -1111,22 +957,21 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def PlexTVShows(self, embycursor, kodicursor):
|
def PlexTVShows(self):
|
||||||
# Initialize
|
# Initialize
|
||||||
plx = PlexAPI.PlexAPI()
|
plx = PlexAPI.PlexAPI()
|
||||||
compare = self.compare
|
|
||||||
pdialog = self.pDialog
|
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
self.allPlexElementsId = {}
|
self.allPlexElementsId = {}
|
||||||
# Get shows from emby
|
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
|
||||||
tvshows = itemtypes.TVShows(embycursor, kodicursor)
|
|
||||||
|
|
||||||
views = plx.GetPlexCollections('show')
|
views = plx.GetPlexCollections('show')
|
||||||
self.logMsg("Media folders: %s" % views, 1)
|
self.logMsg("Media folders: %s" % views, 1)
|
||||||
|
|
||||||
self.allKodiElementsId = {}
|
self.allKodiElementsId = {}
|
||||||
if compare:
|
if self.compare:
|
||||||
|
# Get movies from Plex server
|
||||||
|
embyconn = utils.kodiSQL('emby')
|
||||||
|
embycursor = embyconn.cursor()
|
||||||
|
emby_db = embydb.Embydb_Functions(embycursor)
|
||||||
# Pull the list of TV shows already in Kodi
|
# Pull the list of TV shows already in Kodi
|
||||||
try:
|
try:
|
||||||
all_koditvshows = dict(emby_db.getChecksum('Series'))
|
all_koditvshows = dict(emby_db.getChecksum('Series'))
|
||||||
|
@ -1139,145 +984,64 @@ class LibrarySync(threading.Thread):
|
||||||
self.allKodiElementsId.update(all_kodiepisodes)
|
self.allKodiElementsId.update(all_kodiepisodes)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
embyconn.close()
|
||||||
|
|
||||||
|
##### PROCESS TV Shows #####
|
||||||
for view in views:
|
for view in views:
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
|
self.allPlexElementsId = {}
|
||||||
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:
|
allPlexTvShows = plx.GetPlexSectionResults(viewId)
|
||||||
pdialog.update(
|
# Populate self.updatelist and self.allPlexElementsId
|
||||||
heading=self.addonName,
|
self.GetUpdatelist(allPlexTvShows)
|
||||||
message="Gathering TV Shows from view: %s..." % viewName)
|
# Process self.updatelist
|
||||||
all_plexTvShows = plx.GetPlexSectionResults(viewId)
|
self.GetAndProcessXMLs('TVShows',
|
||||||
|
viewName,
|
||||||
|
viewId,
|
||||||
|
'add_update')
|
||||||
|
self.logMsg("Processed view %s with ID %s" % (viewName, viewId), 1)
|
||||||
|
|
||||||
# Populate self.updatelist with TV shows and self.allPlexElementsId
|
# Save for later use
|
||||||
self.GetUpdatelist(all_plexTvShows, viewName)
|
allPlexTvShowsId = self.allPlexElementsId
|
||||||
|
|
||||||
# Run through self.updatelist, get XML metadata per item and safe
|
##### PROCESS TV Seasons #####
|
||||||
# to Kodi
|
# Cycle through tv shows
|
||||||
self.ProcessUpdateList(tvshows, view)
|
for tvShowId in allPlexTvShowsId:
|
||||||
|
self.updatelist = []
|
||||||
|
self.allPlexElementsId = {}
|
||||||
|
# Grab all seasons to tvshow from PMS
|
||||||
|
seasons = plx.GetAllPlexChildren(tvShowId)
|
||||||
|
# Populate self.updatelist and self.allPlexElementsId
|
||||||
|
self.GetUpdatelist(seasons)
|
||||||
|
# Process self.updatelist
|
||||||
|
self.GetAndProcessXMLs('TVShows',
|
||||||
|
None,
|
||||||
|
tvShowId, # send showId instead of viewid
|
||||||
|
'add_updateSeason')
|
||||||
|
XMLtvshow = plx.GetPlexMetadata(tvShowId)
|
||||||
|
with itemtypes.TVShows() as TVshow:
|
||||||
|
TVshow.refreshSeasonEntry(XMLtvshow, tvShowId)
|
||||||
|
self.logMsg("Processed all seasons of TV show with Plex Id %s" % tvShowId, 1)
|
||||||
|
|
||||||
|
##### PROCESS TV Episodes #####
|
||||||
|
# Cycle through tv shows
|
||||||
if compare:
|
for tvShowId in allPlexTvShowsId:
|
||||||
# Manual sync
|
self.updatelist = []
|
||||||
for plexTvShow in all_plexTvShows:
|
self.allPlexElementsId = {}
|
||||||
if self.shouldStop():
|
# Grab all episodes to tvshow from PMS
|
||||||
return False
|
episodes = plx.GetAllPlexLeaves(tvShowId)
|
||||||
API = plx(plexTvShow)
|
# Populate self.updatelist and self.allPlexElementsId
|
||||||
plex_checksum = API.getChecksum()
|
self.GetUpdatelist(episodes)
|
||||||
itemid = API.getKey()
|
# Process self.updatelist
|
||||||
kodi_checksum = all_kodimoviesId.get(itemid)
|
self.GetAndProcessXMLs('TVShows',
|
||||||
all_plextvshowsIds[itemid] = itemid
|
None,
|
||||||
kodi_checksum = all_koditvshows.get(itemid)
|
None,
|
||||||
#if kodi_checksum != plex_checksum:
|
'add_updateEpisode')
|
||||||
|
self.logMsg("Processed all episodes of TV show with Plex Id %s" % tvShowId, 1)
|
||||||
|
|
||||||
if all_koditvshows.get(itemid) != API.getChecksum():
|
|
||||||
# Only update if movie is not in Kodi or checksum is different
|
|
||||||
updatelist.append(itemid)
|
|
||||||
|
|
||||||
self.logMsg("TVShows to update for %s: %s" % (viewName, updatelist), 1)
|
|
||||||
embytvshows = emby.getFullItems(updatelist)
|
|
||||||
total = len(updatelist)
|
|
||||||
del updatelist[:]
|
|
||||||
else:
|
|
||||||
all_embytvshows = emby.getShows(viewId)
|
|
||||||
total = all_embytvshows['TotalRecordCount']
|
|
||||||
embytvshows = all_embytvshows['Items']
|
|
||||||
|
|
||||||
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
for embytvshow in embytvshows:
|
|
||||||
# Process individual show
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
itemid = embytvshow['Id']
|
|
||||||
title = embytvshow['Name']
|
|
||||||
if pdialog:
|
|
||||||
percentage = int((float(count) / float(total))*100)
|
|
||||||
pdialog.update(percentage, message=title)
|
|
||||||
count += 1
|
|
||||||
tvshows.add_update(embytvshow, viewName, viewId)
|
|
||||||
|
|
||||||
if not compare:
|
|
||||||
# Process episodes
|
|
||||||
all_episodes = emby.getEpisodesbyShow(itemid)
|
|
||||||
for episode in all_episodes['Items']:
|
|
||||||
|
|
||||||
# Process individual show
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
episodetitle = episode['Name']
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(percentage, message="%s - %s" % (title, episodetitle))
|
|
||||||
tvshows.add_updateEpisode(episode)
|
|
||||||
else:
|
|
||||||
if compare:
|
|
||||||
# Get all episodes in view
|
|
||||||
if pdialog:
|
|
||||||
pdialog.update(
|
|
||||||
heading="Emby for Kodi",
|
|
||||||
message="Comparing episodes from view: %s..." % viewName)
|
|
||||||
|
|
||||||
all_embyepisodes = emby.getEpisodes(viewId, basic=True)
|
|
||||||
for embyepisode in all_embyepisodes['Items']:
|
|
||||||
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
API = api.API(embyepisode)
|
|
||||||
itemid = embyepisode['Id']
|
|
||||||
all_embyepisodesIds.add(itemid)
|
|
||||||
|
|
||||||
if all_kodiepisodes.get(itemid) != API.getChecksum():
|
|
||||||
# Only update if movie is not in Kodi or checksum is different
|
|
||||||
updatelist.append(itemid)
|
|
||||||
|
|
||||||
self.logMsg("Episodes to update for %s: %s" % (viewName, updatelist), 1)
|
|
||||||
embyepisodes = emby.getFullItems(updatelist)
|
|
||||||
total = len(updatelist)
|
|
||||||
del updatelist[:]
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
for episode in embyepisodes:
|
|
||||||
|
|
||||||
# Process individual episode
|
|
||||||
if self.shouldStop():
|
|
||||||
return False
|
|
||||||
|
|
||||||
title = episode['SeriesName']
|
|
||||||
episodetitle = episode['Name']
|
|
||||||
if pdialog:
|
|
||||||
percentage = int((float(count) / float(total))*100)
|
|
||||||
pdialog.update(percentage, message="%s - %s" % (title, episodetitle))
|
|
||||||
count += 1
|
|
||||||
tvshows.add_updateEpisode(episode)
|
|
||||||
else:
|
|
||||||
self.logMsg("TVShows finished.", 2)
|
|
||||||
|
|
||||||
##### PROCESS DELETES #####
|
|
||||||
if compare:
|
|
||||||
# Manual sync, process deletes
|
|
||||||
for koditvshow in all_koditvshows:
|
|
||||||
if koditvshow not in all_embytvshowsIds:
|
|
||||||
tvshows.remove(koditvshow)
|
|
||||||
else:
|
|
||||||
self.logMsg("TVShows compare finished.", 1)
|
|
||||||
|
|
||||||
for kodiepisode in all_kodiepisodes:
|
|
||||||
if kodiepisode not in all_embyepisodesIds:
|
|
||||||
tvshows.remove(kodiepisode)
|
|
||||||
else:
|
|
||||||
self.logMsg("Episodes compare finished.", 1)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue