Fix thread methods

This commit is contained in:
tomkat83 2017-05-17 13:55:24 +02:00
parent 2615ecfd79
commit 06727fca71
14 changed files with 68 additions and 65 deletions

View file

@ -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')

View file

@ -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):
""" """
""" """

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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):
""" """
""" """

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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