Introduce playlist locking; override watchdog dispatching
This commit is contained in:
parent
2971dd3f7c
commit
c98a8456ff
1 changed files with 34 additions and 20 deletions
|
@ -2,6 +2,7 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
|
@ -19,6 +20,11 @@ import state
|
||||||
|
|
||||||
LOG = getLogger("PLEX." + __name__)
|
LOG = getLogger("PLEX." + __name__)
|
||||||
|
|
||||||
|
# Necessary to temporarily hold back librarysync/websocket listener when doing
|
||||||
|
# a full sync
|
||||||
|
LOCK = Lock()
|
||||||
|
LOCKER = utils.LockFunction(LOCK)
|
||||||
|
|
||||||
# Which playlist formates are supported by PKC?
|
# Which playlist formates are supported by PKC?
|
||||||
SUPPORTED_FILETYPES = (
|
SUPPORTED_FILETYPES = (
|
||||||
'm3u',
|
'm3u',
|
||||||
|
@ -27,6 +33,12 @@ SUPPORTED_FILETYPES = (
|
||||||
# 'cue',
|
# 'cue',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Watchdog copy-paste
|
||||||
|
EVENT_TYPE_MOVED = 'moved'
|
||||||
|
EVENT_TYPE_DELETED = 'deleted'
|
||||||
|
EVENT_TYPE_CREATED = 'created'
|
||||||
|
EVENT_TYPE_MODIFIED = 'modified'
|
||||||
|
|
||||||
# m3u files do not have encoding specified
|
# m3u files do not have encoding specified
|
||||||
if v.PLATFORM == 'Windows':
|
if v.PLATFORM == 'Windows':
|
||||||
ENCODING = 'mbcs'
|
ENCODING = 'mbcs'
|
||||||
|
@ -267,6 +279,7 @@ def _kodi_playlist_identical(xml_element):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@LOCKER.lockthis
|
||||||
def process_websocket(plex_id, updated_at, state):
|
def process_websocket(plex_id, updated_at, state):
|
||||||
"""
|
"""
|
||||||
Hit by librarysync to process websocket messages concerning playlists
|
Hit by librarysync to process websocket messages concerning playlists
|
||||||
|
@ -293,7 +306,7 @@ def process_websocket(plex_id, updated_at, state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@utils.log_time
|
@LOCKER.lockthis
|
||||||
def full_sync():
|
def full_sync():
|
||||||
"""
|
"""
|
||||||
Full sync of playlists between Kodi and Plex. Returns True is successful,
|
Full sync of playlists between Kodi and Plex. Returns True is successful,
|
||||||
|
@ -399,30 +412,37 @@ class PlaylistEventhandler(FileSystemEventHandler):
|
||||||
"""
|
"""
|
||||||
PKC eventhandler to monitor Kodi playlists safed to disk
|
PKC eventhandler to monitor Kodi playlists safed to disk
|
||||||
"""
|
"""
|
||||||
@staticmethod
|
def dispatch(self, event):
|
||||||
def _event_relevant(event):
|
|
||||||
"""
|
"""
|
||||||
Returns True if the event is relevant for PKC, False otherwise (e.g.
|
Dispatches events to the appropriate methods.
|
||||||
when a smart playlist *.xsp is considered)
|
|
||||||
|
:param event:
|
||||||
|
The event object representing the file system event.
|
||||||
|
:type event:
|
||||||
|
:class:`FileSystemEvent`
|
||||||
"""
|
"""
|
||||||
LOG.debug('event.is_directory: %s, event.src_path: %s',
|
|
||||||
event.is_directory, event.src_path)
|
|
||||||
if event.is_directory:
|
if event.is_directory:
|
||||||
# todo: take care of folder renames
|
# todo: take care of folder renames
|
||||||
return False
|
return
|
||||||
try:
|
try:
|
||||||
_, extension = event.src_path.rsplit('.', 1)
|
_, extension = event.src_path.rsplit('.', 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return
|
||||||
if extension.lower() not in SUPPORTED_FILETYPES:
|
if extension.lower() not in SUPPORTED_FILETYPES:
|
||||||
return False
|
return
|
||||||
if event.src_path.startswith(v.PLAYLIST_PATH_MIXED):
|
if event.src_path.startswith(v.PLAYLIST_PATH_MIXED):
|
||||||
return False
|
return
|
||||||
return True
|
_method_map = {
|
||||||
|
EVENT_TYPE_MODIFIED: self.on_modified,
|
||||||
|
EVENT_TYPE_MOVED: self.on_moved,
|
||||||
|
EVENT_TYPE_CREATED: self.on_created,
|
||||||
|
EVENT_TYPE_DELETED: self.on_deleted,
|
||||||
|
}
|
||||||
|
event_type = event.event_type
|
||||||
|
with LOCK:
|
||||||
|
_method_map[event_type](event)
|
||||||
|
|
||||||
def on_created(self, event):
|
def on_created(self, event):
|
||||||
if not self._event_relevant(event):
|
|
||||||
return
|
|
||||||
LOG.debug('on_created: %s', event.src_path)
|
LOG.debug('on_created: %s', event.src_path)
|
||||||
playlist = PL.Playlist_Object()
|
playlist = PL.Playlist_Object()
|
||||||
playlist.kodi_path = event.src_path
|
playlist.kodi_path = event.src_path
|
||||||
|
@ -433,8 +453,6 @@ class PlaylistEventhandler(FileSystemEventHandler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_deleted(self, event):
|
def on_deleted(self, event):
|
||||||
if not self._event_relevant(event):
|
|
||||||
return
|
|
||||||
LOG.debug('on_deleted: %s', event.src_path)
|
LOG.debug('on_deleted: %s', event.src_path)
|
||||||
playlist = playlist_object_from_db(path=event.src_path)
|
playlist = playlist_object_from_db(path=event.src_path)
|
||||||
if not playlist:
|
if not playlist:
|
||||||
|
@ -443,8 +461,6 @@ class PlaylistEventhandler(FileSystemEventHandler):
|
||||||
delete_plex_playlist(playlist)
|
delete_plex_playlist(playlist)
|
||||||
|
|
||||||
def on_modified(self, event):
|
def on_modified(self, event):
|
||||||
if not self._event_relevant(event):
|
|
||||||
return
|
|
||||||
LOG.debug('on_modified: %s', event.src_path)
|
LOG.debug('on_modified: %s', event.src_path)
|
||||||
old_playlist = playlist_object_from_db(path=event.src_path)
|
old_playlist = playlist_object_from_db(path=event.src_path)
|
||||||
new_playlist = PL.Playlist_Object()
|
new_playlist = PL.Playlist_Object()
|
||||||
|
@ -468,8 +484,6 @@ class PlaylistEventhandler(FileSystemEventHandler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_moved(self, event):
|
def on_moved(self, event):
|
||||||
if not self._event_relevant(event):
|
|
||||||
return
|
|
||||||
LOG.debug('on_moved: %s to %s', event.src_path, event.dest_path)
|
LOG.debug('on_moved: %s to %s', event.src_path, event.dest_path)
|
||||||
old_playlist = playlist_object_from_db(path=event.src_path)
|
old_playlist = playlist_object_from_db(path=event.src_path)
|
||||||
if not old_playlist:
|
if not old_playlist:
|
||||||
|
|
Loading…
Reference in a new issue