From 56324b1e881d0552f4abc2b0cbb9ba5f8c396cc6 Mon Sep 17 00:00:00 2001 From: croneter Date: Mon, 25 Nov 2019 08:00:43 +0100 Subject: [PATCH] Fix OperationalError when resetting PKC --- resources/lib/migration.py | 3 ++- resources/lib/playlists/__init__.py | 36 +++++++++++++++++++---------- resources/lib/playlists/db.py | 17 ++++++++++++++ resources/lib/playlists/kodi_pl.py | 15 ++++++++++++ resources/lib/plex_db/playlists.py | 13 +++++++++++ resources/lib/utils.py | 27 ++-------------------- 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/resources/lib/migration.py b/resources/lib/migration.py index ae04e96a..13ec7729 100644 --- a/resources/lib/migration.py +++ b/resources/lib/migration.py @@ -64,7 +64,8 @@ def check_migration(): if not utils.compare_version(last_migration, '2.9.3'): LOG.info('Migrating to version 2.9.2') # Re-sync all playlists to Kodi - utils.wipe_synched_playlists() + from .playlists import remove_synced_playlists + remove_synced_playlists() if not utils.compare_version(last_migration, '2.9.7'): LOG.info('Migrating to version 2.9.6') diff --git a/resources/lib/playlists/__init__.py b/resources/lib/playlists/__init__.py index b3658ba0..d865087f 100644 --- a/resources/lib/playlists/__init__.py +++ b/resources/lib/playlists/__init__.py @@ -68,6 +68,18 @@ def kodi_playlist_monitor(): return observer +def remove_synced_playlists(): + """ + Deletes all synched playlists on the Kodi side, not on the Plex side + """ + LOG.info('Removing all playlists that we synced to Kodi') + with app.APP.lock_playlists: + paths = db.get_all_kodi_playlist_paths() + kodi_pl.delete_kodi_playlists(paths) + db.wipe_table() + LOG.info('Done removing all synced playlists') + + def websocket(plex_id, status): """ Call this function to process websocket messages from the PMS @@ -370,19 +382,19 @@ class PlaylistEventhandler(events.FileSystemEventHandler): """ path = event.dest_path if event.event_type == events.EVENT_TYPE_MOVED \ else event.src_path - if not sync_kodi_playlist(path): - return - 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, - events.EVENT_TYPE_MOVED: self.on_moved, - events.EVENT_TYPE_CREATED: self.on_created, - events.EVENT_TYPE_DELETED: self.on_deleted, - } with app.APP.lock_playlists: + if not sync_kodi_playlist(path): + return + 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, + events.EVENT_TYPE_MOVED: self.on_moved, + events.EVENT_TYPE_CREATED: self.on_created, + events.EVENT_TYPE_DELETED: self.on_deleted, + } _method_map[event.event_type](event) def on_created(self, event): diff --git a/resources/lib/playlists/db.py b/resources/lib/playlists/db.py index 6b63c39a..673fc02a 100644 --- a/resources/lib/playlists/db.py +++ b/resources/lib/playlists/db.py @@ -57,6 +57,23 @@ def get_playlist(path=None, plex_id=None): return playlist +def get_all_kodi_playlist_paths(): + """ + Returns a list with all paths for the playlists on the Kodi side + """ + with PlexDB() as plexdb: + paths = list(plexdb.all_kodi_paths()) + return paths + + +def wipe_table(): + """ + Deletes all playlists entries in the Plex DB + """ + with PlexDB() as plexdb: + plexdb.wipe_playlists() + + def _m3u_iterator(text): """ Yields e.g. plugin://plugin.video.plexkodiconnect.movies/?plex_id=xxx diff --git a/resources/lib/playlists/kodi_pl.py b/resources/lib/playlists/kodi_pl.py index 4b040c25..8753326d 100644 --- a/resources/lib/playlists/kodi_pl.py +++ b/resources/lib/playlists/kodi_pl.py @@ -96,6 +96,21 @@ def delete(playlist): db.update_playlist(playlist, delete=True) +def delete_kodi_playlists(playlist_paths): + """ + Deletes all the the playlist files passed in; WILL IGNORE THIS CHANGE ON + THE PLEX SIDE! + """ + for path in playlist_paths: + try: + path_ops.remove(path) + # Ensure we're not deleting the playlists on the Plex side later + IGNORE_KODI_PLAYLIST_CHANGE.append(path) + LOG.info('Removed playlist %s', path) + except (OSError, IOError): + LOG.warn('Could not remove playlist %s', path) + + def _write_playlist_to_file(playlist, xml): """ Feed with playlist Playlist. Will write the playlist to a m3u file diff --git a/resources/lib/plex_db/playlists.py b/resources/lib/plex_db/playlists.py index 586e745a..68575bb8 100644 --- a/resources/lib/plex_db/playlists.py +++ b/resources/lib/plex_db/playlists.py @@ -81,3 +81,16 @@ class Playlists(object): playlist.kodi_type = answ[4] playlist.kodi_hash = answ[5] return playlist + + def all_kodi_paths(self): + """ + Returns a generator for all kodi_paths of all synched playlists + """ + self.cursor.execute('SELECT kodi_path FROM playlists') + return (x[0] for x in self.cursor) + + def wipe_playlists(self): + """ + Deletes all entries in the playlists table + """ + self.cursor.execute('DELETE FROM playlists') diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 0b025128..3bf26dc2 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -525,29 +525,6 @@ def delete_temporary_subtitles(): root, file, err) -def wipe_synched_playlists(): - """ - Deletes all synched playlist files on the Kodi side; resets the Plex table - listing all synched Plex playlists - """ - from . import plex_db - try: - with plex_db.PlexDB() as plexdb: - plexdb.cursor.execute('SELECT kodi_path FROM playlists') - playlist_paths = [x[0] for x in plexdb.cursor] - except OperationalError: - # Plex DB completely empty yet - playlist_paths = [] - for path in playlist_paths: - try: - path_ops.remove(path) - LOG.info('Removed playlist %s', path) - except (OSError, IOError): - LOG.warn('Could not remove playlist %s', path) - # Now wipe our database - plex_db.wipe(table='playlists') - - def wipe_database(reboot=True): """ Deletes all Plex playlists as well as video nodes, then clears Kodi as well @@ -557,10 +534,10 @@ def wipe_database(reboot=True): LOG.warn('Start wiping') from .library_sync.sections import delete_files from . import kodi_db, plex_db + from .playlists import remove_synced_playlists # Clean up the playlists and video nodes delete_files() - # Wipe all synched playlists - wipe_synched_playlists() + remove_synced_playlists() try: with plex_db.PlexDB() as plexdb: if plexdb.songs_have_been_synced():