import random from datetime import timedelta from module.config.utils import get_server_next_update from module.logger import logger from module.smart_mgmt.downtime_fetcher import DowntimeFetcher, FetchError class DowntimeFetch: def __init__(self, config): self.config = config def _set_downtime(self, window, title): self.config.modified['DowntimeMgmt.Downtime.Window'] = window self.config.modified['DowntimeMgmt.Downtime.Title'] = title self.config.update() def _update_downtime(self) -> bool: """Fetch downtime via fetcher and write cross-task config.""" try: payload = DowntimeFetcher().run() except FetchError as e: # Expected operational failure (API error, collection missing, no cache); # degrade gracefully and let the caller reschedule logger.warning(f'Fetch downtime failed: {e}') return False except Exception: # Unexpected programming error; full traceback for diagnosis logger.exception('Unexpected error during downtime fetch') return False self._set_downtime(payload.get('window', ''), payload.get('title', '')) return True def run(self): success = False if self.config.SERVER != 'cn': # Downtime fetch targets CN Bilibili notices only; skip on other servers logger.warning('Downtime fetch is only available for CN server, skip') else: success = self._update_downtime() if success: # Stagger execution across instances within 5 minutes after server update next_update = get_server_next_update(self.config.Scheduler_ServerUpdate) target = next_update + timedelta(seconds=random.randint(0, 300)) self.config.task_delay(target=target) else: self.config.task_delay(success=False)