Fix thread methods
This commit is contained in:
parent
2615ecfd79
commit
06727fca71
14 changed files with 68 additions and 65 deletions
|
@ -2566,7 +2566,6 @@ class API():
|
||||||
if forceCheck is False:
|
if forceCheck is False:
|
||||||
# Validate the path is correct with user intervention
|
# Validate the path is correct with user intervention
|
||||||
if self.askToValidate(path):
|
if self.askToValidate(path):
|
||||||
import state
|
|
||||||
state.STOP_SYNC = True
|
state.STOP_SYNC = True
|
||||||
path = None
|
path = None
|
||||||
window('plex_pathverified', value='true')
|
window('plex_pathverified', value='true')
|
||||||
|
|
|
@ -7,14 +7,13 @@ from urllib import urlencode
|
||||||
|
|
||||||
from xbmc import sleep, executebuiltin
|
from xbmc import sleep, executebuiltin
|
||||||
|
|
||||||
from utils import settings, ThreadMethods
|
from utils import settings, thread_methods
|
||||||
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
||||||
httppersist, plexsettings
|
httppersist, plexsettings
|
||||||
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
import player
|
import player
|
||||||
import variables as v
|
import variables as v
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_suspends=[state.PMS_STATUS])
|
@thread_methods(add_suspends=['PMS_STATUS'])
|
||||||
class PlexCompanion(Thread):
|
class PlexCompanion(Thread):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,8 +13,7 @@ from xbmc import executeJSONRPC, sleep, translatePath
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
||||||
ThreadMethods, dialog, exists_dir
|
thread_methods, dialog, exists_dir
|
||||||
import state
|
|
||||||
|
|
||||||
# Disable annoying requests warnings
|
# Disable annoying requests warnings
|
||||||
import requests.packages.urllib3
|
import requests.packages.urllib3
|
||||||
|
@ -127,8 +126,8 @@ def double_urldecode(text):
|
||||||
return unquote(unquote(text))
|
return unquote(unquote(text))
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_stops=[state.STOP_SYNC],
|
@thread_methods(add_stops=['STOP_SYNC'],
|
||||||
add_suspends=[state.SUSPEND_LIBRARY_THREAD, state.DB_SCAN])
|
add_suspends=['SUSPEND_LIBRARY_THREAD', 'DB_SCAN'])
|
||||||
class Image_Cache_Thread(Thread):
|
class Image_Cache_Thread(Thread):
|
||||||
xbmc_host = 'localhost'
|
xbmc_host = 'localhost'
|
||||||
xbmc_port, xbmc_username, xbmc_password = setKodiWebServerDetails()
|
xbmc_port, xbmc_username, xbmc_password = setKodiWebServerDetails()
|
||||||
|
|
|
@ -6,7 +6,7 @@ from Queue import Queue
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import window, ThreadMethods
|
from utils import window, thread_methods
|
||||||
import state
|
import state
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -15,7 +15,7 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods
|
@thread_methods
|
||||||
class Monitor_Window(Thread):
|
class Monitor_Window(Thread):
|
||||||
"""
|
"""
|
||||||
Monitors window('plex_command') for new entries that we need to take care
|
Monitors window('plex_command') for new entries that we need to take care
|
||||||
|
|
|
@ -5,11 +5,10 @@ from Queue import Empty
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import ThreadMethods, window
|
from utils import thread_methods
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
import itemtypes
|
import itemtypes
|
||||||
import variables as v
|
import variables as v
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -18,8 +17,8 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_suspends=[state.SUSPEND_LIBRARY_THREAD, state.DB_SCAN],
|
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD', 'DB_SCAN'],
|
||||||
add_stops=[state.STOP_SYNC])
|
add_stops=['STOP_SYNC'])
|
||||||
class Process_Fanart_Thread(Thread):
|
class Process_Fanart_Thread(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded download of additional fanart in the background
|
Threaded download of additional fanart in the background
|
||||||
|
|
|
@ -5,10 +5,9 @@ from Queue import Empty
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import ThreadMethods, window
|
from utils import thread_methods, window
|
||||||
from PlexFunctions import GetPlexMetadata, GetAllPlexChildren
|
from PlexFunctions import GetPlexMetadata, GetAllPlexChildren
|
||||||
import sync_info
|
import sync_info
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_stops=[state.SUSPEND_LIBRARY_THREAD])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
||||||
class Threaded_Get_Metadata(Thread):
|
class Threaded_Get_Metadata(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded download of Plex XML metadata for a certain library item.
|
Threaded download of Plex XML metadata for a certain library item.
|
||||||
|
|
|
@ -5,10 +5,9 @@ from Queue import Empty
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import ThreadMethods
|
from utils import thread_methods
|
||||||
import itemtypes
|
import itemtypes
|
||||||
import sync_info
|
import sync_info
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
log = getLogger("PLEX."+__name__)
|
log = getLogger("PLEX."+__name__)
|
||||||
|
@ -16,7 +15,7 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_stops=[state.SUSPEND_LIBRARY_THREAD])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
||||||
class Threaded_Process_Metadata(Thread):
|
class Threaded_Process_Metadata(Thread):
|
||||||
"""
|
"""
|
||||||
Not yet implemented for more than 1 thread - if ever. Only to be called by
|
Not yet implemented for more than 1 thread - if ever. Only to be called by
|
||||||
|
|
|
@ -4,8 +4,7 @@ from threading import Thread, Lock
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import ThreadMethods, language as lang
|
from utils import thread_methods, language as lang
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -19,7 +18,7 @@ LOCK = Lock()
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_stops=[state.SUSPEND_LIBRARY_THREAD])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
||||||
class Threaded_Show_Sync_Info(Thread):
|
class Threaded_Show_Sync_Info(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded class to show the Kodi statusbar of the metadata download.
|
Threaded class to show the Kodi statusbar of the metadata download.
|
||||||
|
|
|
@ -10,7 +10,7 @@ import xbmcgui
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
||||||
ThreadMethods, create_actor_db_index, dialog, LogTime, getScreensaver,\
|
thread_methods, create_actor_db_index, dialog, LogTime, getScreensaver,\
|
||||||
setScreensaver, playlistXSP, language as lang, DateToKodi, reset,\
|
setScreensaver, playlistXSP, language as lang, DateToKodi, reset,\
|
||||||
advancedsettings_tweaks, tryDecode, deletePlaylists, deleteNodes
|
advancedsettings_tweaks, tryDecode, deletePlaylists, deleteNodes
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
@ -38,8 +38,8 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_stops=[state.STOP_SYNC],
|
@thread_methods(add_stops=['STOP_SYNC'],
|
||||||
add_suspends=[state.SUSPEND_LIBRARY_THREAD])
|
add_suspends=['SUSPEND_LIBRARY_THREAD'])
|
||||||
class LibrarySync(Thread):
|
class LibrarySync(Thread):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,13 +5,12 @@ from threading import RLock, Thread
|
||||||
|
|
||||||
from xbmc import sleep, Player, PlayList, PLAYLIST_MUSIC, PLAYLIST_VIDEO
|
from xbmc import sleep, Player, PlayList, PLAYLIST_MUSIC, PLAYLIST_VIDEO
|
||||||
|
|
||||||
from utils import window, ThreadMethods
|
from utils import window, thread_methods
|
||||||
import playlist_func as PL
|
import playlist_func as PL
|
||||||
from PlexFunctions import ConvertPlexToKodiTime, GetAllPlexChildren
|
from PlexFunctions import ConvertPlexToKodiTime, GetAllPlexChildren
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
from playbackutils import PlaybackUtils
|
from playbackutils import PlaybackUtils
|
||||||
import variables as v
|
import variables as v
|
||||||
import state
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
@ -22,7 +21,7 @@ PLUGIN = 'plugin://%s' % v.ADDON_ID
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_suspends=[state.PMS_STATUS])
|
@thread_methods(add_suspends=['PMS_STATUS'])
|
||||||
class Playqueue(Thread):
|
class Playqueue(Thread):
|
||||||
"""
|
"""
|
||||||
Monitors Kodi's playqueues for changes on the Kodi side
|
Monitors Kodi's playqueues for changes on the Kodi side
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
# Quit PKC
|
# Quit PKC
|
||||||
STOP_PKC = False
|
STOP_PKC = False
|
||||||
|
|
||||||
|
|
||||||
# Usually triggered by another Python instance - will have to be set (by
|
# Usually triggered by another Python instance - will have to be set (by
|
||||||
# polling window) through e.g. librarysync thread
|
# polling window) through e.g. librarysync thread
|
||||||
SUSPEND_LIBRARY_THREAD = False
|
SUSPEND_LIBRARY_THREAD = False
|
||||||
# Set if user decided to cancel sync
|
# Set if user decided to cancel sync
|
||||||
STOP_SYNC = False
|
STOP_SYNC = False
|
||||||
# Set if a Plex-Kodi DB sync is being done - along with window('plex_dbScan')
|
# Set if a Plex-Kodi DB sync is being done - along with
|
||||||
# set to 'true'
|
# window('plex_dbScan') set to 'true'
|
||||||
DB_SCAN = False
|
DB_SCAN = False
|
||||||
# Plex Media Server Status - along with window('plex_serverStatus')
|
# Plex Media Server Status - along with window('plex_serverStatus')
|
||||||
PMS_STATUS = False
|
PMS_STATUS = False
|
||||||
|
|
|
@ -10,7 +10,7 @@ import xbmcaddon
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
|
|
||||||
from utils import window, settings, language as lang, ThreadMethods
|
from utils import window, settings, language as lang, thread_methods
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
import PlexAPI
|
import PlexAPI
|
||||||
|
@ -24,7 +24,7 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_suspends=[state.SUSPEND_USER_CLIENT])
|
@thread_methods(add_suspends=['SUSPEND_USER_CLIENT'])
|
||||||
class UserClient(threading.Thread):
|
class UserClient(threading.Thread):
|
||||||
|
|
||||||
# Borg - multiple instances, shared state
|
# Borg - multiple instances, shared state
|
||||||
|
|
|
@ -86,7 +86,7 @@ def plex_command(key, value):
|
||||||
value: either 'True' or 'False'
|
value: either 'True' or 'False'
|
||||||
"""
|
"""
|
||||||
while window('plex_command'):
|
while window('plex_command'):
|
||||||
xbmc.sleep(1)
|
xbmc.sleep(5)
|
||||||
window('plex_command', value='%s-%s' % (key, value))
|
window('plex_command', value='%s-%s' % (key, value))
|
||||||
|
|
||||||
|
|
||||||
|
@ -920,7 +920,7 @@ def LogTime(func):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def ThreadMethods(cls=None, add_stops=None, add_suspends=None):
|
def thread_methods(cls=None, add_stops=None, add_suspends=None):
|
||||||
"""
|
"""
|
||||||
Decorator to add the following methods to a threading class:
|
Decorator to add the following methods to a threading class:
|
||||||
|
|
||||||
|
@ -928,52 +928,69 @@ def ThreadMethods(cls=None, add_stops=None, add_suspends=None):
|
||||||
resume_thread(): resumes the thread
|
resume_thread(): resumes the thread
|
||||||
stop_thread(): stopps/kills the thread
|
stop_thread(): stopps/kills the thread
|
||||||
|
|
||||||
thread_suspended(): returns True if thread is suspend_thread
|
thread_suspended(): returns True if thread is suspended
|
||||||
thread_stopped(): returns True if thread is stopped (or should stop ;-))
|
thread_stopped(): returns True if thread is stopped (or should stop ;-))
|
||||||
ALSO stops if PKC should exit
|
ALSO returns True if PKC should exit
|
||||||
|
|
||||||
Also adds the following class attributes:
|
Also adds the following class attributes:
|
||||||
_thread_stopped
|
__thread_stopped
|
||||||
_thread_suspended
|
__thread_suspended
|
||||||
|
__stops
|
||||||
|
__suspends
|
||||||
|
|
||||||
invoke with either
|
invoke with either
|
||||||
@NewThreadMethods
|
@Newthread_methods
|
||||||
class MyClass():
|
class MyClass():
|
||||||
or
|
or
|
||||||
@NewThreadMethods(add_stops=[state.SUSPEND_LIBRARY_TRHEAD],
|
@Newthread_methods(add_stops=['SUSPEND_LIBRARY_TRHEAD'],
|
||||||
add_suspends=[state.WHATEVER, state.WHATEVER2])
|
add_suspends=['DB_SCAN', 'WHATEVER'])
|
||||||
class MyClass():
|
class MyClass():
|
||||||
"""
|
"""
|
||||||
|
# So we don't need to invoke with ()
|
||||||
if cls is None:
|
if cls is None:
|
||||||
return partial(ThreadMethods,
|
return partial(thread_methods,
|
||||||
add_stops=add_stops,
|
add_stops=add_stops,
|
||||||
add_suspends=add_suspends)
|
add_suspends=add_suspends)
|
||||||
# Make sure we have an iterable
|
# Because we need a reference, not a copy of the immutable objects in
|
||||||
add_stops = add_stops or []
|
# state, we need to look up state every time explicitly
|
||||||
add_suspends = add_suspends or []
|
cls.__stops = ['STOP_PKC']
|
||||||
|
if add_stops is not None:
|
||||||
|
cls.__stops.extend(add_stops)
|
||||||
|
cls.__suspends = add_suspends or []
|
||||||
|
|
||||||
# Attach new attributes to class
|
# Attach new attributes to class
|
||||||
cls._thread_stopped = False
|
cls.__thread_stopped = False
|
||||||
cls._thread_suspended = False
|
cls.__thread_suspended = False
|
||||||
|
|
||||||
# Define new class methods and attach them to class
|
# Define new class methods and attach them to class
|
||||||
def stop_thread(self):
|
def stop_thread(self):
|
||||||
self._thread_stopped = True
|
self.__thread_stopped = True
|
||||||
cls.stop_thread = stop_thread
|
cls.stop_thread = stop_thread
|
||||||
|
|
||||||
def suspend_thread(self):
|
def suspend_thread(self):
|
||||||
self._thread_suspended = True
|
self.__thread_suspended = True
|
||||||
cls.suspend_thread = suspend_thread
|
cls.suspend_thread = suspend_thread
|
||||||
|
|
||||||
def resume_thread(self):
|
def resume_thread(self):
|
||||||
self._thread_suspended = False
|
self.__thread_suspended = False
|
||||||
cls.resume_thread = resume_thread
|
cls.resume_thread = resume_thread
|
||||||
|
|
||||||
def thread_suspended(self):
|
def thread_suspended(self):
|
||||||
return self._thread_suspended or any(add_suspends)
|
if self.__thread_suspended is True:
|
||||||
|
return True
|
||||||
|
for suspend in self.__suspends:
|
||||||
|
if getattr(state, suspend):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
cls.thread_suspended = thread_suspended
|
cls.thread_suspended = thread_suspended
|
||||||
|
|
||||||
def thread_stopped(self):
|
def thread_stopped(self):
|
||||||
return self._thread_stopped or state.STOP_PKC or any(add_stops)
|
if self.__thread_stopped is True:
|
||||||
|
return True
|
||||||
|
for stop in self.__stops:
|
||||||
|
if getattr(state, stop):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
cls.thread_stopped = thread_stopped
|
cls.thread_stopped = thread_stopped
|
||||||
|
|
||||||
# Return class to render this a decorator
|
# Return class to render this a decorator
|
||||||
|
|
|
@ -11,7 +11,7 @@ from ssl import CERT_NONE
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep
|
||||||
|
|
||||||
from utils import window, settings, ThreadMethods
|
from utils import window, settings, thread_methods
|
||||||
from companion import process_command
|
from companion import process_command
|
||||||
import state
|
import state
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ThreadMethods(add_suspends=[state.SUSPEND_LIBRARY_THREAD])
|
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD'])
|
||||||
class WebSocket(Thread):
|
class WebSocket(Thread):
|
||||||
opcode_data = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)
|
opcode_data = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)
|
||||||
|
|
||||||
|
@ -140,10 +140,10 @@ class WebSocket(Thread):
|
||||||
|
|
||||||
def stopThread(self):
|
def stopThread(self):
|
||||||
"""
|
"""
|
||||||
Overwrite this method from ThreadMethods to close websockets
|
Overwrite this method from thread_methods to close websockets
|
||||||
"""
|
"""
|
||||||
log.info("Stopping %s thread." % self.__class__.__name__)
|
log.info("Stopping %s thread." % self.__class__.__name__)
|
||||||
self._threadStopped = True
|
self.__threadStopped = True
|
||||||
try:
|
try:
|
||||||
self.ws.shutdown()
|
self.ws.shutdown()
|
||||||
except:
|
except:
|
||||||
|
@ -209,6 +209,7 @@ class PMS_Websocket(WebSocket):
|
||||||
window('plex_online', value='false')
|
window('plex_online', value='false')
|
||||||
|
|
||||||
|
|
||||||
|
@thread_methods(add_suspends=['RESTRICTED_USER', 'PLEX_TOKEN'])
|
||||||
class Alexa_Websocket(WebSocket):
|
class Alexa_Websocket(WebSocket):
|
||||||
"""
|
"""
|
||||||
Websocket connection to talk to Amazon Alexa
|
Websocket connection to talk to Amazon Alexa
|
||||||
|
@ -247,11 +248,3 @@ class Alexa_Websocket(WebSocket):
|
||||||
|
|
||||||
def IOError_response(self):
|
def IOError_response(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def thread_suspended(self):
|
|
||||||
"""
|
|
||||||
Overwrite to ignore library sync stuff and allow to check for
|
|
||||||
RESTRICTED_USER and PLEX_TOKEN
|
|
||||||
"""
|
|
||||||
return self._thread_suspended or state.RESTRICTED_USER \
|
|
||||||
or not state.PLEX_TOKEN
|
|
||||||
|
|
Loading…
Reference in a new issue