Merge pull request #761 from croneter/fix-playlists
Fix rare cases where playlists were being created
This commit is contained in:
commit
a2cd5bec76
3 changed files with 25 additions and 37 deletions
|
@ -34,11 +34,6 @@ SUPPORTED_FILETYPES = (
|
||||||
# 'pls',
|
# 'pls',
|
||||||
# 'cue',
|
# '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)
|
plex_id = int(plex_id)
|
||||||
with app.APP.lock_playlists:
|
with app.APP.lock_playlists:
|
||||||
playlist = db.get_playlist(plex_id=plex_id)
|
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',
|
LOG.debug('Ignoring detected Plex playlist change for %s',
|
||||||
playlist)
|
playlist)
|
||||||
IGNORE_PLEX_PLAYLIST_CHANGE.remove(plex_id)
|
plex_pl.IGNORE_PLEX_PLAYLIST_CHANGE.remove(plex_id)
|
||||||
return
|
return
|
||||||
if playlist and status == 9:
|
if playlist and status == 9:
|
||||||
# Won't be able to download metadata of the deleted playlist
|
# Won't be able to download metadata of the deleted playlist
|
||||||
if sync_plex_playlist(playlist=playlist):
|
if sync_plex_playlist(playlist=playlist):
|
||||||
LOG.debug('Plex deletion of playlist detected: %s', playlist)
|
LOG.debug('Plex deletion of playlist detected: %s', playlist)
|
||||||
try:
|
try:
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id)
|
|
||||||
kodi_pl.delete(playlist)
|
kodi_pl.delete(playlist)
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.remove(plex_id)
|
pass
|
||||||
return
|
return
|
||||||
xml = pms.metadata(plex_id)
|
xml = pms.metadata(plex_id)
|
||||||
if xml is None:
|
if xml is None:
|
||||||
|
@ -130,7 +124,6 @@ def websocket(plex_id, status):
|
||||||
else:
|
else:
|
||||||
LOG.debug('Change of Plex playlist detected: %s',
|
LOG.debug('Change of Plex playlist detected: %s',
|
||||||
playlist)
|
playlist)
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id)
|
|
||||||
kodi_pl.delete(playlist)
|
kodi_pl.delete(playlist)
|
||||||
create = True
|
create = True
|
||||||
elif not playlist and not status == 9:
|
elif not playlist and not status == 9:
|
||||||
|
@ -139,10 +132,9 @@ def websocket(plex_id, status):
|
||||||
create = True
|
create = True
|
||||||
# To the actual work
|
# To the actual work
|
||||||
if create:
|
if create:
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(plex_id)
|
|
||||||
kodi_pl.create(plex_id)
|
kodi_pl.create(plex_id)
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.remove(plex_id)
|
pass
|
||||||
|
|
||||||
|
|
||||||
def full_sync():
|
def full_sync():
|
||||||
|
@ -187,41 +179,33 @@ def _full_sync():
|
||||||
if not playlist:
|
if not playlist:
|
||||||
LOG.debug('New Plex playlist %s discovered: %s',
|
LOG.debug('New Plex playlist %s discovered: %s',
|
||||||
api.plex_id(), api.title())
|
api.plex_id(), api.title())
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(api.plex_id())
|
|
||||||
try:
|
try:
|
||||||
kodi_pl.create(api.plex_id())
|
kodi_pl.create(api.plex_id())
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
LOG.info('Skipping creation of playlist %s', api.plex_id())
|
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():
|
elif playlist.plex_updatedat != api.updated_at():
|
||||||
LOG.debug('Detected changed Plex playlist %s: %s',
|
LOG.debug('Detected changed Plex playlist %s: %s',
|
||||||
api.plex_id(), api.title())
|
api.plex_id(), api.title())
|
||||||
# Since we are DELETING a playlist, we need to catch with path!
|
# Since we are DELETING a playlist, we need to catch with path!
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path)
|
|
||||||
try:
|
try:
|
||||||
kodi_pl.delete(playlist)
|
kodi_pl.delete(playlist)
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
LOG.info('Skipping recreation of playlist %s', api.plex_id())
|
LOG.info('Skipping recreation of playlist %s', api.plex_id())
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path)
|
|
||||||
else:
|
else:
|
||||||
IGNORE_KODI_PLAYLIST_CHANGE.append(api.plex_id())
|
|
||||||
try:
|
try:
|
||||||
kodi_pl.create(api.plex_id())
|
kodi_pl.create(api.plex_id())
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
LOG.info('Could not recreate playlist %s', api.plex_id())
|
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
|
# Get rid of old Plex playlists that were deleted on the Plex side
|
||||||
for plex_id in old_plex_ids:
|
for plex_id in old_plex_ids:
|
||||||
if isCanceled():
|
if isCanceled():
|
||||||
return False
|
return False
|
||||||
playlist = db.get_playlist(plex_id=plex_id)
|
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)
|
LOG.debug('Removing outdated Plex playlist from Kodi: %s', playlist)
|
||||||
try:
|
try:
|
||||||
kodi_pl.delete(playlist)
|
kodi_pl.delete(playlist)
|
||||||
except PlaylistError:
|
except PlaylistError:
|
||||||
LOG.debug('Skipping deletion of playlist: %s', playlist)
|
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.
|
# Look at all supported Kodi playlists. Check whether they are in the DB.
|
||||||
old_kodi_paths = db.kodi_playlist_paths()
|
old_kodi_paths = db.kodi_playlist_paths()
|
||||||
for root, _, files in path_ops.walk(v.PLAYLIST_PATH):
|
for root, _, files in path_ops.walk(v.PLAYLIST_PATH):
|
||||||
|
@ -250,7 +234,6 @@ def _full_sync():
|
||||||
LOG.info('Skipping Kodi playlist %s', path)
|
LOG.info('Skipping Kodi playlist %s', path)
|
||||||
else:
|
else:
|
||||||
LOG.debug('Changed Kodi playlist detected: %s', path)
|
LOG.debug('Changed Kodi playlist detected: %s', path)
|
||||||
IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id)
|
|
||||||
plex_pl.delete(playlist)
|
plex_pl.delete(playlist)
|
||||||
playlist.kodi_hash = kodi_hash
|
playlist.kodi_hash = kodi_hash
|
||||||
try:
|
try:
|
||||||
|
@ -386,15 +369,9 @@ class PlaylistEventhandler(events.FileSystemEventHandler):
|
||||||
else event.src_path
|
else event.src_path
|
||||||
if not sync_kodi_playlist(path):
|
if not sync_kodi_playlist(path):
|
||||||
return
|
return
|
||||||
playlist = db.get_playlist(path=path)
|
if path in kodi_pl.IGNORE_KODI_PLAYLIST_CHANGE:
|
||||||
if playlist and playlist.plex_id in IGNORE_KODI_PLAYLIST_CHANGE:
|
LOG.debug('Ignoring event %s', event)
|
||||||
LOG.debug('Ignoring event %s for playlist %s', event, playlist)
|
kodi_pl.IGNORE_KODI_PLAYLIST_CHANGE.remove(path)
|
||||||
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)
|
|
||||||
return
|
return
|
||||||
_method_map = {
|
_method_map = {
|
||||||
events.EVENT_TYPE_MODIFIED: self.on_modified,
|
events.EVENT_TYPE_MODIFIED: self.on_modified,
|
||||||
|
|
|
@ -14,10 +14,10 @@ from ..plex_api import API
|
||||||
from .. import utils, path_ops, variables as v
|
from .. import utils, path_ops, variables as v
|
||||||
###############################################################################
|
###############################################################################
|
||||||
LOG = getLogger('PLEX.playlists.kodi_pl')
|
LOG = getLogger('PLEX.playlists.kodi_pl')
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
REGEX_FILE_NUMBERING = re.compile(r'''_(\d\d)\.\w+$''')
|
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):
|
def create(plex_id):
|
||||||
|
@ -54,8 +54,8 @@ def create(plex_id):
|
||||||
else:
|
else:
|
||||||
number = int(occurance.group(1)) + 1
|
number = int(occurance.group(1)) + 1
|
||||||
if number > 3:
|
if number > 3:
|
||||||
LOG.error('Detected spanning tree issue, abort sync for %s',
|
LOG.warn('Detected spanning tree issue, abort sync for %s',
|
||||||
playlist)
|
playlist)
|
||||||
raise PlaylistError('Spanning tree warning')
|
raise PlaylistError('Spanning tree warning')
|
||||||
basename = re.sub(REGEX_FILE_NUMBERING, '', path)
|
basename = re.sub(REGEX_FILE_NUMBERING, '', path)
|
||||||
path = '%s_%02d.m3u' % (basename, number)
|
path = '%s_%02d.m3u' % (basename, number)
|
||||||
|
@ -65,7 +65,12 @@ def create(plex_id):
|
||||||
if xml_playlist is None:
|
if xml_playlist is None:
|
||||||
LOG.error('Could not get Plex playlist %s', plex_id)
|
LOG.error('Could not get Plex playlist %s', plex_id)
|
||||||
raise PlaylistError('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)
|
playlist.kodi_hash = utils.generate_file_md5(path)
|
||||||
db.update_playlist(playlist)
|
db.update_playlist(playlist)
|
||||||
LOG.debug('Created Kodi playlist based on Plex playlist: %s', playlist)
|
LOG.debug('Created Kodi playlist based on Plex playlist: %s', playlist)
|
||||||
|
@ -79,12 +84,14 @@ def delete(playlist):
|
||||||
Returns None or raises PlaylistError
|
Returns None or raises PlaylistError
|
||||||
"""
|
"""
|
||||||
if path_ops.exists(playlist.kodi_path):
|
if path_ops.exists(playlist.kodi_path):
|
||||||
|
IGNORE_KODI_PLAYLIST_CHANGE.append(playlist.kodi_path)
|
||||||
try:
|
try:
|
||||||
path_ops.remove(playlist.kodi_path)
|
path_ops.remove(playlist.kodi_path)
|
||||||
LOG.debug('Deleted Kodi playlist: %s', playlist)
|
LOG.debug('Deleted Kodi playlist: %s', playlist)
|
||||||
except (OSError, IOError) as err:
|
except (OSError, IOError) as err:
|
||||||
LOG.error('Could not delete Kodi playlist file %s. Error:\n%s: %s',
|
LOG.error('Could not delete Kodi playlist file %s. Error:\n%s: %s',
|
||||||
playlist, err.errno, err.strerror)
|
playlist, err.errno, err.strerror)
|
||||||
|
IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path)
|
||||||
raise PlaylistError('Could not delete %s' % playlist.kodi_path)
|
raise PlaylistError('Could not delete %s' % playlist.kodi_path)
|
||||||
db.update_playlist(playlist, delete=True)
|
db.update_playlist(playlist, delete=True)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ from .common import PlaylistError
|
||||||
from . import pms, db
|
from . import pms, db
|
||||||
###############################################################################
|
###############################################################################
|
||||||
LOG = getLogger('PLEX.playlists.plex_pl')
|
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:
|
if not plex_ids:
|
||||||
LOG.warning('No Plex ids found for playlist %s', playlist)
|
LOG.warning('No Plex ids found for playlist %s', playlist)
|
||||||
raise PlaylistError
|
raise PlaylistError
|
||||||
|
IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id)
|
||||||
pms.add_items(playlist, plex_ids)
|
pms.add_items(playlist, plex_ids)
|
||||||
db.update_playlist(playlist)
|
db.update_playlist(playlist)
|
||||||
LOG.debug('Done creating Plex playlist %s', playlist)
|
LOG.debug('Done creating Plex playlist %s', playlist)
|
||||||
|
@ -40,5 +43,6 @@ def delete(playlist):
|
||||||
Returns None or raises PlaylistError
|
Returns None or raises PlaylistError
|
||||||
"""
|
"""
|
||||||
LOG.debug('Deleting playlist from PMS: %s', playlist)
|
LOG.debug('Deleting playlist from PMS: %s', playlist)
|
||||||
|
IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id)
|
||||||
pms.delete(playlist)
|
pms.delete(playlist)
|
||||||
db.update_playlist(playlist, delete=True)
|
db.update_playlist(playlist, delete=True)
|
||||||
|
|
Loading…
Reference in a new issue