Merge pull request #1384 from croneter/py3-sync-playstates

Quickly sync recently watched items before synching the playstates of the entire Plex library
This commit is contained in:
croneter 2021-03-07 17:19:18 +01:00 committed by GitHub
commit ed93771d12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -136,7 +136,7 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
LOG.error('Could not entirely process section %s', section) LOG.error('Could not entirely process section %s', section)
self.successful = False self.successful = False
def threaded_get_generators(self, kinds, section_queue, all_items): def threaded_get_generators(self, kinds, section_queue, items):
""" """
Getting iterators is costly, so let's do it in a dedicated thread Getting iterators is costly, so let's do it in a dedicated thread
""" """
@ -153,17 +153,28 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
continue continue
section = sections.get_sync_section(section, section = sections.get_sync_section(section,
plex_type=kind[0]) plex_type=kind[0])
if self.repair or all_items: timestamp = section.last_sync - UPDATED_AT_SAFETY \
if section.last_sync else None
if items == 'all':
updated_at = None updated_at = None
else: last_viewed_at = None
updated_at = section.last_sync - UPDATED_AT_SAFETY \ elif items == 'watched':
if section.last_sync else None if not timestamp:
# No need to sync playstate updates since section
# has not yet been synched
continue
else:
updated_at = None
last_viewed_at = timestamp
elif items == 'updated':
updated_at = timestamp
last_viewed_at = None
try: try:
section.iterator = PF.get_section_iterator( section.iterator = PF.get_section_iterator(
section.section_id, section.section_id,
plex_type=section.plex_type, plex_type=section.plex_type,
updated_at=updated_at, updated_at=updated_at,
last_viewed_at=None) last_viewed_at=last_viewed_at)
except RuntimeError: except RuntimeError:
LOG.error('Sync at least partially unsuccessful!') LOG.error('Sync at least partially unsuccessful!')
LOG.error('Error getting section iterator %s', section) LOG.error('Error getting section iterator %s', section)
@ -194,19 +205,42 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
(v.PLEX_TYPE_ARTIST, v.PLEX_TYPE_ARTIST), (v.PLEX_TYPE_ARTIST, v.PLEX_TYPE_ARTIST),
(v.PLEX_TYPE_ALBUM, v.PLEX_TYPE_ARTIST), (v.PLEX_TYPE_ALBUM, v.PLEX_TYPE_ARTIST),
]) ])
# ADD NEW ITEMS # ADD NEW ITEMS
# We need to enforce syncing e.g. show before season before episode # We need to enforce syncing e.g. show before season before episode
bg.FunctionAsTask(self.threaded_get_generators, bg.FunctionAsTask(self.threaded_get_generators,
None, None,
kinds, section_queue, False).start() kinds,
section_queue,
items='all' if self.repair else 'updated').start()
# Do the heavy lifting # Do the heavy lifting
self.process_new_and_changed_items(section_queue, processing_queue) self.process_new_and_changed_items(section_queue, processing_queue)
common.update_kodi_library(video=True, music=True) common.update_kodi_library(video=True, music=True)
if self.should_cancel() or not self.successful: if self.should_cancel() or not self.successful:
return return
# In order to not delete all your songs again for playstate synch
if app.SYNC.enable_music:
kinds.extend([
(v.PLEX_TYPE_SONG, v.PLEX_TYPE_ARTIST),
])
# Update playstate progress since last sync - especially useful for
# users of very large libraries since this step is very fast
# These playstates will be synched twice
LOG.debug('Start synching playstate for last watched items')
bg.FunctionAsTask(self.threaded_get_generators,
None,
kinds,
section_queue,
items='watched').start()
self.processing_loop_playstates(section_queue)
if self.should_cancel() or not self.successful:
return
# Sync Plex playlists to Kodi and vice-versa # Sync Plex playlists to Kodi and vice-versa
if common.PLAYLIST_SYNC_ENABLED: if common.PLAYLIST_SYNC_ENABLED:
LOG.debug('Start playlist sync')
if self.show_dialog: if self.show_dialog:
if self.dialog: if self.dialog:
self.dialog.close() self.dialog.close()
@ -217,14 +251,9 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
return return
# SYNC PLAYSTATE of ALL items (otherwise we won't pick up on items that # SYNC PLAYSTATE of ALL items (otherwise we won't pick up on items that
# were set to unwatched). Also mark all items on the PMS to be able # were set to unwatched or changed user ratings). Also mark all items on
# to delete the ones still in Kodi # the PMS to be able to delete the ones still in Kodi
LOG.debug('Start synching playstate and userdata for every item') LOG.debug('Start synching playstate and userdata for every item')
if app.SYNC.enable_music:
# In order to not delete all your songs again
kinds.extend([
(v.PLEX_TYPE_SONG, v.PLEX_TYPE_ARTIST),
])
# Make sure we're not showing an item's title in the sync dialog # Make sure we're not showing an item's title in the sync dialog
if not self.show_dialog_userdata and self.dialog: if not self.show_dialog_userdata and self.dialog:
# Close the progress indicator dialog # Close the progress indicator dialog
@ -232,7 +261,9 @@ class FullSync(common.LibrarySyncMixin, bg.KillableThread):
self.dialog = None self.dialog = None
bg.FunctionAsTask(self.threaded_get_generators, bg.FunctionAsTask(self.threaded_get_generators,
None, None,
kinds, section_queue, True).start() kinds,
section_queue,
items='all').start()
self.processing_loop_playstates(section_queue) self.processing_loop_playstates(section_queue)
if self.should_cancel() or not self.successful: if self.should_cancel() or not self.successful:
return return