diff --git a/CHANGES.md b/CHANGES.md index 9a3d9eeb..9969004a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,12 @@ -### 0.13.8 (2017-12-27 15:45:00 UTC) +### 0.14.0 (2018-xx-xx xx:xx:xx UTC) + +* Change improve core scheduler logic + + +[develop changelog] + + +### 0.13.8 (2017-12-27 15:45:00 UTC) * Fix HD4Free provider diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 07e44b79..98631041 100755 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -1414,10 +1414,8 @@ def enabled_schedulers(is_init=False): # ([], [traktCheckerScheduler])[USE_TRAKT] + \ for s in ([], [events])[is_init] + \ [recentSearchScheduler, backlogSearchScheduler, showUpdateScheduler, - versionCheckScheduler, showQueueScheduler, searchQueueScheduler] + \ - ([], [properFinderScheduler])[DOWNLOAD_PROPERS] + \ - ([], [autoPostProcesserScheduler])[PROCESS_AUTOMATICALLY] + \ - ([], [subtitlesFinderScheduler])[USE_SUBTITLES] + \ + versionCheckScheduler, showQueueScheduler, searchQueueScheduler, properFinderScheduler, + autoPostProcesserScheduler, subtitlesFinderScheduler] + \ ([events], [])[is_init]: yield s @@ -1501,7 +1499,7 @@ def halt(): logger.log('Fail, thread %s did not exit' % ADBA_CONNECTION.name) for thread in enabled_schedulers(): - thread.stop.set() + thread.stop() for thread in enabled_schedulers(): try: diff --git a/sickbeard/auto_post_processer.py b/sickbeard/auto_post_processer.py index e8bc66b9..90bec256 100644 --- a/sickbeard/auto_post_processer.py +++ b/sickbeard/auto_post_processer.py @@ -27,6 +27,12 @@ class PostProcesser(): def __init__(self): self.amActive = False + @staticmethod + def check_paused(): + if sickbeard.PROCESS_AUTOMATICALLY: + return False + return True + def run(self): if not sickbeard.PROCESS_AUTOMATICALLY: return diff --git a/sickbeard/config.py b/sickbeard/config.py index d2b68811..4e7573f8 100644 --- a/sickbeard/config.py +++ b/sickbeard/config.py @@ -197,15 +197,7 @@ def change_DOWNLOAD_PROPERS(download_propers): return sickbeard.DOWNLOAD_PROPERS = download_propers - if sickbeard.DOWNLOAD_PROPERS: - sickbeard.properFinderScheduler.start() - else: - sickbeard.properFinderScheduler.stop.set() - logger.log(u'Waiting for the PROPERFINDER thread to exit') - try: - sickbeard.properFinderScheduler.join(10) - except: - pass + sickbeard.properFinderScheduler.check_paused() def change_USE_TRAKT(use_trakt): @@ -216,7 +208,7 @@ def change_USE_TRAKT(use_trakt): # if sickbeard.USE_TRAKT: # sickbeard.traktCheckerScheduler.start() # else: - # sickbeard.traktCheckerScheduler.stop.set() + # sickbeard.traktCheckerScheduler.stop() # logger.log(u'Waiting for the TRAKTCHECKER thread to exit') # try: # sickbeard.traktCheckerScheduler.join(10) @@ -229,21 +221,7 @@ def change_USE_SUBTITLES(use_subtitles): return sickbeard.USE_SUBTITLES = use_subtitles - if sickbeard.USE_SUBTITLES and not sickbeard.subtitlesFinderScheduler.isAlive(): - sickbeard.subtitlesFinderScheduler = sickbeard.scheduler.Scheduler( - sickbeard.subtitles.SubtitlesFinder(), - cycleTime=datetime.timedelta(hours=sickbeard.SUBTITLES_FINDER_FREQUENCY), - threadName='FINDSUBTITLES', silent=False) - sickbeard.subtitlesFinderScheduler.start() - else: - sickbeard.subtitlesFinderScheduler.stop.set() - sickbeard.subtitlesFinderScheduler.silent = True - threadname = sickbeard.subtitlesFinderScheduler.name - try: - sickbeard.subtitlesFinderScheduler.join(10) - logger.log('Thread %s has exit' % threadname) - except RuntimeError: - logger.log('Fail, thread %s did not exit' % threadname) + sickbeard.subtitlesFinderScheduler.check_paused() def CheckSection(CFG, sec): diff --git a/sickbeard/scheduler.py b/sickbeard/scheduler.py index 562188fa..7724a6b8 100644 --- a/sickbeard/scheduler.py +++ b/sickbeard/scheduler.py @@ -27,7 +27,7 @@ from sickbeard.exceptions import ex class Scheduler(threading.Thread): def __init__(self, action, cycleTime=datetime.timedelta(minutes=10), run_delay=datetime.timedelta(minutes=0), - start_time=None, threadName="ScheduledThread", silent=True, prevent_cycle_run=None): + start_time=None, threadName="ScheduledThread", silent=True, prevent_cycle_run=None, paused=False): super(Scheduler, self).__init__() self.lastRun = datetime.datetime.now() + run_delay - cycleTime @@ -38,10 +38,32 @@ class Scheduler(threading.Thread): self.name = threadName self.silent = silent - self.stop = threading.Event() + self._stop = threading.Event() + self._unpause = threading.Event() + if not paused: + self._unpause.set() self.lock = threading.Lock() self.force = False + def pause(self): + self._unpause.clear() + + def unpause(self): + self._unpause.set() + + def stop(self): + self._stop.set() + self.unpause() + + def check_paused(self): + if hasattr(self.action, 'check_paused'): + if self.action.check_paused(): + self.pause() + self.silent = True + else: + self.unpause() + self.silent = False + def timeLeft(self): return self.cycleTime - (datetime.datetime.now() - self.lastRun) @@ -52,8 +74,10 @@ class Scheduler(threading.Thread): return False def run(self): + self.check_paused() - while not self.stop.is_set(): + # if self._unpause Event() is NOT set the loop pauses + while self._unpause.wait() and not self._stop.is_set(): try: current_time = datetime.datetime.now() @@ -100,4 +124,5 @@ class Scheduler(threading.Thread): time.sleep(1) # exiting thread - self.stop.clear() \ No newline at end of file + self._stop.clear() + self._unpause.clear() \ No newline at end of file diff --git a/sickbeard/search_propers.py b/sickbeard/search_propers.py index e2cb2817..923be08c 100644 --- a/sickbeard/search_propers.py +++ b/sickbeard/search_propers.py @@ -29,6 +29,12 @@ class ProperSearcher: self.search_intervals = [('daily', '24 hours', 24 * 60), ('4h', '4 hours', 4 * 60), ('90m', '90 mins', 90), ('45m', '45 mins', 45), ('15m', '15 mins', 15)] + @staticmethod + def check_paused(): + if sickbeard.DOWNLOAD_PROPERS: + return False + return True + def run(self): self.amActive = True diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py index 7e0c5313..1989c0c9 100644 --- a/sickbeard/subtitles.py +++ b/sickbeard/subtitles.py @@ -86,6 +86,12 @@ class SubtitlesFinder(): The SubtitlesFinder will be executed every hour but will not necessarly search and download subtitles. Only if the defined rule is true """ + @staticmethod + def check_paused(): + if sickbeard.USE_SUBTITLES: + return False + return True + def run(self, force=False): if len(sickbeard.subtitles.getEnabledServiceList()) < 1: logger.log(u'Not enough services selected. At least 1 service is required to search subtitles in the background', logger.ERROR) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index cb7babbb..45c93c41 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -5028,7 +5028,7 @@ class ConfigSearch(Config): sickbeard.IGNORE_WORDS = ignore_words if ignore_words else '' sickbeard.REQUIRE_WORDS = require_words if require_words else '' - sickbeard.DOWNLOAD_PROPERS = config.checkbox_to_value(download_propers) + config.change_DOWNLOAD_PROPERS(config.checkbox_to_value(download_propers)) sickbeard.PROPERS_WEBDL_ONEGRP = config.checkbox_to_value(propers_webdl_onegrp) if sickbeard.CHECK_PROPERS_INTERVAL != check_propers_interval: sickbeard.CHECK_PROPERS_INTERVAL = check_propers_interval @@ -5121,21 +5121,11 @@ class ConfigPostProcessing(Config): results += ['Unable to create directory ' + os.path.normpath(tv_download_dir) + ', dir not changed.'] new_val = config.checkbox_to_value(process_automatically) - if new_val != sickbeard.PROCESS_AUTOMATICALLY: - if not sickbeard.PROCESS_AUTOMATICALLY and not sickbeard.autoPostProcesserScheduler.ident: - try: - sickbeard.autoPostProcesserScheduler.start() - except: - pass - sickbeard.PROCESS_AUTOMATICALLY = new_val + sickbeard.PROCESS_AUTOMATICALLY = new_val + sickbeard.autoPostProcesserScheduler.check_paused() config.change_AUTOPOSTPROCESSER_FREQUENCY(autopostprocesser_frequency) - if sickbeard.PROCESS_AUTOMATICALLY: - sickbeard.autoPostProcesserScheduler.silent = False - else: - sickbeard.autoPostProcesserScheduler.silent = True - if unpack: if self.isRarSupported() != 'not supported': sickbeard.UNPACK = config.checkbox_to_value(unpack)