diff --git a/resources/lib/playlists/__init__.py b/resources/lib/playlists/__init__.py index 9d35125c..231b1865 100644 --- a/resources/lib/playlists/__init__.py +++ b/resources/lib/playlists/__init__.py @@ -34,11 +34,6 @@ SUPPORTED_FILETYPES = ( # 'pls', # 'cue', ) -# Avoid endless loops. Store Plex IDs for creating, Kodi paths for deleting! -IGNORE_KODI_PLAYLIST_CHANGE = list() -# Used for updating Plex playlists due to Kodi changes - Plex playlist -# will have to be deleted first. Add Plex ids! -IGNORE_PLEX_PLAYLIST_CHANGE = list() ############################################################################### @@ -99,20 +94,19 @@ def websocket(plex_id, status): plex_id = int(plex_id) with app.APP.lock_playlists: playlist = db.get_playlist(plex_id=plex_id) - if plex_id in IGNORE_PLEX_PLAYLIST_CHANGE: + if plex_id in plex_pl.IGNORE_PLEX_PLAYLIST_CHANGE: LOG.debug('Ignoring detected Plex playlist change for %s', playlist) - IGNORE_PLEX_PLAYLIST_CHANGE.remove(plex_id) + plex_pl.IGNORE_PLEX_PLAYLIST_CHANGE.remove(plex_id) return if playlist and status == 9: # Won't be able to download metadata of the deleted playlist if sync_plex_playlist(playlist=playlist): LOG.debug('Plex deletion of playlist detected: %s', playlist) try: - IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id) kodi_pl.delete(playlist) except PlaylistError: - IGNORE_KODI_PLAYLIST_CHANGE.remove(plex_id) + pass return xml = pms.metadata(plex_id) if xml is None: @@ -130,7 +124,6 @@ def websocket(plex_id, status): else: LOG.debug('Change of Plex playlist detected: %s', playlist) - IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id) kodi_pl.delete(playlist) create = True elif not playlist and not status == 9: @@ -139,10 +132,9 @@ def websocket(plex_id, status): create = True # To the actual work if create: - IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id) kodi_pl.create(plex_id) except PlaylistError: - IGNORE_KODI_PLAYLIST_CHANGE.remove(plex_id) + pass def full_sync(): @@ -187,41 +179,33 @@ def _full_sync(): if not playlist: LOG.debug('New Plex playlist %s discovered: %s', api.plex_id(), api.title()) - IGNORE_KODI_PLAYLIST_CHANGE.append(api.plex_id()) try: kodi_pl.create(api.plex_id()) except PlaylistError: LOG.info('Skipping creation of playlist %s', api.plex_id()) - IGNORE_KODI_PLAYLIST_CHANGE.remove(api.plex_id()) elif playlist.plex_updatedat != api.updated_at(): LOG.debug('Detected changed Plex playlist %s: %s', api.plex_id(), api.title()) # Since we are DELETING a playlist, we need to catch with path! - IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path) try: kodi_pl.delete(playlist) except PlaylistError: LOG.info('Skipping recreation of playlist %s', api.plex_id()) - IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path) else: - IGNORE_KODI_PLAYLIST_CHANGE.append(api.plex_id()) try: kodi_pl.create(api.plex_id()) except PlaylistError: LOG.info('Could not recreate playlist %s', api.plex_id()) - IGNORE_KODI_PLAYLIST_CHANGE.remove(api.plex_id()) # Get rid of old Plex playlists that were deleted on the Plex side for plex_id in old_plex_ids: if isCanceled(): return False playlist = db.get_playlist(plex_id=plex_id) - IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path) LOG.debug('Removing outdated Plex playlist from Kodi: %s', playlist) try: kodi_pl.delete(playlist) except PlaylistError: LOG.debug('Skipping deletion of playlist: %s', playlist) - IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path) # Look at all supported Kodi playlists. Check whether they are in the DB. old_kodi_paths = db.kodi_playlist_paths() for root, _, files in path_ops.walk(v.PLAYLIST_PATH): @@ -250,7 +234,6 @@ def _full_sync(): LOG.info('Skipping Kodi playlist %s', path) else: LOG.debug('Changed Kodi playlist detected: %s', path) - IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id) plex_pl.delete(playlist) playlist.kodi_hash = kodi_hash try: @@ -386,15 +369,9 @@ class PlaylistEventhandler(events.FileSystemEventHandler): else event.src_path if not sync_kodi_playlist(path): return - playlist = db.get_playlist(path=path) - if playlist and playlist.plex_id in IGNORE_KODI_PLAYLIST_CHANGE: - LOG.debug('Ignoring event %s for playlist %s', event, playlist) - IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.plex_id) - return - if not playlist and path in IGNORE_KODI_PLAYLIST_CHANGE: - LOG.debug('Ignoring deletion event %s for playlist %s', - event, playlist) - IGNORE_KODI_PLAYLIST_CHANGE.remove(path) + if path in kodi_pl.IGNORE_KODI_PLAYLIST_CHANGE: + LOG.debug('Ignoring event %s', event) + kodi_pl.IGNORE_KODI_PLAYLIST_CHANGE.remove(path) return _method_map = { events.EVENT_TYPE_MODIFIED: self.on_modified, diff --git a/resources/lib/playlists/kodi_pl.py b/resources/lib/playlists/kodi_pl.py index f131d79d..f9413144 100644 --- a/resources/lib/playlists/kodi_pl.py +++ b/resources/lib/playlists/kodi_pl.py @@ -14,10 +14,10 @@ from ..plex_api import API from .. import utils, path_ops, variables as v ############################################################################### LOG = getLogger('PLEX.playlists.kodi_pl') - -############################################################################### - REGEX_FILE_NUMBERING = re.compile(r'''_(\d\d)\.\w+$''') +# Avoid endless loops. Store the Kodi paths +IGNORE_KODI_PLAYLIST_CHANGE = list() +############################################################################### def create(plex_id): @@ -54,8 +54,8 @@ def create(plex_id): else: number = int(occurance.group(1)) + 1 if number > 3: - LOG.error('Detected spanning tree issue, abort sync for %s', - playlist) + LOG.warn('Detected spanning tree issue, abort sync for %s', + playlist) raise PlaylistError('Spanning tree warning') basename = re.sub(REGEX_FILE_NUMBERING, '', path) path = '%s_%02d.m3u' % (basename, number) @@ -65,7 +65,12 @@ def create(plex_id): if xml_playlist is None: LOG.error('Could not get Plex playlist %s', plex_id) raise PlaylistError('Could not get Plex playlist %s' % plex_id) - _write_playlist_to_file(playlist, xml_playlist) + IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path) + try: + _write_playlist_to_file(playlist, xml_playlist) + except Exception: + IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path) + raise playlist.kodi_hash = utils.generate_file_md5(path) db.update_playlist(playlist) LOG.debug('Created Kodi playlist based on Plex playlist: %s', playlist) @@ -79,12 +84,14 @@ def delete(playlist): Returns None or raises PlaylistError """ if path_ops.exists(playlist.kodi_path): + IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path) try: path_ops.remove(playlist.kodi_path) LOG.debug('Deleted Kodi playlist: %s', playlist) except (OSError, IOError) as err: LOG.error('Could not delete Kodi playlist file %s. Error:\n%s: %s', playlist, err.errno, err.strerror) + IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path) raise PlaylistError('Could not delete %s' % playlist.kodi_path) db.update_playlist(playlist, delete=True) diff --git a/resources/lib/playlists/plex_pl.py b/resources/lib/playlists/plex_pl.py index d7edc432..03c863a4 100644 --- a/resources/lib/playlists/plex_pl.py +++ b/resources/lib/playlists/plex_pl.py @@ -10,7 +10,9 @@ from .common import PlaylistError from . import pms, db ############################################################################### LOG = getLogger('PLEX.playlists.plex_pl') - +# Used for updating Plex playlists due to Kodi changes - Plex playlist +# will have to be deleted first. Add Plex ids! +IGNORE_PLEX_PLAYLIST_CHANGE = list() ############################################################################### @@ -28,6 +30,7 @@ def create(playlist): if not plex_ids: LOG.warning('No Plex ids found for playlist %s', playlist) raise PlaylistError + IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id) pms.add_items(playlist, plex_ids) db.update_playlist(playlist) LOG.debug('Done creating Plex playlist %s', playlist) @@ -40,5 +43,6 @@ def delete(playlist): Returns None or raises PlaylistError """ LOG.debug('Deleting playlist from PMS: %s', playlist) + IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id) pms.delete(playlist) db.update_playlist(playlist, delete=True)