From 6a292d29f62e58a407c4355abb24dd16dc01c0e9 Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 27 Apr 2019 10:41:07 +0200 Subject: [PATCH 1/4] Safe Plex library section uuid to plex.db instead of kodi tagid --- resources/lib/library_sync/sections.py | 28 ++++++++++++++------------ resources/lib/plex_db/common.py | 2 +- resources/lib/plex_db/sections.py | 14 ++++++------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/resources/lib/library_sync/sections.py b/resources/lib/library_sync/sections.py index 5a57be7d..16f62c63 100644 --- a/resources/lib/library_sync/sections.py +++ b/resources/lib/library_sync/sections.py @@ -42,6 +42,8 @@ class Section(object): def __init__(self, index=None, xml_element=None, section_db_element=None): # Unique Plex id of this Plex library section self._section_id = None # int + # Plex librarySectionUUID, unique for this section + self.uuid = None # Building block for window variable self._node = None # unicode # Index of this section (as section_id might not be subsequent) @@ -58,9 +60,6 @@ class Section(object): # Do we sync all items of this section to the Kodi DB? # This will be set with section_type!! 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 # Kodi database? self.last_sync = None # int @@ -90,16 +89,20 @@ class Section(object): elif section_db_element: self.from_db_element(section_db_element) - def __repr__(self): + def __unicode__(self): return ("{{" "'index': {self.index}, " "'name': '{self.name}', " "'section_id': {self.section_id}, " "'section_type': '{self.section_type}', " "'sync_to_kodi': {self.sync_to_kodi}, " - "'last_sync': {self.last_sync}" - "}}").format(self=self).encode('utf-8') - __str__ = __repr__ + "'last_sync': {self.last_sync}, " + "'uuid': {self.uuid}" + "}}").format(self=self) + + def __str__(self): + return unicode(self).encode('utf-8') + __repr__ = __str__ def __nonzero__(self): return (self.section_id is not None and @@ -164,9 +167,9 @@ class Section(object): def from_db_element(self, section_db_element): self.section_id = section_db_element['section_id'] + self.uuid = section_db_element['uuid'] self.name = section_db_element['section_name'] 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.last_sync = section_db_element['last_sync'] @@ -176,6 +179,7 @@ class Section(object): """ api = API(xml_element) self.section_id = utils.cast(int, xml_element.get('key')) + self.uuid = xml_element.get('uuid') self.name = api.title() self.section_type = api.plex_type() self.icon = api.one_artwork('composite') @@ -204,17 +208,17 @@ class Section(object): raise RuntimeError('Section not clearly defined: %s' % self) if plexdb: plexdb.add_section(self.section_id, + self.uuid, self.name, self.section_type, - self.kodi_tagid, self.sync_to_kodi, self.last_sync) else: with PlexDB(lock=False) as plexdb: plexdb.add_section(self.section_id, + self.uuid, self.name, self.section_type, - self.kodi_tagid, self.sync_to_kodi, self.last_sync) @@ -291,7 +295,7 @@ class Section(object): path_ops.makedirs(self.path) # Create a tag just like the section name in the Kodi DB 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 self.order = 0 if not path_ops.exists(path_ops.path.join(self.path, 'index.xml')): @@ -441,7 +445,6 @@ def _retrieve_old_settings(sections, old_sections): Thus sets to the old values: section.last_sync - section.kodi_tagid section.sync_to_kodi section.last_sync """ @@ -449,7 +452,6 @@ def _retrieve_old_settings(sections, old_sections): for old_section in old_sections: if section == old_section: section.last_sync = old_section.last_sync - section.kodi_tagid = old_section.kodi_tagid section.sync_to_kodi = old_section.sync_to_kodi section.last_sync = old_section.last_sync diff --git a/resources/lib/plex_db/common.py b/resources/lib/plex_db/common.py index 65f5ca6d..bf7d3890 100644 --- a/resources/lib/plex_db/common.py +++ b/resources/lib/plex_db/common.py @@ -194,9 +194,9 @@ def initialize(): plexdb.cursor.execute(''' CREATE TABLE IF NOT EXISTS sections( section_id INTEGER PRIMARY KEY, + uuid TEXT, section_name TEXT, plex_type TEXT, - kodi_tagid INTEGER, sync_to_kodi INTEGER, last_sync INTEGER) ''') diff --git a/resources/lib/plex_db/sections.py b/resources/lib/plex_db/sections.py index a65e3cec..1c61295b 100644 --- a/resources/lib/plex_db/sections.py +++ b/resources/lib/plex_db/sections.py @@ -15,9 +15,9 @@ class Sections(object): """ For section_id, returns the dict section_id INTEGER PRIMARY KEY, + uuid TEXT, section_name TEXT, plex_type TEXT, - kodi_tagid INTEGER, sync_to_kodi BOOL, last_sync INTEGER """ @@ -31,9 +31,9 @@ class Sections(object): return return { 'section_id': entry[0], - 'section_name': entry[1], - 'plex_type': entry[2], - 'kodi_tagid': entry[3], + 'uuid': entry[1], + 'section_name': entry[2], + 'plex_type': entry[3], 'sync_to_kodi': entry[4] == 1, 'last_sync': entry[5] } @@ -49,7 +49,7 @@ class Sections(object): except TypeError: 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): """ Appends a Plex section to the Plex sections table @@ -58,18 +58,18 @@ class Sections(object): query = ''' INSERT OR REPLACE INTO sections( section_id, + uuid, section_name, plex_type, - kodi_tagid, sync_to_kodi, last_sync) VALUES (?, ?, ?, ?, ?, ?) ''' self.cursor.execute(query, (section_id, + uuid, section_name, plex_type, - kodi_tagid, sync_to_kodi, last_sync)) From ab5ab966e41cd6eeb2702a5a8811cd9a77cd89d2 Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 27 Apr 2019 10:59:51 +0200 Subject: [PATCH 2/4] Use section for sync process --- resources/lib/itemtypes/movies.py | 9 ++++---- resources/lib/itemtypes/music.py | 29 ++++++++++--------------- resources/lib/itemtypes/tvshows.py | 28 ++++++++++-------------- resources/lib/library_sync/full_sync.py | 6 ++--- resources/lib/library_sync/websocket.py | 11 ++++++++-- 5 files changed, 37 insertions(+), 46 deletions(-) diff --git a/resources/lib/itemtypes/movies.py b/resources/lib/itemtypes/movies.py index 6a388d26..2527a753 100644 --- a/resources/lib/itemtypes/movies.py +++ b/resources/lib/itemtypes/movies.py @@ -14,8 +14,7 @@ class Movie(ItemBase): """ Used for plex library-type movies """ - def add_update(self, xml, section_name=None, section_id=None, - children=None): + def add_update(self, xml, section, children=None): """ Process single movie """ @@ -174,7 +173,7 @@ class Movie(ItemBase): self.kodidb.modify_streams(file_id, api.mediastreams(), runtime) self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_MOVIE, studios) - tags = [section_name] + tags = [section.name] if collections: for plex_set_id, set_name in collections: set_api = None @@ -189,7 +188,7 @@ class Movie(ItemBase): # e.g. when added via websocket LOG.debug('Costly looking up Plex collection %s: %s', 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 if index == plex_set_id: set_xml = PF.GetPlexMetadata(coll_plex_id) @@ -217,7 +216,7 @@ class Movie(ItemBase): dateplayed) self.plexdb.add_movie(plex_id=plex_id, checksum=api.checksum(), - section_id=section_id, + section_id=section.id, kodi_id=kodi_id, kodi_fileid=file_id, kodi_pathid=kodi_pathid, diff --git a/resources/lib/itemtypes/music.py b/resources/lib/itemtypes/music.py index f54fac45..81247a17 100644 --- a/resources/lib/itemtypes/music.py +++ b/resources/lib/itemtypes/music.py @@ -154,8 +154,7 @@ class Artist(MusicMixin, ItemBase): """ For Plex library-type artists """ - def add_update(self, xml, section_name=None, section_id=None, - children=None): + def add_update(self, xml, section, children=None): """ Process a single artist """ @@ -210,14 +209,13 @@ class Artist(MusicMixin, ItemBase): v.KODI_TYPE_ARTIST) self.plexdb.add_artist(plex_id, api.checksum(), - section_id, + section.id, kodi_id, self.last_sync) class Album(MusicMixin, ItemBase): - def add_update(self, xml, section_name=None, section_id=None, - children=None, scan_children=True): + def add_update(self, xml, section, children=None, scan_children=True): """ Process a single album scan_children: set to False if you don't want to add children, e.g. to @@ -250,8 +248,7 @@ class Album(MusicMixin, ItemBase): Artist(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(artist_xml[0], - section_name, - section_id) + section=section) artist = self.plexdb.artist(parent_id) if not artist: LOG.error('Adding artist %s failed for %s', @@ -363,7 +360,7 @@ class Album(MusicMixin, ItemBase): v.KODI_TYPE_ALBUM) self.plexdb.add_album(plex_id, api.checksum(), - section_id, + section.id, artist_id, parent_id, kodi_id, @@ -375,8 +372,7 @@ class Album(MusicMixin, ItemBase): kodidb=self.kodidb) for song in children: context.add_update(song, - section_name=section_name, - section_id=section_id, + section=section, album_xml=xml, genres=genres, genre=genre, @@ -384,9 +380,8 @@ class Album(MusicMixin, ItemBase): class Song(MusicMixin, ItemBase): - def add_update(self, xml, section_name=None, section_id=None, - children=None, album_xml=None, genres=None, genre=None, - compilation=None): + def add_update(self, xml, section, children=None, album_xml=None, + genres=None, genre=None, compilation=None): """ Process single song/track """ @@ -421,8 +416,7 @@ class Song(MusicMixin, ItemBase): Artist(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(artist_xml[0], - section_name, - section_id) + section=section) artist = self.plexdb.artist(artist_id) if not artist: LOG.error('Still could not find grandparent artist %s for %s', @@ -477,8 +471,7 @@ class Song(MusicMixin, ItemBase): Album(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(album_xml[0], - section_name, - section_id, + section=section, children=[xml], scan_children=False) album = self.plexdb.album(album_id) @@ -659,7 +652,7 @@ class Song(MusicMixin, ItemBase): v.KODI_TYPE_ALBUM) self.plexdb.add_song(plex_id, api.checksum(), - section_id, + section.id, artist_id, grandparent_id, album_id, diff --git a/resources/lib/itemtypes/tvshows.py b/resources/lib/itemtypes/tvshows.py index 2fd7acd6..7d0de95f 100644 --- a/resources/lib/itemtypes/tvshows.py +++ b/resources/lib/itemtypes/tvshows.py @@ -143,8 +143,7 @@ class Show(TvShowMixin, ItemBase): """ For Plex library-type TV shows """ - def add_update(self, xml, section_name=None, section_id=None, - children=None): + def add_update(self, xml, section, children=None): """ Process a single show """ @@ -274,20 +273,19 @@ class Show(TvShowMixin, ItemBase): # Process studios self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_SHOW, studios) # Process tags: view, PMS collection tags - tags = [section_name] + tags = [section.name] tags.extend([i for _, i in api.collection_list()]) self.kodidb.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags) self.plexdb.add_show(plex_id=plex_id, checksum=api.checksum(), - section_id=section_id, + section_id=section.id, kodi_id=kodi_id, kodi_pathid=kodi_pathid, last_sync=self.last_sync) class Season(TvShowMixin, ItemBase): - def add_update(self, xml, section_name=None, section_id=None, - children=None): + def add_update(self, xml, section, children=None): """ Process a single season of a certain tv show """ @@ -315,8 +313,7 @@ class Season(TvShowMixin, ItemBase): Show(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(show_xml[0], - section_name, - section_id) + section=section) show = self.plexdb.show(show_id) if not show: LOG.error('Still could not find parent tv show %s', show_id) @@ -346,7 +343,7 @@ class Season(TvShowMixin, ItemBase): v.KODI_TYPE_SEASON) self.plexdb.add_season(plex_id=plex_id, checksum=api.checksum(), - section_id=section_id, + section_id=section.id, show_id=show_id, parent_id=parent_id, kodi_id=kodi_id, @@ -354,8 +351,7 @@ class Season(TvShowMixin, ItemBase): class Episode(TvShowMixin, ItemBase): - def add_update(self, xml, section_name=None, section_id=None, - children=None): + def add_update(self, xml, section, children=None): """ Process single episode """ @@ -402,8 +398,7 @@ class Episode(TvShowMixin, ItemBase): Show(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(show_xml[0], - section_name, - section_id) + section=section) show = self.plexdb.show(show_id) if not show: LOG.error('Still could not find grandparent tv show %s', show_id) @@ -423,8 +418,7 @@ class Episode(TvShowMixin, ItemBase): Season(self.last_sync, plexdb=self.plexdb, kodidb=self.kodidb).add_update(season_xml[0], - section_name, - section_id) + section=section) season = self.plexdb.season(season_id) if not season: LOG.error('Still could not find parent season %s', season_id) @@ -543,7 +537,7 @@ class Episode(TvShowMixin, ItemBase): userdata['LastPlayedDate']) self.plexdb.add_episode(plex_id=plex_id, checksum=api.checksum(), - section_id=section_id, + section_id=section.id, show_id=show_id, grandparent_id=grandparent_id, season_id=season_id, @@ -619,7 +613,7 @@ class Episode(TvShowMixin, ItemBase): userdata['LastPlayedDate']) self.plexdb.add_episode(plex_id=plex_id, checksum=api.checksum(), - section_id=section_id, + section_id=section.id, show_id=show_id, grandparent_id=grandparent_id, season_id=season_id, diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index 218bf23d..44dcdbbe 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -140,8 +140,7 @@ class FullSync(common.fullsync_mixin): self.queue.task_done() if isinstance(item, dict): context.add_update(item['xml'][0], - section_name=section.name, - section_id=section.id, + section=section, children=item['children']) self.title = item['xml'][0].get('title') self.processed += 1 @@ -233,8 +232,7 @@ class FullSync(common.fullsync_mixin): if not itemtype.update_userdata(xml_item, section.plex_type): # Somehow did not sync this item yet itemtype.add_update(xml_item, - section_name=section.name, - section_id=section.section_id) + section=section) itemtype.plexdb.update_last_sync(int(xml_item.attrib['ratingKey']), section.plex_type, self.current_sync) diff --git a/resources/lib/library_sync/websocket.py b/resources/lib/library_sync/websocket.py index db096d23..f7fcf4f4 100644 --- a/resources/lib/library_sync/websocket.py +++ b/resources/lib/library_sync/websocket.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, unicode_literals from logging import getLogger +from . import sections from .common import update_kodi_library, PLAYLIST_SYNC_ENABLED from .fanart import SYNC_FANART, FanartTask 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']) return False, False, False 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: typus.add_update(xml[0], - section_name=xml.get('librarySectionTitle'), - section_id=xml.get('librarySectionID')) + section=section) cache_artwork(message['plex_id'], plex_type) return True, plex_type in v.PLEX_VIDEOTYPES, plex_type in v.PLEX_AUDIOTYPES From e76fd03915f0d4436d22dd17a4596beeeb546d19 Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 27 Apr 2019 11:17:29 +0200 Subject: [PATCH 3/4] Safe section uuid when synching --- resources/lib/itemtypes/movies.py | 1 + resources/lib/itemtypes/music.py | 3 ++ resources/lib/itemtypes/tvshows.py | 4 ++ resources/lib/plex_db/common.py | 7 ++++ resources/lib/plex_db/movies.py | 20 +++++---- resources/lib/plex_db/music.py | 56 +++++++++++++++---------- resources/lib/plex_db/tvshows.py | 65 +++++++++++++++++------------- 7 files changed, 100 insertions(+), 56 deletions(-) diff --git a/resources/lib/itemtypes/movies.py b/resources/lib/itemtypes/movies.py index 2527a753..409534d0 100644 --- a/resources/lib/itemtypes/movies.py +++ b/resources/lib/itemtypes/movies.py @@ -217,6 +217,7 @@ class Movie(ItemBase): self.plexdb.add_movie(plex_id=plex_id, checksum=api.checksum(), section_id=section.id, + section_uuid=section.uuid, kodi_id=kodi_id, kodi_fileid=file_id, kodi_pathid=kodi_pathid, diff --git a/resources/lib/itemtypes/music.py b/resources/lib/itemtypes/music.py index 81247a17..aa2ebda5 100644 --- a/resources/lib/itemtypes/music.py +++ b/resources/lib/itemtypes/music.py @@ -210,6 +210,7 @@ class Artist(MusicMixin, ItemBase): self.plexdb.add_artist(plex_id, api.checksum(), section.id, + section.uuid, kodi_id, self.last_sync) @@ -361,6 +362,7 @@ class Album(MusicMixin, ItemBase): self.plexdb.add_album(plex_id, api.checksum(), section.id, + section.uuid, artist_id, parent_id, kodi_id, @@ -653,6 +655,7 @@ class Song(MusicMixin, ItemBase): self.plexdb.add_song(plex_id, api.checksum(), section.id, + section.uuid, artist_id, grandparent_id, album_id, diff --git a/resources/lib/itemtypes/tvshows.py b/resources/lib/itemtypes/tvshows.py index 7d0de95f..fc616cdc 100644 --- a/resources/lib/itemtypes/tvshows.py +++ b/resources/lib/itemtypes/tvshows.py @@ -279,6 +279,7 @@ class Show(TvShowMixin, ItemBase): self.plexdb.add_show(plex_id=plex_id, checksum=api.checksum(), section_id=section.id, + section_uuid=section.uuid, kodi_id=kodi_id, kodi_pathid=kodi_pathid, last_sync=self.last_sync) @@ -344,6 +345,7 @@ class Season(TvShowMixin, ItemBase): self.plexdb.add_season(plex_id=plex_id, checksum=api.checksum(), section_id=section.id, + section_uuid=section.uuid, show_id=show_id, parent_id=parent_id, kodi_id=kodi_id, @@ -538,6 +540,7 @@ class Episode(TvShowMixin, ItemBase): self.plexdb.add_episode(plex_id=plex_id, checksum=api.checksum(), section_id=section.id, + section_uuid=section.uuid, show_id=show_id, grandparent_id=grandparent_id, season_id=season_id, @@ -614,6 +617,7 @@ class Episode(TvShowMixin, ItemBase): self.plexdb.add_episode(plex_id=plex_id, checksum=api.checksum(), section_id=section.id, + section_uuid=section.uuid, show_id=show_id, grandparent_id=grandparent_id, season_id=season_id, diff --git a/resources/lib/plex_db/common.py b/resources/lib/plex_db/common.py index bf7d3890..37264a08 100644 --- a/resources/lib/plex_db/common.py +++ b/resources/lib/plex_db/common.py @@ -205,6 +205,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, kodi_fileid INTEGER, kodi_pathid INTEGER, @@ -216,6 +217,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, kodi_pathid INTEGER, fanart_synced INTEGER, @@ -226,6 +228,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, show_id INTEGER, parent_id INTEGER, kodi_id INTEGER, @@ -237,6 +240,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, show_id INTEGER, grandparent_id INTEGER, season_id INTEGER, @@ -253,6 +257,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, last_sync INTEGER) ''') @@ -261,6 +266,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, artist_id INTEGER, parent_id INTEGER, kodi_id INTEGER, @@ -271,6 +277,7 @@ def initialize(): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, artist_id INTEGER, grandparent_id INTEGER, album_id INTEGER, diff --git a/resources/lib/plex_db/movies.py b/resources/lib/plex_db/movies.py index 74ed360b..36c5aad7 100644 --- a/resources/lib/plex_db/movies.py +++ b/resources/lib/plex_db/movies.py @@ -5,8 +5,8 @@ from .. import variables as v class Movies(object): - def add_movie(self, plex_id, checksum, section_id, kodi_id, kodi_fileid, - kodi_pathid, last_sync): + def add_movie(self, plex_id, checksum, section_id, section_uuid, kodi_id, + kodi_fileid, kodi_pathid, last_sync): """ Appends or replaces an entry into the plex table for movies """ @@ -15,18 +15,20 @@ class Movies(object): plex_id, checksum, section_id, + section_uuid, kodi_id, kodi_fileid, kodi_pathid, fanart_synced, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ''' self.cursor.execute( query, (plex_id, checksum, section_id, + section_uuid, kodi_id, kodi_fileid, kodi_pathid, @@ -39,6 +41,7 @@ class Movies(object): plex_id INTEGER PRIMARY KEY ASC, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, kodi_fileid INTEGER, kodi_pathid INTEGER, @@ -61,9 +64,10 @@ class Movies(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'kodi_id': entry[3], - 'kodi_fileid': entry[4], - 'kodi_pathid': entry[5], - 'fanart_synced': entry[6], - 'last_sync': entry[7] + 'section_uuid': entry[3], + 'kodi_id': entry[4], + 'kodi_fileid': entry[5], + 'kodi_pathid': entry[6], + 'fanart_synced': entry[7], + 'last_sync': entry[8] } diff --git a/resources/lib/plex_db/music.py b/resources/lib/plex_db/music.py index ca954ae4..5e3a7523 100644 --- a/resources/lib/plex_db/music.py +++ b/resources/lib/plex_db/music.py @@ -5,7 +5,8 @@ from .. import variables as v 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 """ @@ -14,20 +15,22 @@ class Music(object): plex_id, checksum, section_id, + section_uuid, kodi_id, last_sync) - VALUES (?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?) ''' self.cursor.execute( query, (plex_id, checksum, section_id, + section_uuid, kodi_id, last_sync)) - def add_album(self, plex_id, checksum, section_id, artist_id, parent_id, - kodi_id, last_sync): + def add_album(self, plex_id, checksum, section_id, section_uuid, artist_id, + parent_id, kodi_id, last_sync): """ Appends or replaces an entry into the plex table """ @@ -36,24 +39,27 @@ class Music(object): plex_id, checksum, section_id, + section_uuid, artist_id, parent_id, kodi_id, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''' self.cursor.execute( query, (plex_id, checksum, section_id, + section_uuid, artist_id, parent_id, kodi_id, last_sync)) - def add_song(self, plex_id, checksum, section_id, artist_id, grandparent_id, - album_id, parent_id, kodi_id, kodi_pathid, last_sync): + def add_song(self, plex_id, checksum, section_id, section_uuid, artist_id, + grandparent_id, album_id, parent_id, kodi_id, kodi_pathid, + last_sync): """ Appends or replaces an entry into the plex table """ @@ -62,6 +68,7 @@ class Music(object): plex_id, checksum, section_id, + section_uuid, artist_id, grandparent_id, album_id, @@ -69,13 +76,14 @@ class Music(object): kodi_id, kodi_pathid, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''' self.cursor.execute( query, (plex_id, checksum, section_id, + section_uuid, artist_id, grandparent_id, album_id, @@ -90,6 +98,7 @@ class Music(object): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, last_sync INTEGER """ @@ -105,6 +114,7 @@ class Music(object): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, artist_id INTEGER, # plex_id of the parent artist parent_id INTEGER, # kodi_id of the parent artist kodi_id INTEGER, @@ -122,6 +132,7 @@ class Music(object): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, artist_id INTEGER, # plex_id of the parent artist grandparent_id INTEGER, # kodi_id of the parent artist album_id INTEGER, # plex_id of the parent album @@ -146,13 +157,14 @@ class Music(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'artist_id': entry[3], - 'grandparent_id': entry[4], - 'album_id': entry[5], - 'parent_id': entry[6], - 'kodi_id': entry[7], - 'kodi_pathid': entry[8], - 'last_sync': entry[9] + 'section_uuid': entry[3], + 'artist_id': entry[4], + 'grandparent_id': entry[5], + 'album_id': entry[6], + 'parent_id': entry[7], + 'kodi_id': entry[8], + 'kodi_pathid': entry[9], + 'last_sync': entry[10] } @staticmethod @@ -165,10 +177,11 @@ class Music(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'artist_id': entry[3], - 'parent_id': entry[4], - 'kodi_id': entry[5], - 'last_sync': entry[6] + 'section_uuid': entry[3], + 'artist_id': entry[4], + 'parent_id': entry[5], + 'kodi_id': entry[6], + 'last_sync': entry[7] } @staticmethod @@ -181,8 +194,9 @@ class Music(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'kodi_id': entry[3], - 'last_sync': entry[4] + 'section_uuid': entry[3], + 'kodi_id': entry[4], + 'last_sync': entry[5] } def album_has_songs(self, plex_id): diff --git a/resources/lib/plex_db/tvshows.py b/resources/lib/plex_db/tvshows.py index ae643b0e..41af5fb3 100644 --- a/resources/lib/plex_db/tvshows.py +++ b/resources/lib/plex_db/tvshows.py @@ -5,8 +5,8 @@ from .. import variables as v class TVShows(object): - def add_show(self, plex_id, checksum, section_id, kodi_id, kodi_pathid, - last_sync): + def add_show(self, plex_id, checksum, section_id, section_uuid, kodi_id, + kodi_pathid, last_sync): """ Appends or replaces tv show entry into the plex table """ @@ -16,22 +16,24 @@ class TVShows(object): plex_id, checksum, section_id, + section_uuid, kodi_id, kodi_pathid, fanart_synced, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', (plex_id, checksum, section_id, + section_uuid, kodi_id, kodi_pathid, 0, last_sync)) - def add_season(self, plex_id, checksum, section_id, show_id, parent_id, - kodi_id, last_sync): + def add_season(self, plex_id, checksum, section_id, section_uuid, show_id, + parent_id, kodi_id, last_sync): """ Appends or replaces an entry into the plex table """ @@ -41,23 +43,25 @@ class TVShows(object): plex_id, checksum, section_id, + section_uuid, show_id, parent_id, kodi_id, fanart_synced, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ''', (plex_id, checksum, section_id, + section_uuid, show_id, parent_id, kodi_id, 0, 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, kodi_fileid_2, kodi_pathid, last_sync): """ @@ -69,6 +73,7 @@ class TVShows(object): plex_id, checksum, section_id, + section_uuid, show_id, grandparent_id, season_id, @@ -79,11 +84,12 @@ class TVShows(object): kodi_pathid, fanart_synced, last_sync) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''', (plex_id, checksum, section_id, + section_uuid, show_id, grandparent_id, season_id, @@ -101,6 +107,7 @@ class TVShows(object): plex_id INTEGER PRIMARY KEY ASC, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, kodi_id INTEGER, kodi_pathid INTEGER, fanart_synced INTEGER, @@ -118,6 +125,7 @@ class TVShows(object): plex_id INTEGER PRIMARY KEY, checksum INTEGER UNIQUE, section_id INTEGER, + section_uuid TEXT, show_id INTEGER, # plex_id of the parent show parent_id INTEGER, # kodi_id of the parent show kodi_id INTEGER, @@ -147,16 +155,17 @@ class TVShows(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'show_id': entry[3], - 'grandparent_id': entry[4], - 'season_id': entry[5], - 'parent_id': entry[6], - 'kodi_id': entry[7], - 'kodi_fileid': entry[8], - 'kodi_fileid_2': entry[9], - 'kodi_pathid': entry[10], - 'fanart_synced': entry[11], - 'last_sync': entry[12] + 'section_uuid': entry[3], + 'show_id': entry[4], + 'grandparent_id': entry[5], + 'season_id': entry[6], + 'parent_id': entry[7], + 'kodi_id': entry[8], + 'kodi_fileid': entry[9], + 'kodi_fileid_2': entry[10], + 'kodi_pathid': entry[11], + 'fanart_synced': entry[12], + 'last_sync': entry[13] } @staticmethod @@ -169,10 +178,11 @@ class TVShows(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'kodi_id': entry[3], - 'kodi_pathid': entry[4], - 'fanart_synced': entry[5], - 'last_sync': entry[6] + 'section_uuid': entry[3], + 'kodi_id': entry[4], + 'kodi_pathid': entry[5], + 'fanart_synced': entry[6], + 'last_sync': entry[7] } @staticmethod @@ -185,11 +195,12 @@ class TVShows(object): 'plex_id': entry[0], 'checksum': entry[1], 'section_id': entry[2], - 'show_id': entry[3], - 'parent_id': entry[4], - 'kodi_id': entry[5], - 'fanart_synced': entry[6], - 'last_sync': entry[7] + 'section_uuid': entry[3], + 'show_id': entry[4], + 'parent_id': entry[5], + 'kodi_id': entry[6], + 'fanart_synced': entry[7], + 'last_sync': entry[8] } def season_has_episodes(self, plex_id): From ab8089d3b1d067b16966df36489e7d47694e7f9c Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 27 Apr 2019 11:44:48 +0200 Subject: [PATCH 4/4] Rename section.section_id to section.id --- resources/lib/library_sync/full_sync.py | 29 +++++-------- resources/lib/library_sync/sections.py | 54 ++++++++++++------------- 2 files changed, 36 insertions(+), 47 deletions(-) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index 44dcdbbe..7deafb17 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -25,18 +25,16 @@ UPDATED_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 Plex library section we're looking at """ - def __init__(self, context, total_number_of_items, section_name, - section_id, plex_type): - self.context = context + def __init__(self, total_number_of_items, section): + super(InitNewSection, self).__init__() + # Copy all section attributes to this instance + self.__dict__.update(section.__dict__) self.total = total_number_of_items - self.name = section_name - self.id = section_id - self.plex_type = plex_type class FullSync(common.fullsync_mixin): @@ -167,12 +165,7 @@ class FullSync(common.fullsync_mixin): # Sync new, updated and deleted items iterator = section.iterator # Tell the processing thread about this new section - queue_info = InitNewSection(section.context, - iterator.total, - iterator.get('librarySectionTitle', - iterator.get('title1')), - section.section_id, - section.plex_type) + queue_info = InitNewSection(iterator.total, section) self.queue.put(queue_info) last = True # To keep track of the item-number in order to kill while loops @@ -210,11 +203,7 @@ class FullSync(common.fullsync_mixin): # Sync new, updated and deleted items iterator = section.iterator # Tell the processing thread about this new section - queue_info = InitNewSection(section.context, - iterator.total, - section.name, - section.section_id, - section.plex_type) + queue_info = InitNewSection(iterator.total, section) self.queue.put(queue_info) self.total = iterator.total self.section_name = section.name @@ -272,7 +261,7 @@ class FullSync(common.fullsync_mixin): updated_at = section.last_sync - UPDATED_AT_SAFETY \ if section.last_sync else None try: - element.iterator = PF.SectionItems(section.section_id, + element.iterator = PF.SectionItems(section.id, plex_type=element.plex_type, updated_at=updated_at, last_viewed_at=None) @@ -329,7 +318,7 @@ class FullSync(common.fullsync_mixin): # some items from the PMS with PlexDB() as plexdb: # 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) common.update_kodi_library(video=True, music=True) # In order to not delete all your songs again diff --git a/resources/lib/library_sync/sections.py b/resources/lib/library_sync/sections.py index 16f62c63..74d72fc8 100644 --- a/resources/lib/library_sync/sections.py +++ b/resources/lib/library_sync/sections.py @@ -41,12 +41,12 @@ class Section(object): """ def __init__(self, index=None, xml_element=None, section_db_element=None): # 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 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 self._index = None # Codacy-bug self.index = index # int @@ -93,7 +93,7 @@ class Section(object): return ("{{" "'index': {self.index}, " "'name': '{self.name}', " - "'section_id': {self.section_id}, " + "'id': {self.id}, " "'section_type': '{self.section_type}', " "'sync_to_kodi': {self.sync_to_kodi}, " "'last_sync': {self.last_sync}, " @@ -105,12 +105,12 @@ class Section(object): __repr__ = __str__ 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.section_type is not None) def __eq__(self, section): - return (self.section_id == section.section_id and + return (self.id == section.id and self.name == section.name and self.section_type == section.section_type) @@ -118,12 +118,12 @@ class Section(object): return not self == section @property - def section_id(self): - return self._section_id + def id(self): + return self._id - @section_id.setter - def section_id(self, value): - self._section_id = value + @id.setter + def id(self, value): + self._id = value self._path = path_ops.path.join(LIBRARY_PATH, 'Plex-%s' % value, '') self._playlist_path = path_ops.path.join(PLAYLISTS_PATH, 'Plex %s.xsp' % value) @@ -166,7 +166,7 @@ class Section(object): return self._playlist_path 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.section_type = section_db_element['plex_type'] @@ -178,7 +178,7 @@ class Section(object): Reads section from a PMS xml (Plex id, name, Plex type) """ 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.section_type = api.plex_type() @@ -207,7 +207,7 @@ class Section(object): if not self: raise RuntimeError('Section not clearly defined: %s' % self) if plexdb: - plexdb.add_section(self.section_id, + plexdb.add_section(self.id, self.uuid, self.name, self.section_type, @@ -215,7 +215,7 @@ class Section(object): self.last_sync) else: with PlexDB(lock=False) as plexdb: - plexdb.add_section(self.section_id, + plexdb.add_section(self.id, self.uuid, self.name, self.section_type, @@ -245,21 +245,21 @@ class Section(object): # nodes as "submenus" once the user navigates into this section args = { 'mode': 'browseplex', - 'key': '/library/sections/%s' % self.section_id, + 'key': '/library/sections/%s' % self.id, 'plex_type': self.section_type, - 'section_id': unicode(self.section_id) + 'section_id': unicode(self.id) } if not self.sync_to_kodi: args['synched'] = 'false' addon_index = self.addon_path(args) if self.sync_to_kodi and self.section_type in v.PLEX_VIDEOTYPES: path = 'library://video/Plex-{0}/{0}_all.xml' - path = path.format(self.section_id) - index = 'library://video/Plex-%s' % self.section_id + path = path.format(self.id) + index = 'library://video/Plex-%s' % self.id else: # No xmls to link to - let's show the listings on the fly 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) # .index will list all possible nodes for this library utils.window('%s.index' % self.node, value=index) @@ -277,7 +277,7 @@ class Section(object): # Pictures utils.window('%s.path' % self.node, 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 utils.window('%s.addon_index' % self.node, value=addon_index) if not self.sync_to_kodi: @@ -316,7 +316,7 @@ class Section(object): def _build_node(self, node_type, node_name, args, content, pms_node): self.content = content 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) if not path_ops.exists(path): if pms_node: @@ -327,7 +327,7 @@ class Section(object): xml = getattr(nodes, 'node_%s' % node_type)(self, node_name) self._write_xml(xml, xml_name) 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) def _write_xml(self, xml, xml_name): @@ -366,13 +366,13 @@ class Section(object): # if node_type == 'all': # var = self.node # 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) # else: var = '%s.%s' % (self.node, node_type) utils.window('%s.index' % var, value=path) 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.type' % var, value=self.content) utils.window('%s.content' % var, value=path) @@ -407,10 +407,10 @@ class Section(object): Removes this sections completely from the Plex DB """ if plexdb: - plexdb.remove_section(self.section_id) + plexdb.remove_section(self.id) else: with PlexDB(lock=False) as plexdb: - plexdb.remove_section(self.section_id) + plexdb.remove_section(self.id) def remove(self): """ @@ -473,7 +473,7 @@ def _delete_kodi_db_items(section): for plex_type, context in types: while True: 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, BATCH_SIZE)) with kodi_context(texture_db=True) as kodidb: