From bf991649788ad6c35f1b8f0c085cd1d522479787 Mon Sep 17 00:00:00 2001 From: JackDandy Date: Thu, 19 Jun 2014 08:12:30 +0100 Subject: [PATCH] Refactor scheduler and upstream ports. Move start time check from properFinder and showUpdater into scheduler. Add show how long to next propers search at end of each run. Change proper finder and show updater to silent thread logging. Change Scheduler runImmediately to run_delay. --- sickbeard/__init__.py | 86 +++++++++++++++++++++------------------ sickbeard/properFinder.py | 32 ++++----------- sickbeard/scheduler.py | 31 ++++++++++---- sickbeard/showUpdater.py | 17 ++------ sickbeard/webserve.py | 4 -- 5 files changed, 79 insertions(+), 91 deletions(-) diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 98c684d5..067095e9 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -942,70 +942,76 @@ def initialize(consoleLogging=True): newznabProviderList = providers.getNewznabProviderList(NEWZNAB_DATA) providerList = providers.makeProviderList() - maintenanceScheduler = scheduler.Scheduler(maintenance.Maintenance(), - cycleTime=datetime.timedelta(hours=1), - threadName="MAINTENANCE", - silent=True, - runImmediately=True) - - dailySearchScheduler = scheduler.Scheduler(dailysearcher.DailySearcher(), - cycleTime=datetime.timedelta(minutes=DAILYSEARCH_FREQUENCY), - threadName="DAILYSEARCHER", - silent=True, - runImmediately=DAILYSEARCH_STARTUP) - - showUpdateScheduler = scheduler.Scheduler(showUpdater.ShowUpdater(), - cycleTime=showUpdater.ShowUpdater().updateInterval, - threadName="SHOWUPDATER", - runImmediately=False) - + # initialize schedulers + # updaters + update_now = datetime.timedelta(minutes=0) versionCheckScheduler = scheduler.Scheduler(versionChecker.CheckVersion(), cycleTime=datetime.timedelta(hours=UPDATE_FREQUENCY), threadName="CHECKVERSION", - runImmediately=True) + silent=False) + + maintenanceScheduler = scheduler.Scheduler(maintenance.Maintenance(), + cycleTime=datetime.timedelta(hours=1), + threadName="MAINTENANCE") showQueueScheduler = scheduler.Scheduler(show_queue.ShowQueue(), cycleTime=datetime.timedelta(seconds=3), - threadName="SHOWQUEUE", - silent=True, - runImmediately=True) + threadName="SHOWQUEUE") + showUpdateScheduler = scheduler.Scheduler(showUpdater.ShowUpdater(), + cycleTime=datetime.timedelta(hours=1), + threadName="SHOWUPDATER", + start_time=datetime.time(hour=3)) # 3 AM + + # searchers searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(), cycleTime=datetime.timedelta(seconds=3), - threadName="SEARCHQUEUE", - silent=True) + threadName="SEARCHQUEUE") + + update_interval = datetime.timedelta(minutes=DAILYSEARCH_FREQUENCY) + dailySearchScheduler = scheduler.Scheduler(dailysearcher.DailySearcher(), + cycleTime=update_interval, + threadName="DAILYSEARCHER", + run_delay=update_now if DAILYSEARCH_STARTUP + else update_interval) + + update_interval = datetime.timedelta(minutes=BACKLOG_FREQUENCY) + backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(), + cycleTime=update_interval, + threadName="BACKLOG", + run_delay=update_now if BACKLOG_STARTUP + else update_interval) + + search_intervals = {'15m': 15, '45m': 45, '90m': 90, '4h': 4*60, 'daily': 24*60} + if CHECK_PROPERS_INTERVAL in search_intervals: + update_interval = datetime.timedelta(minutes=search_intervals[CHECK_PROPERS_INTERVAL]) + run_at = None + else: + update_interval = datetime.timedelta(hours=1) + run_at = datetime.time(hour=1) # 1 AM properFinderScheduler = scheduler.Scheduler(properFinder.ProperFinder(), - cycleTime=properFinder.ProperFinder().updateInterval, + cycleTime=update_interval, threadName="FINDPROPERS", - silent=False if DOWNLOAD_PROPERS else True, - runImmediately=True) + start_time=run_at, + run_delay=update_interval) + # processors autoPostProcesserScheduler = scheduler.Scheduler(autoPostProcesser.PostProcesser(), cycleTime=datetime.timedelta( minutes=AUTOPOSTPROCESSER_FREQUENCY), threadName="POSTPROCESSER", - silent=False if PROCESS_AUTOMATICALLY else True, - runImmediately=True) + silent=not PROCESS_AUTOMATICALLY) traktWatchListCheckerScheduler = scheduler.Scheduler(traktWatchListChecker.TraktChecker(), cycleTime=datetime.timedelta(hours=1), threadName="TRAKTWATCHLIST", - silent=False if USE_TRAKT else True, - runImmediately=True) + silent=not USE_TRAKT) subtitlesFinderScheduler = scheduler.Scheduler(subtitles.SubtitlesFinder(), cycleTime=datetime.timedelta(hours=SUBTITLES_FINDER_FREQUENCY), threadName="FINDSUBTITLES", - silent=False if USE_SUBTITLES else True, - runImmediately=True) - - backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(), - cycleTime=datetime.timedelta( - minutes=BACKLOG_FREQUENCY), - threadName="BACKLOG", - silent=True, - runImmediately=BACKLOG_STARTUP) + silent=not USE_SUBTITLES) # dynamically load provider settings for curTorrentProvider in [curProvider for curProvider in providers.sortedProviderList() if @@ -1829,4 +1835,4 @@ def autoreload_shutdown(): halt() # save settings - saveAll() \ No newline at end of file + saveAll() diff --git a/sickbeard/properFinder.py b/sickbeard/properFinder.py index 4486aafa..7ab62e33 100644 --- a/sickbeard/properFinder.py +++ b/sickbeard/properFinder.py @@ -39,31 +39,12 @@ from name_parser.parser import NameParser, InvalidNameException class ProperFinder(): def __init__(self): self.amActive = False - self.updateInterval = datetime.timedelta(hours=1) - - check_propers_interval = {'15m': 15, '45m': 45, '90m': 90, '4h': 4*60, 'daily': 24*60} - for curInterval in ('15m', '45m', '90m', '4h', 'daily'): - if sickbeard.CHECK_PROPERS_INTERVAL == curInterval: - self.updateInterval = datetime.timedelta(minutes = check_propers_interval[curInterval]) def run(self, force=False): if not sickbeard.DOWNLOAD_PROPERS: return - # look for propers every night at 1 AM - updateTime = datetime.time(hour=1) - - logger.log(u"Checking proper time", logger.DEBUG) - - hourDiff = datetime.datetime.today().time().hour - updateTime.hour - dayDiff = (datetime.date.today() - self._get_lastProperSearch()).days - - if sickbeard.CHECK_PROPERS_INTERVAL == "daily" and not force: - # if it's less than an interval after the update time then do an update - if not (hourDiff >= 0 and hourDiff < self.updateInterval.seconds / 3600 or dayDiff >= 1): - return - logger.log(u"Beginning the search for new propers") self.amActive = True @@ -75,11 +56,14 @@ class ProperFinder(): self._set_lastProperSearch(datetime.datetime.today().toordinal()) - msg = u"Completed the search for new propers, next check " - if sickbeard.CHECK_PROPERS_INTERVAL == "daily": - logger.log(u"%sat 1am tomorrow" % msg) - else: - logger.log(u"%sin ~%s" % (msg, sickbeard.CHECK_PROPERS_INTERVAL)) + run_at = "" + if None is sickbeard.properFinderScheduler.start_time: + run_in = sickbeard.properFinderScheduler.lastRun + sickbeard.properFinderScheduler.cycleTime - datetime.datetime.now() + hours, remainder = divmod(run_in.seconds, 3600) + minutes, seconds = divmod(remainder, 60) + run_at = u", next check in approx. " + ("%dh, %dm" % (hours, minutes) if 0 < hours else "%dm, %ds" % (minutes, seconds)) + + logger.log(u"Completed the search for new propers%s" % run_at) self.amActive = False diff --git a/sickbeard/scheduler.py b/sickbeard/scheduler.py index 7a4330aa..70ae21ae 100644 --- a/sickbeard/scheduler.py +++ b/sickbeard/scheduler.py @@ -26,16 +26,14 @@ from sickbeard.exceptions import ex class Scheduler: - def __init__(self, action, cycleTime=datetime.timedelta(minutes=10), runImmediately=True, - threadName="ScheduledThread", silent=False): + def __init__(self, action, cycleTime=datetime.timedelta(minutes=10), run_delay=datetime.timedelta(minutes=0), + start_time=None, threadName="ScheduledThread", silent=True): - if runImmediately: - self.lastRun = datetime.datetime.fromordinal(1) - else: - self.lastRun = datetime.datetime.now() + self.lastRun = datetime.datetime.now() + run_delay - cycleTime self.action = action self.cycleTime = cycleTime + self.start_time = start_time self.thread = None self.threadName = threadName @@ -64,10 +62,25 @@ class Scheduler: while True: - currentTime = datetime.datetime.now() + current_time = datetime.datetime.now() + should_run = False + + # check if interval has passed + if current_time - self.lastRun >= self.cycleTime: + # check if wanting to start around certain time taking interval into account + if self.start_time: + hour_diff = current_time.time().hour - self.start_time.hour + if not hour_diff < 0 and hour_diff < self.cycleTime.seconds / 3600: + should_run = True + else: + # set lastRun to only check start_time after another cycleTime + self.lastRun = current_time + else: + should_run = True + + if should_run: + self.lastRun = current_time - if currentTime - self.lastRun > self.cycleTime: - self.lastRun = currentTime try: if not self.silent: logger.log(u"Starting new thread: " + self.threadName, logger.DEBUG) diff --git a/sickbeard/showUpdater.py b/sickbeard/showUpdater.py index 0bba386e..70b00865 100644 --- a/sickbeard/showUpdater.py +++ b/sickbeard/showUpdater.py @@ -31,26 +31,13 @@ from sickbeard import network_timezones from sickbeard import failed_history class ShowUpdater(): - def __init__(self): - self.updateInterval = datetime.timedelta(hours=1) def run(self, force=False): - # update at 3 AM - run_updater_time = datetime.time(hour=3) - update_datetime = datetime.datetime.now() update_date = update_datetime.date() - logger.log(u"Checking update interval", logger.DEBUG) - - hour_diff = update_datetime.time().hour - run_updater_time.hour - - # if it's less than an interval after the update time then do an update (or if we're forcing it) - if hour_diff >= 0 and hour_diff < self.updateInterval.seconds / 3600 or force: - logger.log(u"Doing full update on all shows") - else: - return + logger.log(u"Doing full update on all shows") # clean out cache directory, remove everything > 12 hours old if sickbeard.CACHE_DIR: @@ -114,3 +101,5 @@ class ShowUpdater(): logger.log(u"Automatic update failed: " + ex(e), logger.ERROR) ui.ProgressIndicators.setIndicator('dailyUpdate', ui.QueueProgressIndicator("Daily Update", piList)) + + logger.log(u"Completed full update on all shows") diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 07bd99e5..011306ee 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -1566,10 +1566,6 @@ class ConfigSearch(MainHandler): sickbeard.IGNORE_WORDS = ignore_words if ignore_words else "" sickbeard.DOWNLOAD_PROPERS = config.checkbox_to_value(download_propers) - if sickbeard.DOWNLOAD_PROPERS: - sickbeard.properFinderScheduler.silent = False - else: - sickbeard.properFinderScheduler.silent = True sickbeard.CHECK_PROPERS_INTERVAL = check_propers_interval sickbeard.ALLOW_HIGH_PRIORITY = config.checkbox_to_value(allow_high_priority)