Merge pull request #841 from croneter/section-uuid

Safe Plex librarySectionUUID to our plex.db to speed up certain operations
This commit is contained in:
croneter 2019-04-27 12:07:27 +02:00 committed by GitHub
commit edb9d6e2b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 196 additions and 170 deletions

View file

@ -14,8 +14,7 @@ class Movie(ItemBase):
""" """
Used for plex library-type movies Used for plex library-type movies
""" """
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None):
children=None):
""" """
Process single movie Process single movie
""" """
@ -174,7 +173,7 @@ class Movie(ItemBase):
self.kodidb.modify_streams(file_id, api.mediastreams(), runtime) self.kodidb.modify_streams(file_id, api.mediastreams(), runtime)
self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_MOVIE, studios) self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_MOVIE, studios)
tags = [section_name] tags = [section.name]
if collections: if collections:
for plex_set_id, set_name in collections: for plex_set_id, set_name in collections:
set_api = None set_api = None
@ -189,7 +188,7 @@ class Movie(ItemBase):
# e.g. when added via websocket # e.g. when added via websocket
LOG.debug('Costly looking up Plex collection %s: %s', LOG.debug('Costly looking up Plex collection %s: %s',
plex_set_id, set_name) plex_set_id, set_name)
for index, coll_plex_id in api.collections_match(section_id): for index, coll_plex_id in api.collections_match(section.id):
# Get Plex artwork for collections - a pain # Get Plex artwork for collections - a pain
if index == plex_set_id: if index == plex_set_id:
set_xml = PF.GetPlexMetadata(coll_plex_id) set_xml = PF.GetPlexMetadata(coll_plex_id)
@ -217,7 +216,8 @@ class Movie(ItemBase):
dateplayed) dateplayed)
self.plexdb.add_movie(plex_id=plex_id, self.plexdb.add_movie(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section.id,
section_uuid=section.uuid,
kodi_id=kodi_id, kodi_id=kodi_id,
kodi_fileid=file_id, kodi_fileid=file_id,
kodi_pathid=kodi_pathid, kodi_pathid=kodi_pathid,

View file

@ -154,8 +154,7 @@ class Artist(MusicMixin, ItemBase):
""" """
For Plex library-type artists For Plex library-type artists
""" """
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None):
children=None):
""" """
Process a single artist Process a single artist
""" """
@ -210,14 +209,14 @@ class Artist(MusicMixin, ItemBase):
v.KODI_TYPE_ARTIST) v.KODI_TYPE_ARTIST)
self.plexdb.add_artist(plex_id, self.plexdb.add_artist(plex_id,
api.checksum(), api.checksum(),
section_id, section.id,
section.uuid,
kodi_id, kodi_id,
self.last_sync) self.last_sync)
class Album(MusicMixin, ItemBase): class Album(MusicMixin, ItemBase):
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None, scan_children=True):
children=None, scan_children=True):
""" """
Process a single album Process a single album
scan_children: set to False if you don't want to add children, e.g. to scan_children: set to False if you don't want to add children, e.g. to
@ -250,8 +249,7 @@ class Album(MusicMixin, ItemBase):
Artist(self.last_sync, Artist(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(artist_xml[0], kodidb=self.kodidb).add_update(artist_xml[0],
section_name, section=section)
section_id)
artist = self.plexdb.artist(parent_id) artist = self.plexdb.artist(parent_id)
if not artist: if not artist:
LOG.error('Adding artist %s failed for %s', LOG.error('Adding artist %s failed for %s',
@ -363,7 +361,8 @@ class Album(MusicMixin, ItemBase):
v.KODI_TYPE_ALBUM) v.KODI_TYPE_ALBUM)
self.plexdb.add_album(plex_id, self.plexdb.add_album(plex_id,
api.checksum(), api.checksum(),
section_id, section.id,
section.uuid,
artist_id, artist_id,
parent_id, parent_id,
kodi_id, kodi_id,
@ -375,8 +374,7 @@ class Album(MusicMixin, ItemBase):
kodidb=self.kodidb) kodidb=self.kodidb)
for song in children: for song in children:
context.add_update(song, context.add_update(song,
section_name=section_name, section=section,
section_id=section_id,
album_xml=xml, album_xml=xml,
genres=genres, genres=genres,
genre=genre, genre=genre,
@ -384,9 +382,8 @@ class Album(MusicMixin, ItemBase):
class Song(MusicMixin, ItemBase): class Song(MusicMixin, ItemBase):
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None, album_xml=None,
children=None, album_xml=None, genres=None, genre=None, genres=None, genre=None, compilation=None):
compilation=None):
""" """
Process single song/track Process single song/track
""" """
@ -421,8 +418,7 @@ class Song(MusicMixin, ItemBase):
Artist(self.last_sync, Artist(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(artist_xml[0], kodidb=self.kodidb).add_update(artist_xml[0],
section_name, section=section)
section_id)
artist = self.plexdb.artist(artist_id) artist = self.plexdb.artist(artist_id)
if not artist: if not artist:
LOG.error('Still could not find grandparent artist %s for %s', LOG.error('Still could not find grandparent artist %s for %s',
@ -477,8 +473,7 @@ class Song(MusicMixin, ItemBase):
Album(self.last_sync, Album(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(album_xml[0], kodidb=self.kodidb).add_update(album_xml[0],
section_name, section=section,
section_id,
children=[xml], children=[xml],
scan_children=False) scan_children=False)
album = self.plexdb.album(album_id) album = self.plexdb.album(album_id)
@ -659,7 +654,8 @@ class Song(MusicMixin, ItemBase):
v.KODI_TYPE_ALBUM) v.KODI_TYPE_ALBUM)
self.plexdb.add_song(plex_id, self.plexdb.add_song(plex_id,
api.checksum(), api.checksum(),
section_id, section.id,
section.uuid,
artist_id, artist_id,
grandparent_id, grandparent_id,
album_id, album_id,

View file

@ -143,8 +143,7 @@ class Show(TvShowMixin, ItemBase):
""" """
For Plex library-type TV shows For Plex library-type TV shows
""" """
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None):
children=None):
""" """
Process a single show Process a single show
""" """
@ -274,20 +273,20 @@ class Show(TvShowMixin, ItemBase):
# Process studios # Process studios
self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_SHOW, studios) self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_SHOW, studios)
# Process tags: view, PMS collection tags # Process tags: view, PMS collection tags
tags = [section_name] tags = [section.name]
tags.extend([i for _, i in api.collection_list()]) tags.extend([i for _, i in api.collection_list()])
self.kodidb.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags) self.kodidb.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags)
self.plexdb.add_show(plex_id=plex_id, self.plexdb.add_show(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section.id,
section_uuid=section.uuid,
kodi_id=kodi_id, kodi_id=kodi_id,
kodi_pathid=kodi_pathid, kodi_pathid=kodi_pathid,
last_sync=self.last_sync) last_sync=self.last_sync)
class Season(TvShowMixin, ItemBase): class Season(TvShowMixin, ItemBase):
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None):
children=None):
""" """
Process a single season of a certain tv show Process a single season of a certain tv show
""" """
@ -315,8 +314,7 @@ class Season(TvShowMixin, ItemBase):
Show(self.last_sync, Show(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(show_xml[0], kodidb=self.kodidb).add_update(show_xml[0],
section_name, section=section)
section_id)
show = self.plexdb.show(show_id) show = self.plexdb.show(show_id)
if not show: if not show:
LOG.error('Still could not find parent tv show %s', show_id) LOG.error('Still could not find parent tv show %s', show_id)
@ -346,7 +344,8 @@ class Season(TvShowMixin, ItemBase):
v.KODI_TYPE_SEASON) v.KODI_TYPE_SEASON)
self.plexdb.add_season(plex_id=plex_id, self.plexdb.add_season(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section.id,
section_uuid=section.uuid,
show_id=show_id, show_id=show_id,
parent_id=parent_id, parent_id=parent_id,
kodi_id=kodi_id, kodi_id=kodi_id,
@ -354,8 +353,7 @@ class Season(TvShowMixin, ItemBase):
class Episode(TvShowMixin, ItemBase): class Episode(TvShowMixin, ItemBase):
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section, children=None):
children=None):
""" """
Process single episode Process single episode
""" """
@ -402,8 +400,7 @@ class Episode(TvShowMixin, ItemBase):
Show(self.last_sync, Show(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(show_xml[0], kodidb=self.kodidb).add_update(show_xml[0],
section_name, section=section)
section_id)
show = self.plexdb.show(show_id) show = self.plexdb.show(show_id)
if not show: if not show:
LOG.error('Still could not find grandparent tv show %s', show_id) LOG.error('Still could not find grandparent tv show %s', show_id)
@ -423,8 +420,7 @@ class Episode(TvShowMixin, ItemBase):
Season(self.last_sync, Season(self.last_sync,
plexdb=self.plexdb, plexdb=self.plexdb,
kodidb=self.kodidb).add_update(season_xml[0], kodidb=self.kodidb).add_update(season_xml[0],
section_name, section=section)
section_id)
season = self.plexdb.season(season_id) season = self.plexdb.season(season_id)
if not season: if not season:
LOG.error('Still could not find parent season %s', season_id) LOG.error('Still could not find parent season %s', season_id)
@ -543,7 +539,8 @@ class Episode(TvShowMixin, ItemBase):
userdata['LastPlayedDate']) userdata['LastPlayedDate'])
self.plexdb.add_episode(plex_id=plex_id, self.plexdb.add_episode(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section.id,
section_uuid=section.uuid,
show_id=show_id, show_id=show_id,
grandparent_id=grandparent_id, grandparent_id=grandparent_id,
season_id=season_id, season_id=season_id,
@ -619,7 +616,8 @@ class Episode(TvShowMixin, ItemBase):
userdata['LastPlayedDate']) userdata['LastPlayedDate'])
self.plexdb.add_episode(plex_id=plex_id, self.plexdb.add_episode(plex_id=plex_id,
checksum=api.checksum(), checksum=api.checksum(),
section_id=section_id, section_id=section.id,
section_uuid=section.uuid,
show_id=show_id, show_id=show_id,
grandparent_id=grandparent_id, grandparent_id=grandparent_id,
season_id=season_id, season_id=season_id,

View file

@ -25,18 +25,16 @@ UPDATED_AT_SAFETY = 60 * 5
LAST_VIEWED_AT_SAFETY = 60 * 5 LAST_VIEWED_AT_SAFETY = 60 * 5
class InitNewSection(object): class InitNewSection(sections.Section):
""" """
Throw this into the queue used for ProcessMetadata to tell it which Throw this into the queue used for ProcessMetadata to tell it which
Plex library section we're looking at Plex library section we're looking at
""" """
def __init__(self, context, total_number_of_items, section_name, def __init__(self, total_number_of_items, section):
section_id, plex_type): super(InitNewSection, self).__init__()
self.context = context # Copy all section attributes to this instance
self.__dict__.update(section.__dict__)
self.total = total_number_of_items self.total = total_number_of_items
self.name = section_name
self.id = section_id
self.plex_type = plex_type
class FullSync(common.fullsync_mixin): class FullSync(common.fullsync_mixin):
@ -140,8 +138,7 @@ class FullSync(common.fullsync_mixin):
self.queue.task_done() self.queue.task_done()
if isinstance(item, dict): if isinstance(item, dict):
context.add_update(item['xml'][0], context.add_update(item['xml'][0],
section_name=section.name, section=section,
section_id=section.id,
children=item['children']) children=item['children'])
self.title = item['xml'][0].get('title') self.title = item['xml'][0].get('title')
self.processed += 1 self.processed += 1
@ -168,12 +165,7 @@ class FullSync(common.fullsync_mixin):
# Sync new, updated and deleted items # Sync new, updated and deleted items
iterator = section.iterator iterator = section.iterator
# Tell the processing thread about this new section # Tell the processing thread about this new section
queue_info = InitNewSection(section.context, queue_info = InitNewSection(iterator.total, section)
iterator.total,
iterator.get('librarySectionTitle',
iterator.get('title1')),
section.section_id,
section.plex_type)
self.queue.put(queue_info) self.queue.put(queue_info)
last = True last = True
# To keep track of the item-number in order to kill while loops # To keep track of the item-number in order to kill while loops
@ -211,11 +203,7 @@ class FullSync(common.fullsync_mixin):
# Sync new, updated and deleted items # Sync new, updated and deleted items
iterator = section.iterator iterator = section.iterator
# Tell the processing thread about this new section # Tell the processing thread about this new section
queue_info = InitNewSection(section.context, queue_info = InitNewSection(iterator.total, section)
iterator.total,
section.name,
section.section_id,
section.plex_type)
self.queue.put(queue_info) self.queue.put(queue_info)
self.total = iterator.total self.total = iterator.total
self.section_name = section.name self.section_name = section.name
@ -233,8 +221,7 @@ class FullSync(common.fullsync_mixin):
if not itemtype.update_userdata(xml_item, section.plex_type): if not itemtype.update_userdata(xml_item, section.plex_type):
# Somehow did not sync this item yet # Somehow did not sync this item yet
itemtype.add_update(xml_item, itemtype.add_update(xml_item,
section_name=section.name, section=section)
section_id=section.section_id)
itemtype.plexdb.update_last_sync(int(xml_item.attrib['ratingKey']), itemtype.plexdb.update_last_sync(int(xml_item.attrib['ratingKey']),
section.plex_type, section.plex_type,
self.current_sync) self.current_sync)
@ -274,7 +261,7 @@ class FullSync(common.fullsync_mixin):
updated_at = section.last_sync - UPDATED_AT_SAFETY \ updated_at = section.last_sync - UPDATED_AT_SAFETY \
if section.last_sync else None if section.last_sync else None
try: try:
element.iterator = PF.SectionItems(section.section_id, element.iterator = PF.SectionItems(section.id,
plex_type=element.plex_type, plex_type=element.plex_type,
updated_at=updated_at, updated_at=updated_at,
last_viewed_at=None) last_viewed_at=None)
@ -331,7 +318,7 @@ class FullSync(common.fullsync_mixin):
# some items from the PMS # some items from the PMS
with PlexDB() as plexdb: with PlexDB() as plexdb:
# Set the new time mark for the next delta sync # Set the new time mark for the next delta sync
plexdb.update_section_last_sync(section.section_id, plexdb.update_section_last_sync(section.id,
self.current_sync) self.current_sync)
common.update_kodi_library(video=True, music=True) common.update_kodi_library(video=True, music=True)
# In order to not delete all your songs again # In order to not delete all your songs again

View file

@ -41,10 +41,12 @@ class Section(object):
""" """
def __init__(self, index=None, xml_element=None, section_db_element=None): def __init__(self, index=None, xml_element=None, section_db_element=None):
# Unique Plex id of this Plex library section # Unique Plex id of this Plex library section
self._section_id = None # int self._id = None # int
# Plex librarySectionUUID, unique for this section
self.uuid = None
# Building block for window variable # Building block for window variable
self._node = None # unicode self._node = None # unicode
# Index of this section (as section_id might not be subsequent) # Index of this section (as id might not be subsequent)
# This follows 1:1 the sequence in with the PMS returns the sections # This follows 1:1 the sequence in with the PMS returns the sections
self._index = None # Codacy-bug self._index = None # Codacy-bug
self.index = index # int self.index = index # int
@ -58,9 +60,6 @@ class Section(object):
# Do we sync all items of this section to the Kodi DB? # Do we sync all items of this section to the Kodi DB?
# This will be set with section_type!! # This will be set with section_type!!
self.sync_to_kodi = None # bool self.sync_to_kodi = None # bool
# For sections to be synched, the section name will be recorded as a
# tag. This is the corresponding id for this tag
self.kodi_tagid = None # int
# When was this section last successfully/completely synched to the # When was this section last successfully/completely synched to the
# Kodi database? # Kodi database?
self.last_sync = None # int self.last_sync = None # int
@ -90,24 +89,28 @@ class Section(object):
elif section_db_element: elif section_db_element:
self.from_db_element(section_db_element) self.from_db_element(section_db_element)
def __repr__(self): def __unicode__(self):
return ("{{" return ("{{"
"'index': {self.index}, " "'index': {self.index}, "
"'name': '{self.name}', " "'name': '{self.name}', "
"'section_id': {self.section_id}, " "'id': {self.id}, "
"'section_type': '{self.section_type}', " "'section_type': '{self.section_type}', "
"'sync_to_kodi': {self.sync_to_kodi}, " "'sync_to_kodi': {self.sync_to_kodi}, "
"'last_sync': {self.last_sync}" "'last_sync': {self.last_sync}, "
"}}").format(self=self).encode('utf-8') "'uuid': {self.uuid}"
__str__ = __repr__ "}}").format(self=self)
def __str__(self):
return unicode(self).encode('utf-8')
__repr__ = __str__
def __nonzero__(self): def __nonzero__(self):
return (self.section_id is not None and return (self.id is not None and
self.name is not None and self.name is not None and
self.section_type is not None) self.section_type is not None)
def __eq__(self, section): def __eq__(self, section):
return (self.section_id == section.section_id and return (self.id == section.id and
self.name == section.name and self.name == section.name and
self.section_type == section.section_type) self.section_type == section.section_type)
@ -115,12 +118,12 @@ class Section(object):
return not self == section return not self == section
@property @property
def section_id(self): def id(self):
return self._section_id return self._id
@section_id.setter @id.setter
def section_id(self, value): def id(self, value):
self._section_id = value self._id = value
self._path = path_ops.path.join(LIBRARY_PATH, 'Plex-%s' % value, '') self._path = path_ops.path.join(LIBRARY_PATH, 'Plex-%s' % value, '')
self._playlist_path = path_ops.path.join(PLAYLISTS_PATH, self._playlist_path = path_ops.path.join(PLAYLISTS_PATH,
'Plex %s.xsp' % value) 'Plex %s.xsp' % value)
@ -163,10 +166,10 @@ class Section(object):
return self._playlist_path return self._playlist_path
def from_db_element(self, section_db_element): def from_db_element(self, section_db_element):
self.section_id = section_db_element['section_id'] self.id = section_db_element['section_id']
self.uuid = section_db_element['uuid']
self.name = section_db_element['section_name'] self.name = section_db_element['section_name']
self.section_type = section_db_element['plex_type'] self.section_type = section_db_element['plex_type']
self.kodi_tagid = section_db_element['kodi_tagid']
self.sync_to_kodi = section_db_element['sync_to_kodi'] self.sync_to_kodi = section_db_element['sync_to_kodi']
self.last_sync = section_db_element['last_sync'] self.last_sync = section_db_element['last_sync']
@ -175,7 +178,8 @@ class Section(object):
Reads section from a PMS xml (Plex id, name, Plex type) Reads section from a PMS xml (Plex id, name, Plex type)
""" """
api = API(xml_element) api = API(xml_element)
self.section_id = utils.cast(int, xml_element.get('key')) self.id = utils.cast(int, xml_element.get('key'))
self.uuid = xml_element.get('uuid')
self.name = api.title() self.name = api.title()
self.section_type = api.plex_type() self.section_type = api.plex_type()
self.icon = api.one_artwork('composite') self.icon = api.one_artwork('composite')
@ -203,18 +207,18 @@ class Section(object):
if not self: if not self:
raise RuntimeError('Section not clearly defined: %s' % self) raise RuntimeError('Section not clearly defined: %s' % self)
if plexdb: if plexdb:
plexdb.add_section(self.section_id, plexdb.add_section(self.id,
self.uuid,
self.name, self.name,
self.section_type, self.section_type,
self.kodi_tagid,
self.sync_to_kodi, self.sync_to_kodi,
self.last_sync) self.last_sync)
else: else:
with PlexDB(lock=False) as plexdb: with PlexDB(lock=False) as plexdb:
plexdb.add_section(self.section_id, plexdb.add_section(self.id,
self.uuid,
self.name, self.name,
self.section_type, self.section_type,
self.kodi_tagid,
self.sync_to_kodi, self.sync_to_kodi,
self.last_sync) self.last_sync)
@ -241,21 +245,21 @@ class Section(object):
# nodes as "submenus" once the user navigates into this section # nodes as "submenus" once the user navigates into this section
args = { args = {
'mode': 'browseplex', 'mode': 'browseplex',
'key': '/library/sections/%s' % self.section_id, 'key': '/library/sections/%s' % self.id,
'plex_type': self.section_type, 'plex_type': self.section_type,
'section_id': unicode(self.section_id) 'section_id': unicode(self.id)
} }
if not self.sync_to_kodi: if not self.sync_to_kodi:
args['synched'] = 'false' args['synched'] = 'false'
addon_index = self.addon_path(args) addon_index = self.addon_path(args)
if self.sync_to_kodi and self.section_type in v.PLEX_VIDEOTYPES: if self.sync_to_kodi and self.section_type in v.PLEX_VIDEOTYPES:
path = 'library://video/Plex-{0}/{0}_all.xml' path = 'library://video/Plex-{0}/{0}_all.xml'
path = path.format(self.section_id) path = path.format(self.id)
index = 'library://video/Plex-%s' % self.section_id index = 'library://video/Plex-%s' % self.id
else: else:
# No xmls to link to - let's show the listings on the fly # No xmls to link to - let's show the listings on the fly
index = addon_index index = addon_index
args['key'] = '/library/sections/%s/all' % self.section_id args['key'] = '/library/sections/%s/all' % self.id
path = self.addon_path(args) path = self.addon_path(args)
# .index will list all possible nodes for this library # .index will list all possible nodes for this library
utils.window('%s.index' % self.node, value=index) utils.window('%s.index' % self.node, value=index)
@ -273,7 +277,7 @@ class Section(object):
# Pictures # Pictures
utils.window('%s.path' % self.node, utils.window('%s.path' % self.node,
value='ActivateWindow(pictures,%s,return)' % path) value='ActivateWindow(pictures,%s,return)' % path)
utils.window('%s.id' % self.node, value=str(self.section_id)) utils.window('%s.id' % self.node, value=str(self.id))
# To let the user navigate into this node when selecting widgets # To let the user navigate into this node when selecting widgets
utils.window('%s.addon_index' % self.node, value=addon_index) utils.window('%s.addon_index' % self.node, value=addon_index)
if not self.sync_to_kodi: if not self.sync_to_kodi:
@ -291,7 +295,7 @@ class Section(object):
path_ops.makedirs(self.path) path_ops.makedirs(self.path)
# Create a tag just like the section name in the Kodi DB # Create a tag just like the section name in the Kodi DB
with kodi_db.KodiVideoDB(lock=False) as kodidb: with kodi_db.KodiVideoDB(lock=False) as kodidb:
self.kodi_tagid = kodidb.create_tag(self.name) kodidb.create_tag(self.name)
# The xmls are numbered in order of appearance # The xmls are numbered in order of appearance
self.order = 0 self.order = 0
if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')): if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')):
@ -312,7 +316,7 @@ class Section(object):
def _build_node(self, node_type, node_name, args, content, pms_node): def _build_node(self, node_type, node_name, args, content, pms_node):
self.content = content self.content = content
node_name = node_name.format(self=self) node_name = node_name.format(self=self)
xml_name = '%s_%s.xml' % (self.section_id, node_type) xml_name = '%s_%s.xml' % (self.id, node_type)
path = path_ops.path.join(self.path, xml_name) path = path_ops.path.join(self.path, xml_name)
if not path_ops.exists(path): if not path_ops.exists(path):
if pms_node: if pms_node:
@ -323,7 +327,7 @@ class Section(object):
xml = getattr(nodes, 'node_%s' % node_type)(self, node_name) xml = getattr(nodes, 'node_%s' % node_type)(self, node_name)
self._write_xml(xml, xml_name) self._write_xml(xml, xml_name)
self.order += 1 self.order += 1
path = 'library://video/Plex-%s/%s' % (self.section_id, xml_name) path = 'library://video/Plex-%s/%s' % (self.id, xml_name)
self._window_node(path, node_name, node_type, pms_node) self._window_node(path, node_name, node_type, pms_node)
def _write_xml(self, xml, xml_name): def _write_xml(self, xml, xml_name):
@ -362,13 +366,13 @@ class Section(object):
# if node_type == 'all': # if node_type == 'all':
# var = self.node # var = self.node
# utils.window('%s.index' % var, # utils.window('%s.index' % var,
# value=path.replace('%s_all.xml' % self.section_id, '')) # value=path.replace('%s_all.xml' % self.id, ''))
# utils.window('%s.title' % var, value=self.name) # utils.window('%s.title' % var, value=self.name)
# else: # else:
var = '%s.%s' % (self.node, node_type) var = '%s.%s' % (self.node, node_type)
utils.window('%s.index' % var, value=path) utils.window('%s.index' % var, value=path)
utils.window('%s.title' % var, value=node_name) utils.window('%s.title' % var, value=node_name)
utils.window('%s.id' % var, value=str(self.section_id)) utils.window('%s.id' % var, value=str(self.id))
utils.window('%s.path' % var, value=window_path) utils.window('%s.path' % var, value=window_path)
utils.window('%s.type' % var, value=self.content) utils.window('%s.type' % var, value=self.content)
utils.window('%s.content' % var, value=path) utils.window('%s.content' % var, value=path)
@ -403,10 +407,10 @@ class Section(object):
Removes this sections completely from the Plex DB Removes this sections completely from the Plex DB
""" """
if plexdb: if plexdb:
plexdb.remove_section(self.section_id) plexdb.remove_section(self.id)
else: else:
with PlexDB(lock=False) as plexdb: with PlexDB(lock=False) as plexdb:
plexdb.remove_section(self.section_id) plexdb.remove_section(self.id)
def remove(self): def remove(self):
""" """
@ -441,7 +445,6 @@ def _retrieve_old_settings(sections, old_sections):
Thus sets to the old values: Thus sets to the old values:
section.last_sync section.last_sync
section.kodi_tagid
section.sync_to_kodi section.sync_to_kodi
section.last_sync section.last_sync
""" """
@ -449,7 +452,6 @@ def _retrieve_old_settings(sections, old_sections):
for old_section in old_sections: for old_section in old_sections:
if section == old_section: if section == old_section:
section.last_sync = old_section.last_sync section.last_sync = old_section.last_sync
section.kodi_tagid = old_section.kodi_tagid
section.sync_to_kodi = old_section.sync_to_kodi section.sync_to_kodi = old_section.sync_to_kodi
section.last_sync = old_section.last_sync section.last_sync = old_section.last_sync
@ -471,7 +473,7 @@ def _delete_kodi_db_items(section):
for plex_type, context in types: for plex_type, context in types:
while True: while True:
with PlexDB() as plexdb: with PlexDB() as plexdb:
plex_ids = list(plexdb.plexid_by_sectionid(section.section_id, plex_ids = list(plexdb.plexid_by_sectionid(section.id,
plex_type, plex_type,
BATCH_SIZE)) BATCH_SIZE))
with kodi_context(texture_db=True) as kodidb: with kodi_context(texture_db=True) as kodidb:

View file

@ -3,6 +3,7 @@
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from logging import getLogger from logging import getLogger
from . import sections
from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED
from .fanart import SYNC_FANART, FanartTask from .fanart import SYNC_FANART, FanartTask
from ..plex_api import API from ..plex_api import API
@ -122,10 +123,16 @@ def process_new_item_message(message):
LOG.error('Could not download metadata for %s', message['plex_id']) LOG.error('Could not download metadata for %s', message['plex_id'])
return False, False, False return False, False, False
LOG.debug("Processing new/updated PMS item: %s", message['plex_id']) LOG.debug("Processing new/updated PMS item: %s", message['plex_id'])
section_id = utils.cast(int, xml.get('librarySectionID'))
for section in sections.SECTIONS:
if section.id == section_id:
break
else:
LOG.error('Section id %s not yet encountered', section_id)
return False, False, False
with itemtypes.ITEMTYPE_FROM_PLEXTYPE[plex_type](timing.unix_timestamp()) as typus: with itemtypes.ITEMTYPE_FROM_PLEXTYPE[plex_type](timing.unix_timestamp()) as typus:
typus.add_update(xml[0], typus.add_update(xml[0],
section_name=xml.get('librarySectionTitle'), section=section)
section_id=xml.get('librarySectionID'))
cache_artwork(message['plex_id'], plex_type) cache_artwork(message['plex_id'], plex_type)
return True, plex_type in v.PLEX_VIDEOTYPES, plex_type in v.PLEX_AUDIOTYPES return True, plex_type in v.PLEX_VIDEOTYPES, plex_type in v.PLEX_AUDIOTYPES

View file

@ -194,9 +194,9 @@ def initialize():
plexdb.cursor.execute(''' plexdb.cursor.execute('''
CREATE TABLE IF NOT EXISTS sections( CREATE TABLE IF NOT EXISTS sections(
section_id INTEGER PRIMARY KEY, section_id INTEGER PRIMARY KEY,
uuid TEXT,
section_name TEXT, section_name TEXT,
plex_type TEXT, plex_type TEXT,
kodi_tagid INTEGER,
sync_to_kodi INTEGER, sync_to_kodi INTEGER,
last_sync INTEGER) last_sync INTEGER)
''') ''')
@ -205,6 +205,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
kodi_fileid INTEGER, kodi_fileid INTEGER,
kodi_pathid INTEGER, kodi_pathid INTEGER,
@ -216,6 +217,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
kodi_pathid INTEGER, kodi_pathid INTEGER,
fanart_synced INTEGER, fanart_synced INTEGER,
@ -226,6 +228,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
show_id INTEGER, show_id INTEGER,
parent_id INTEGER, parent_id INTEGER,
kodi_id INTEGER, kodi_id INTEGER,
@ -237,6 +240,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
show_id INTEGER, show_id INTEGER,
grandparent_id INTEGER, grandparent_id INTEGER,
season_id INTEGER, season_id INTEGER,
@ -253,6 +257,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
last_sync INTEGER) last_sync INTEGER)
''') ''')
@ -261,6 +266,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
artist_id INTEGER, artist_id INTEGER,
parent_id INTEGER, parent_id INTEGER,
kodi_id INTEGER, kodi_id INTEGER,
@ -271,6 +277,7 @@ def initialize():
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
artist_id INTEGER, artist_id INTEGER,
grandparent_id INTEGER, grandparent_id INTEGER,
album_id INTEGER, album_id INTEGER,

View file

@ -5,8 +5,8 @@ from .. import variables as v
class Movies(object): class Movies(object):
def add_movie(self, plex_id, checksum, section_id, kodi_id, kodi_fileid, def add_movie(self, plex_id, checksum, section_id, section_uuid, kodi_id,
kodi_pathid, last_sync): kodi_fileid, kodi_pathid, last_sync):
""" """
Appends or replaces an entry into the plex table for movies Appends or replaces an entry into the plex table for movies
""" """
@ -15,18 +15,20 @@ class Movies(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
kodi_fileid, kodi_fileid,
kodi_pathid, kodi_pathid,
fanart_synced, fanart_synced,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''' '''
self.cursor.execute( self.cursor.execute(
query, query,
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
kodi_fileid, kodi_fileid,
kodi_pathid, kodi_pathid,
@ -39,6 +41,7 @@ class Movies(object):
plex_id INTEGER PRIMARY KEY ASC, plex_id INTEGER PRIMARY KEY ASC,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
kodi_fileid INTEGER, kodi_fileid INTEGER,
kodi_pathid INTEGER, kodi_pathid INTEGER,
@ -61,9 +64,10 @@ class Movies(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'kodi_id': entry[3], 'section_uuid': entry[3],
'kodi_fileid': entry[4], 'kodi_id': entry[4],
'kodi_pathid': entry[5], 'kodi_fileid': entry[5],
'fanart_synced': entry[6], 'kodi_pathid': entry[6],
'last_sync': entry[7] 'fanart_synced': entry[7],
'last_sync': entry[8]
} }

View file

@ -5,7 +5,8 @@ from .. import variables as v
class Music(object): class Music(object):
def add_artist(self, plex_id, checksum, section_id, kodi_id, last_sync): def add_artist(self, plex_id, checksum, section_id, section_uuid, kodi_id,
last_sync):
""" """
Appends or replaces music artist entry into the plex table Appends or replaces music artist entry into the plex table
""" """
@ -14,20 +15,22 @@ class Music(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
''' '''
self.cursor.execute( self.cursor.execute(
query, query,
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
last_sync)) last_sync))
def add_album(self, plex_id, checksum, section_id, artist_id, parent_id, def add_album(self, plex_id, checksum, section_id, section_uuid, artist_id,
kodi_id, last_sync): parent_id, kodi_id, last_sync):
""" """
Appends or replaces an entry into the plex table Appends or replaces an entry into the plex table
""" """
@ -36,24 +39,27 @@ class Music(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
artist_id, artist_id,
parent_id, parent_id,
kodi_id, kodi_id,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''' '''
self.cursor.execute( self.cursor.execute(
query, query,
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
artist_id, artist_id,
parent_id, parent_id,
kodi_id, kodi_id,
last_sync)) last_sync))
def add_song(self, plex_id, checksum, section_id, artist_id, grandparent_id, def add_song(self, plex_id, checksum, section_id, section_uuid, artist_id,
album_id, parent_id, kodi_id, kodi_pathid, last_sync): grandparent_id, album_id, parent_id, kodi_id, kodi_pathid,
last_sync):
""" """
Appends or replaces an entry into the plex table Appends or replaces an entry into the plex table
""" """
@ -62,6 +68,7 @@ class Music(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
artist_id, artist_id,
grandparent_id, grandparent_id,
album_id, album_id,
@ -69,13 +76,14 @@ class Music(object):
kodi_id, kodi_id,
kodi_pathid, kodi_pathid,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''' '''
self.cursor.execute( self.cursor.execute(
query, query,
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
artist_id, artist_id,
grandparent_id, grandparent_id,
album_id, album_id,
@ -90,6 +98,7 @@ class Music(object):
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
last_sync INTEGER last_sync INTEGER
""" """
@ -105,6 +114,7 @@ class Music(object):
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
artist_id INTEGER, # plex_id of the parent artist artist_id INTEGER, # plex_id of the parent artist
parent_id INTEGER, # kodi_id of the parent artist parent_id INTEGER, # kodi_id of the parent artist
kodi_id INTEGER, kodi_id INTEGER,
@ -122,6 +132,7 @@ class Music(object):
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
artist_id INTEGER, # plex_id of the parent artist artist_id INTEGER, # plex_id of the parent artist
grandparent_id INTEGER, # kodi_id of the parent artist grandparent_id INTEGER, # kodi_id of the parent artist
album_id INTEGER, # plex_id of the parent album album_id INTEGER, # plex_id of the parent album
@ -146,13 +157,14 @@ class Music(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'artist_id': entry[3], 'section_uuid': entry[3],
'grandparent_id': entry[4], 'artist_id': entry[4],
'album_id': entry[5], 'grandparent_id': entry[5],
'parent_id': entry[6], 'album_id': entry[6],
'kodi_id': entry[7], 'parent_id': entry[7],
'kodi_pathid': entry[8], 'kodi_id': entry[8],
'last_sync': entry[9] 'kodi_pathid': entry[9],
'last_sync': entry[10]
} }
@staticmethod @staticmethod
@ -165,10 +177,11 @@ class Music(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'artist_id': entry[3], 'section_uuid': entry[3],
'parent_id': entry[4], 'artist_id': entry[4],
'kodi_id': entry[5], 'parent_id': entry[5],
'last_sync': entry[6] 'kodi_id': entry[6],
'last_sync': entry[7]
} }
@staticmethod @staticmethod
@ -181,8 +194,9 @@ class Music(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'kodi_id': entry[3], 'section_uuid': entry[3],
'last_sync': entry[4] 'kodi_id': entry[4],
'last_sync': entry[5]
} }
def album_has_songs(self, plex_id): def album_has_songs(self, plex_id):

View file

@ -15,9 +15,9 @@ class Sections(object):
""" """
For section_id, returns the dict For section_id, returns the dict
section_id INTEGER PRIMARY KEY, section_id INTEGER PRIMARY KEY,
uuid TEXT,
section_name TEXT, section_name TEXT,
plex_type TEXT, plex_type TEXT,
kodi_tagid INTEGER,
sync_to_kodi BOOL, sync_to_kodi BOOL,
last_sync INTEGER last_sync INTEGER
""" """
@ -31,9 +31,9 @@ class Sections(object):
return return
return { return {
'section_id': entry[0], 'section_id': entry[0],
'section_name': entry[1], 'uuid': entry[1],
'plex_type': entry[2], 'section_name': entry[2],
'kodi_tagid': entry[3], 'plex_type': entry[3],
'sync_to_kodi': entry[4] == 1, 'sync_to_kodi': entry[4] == 1,
'last_sync': entry[5] 'last_sync': entry[5]
} }
@ -49,7 +49,7 @@ class Sections(object):
except TypeError: except TypeError:
pass pass
def add_section(self, section_id, section_name, plex_type, kodi_tagid, def add_section(self, section_id, uuid, section_name, plex_type,
sync_to_kodi, last_sync): sync_to_kodi, last_sync):
""" """
Appends a Plex section to the Plex sections table Appends a Plex section to the Plex sections table
@ -58,18 +58,18 @@ class Sections(object):
query = ''' query = '''
INSERT OR REPLACE INTO sections( INSERT OR REPLACE INTO sections(
section_id, section_id,
uuid,
section_name, section_name,
plex_type, plex_type,
kodi_tagid,
sync_to_kodi, sync_to_kodi,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
''' '''
self.cursor.execute(query, self.cursor.execute(query,
(section_id, (section_id,
uuid,
section_name, section_name,
plex_type, plex_type,
kodi_tagid,
sync_to_kodi, sync_to_kodi,
last_sync)) last_sync))

View file

@ -5,8 +5,8 @@ from .. import variables as v
class TVShows(object): class TVShows(object):
def add_show(self, plex_id, checksum, section_id, kodi_id, kodi_pathid, def add_show(self, plex_id, checksum, section_id, section_uuid, kodi_id,
last_sync): kodi_pathid, last_sync):
""" """
Appends or replaces tv show entry into the plex table Appends or replaces tv show entry into the plex table
""" """
@ -16,22 +16,24 @@ class TVShows(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
kodi_pathid, kodi_pathid,
fanart_synced, fanart_synced,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', ''',
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
kodi_id, kodi_id,
kodi_pathid, kodi_pathid,
0, 0,
last_sync)) last_sync))
def add_season(self, plex_id, checksum, section_id, show_id, parent_id, def add_season(self, plex_id, checksum, section_id, section_uuid, show_id,
kodi_id, last_sync): parent_id, kodi_id, last_sync):
""" """
Appends or replaces an entry into the plex table Appends or replaces an entry into the plex table
""" """
@ -41,23 +43,25 @@ class TVShows(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
show_id, show_id,
parent_id, parent_id,
kodi_id, kodi_id,
fanart_synced, fanart_synced,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', ''',
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
show_id, show_id,
parent_id, parent_id,
kodi_id, kodi_id,
0, 0,
last_sync)) last_sync))
def add_episode(self, plex_id, checksum, section_id, show_id, def add_episode(self, plex_id, checksum, section_id, section_uuid, show_id,
grandparent_id, season_id, parent_id, kodi_id, kodi_fileid, grandparent_id, season_id, parent_id, kodi_id, kodi_fileid,
kodi_fileid_2, kodi_pathid, last_sync): kodi_fileid_2, kodi_pathid, last_sync):
""" """
@ -69,6 +73,7 @@ class TVShows(object):
plex_id, plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
show_id, show_id,
grandparent_id, grandparent_id,
season_id, season_id,
@ -79,11 +84,12 @@ class TVShows(object):
kodi_pathid, kodi_pathid,
fanart_synced, fanart_synced,
last_sync) last_sync)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', ''',
(plex_id, (plex_id,
checksum, checksum,
section_id, section_id,
section_uuid,
show_id, show_id,
grandparent_id, grandparent_id,
season_id, season_id,
@ -101,6 +107,7 @@ class TVShows(object):
plex_id INTEGER PRIMARY KEY ASC, plex_id INTEGER PRIMARY KEY ASC,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
kodi_id INTEGER, kodi_id INTEGER,
kodi_pathid INTEGER, kodi_pathid INTEGER,
fanart_synced INTEGER, fanart_synced INTEGER,
@ -118,6 +125,7 @@ class TVShows(object):
plex_id INTEGER PRIMARY KEY, plex_id INTEGER PRIMARY KEY,
checksum INTEGER UNIQUE, checksum INTEGER UNIQUE,
section_id INTEGER, section_id INTEGER,
section_uuid TEXT,
show_id INTEGER, # plex_id of the parent show show_id INTEGER, # plex_id of the parent show
parent_id INTEGER, # kodi_id of the parent show parent_id INTEGER, # kodi_id of the parent show
kodi_id INTEGER, kodi_id INTEGER,
@ -147,16 +155,17 @@ class TVShows(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'show_id': entry[3], 'section_uuid': entry[3],
'grandparent_id': entry[4], 'show_id': entry[4],
'season_id': entry[5], 'grandparent_id': entry[5],
'parent_id': entry[6], 'season_id': entry[6],
'kodi_id': entry[7], 'parent_id': entry[7],
'kodi_fileid': entry[8], 'kodi_id': entry[8],
'kodi_fileid_2': entry[9], 'kodi_fileid': entry[9],
'kodi_pathid': entry[10], 'kodi_fileid_2': entry[10],
'fanart_synced': entry[11], 'kodi_pathid': entry[11],
'last_sync': entry[12] 'fanart_synced': entry[12],
'last_sync': entry[13]
} }
@staticmethod @staticmethod
@ -169,10 +178,11 @@ class TVShows(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'kodi_id': entry[3], 'section_uuid': entry[3],
'kodi_pathid': entry[4], 'kodi_id': entry[4],
'fanart_synced': entry[5], 'kodi_pathid': entry[5],
'last_sync': entry[6] 'fanart_synced': entry[6],
'last_sync': entry[7]
} }
@staticmethod @staticmethod
@ -185,11 +195,12 @@ class TVShows(object):
'plex_id': entry[0], 'plex_id': entry[0],
'checksum': entry[1], 'checksum': entry[1],
'section_id': entry[2], 'section_id': entry[2],
'show_id': entry[3], 'section_uuid': entry[3],
'parent_id': entry[4], 'show_id': entry[4],
'kodi_id': entry[5], 'parent_id': entry[5],
'fanart_synced': entry[6], 'kodi_id': entry[6],
'last_sync': entry[7] 'fanart_synced': entry[7],
'last_sync': entry[8]
} }
def season_has_episodes(self, plex_id): def season_has_episodes(self, plex_id):