Esempio n. 1
0
 def run(self):
     """ Run all the URI's and filters """
     if not sabnzbd.PAUSED_ALL:
         active = False
         if self.next_run < time.time():
             self.next_run = time.time() + cfg.rss_rate() * 60
         feeds = config.get_rss()
         try:
             for feed in feeds:
                 if feeds[feed].enable():
                     logging.info(
                         'Starting scheduled RSS read-out for "%s"', feed)
                     active = True
                     self.run_feed(feed, download=True, ignoreFirst=True)
                     # Wait 15 seconds, else sites may get irritated
                     for unused in range(15):
                         if self.shutdown:
                             return
                         else:
                             time.sleep(1.0)
         except (KeyError, RuntimeError):
             # Feed must have been deleted
             logging.info(
                 "RSS read-out crashed, feed must have been deleted or edited"
             )
             logging.debug("Traceback: ", exc_info=True)
             pass
         if active:
             self.save()
             logging.info("Finished scheduled RSS read-outs")
Esempio n. 2
0
def init():
    """ Create the scheduler and set all required events """
    global __SCHED

    reset_guardian()
    __SCHED = kronos.ThreadedScheduler()
    rss_planned = False

    for schedule in cfg.schedules():
        arguments = []
        argument_list = None
        try:
            m, h, d, action_name = schedule.split()
        except:
            m, h, d, action_name, argument_list = schedule.split(None, 4)
        if argument_list:
            arguments = argument_list.split()

        action_name = action_name.lower()
        try:
            m = int(m)
            h = int(h)
        except:
            logging.warning(T('Bad schedule %s at %s:%s'), action_name, m, h)
            continue

        if d.isdigit():
            d = [int(i) for i in d]
        else:
            d = range(1, 8)

        if action_name == 'resume':
            action = scheduled_resume
            arguments = []
        elif action_name == 'pause':
            action = sabnzbd.downloader.Downloader.do.pause
            arguments = []
        elif action_name == 'pause_all':
            action = sabnzbd.pause_all
            arguments = []
        elif action_name == 'shutdown':
            action = sabnzbd.shutdown_program
            arguments = []
        elif action_name == 'restart':
            action = sabnzbd.restart_program
            arguments = []
        elif action_name == 'pause_post':
            action = pp_pause
        elif action_name == 'resume_post':
            action = pp_resume
        elif action_name == 'speedlimit' and arguments != []:
            action = sabnzbd.downloader.Downloader.do.limit_speed
        elif action_name == 'enable_server' and arguments != []:
            action = sabnzbd.enable_server
        elif action_name == 'disable_server' and arguments != []:
            action = sabnzbd.disable_server
        elif action_name == 'scan_folder':
            action = sabnzbd.dirscanner.dirscan
        elif action_name == 'rss_scan':
            action = rss.run_method
            rss_planned = True
        elif action_name == 'remove_failed':
            action = sabnzbd.api.history_remove_failed
        elif action_name == 'remove_completed':
            action = sabnzbd.api.history_remove_completed
        elif action_name == 'enable_quota':
            action = sabnzbd.bpsmeter.BPSMeter.do.set_status
            arguments = [True]
        elif action_name == 'disable_quota':
            action = sabnzbd.bpsmeter.BPSMeter.do.set_status
            arguments = [False]
        elif action_name == 'pause_all_low':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [LOW_PRIORITY]
        elif action_name == 'pause_all_normal':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [NORMAL_PRIORITY]
        elif action_name == 'pause_all_high':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [HIGH_PRIORITY]
        elif action_name == 'resume_all_low':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [LOW_PRIORITY]
        elif action_name == 'resume_all_normal':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [NORMAL_PRIORITY]
        elif action_name == 'resume_all_high':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [HIGH_PRIORITY]
        else:
            logging.warning(T('Unknown action: %s'), action_name)
            continue

        logging.debug("scheduling %s(%s) on days %s at %02d:%02d", action_name,
                      arguments, d, h, m)

        __SCHED.add_daytime_task(action, action_name, d, None, (h, m),
                                 kronos.method.sequential, arguments, None)

    # Set Guardian interval to 30 seconds
    __SCHED.add_interval_task(sched_guardian, "Guardian", 15, 30,
                              kronos.method.sequential, None, None)

    # Set RSS check interval
    if not rss_planned:
        interval = cfg.rss_rate()
        delay = random.randint(0, interval - 1)
        logging.debug("Scheduling RSS interval task every %s min (delay=%s)",
                      interval, delay)
        sabnzbd.rss.next_run(time.time() + delay * 60)
        __SCHED.add_interval_task(rss.run_method, "RSS", delay * 60,
                                  interval * 60, kronos.method.sequential,
                                  None, None)
        __SCHED.add_single_task(rss.run_method, 'RSS', 15,
                                kronos.method.sequential, None, None)

    if cfg.version_check():
        # Check for new release, once per week on random time
        m = random.randint(0, 59)
        h = random.randint(0, 23)
        d = (random.randint(1, 7), )

        logging.debug("Scheduling VersionCheck on day %s at %s:%s", d[0], h, m)
        __SCHED.add_daytime_task(sabnzbd.misc.check_latest_version, 'VerCheck',
                                 d, None, (h, m), kronos.method.sequential, [],
                                 None)

    action, hour, minute = sabnzbd.bpsmeter.BPSMeter.do.get_quota()
    if action:
        logging.info('Setting schedule for quota check daily at %s:%s', hour,
                     minute)
        __SCHED.add_daytime_task(action, 'quota_reset', range(1, 8), None,
                                 (hour, minute), kronos.method.sequential, [],
                                 None)

    logging.info('Setting schedule for midnight BPS reset')
    __SCHED.add_daytime_task(sabnzbd.bpsmeter.midnight_action, 'midnight_bps',
                             range(1, 8), None, (0, 0),
                             kronos.method.sequential, [], None)

    # Subscribe to special schedule changes
    cfg.rss_rate.callback(schedule_guard)
Esempio n. 3
0
def init():
    """ Create the scheduler and set all required events """
    global __SCHED

    reset_guardian()
    __SCHED = kronos.ThreadedScheduler()
    rss_planned = False

    for schedule in cfg.schedules():
        arguments = []
        argument_list = None
        try:
            m, h, d, action_name = schedule.split()
        except:
            m, h, d, action_name, argument_list = schedule.split(None, 4)
        if argument_list:
            arguments = argument_list.split()

        action_name = action_name.lower()
        try:
            m = int(m)
            h = int(h)
        except:
            logging.warning(T('Bad schedule %s at %s:%s'), action_name, m, h)
            continue

        if d.isdigit():
            d = [int(i) for i in d]
        else:
            d = range(1, 8)

        if action_name == 'resume':
            action = scheduled_resume
            arguments = []
        elif action_name == 'pause':
            action = sabnzbd.downloader.Downloader.do.pause
            arguments = []
        elif action_name == 'pause_all':
            action = sabnzbd.pause_all
            arguments = []
        elif action_name == 'shutdown':
            action = sabnzbd.shutdown_program
            arguments = []
        elif action_name == 'restart':
            action = sabnzbd.restart_program
            arguments = []
        elif action_name == 'pause_post':
            action = pp_pause
        elif action_name == 'resume_post':
            action = pp_resume
        elif action_name == 'speedlimit' and arguments != []:
            action = sabnzbd.downloader.Downloader.do.limit_speed
        elif action_name == 'enable_server' and arguments != []:
            action = sabnzbd.enable_server
        elif action_name == 'disable_server' and arguments != []:
            action = sabnzbd.disable_server
        elif action_name == 'scan_folder':
            action = sabnzbd.dirscanner.dirscan
        elif action_name == 'rss_scan':
            action = rss.run_method
            rss_planned = True
        elif action_name == 'remove_failed':
            action = sabnzbd.api.history_remove_failed
        elif action_name == 'remove_completed':
            action = sabnzbd.api.history_remove_completed
        elif action_name == 'enable_quota':
            action = sabnzbd.bpsmeter.BPSMeter.do.set_status
            arguments = [True]
        elif action_name == 'disable_quota':
            action = sabnzbd.bpsmeter.BPSMeter.do.set_status
            arguments = [False]
        elif action_name == 'pause_all_low':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [LOW_PRIORITY]
        elif action_name == 'pause_all_normal':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [NORMAL_PRIORITY]
        elif action_name == 'pause_all_high':
            action = sabnzbd.nzbqueue.NzbQueue.do.pause_on_prio
            arguments = [HIGH_PRIORITY]
        elif action_name == 'resume_all_low':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [LOW_PRIORITY]
        elif action_name == 'resume_all_normal':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [NORMAL_PRIORITY]
        elif action_name == 'resume_all_high':
            action = sabnzbd.nzbqueue.NzbQueue.do.resume_on_prio
            arguments = [HIGH_PRIORITY]
        else:
            logging.warning(T('Unknown action: %s'), action_name)
            continue

        logging.debug("scheduling %s(%s) on days %s at %02d:%02d", action_name, arguments, d, h, m)

        __SCHED.add_daytime_task(action, action_name, d, None, (h, m),
                             kronos.method.sequential, arguments, None)

    # Set Guardian interval to 30 seconds
    __SCHED.add_interval_task(sched_guardian, "Guardian", 15, 30,
                                  kronos.method.sequential, None, None)

    # Set RSS check interval
    if not rss_planned:
        interval = cfg.rss_rate()
        delay = random.randint(0, interval - 1)
        logging.debug("Scheduling RSS interval task every %s min (delay=%s)", interval, delay)
        sabnzbd.rss.next_run(time.time() + delay * 60)
        __SCHED.add_interval_task(rss.run_method, "RSS", delay * 60, interval * 60,
                                      kronos.method.sequential, None, None)
        __SCHED.add_single_task(rss.run_method, 'RSS', 15, kronos.method.sequential, None, None)

    if cfg.version_check():
        # Check for new release, once per week on random time
        m = random.randint(0, 59)
        h = random.randint(0, 23)
        d = (random.randint(1, 7), )

        logging.debug("Scheduling VersionCheck on day %s at %s:%s", d[0], h, m)
        __SCHED.add_daytime_task(sabnzbd.misc.check_latest_version, 'VerCheck', d, None, (h, m),
                                 kronos.method.sequential, [], None)

    action, hour, minute = sabnzbd.bpsmeter.BPSMeter.do.get_quota()
    if action:
        logging.info('Setting schedule for quota check daily at %s:%s', hour, minute)
        __SCHED.add_daytime_task(action, 'quota_reset', range(1, 8), None, (hour, minute),
                                 kronos.method.sequential, [], None)

    logging.info('Setting schedule for midnight BPS reset')
    __SCHED.add_daytime_task(sabnzbd.bpsmeter.midnight_action, 'midnight_bps', range(1, 8), None, (0, 0),
                             kronos.method.sequential, [], None)

    # Subscribe to special schedule changes
    cfg.rss_rate.callback(schedule_guard)
Esempio n. 4
0
def init():
    """ Create the scheduler and set all required events
    """
    global __SCHED

    reset_guardian()
    __SCHED = kronos.ThreadedScheduler()
    rss_planned = False

    for schedule in cfg.schedules():
        arguments = []
        argument_list = None
        try:
            m, h, d, action_name = schedule.split()
        except:
            m, h, d, action_name, argument_list = schedule.split(None, 4)
        if argument_list:
            arguments = argument_list.split()

        action_name = action_name.lower()
        try:
            m = int(m)
            h = int(h)
        except:
            logging.warning(Ta('Bad schedule %s at %s:%s'), action_name, m, h)
            continue

        if d.isdigit():
            d = [int(d)]
        else:
            d = range(1, 8)

        if action_name == 'resume':
            action = scheduled_resume
            arguments = []
        elif action_name == 'pause':
            action = sabnzbd.downloader.Downloader.do.pause
            arguments = []
        elif action_name == 'pause_all':
            action = sabnzbd.pause_all
            arguments = []
        elif action_name == 'shutdown':
            action = sabnzbd.shutdown_program
            arguments = []
        elif action_name == 'restart':
            action = sabnzbd.restart_program
            arguments = []
        elif action_name == 'pause_post':
            action = pp_pause
        elif action_name == 'resume_post':
            action = pp_resume
        elif action_name == 'speedlimit' and arguments != []:
            action = sabnzbd.downloader.Downloader.do.limit_speed
        elif action_name == 'enable_server' and arguments != []:
            action = sabnzbd.enable_server
        elif action_name == 'disable_server' and arguments != []:
            action = sabnzbd.disable_server
        elif action_name == 'scan_folder':
            action = sabnzbd.dirscanner.dirscan
        elif action_name == 'rss_scan':
            action = rss.run_method
            rss_planned = True
        else:
            logging.warning(Ta('Unknown action: %s'), action_name)
            continue

        logging.debug("scheduling %s(%s) on days %s at %s:%s", action_name, arguments, d, h, m)

        __SCHED.add_daytime_task(action, action_name, d, None, (h, m),
                             kronos.method.sequential, arguments, None)

    # Set Guardian interval to 30 seconds
    __SCHED.add_interval_task(sched_guardian, "Guardian", 15, 30,
                                  kronos.method.sequential, None, None)

    # Set RSS check interval
    if not rss_planned:
        interval = cfg.rss_rate()
        delay = random.randint(0, interval-1)
        logging.debug("Scheduling RSS interval task every %s min (delay=%s)", interval, delay)
        __SCHED.add_interval_task(rss.run_method, "RSS", delay*60, interval*60,
                                      kronos.method.sequential, None, None)
        __SCHED.add_single_task(rss.run_method, 'RSS', 15, kronos.method.sequential, None, None)

    if cfg.version_check():
        # Check for new release, once per week on random time
        m = random.randint(0, 59)
        h = random.randint(0, 23)
        d = (random.randint(1, 7), )

        logging.debug("Scheduling VersionCheck on day %s at %s:%s", d[0], h, m)
        __SCHED.add_daytime_task(sabnzbd.misc.check_latest_version, 'VerCheck', d, None, (h, m),
                                 kronos.method.sequential, [], None)


    if cfg.newzbin_bookmarks():
        interval = cfg.bookmark_rate()
        delay = random.randint(0, interval-1)
        logging.debug("Scheduling Bookmark interval task every %s min (delay=%s)", interval, delay)
        __SCHED.add_interval_task(Bookmarks.do.run, 'Bookmarks', delay*60, interval*60,
                                  kronos.method.sequential, None, None)
        __SCHED.add_single_task(Bookmarks.do.run, 'Bookmarks', 20, kronos.method.sequential, None, None)


    # Subscribe to special schedule changes
    cfg.newzbin_bookmarks.callback(schedule_guard)
    cfg.bookmark_rate.callback(schedule_guard)
    cfg.rss_rate.callback(schedule_guard)
Esempio n. 5
0
    def load_schedules(self):
        rss_planned = False

        for schedule in cfg.schedules():
            arguments = []
            argument_list = None

            try:
                enabled, m, h, d, action_name = schedule.split()
            except:
                try:
                    enabled, m, h, d, action_name, argument_list = schedule.split(
                        None, 5)
                except:
                    continue  # Bad schedule, ignore

            if argument_list:
                arguments = argument_list.split()

            action_name = action_name.lower()
            try:
                m = int(m)
                h = int(h)
            except:
                logging.warning(T("Bad schedule %s at %s:%s"), action_name, m,
                                h)
                continue

            if d.isdigit():
                d = [int(i) for i in d]
            else:
                d = DAILY_RANGE

            if action_name == "resume":
                action = self.scheduled_resume
                arguments = []
            elif action_name == "pause":
                action = sabnzbd.Downloader.pause
                arguments = []
            elif action_name == "pause_all":
                action = sabnzbd.pause_all
                arguments = []
            elif action_name == "shutdown":
                action = sabnzbd.shutdown_program
                arguments = []
            elif action_name == "restart":
                action = sabnzbd.restart_program
                arguments = []
            elif action_name == "pause_post":
                action = pp_pause
            elif action_name == "resume_post":
                action = pp_resume
            elif action_name == "speedlimit" and arguments != []:
                action = sabnzbd.Downloader.limit_speed
            elif action_name == "enable_server" and arguments != []:
                action = sabnzbd.enable_server
            elif action_name == "disable_server" and arguments != []:
                action = sabnzbd.disable_server
            elif action_name == "scan_folder":
                action = sabnzbd.DirScanner.scan
            elif action_name == "rss_scan":
                action = sabnzbd.RSSReader.run
                rss_planned = True
            elif action_name == "remove_failed":
                action = sabnzbd.api.history_remove_failed
            elif action_name == "remove_completed":
                action = sabnzbd.api.history_remove_completed
            elif action_name == "enable_quota":
                action = sabnzbd.BPSMeter.set_status
                arguments = [True]
            elif action_name == "disable_quota":
                action = sabnzbd.BPSMeter.set_status
                arguments = [False]
            elif action_name == "pause_all_low":
                action = sabnzbd.NzbQueue.pause_on_prio
                arguments = [LOW_PRIORITY]
            elif action_name == "pause_all_normal":
                action = sabnzbd.NzbQueue.pause_on_prio
                arguments = [NORMAL_PRIORITY]
            elif action_name == "pause_all_high":
                action = sabnzbd.NzbQueue.pause_on_prio
                arguments = [HIGH_PRIORITY]
            elif action_name == "resume_all_low":
                action = sabnzbd.NzbQueue.resume_on_prio
                arguments = [LOW_PRIORITY]
            elif action_name == "resume_all_normal":
                action = sabnzbd.NzbQueue.resume_on_prio
                arguments = [NORMAL_PRIORITY]
            elif action_name == "resume_all_high":
                action = sabnzbd.NzbQueue.resume_on_prio
                arguments = [HIGH_PRIORITY]
            elif action_name == "pause_cat":
                action = sabnzbd.NzbQueue.pause_on_cat
                arguments = [argument_list]
            elif action_name == "resume_cat":
                action = sabnzbd.NzbQueue.resume_on_cat
                arguments = [argument_list]
            else:
                logging.warning(T("Unknown action: %s"), action_name)
                continue

            if enabled == "1":
                logging.info("Scheduling %s(%s) on days %s at %02d:%02d",
                             action_name, arguments, d, h, m)
                self.scheduler.add_daytime_task(action,
                                                action_name,
                                                d,
                                                None, (h, m),
                                                args=arguments)
            else:
                logging.debug("Skipping %s(%s) on days %s at %02d:%02d",
                              action_name, arguments, d, h, m)

        # Set RSS check interval
        if not rss_planned:
            interval = cfg.rss_rate()
            delay = random.randint(0, interval - 1)
            logging.info(
                "Scheduling RSS interval task every %s min (delay=%s)",
                interval, delay)
            sabnzbd.RSSReader.next_run = time.time() + delay * 60
            self.scheduler.add_interval_task(sabnzbd.RSSReader.run, "RSS",
                                             delay * 60, interval * 60)
            self.scheduler.add_single_task(sabnzbd.RSSReader.run, "RSS", 15)

        if cfg.version_check():
            # Check for new release, once per week on random time
            m = random.randint(0, 59)
            h = random.randint(0, 23)
            d = (random.randint(1, 7), )

            logging.info("Scheduling VersionCheck on day %s at %s:%s", d[0], h,
                         m)
            self.scheduler.add_daytime_task(sabnzbd.misc.check_latest_version,
                                            "VerCheck", d, None, (h, m))

        action, hour, minute = sabnzbd.BPSMeter.get_quota()
        if action:
            logging.info("Setting schedule for quota check daily at %s:%s",
                         hour, minute)
            self.scheduler.add_daytime_task(action, "quota_reset", DAILY_RANGE,
                                            None, (hour, minute))

        if sabnzbd.misc.int_conv(cfg.history_retention()) > 0:
            logging.info("Setting schedule for midnight auto history-purge")
            self.scheduler.add_daytime_task(
                sabnzbd.database.midnight_history_purge,
                "midnight_history_purge", DAILY_RANGE, None, (0, 0))

        logging.info("Setting schedule for midnight BPS reset")
        self.scheduler.add_daytime_task(sabnzbd.BPSMeter.midnight,
                                        "midnight_bps", DAILY_RANGE, None,
                                        (0, 0))

        logging.info("Setting schedule for server expiration check")
        self.scheduler.add_daytime_task(
            sabnzbd.downloader.check_server_expiration,
            "check_server_expiration", DAILY_RANGE, None, (0, 0))

        logging.info("Setting scheduler for server quota check")
        self.scheduler.add_interval_task(
            sabnzbd.downloader.check_server_quota,
            "check_server_quota",
            0,
            10 * 60,
        )

        # Subscribe to special schedule changes
        cfg.rss_rate.callback(self.scheduler_restart_guard)
Esempio n. 6
0
def init():
    """ Create the scheduler and set all required events
    """
    global __SCHED

    reset_guardian()
    __SCHED = kronos.ThreadedScheduler()
    rss_planned = False

    for schedule in cfg.schedules():
        arguments = []
        argument_list = None
        try:
            m, h, d, action_name = schedule.split()
        except:
            m, h, d, action_name, argument_list = schedule.split(None, 4)
        if argument_list:
            arguments = argument_list.split()

        action_name = action_name.lower()
        try:
            m = int(m)
            h = int(h)
        except:
            logging.warning(Ta('Bad schedule %s at %s:%s'), action_name, m, h)
            continue

        if d.isdigit():
            d = [int(d)]
        else:
            d = range(1, 8)

        if action_name == 'resume':
            action = scheduled_resume
            arguments = []
        elif action_name == 'pause':
            action = sabnzbd.downloader.Downloader.do.pause
            arguments = []
        elif action_name == 'pause_all':
            action = sabnzbd.pause_all
            arguments = []
        elif action_name == 'shutdown':
            action = sabnzbd.shutdown_program
            arguments = []
        elif action_name == 'restart':
            action = sabnzbd.restart_program
            arguments = []
        elif action_name == 'pause_post':
            action = pp_pause
        elif action_name == 'resume_post':
            action = pp_resume
        elif action_name == 'speedlimit' and arguments != []:
            action = sabnzbd.downloader.Downloader.do.limit_speed
        elif action_name == 'enable_server' and arguments != []:
            action = sabnzbd.enable_server
        elif action_name == 'disable_server' and arguments != []:
            action = sabnzbd.disable_server
        elif action_name == 'scan_folder':
            action = sabnzbd.dirscanner.dirscan
        elif action_name == 'rss_scan':
            action = rss.run_method
            rss_planned = True
        else:
            logging.warning(Ta('Unknown action: %s'), action_name)
            continue

        logging.debug("scheduling %s(%s) on days %s at %s:%s", action_name,
                      arguments, d, h, m)

        __SCHED.add_daytime_task(action, action_name, d, None, (h, m),
                                 kronos.method.sequential, arguments, None)

    # Set Guardian interval to 30 seconds
    __SCHED.add_interval_task(sched_guardian, "Guardian", 15, 30,
                              kronos.method.sequential, None, None)

    # Set RSS check interval
    if not rss_planned:
        interval = cfg.rss_rate()
        delay = random.randint(0, interval - 1)
        logging.debug("Scheduling RSS interval task every %s min (delay=%s)",
                      interval, delay)
        __SCHED.add_interval_task(rss.run_method, "RSS", delay * 60,
                                  interval * 60, kronos.method.sequential,
                                  None, None)
        __SCHED.add_single_task(rss.run_method, 'RSS', 15,
                                kronos.method.sequential, None, None)

    if cfg.version_check():
        # Check for new release, once per week on random time
        m = random.randint(0, 59)
        h = random.randint(0, 23)
        d = (random.randint(1, 7), )

        logging.debug("Scheduling VersionCheck on day %s at %s:%s", d[0], h, m)
        __SCHED.add_daytime_task(sabnzbd.misc.check_latest_version, 'VerCheck',
                                 d, None, (h, m), kronos.method.sequential, [],
                                 None)

    if cfg.newzbin_bookmarks():
        interval = cfg.bookmark_rate()
        delay = random.randint(0, interval - 1)
        logging.debug(
            "Scheduling Bookmark interval task every %s min (delay=%s)",
            interval, delay)
        __SCHED.add_interval_task(Bookmarks.do.run, 'Bookmarks', delay * 60,
                                  interval * 60, kronos.method.sequential,
                                  None, None)
        __SCHED.add_single_task(Bookmarks.do.run, 'Bookmarks', 20,
                                kronos.method.sequential, None, None)

    # Subscribe to special schedule changes
    cfg.newzbin_bookmarks.callback(schedule_guard)
    cfg.bookmark_rate.callback(schedule_guard)
    cfg.rss_rate.callback(schedule_guard)