def runProgram(self): # a one-time catch for the startup delay if (utils.getSettingInt("startup_delay") != 0): count = 0 while count < len(self.schedules): if (time.time() > self.schedules[count].next_run): # we missed at least one update, fix this self.schedules[count].next_run = time.time( ) + utils.getSettingInt("startup_delay") * 60 count = count + 1 utils.log(str(utils.getSettingInt('startup_delay'))) # display upgrade messages if they exist if (utils.getSettingInt('upgrade_notes') < UPGRADE_INT): xbmcgui.Dialog().ok(utils.getString(30000), utils.getString(30030)) utils.setSetting('upgrade_notes', str(UPGRADE_INT)) # program has started, check if we should show a notification self.showNotify() while (True): # don't check unless new minute if (time.time() > self.last_run + 60): self.readLastRun() self.evalSchedules() # calculate the sleep time (next minute) now = datetime.now() if (self.monitor.waitForAbort(60 - now.second)): break # clean up monitor on exit del self.monitor
def __init__(self): self.monitor = UpdateMonitor(update_method=self.settingsChanged) self.enabled = utils.getSettingBool("enable_scheduler") self.next_run_path = xbmc.translatePath( utils.data_dir()) + 'next_run.txt' if (self.enabled): # sleep for 2 minutes so Kodi can start and time can update correctly xbmc.Monitor().waitForAbort(120) nr = 0 if (xbmcvfs.exists(self.next_run_path)): fh = xbmcvfs.File(self.next_run_path) try: # check if we saved a run time from the last run nr = float(fh.read()) except ValueError: nr = 0 fh.close() # if we missed and the user wants to play catch-up if (0 < nr <= time.time() and utils.getSettingBool('schedule_miss')): utils.log("scheduled backup was missed, doing it now...") progress_mode = utils.getSettingInt('progress_mode') if (progress_mode == 0): progress_mode = 1 # Kodi just started, don't block it with a foreground progress bar self.doScheduledBackup(progress_mode) self.setup()
def findNextRun(self, now): progress_mode = utils.getSettingInt('progress_mode') # find the cron expression and get the next run time cron_exp = self.parseSchedule() cron_ob = croniter(cron_exp, datetime.fromtimestamp(now)) new_run_time = cron_ob.get_next(float) if (new_run_time != self.next_run): self.next_run = new_run_time utils.log("scheduler will run again on " + utils.getRegionalTimestamp( datetime.fromtimestamp(self.next_run), ['dateshort', 'time'])) # write the next time to a file fh = xbmcvfs.File(self.next_run_path, 'w') fh.write(str(self.next_run)) fh.close() # only show when not in silent mode if (progress_mode != 2): utils.showNotification( utils.getString(30081) + " " + utils.getRegionalTimestamp( datetime.fromtimestamp(self.next_run), ['dateshort', 'time']))
def doScheduledBackup(self, progress_mode): if (progress_mode != 2): utils.showNotification(utils.getString(30053)) backup = XbmcBackup() if (backup.remoteConfigured()): if (utils.getSettingInt('progress_mode') in [0, 1]): backup.backup(True) else: backup.backup(False) # check if this is a "one-off" if (utils.getSettingInt("schedule_interval") == 0): # disable the scheduler after this run self.enabled = False utils.setSetting('enable_scheduler', 'false') else: utils.showNotification(utils.getString(30045))
def start(self): # display upgrade messages if they exist if (utils.getSettingInt('upgrade_notes') < UPGRADE_INT): xbmcgui.Dialog().ok(utils.getString(30010), utils.getString(30132)) utils.setSetting('upgrade_notes', str(UPGRADE_INT)) # check if a backup should be resumed resumeRestore = self._resumeCheck() if (resumeRestore): restore = XbmcBackup() restore.selectRestore(self.restore_point) # skip the advanced settings check restore.skipAdvanced() restore.restore() while (not self.monitor.abortRequested()): if (self.enabled): # scheduler is still on now = time.time() if (self.next_run <= now): progress_mode = utils.getSettingInt('progress_mode') self.doScheduledBackup(progress_mode) # check if we should shut the computer down if (utils.getSettingBool("cron_shutdown")): # wait 10 seconds to make sure all backup processes and files are completed time.sleep(10) xbmc.executebuiltin('ShutDown()') else: # find the next run time like normal self.findNextRun(now) xbmc.sleep(500) # delete monitor to free up memory del self.monitor
def databaseUpdated(self, database): showDialogs = utils.getSettingBool( 'notify_next_run' ) # if the user has selected to show dialogs for library operations # check if we should clean the library if (utils.getSettingBool('clean_libraries')): # check if should update while playing media if (not xbmc.Player().isPlaying() or utils.getSettingBool("run_during_playback")): if (utils.getSettingInt("clean_timer") == 0): # check if we should clean music, or video aJob = CronSchedule() aJob.name = utils.getString(30048) aJob.timer_type = utils.__addon_id__ if ((utils.getSettingInt('library_to_clean') == 0 or utils.getSettingInt('library_to_clean') == 1) and database == 'video'): # create the clean job schedule aJob.command = { 'method': 'VideoLibrary.Clean', 'params': { 'showdialogs': showDialogs } } if ((utils.getSettingInt('library_to_clean') == 2 or utils.getSettingInt('library_to_clean') == 0) and database == 'music'): aJob.command = { 'method': 'AudioLibrary.Clean', 'params': { 'showdialogs': showDialogs } } self.cleanLibrary(aJob) # writeLastRun will trigger notifications self.writeLastRun()
def cleanLibrary(self, cronJob): # check if we should verify with user first unless we're on 'clean after update' if (utils.getSettingBool('user_confirm_clean') and utils.getSettingInt('clean_timer') != 0): # user can decide 'no' here and exit this runClean = xbmcgui.Dialog().yesno(utils.getString(30000), utils.getString(30052), line2=utils.getString(30053), autoclose=15000) if (not runClean): return # run the clean operation utils.log("Cleaning Database") cronJob.executeCommand() # write last run time, will trigger notifications self.writeLastRun()
def parseSchedule(self): schedule_type = utils.getSettingInt("schedule_interval") cron_exp = utils.getSetting("cron_schedule") hour_of_day = utils.getSetting("schedule_time") hour_of_day = int(hour_of_day[0:2]) if (schedule_type == 0 or schedule_type == 1): # every day cron_exp = "0 " + str(hour_of_day) + " * * *" elif (schedule_type == 2): # once a week day_of_week = utils.getSetting("day_of_week") cron_exp = "0 " + str(hour_of_day) + " * * " + day_of_week elif (schedule_type == 3): # first day of month cron_exp = "0 " + str(hour_of_day) + " 1 * *" return cron_exp
def createSchedules(self, forceUpdate=False): utils.log("update timers") self.lock = True # lock so the eval portion does not run self.schedules = [] showDialogs = utils.getSettingBool( 'notify_next_run' ) # if the user has selected to show dialogs for library operations if (utils.getSettingBool('clean_libraries')): # create clean schedule (if needed) if (utils.getSettingInt("clean_timer") != 0): if (utils.getSettingInt('library_to_clean') == 0 or utils.getSettingInt('library_to_clean') == 1): # video clean schedule starts at 12am by default aSchedule = CronSchedule() aSchedule.name = utils.getString(30048) aSchedule.timer_type = utils.__addon_id__ aSchedule.command = { 'method': 'VideoLibrary.Clean', 'params': { 'showdialogs': showDialogs } } if (utils.getSettingInt("clean_timer") == 4): aSchedule.expression = utils.getSetting( "clean_video_cron_expression") else: aSchedule.expression = "0 0 " + aSchedule.cleanLibrarySchedule( utils.getSettingInt("clean_timer")) aSchedule.next_run = self.calcNextRun( aSchedule.expression, time.time()) self.schedules.append(aSchedule) if (utils.getSettingInt('library_to_clean') == 2 or utils.getSettingInt('library_to_clean') == 0): # music clean schedule starts at 2am by default aSchedule = CronSchedule() aSchedule.name = utils.getString(30049) aSchedule.timer_type = utils.__addon_id__ aSchedule.command = { 'method': 'AudioLibrary.Clean', 'params': { 'showdialogs': showDialogs } } if (utils.getSettingInt("clean_timer") == 4): aSchedule.expression = utils.getSetting( "clean_music_cron_expression") else: aSchedule.expression = "0 2 " + aSchedule.cleanLibrarySchedule( utils.getSettingInt("clean_timer")) aSchedule.next_run = self.calcNextRun( aSchedule.expression, time.time()) self.schedules.append(aSchedule) if (utils.getSettingBool('update_video')): utils.log("Creating timer for Video Library") # create the video schedule aSchedule = CronSchedule() aSchedule.name = utils.getString(30012) aSchedule.command = { 'method': 'VideoLibrary.Scan', 'params': { 'showdialogs': showDialogs } } aSchedule.expression = self.checkTimer('video') aSchedule.next_run = self.calcNextRun(aSchedule.expression, self.last_run) self.schedules.append(aSchedule) # add custom video paths (separate timers) customPaths = CustomPathFile('video') for aJob in customPaths.getSchedules(showDialogs): utils.log("Creating timer " + aJob.name) aJob.next_run = self.calcNextRun(aJob.expression, self.last_run) self.schedules.append(aJob) if (utils.getSettingBool('update_music')): utils.log("Creating timer for Music Library") # create the music schedule aSchedule = CronSchedule() aSchedule.name = utils.getString(30013) aSchedule.command = { 'method': 'AudioLibrary.Scan', 'params': { 'showdialogs': showDialogs } } aSchedule.expression = self.checkTimer('music') aSchedule.next_run = self.calcNextRun(aSchedule.expression, self.last_run) self.schedules.append(aSchedule) # add custom music paths (separate timers) customPaths = CustomPathFile('music') for aJob in customPaths.getSchedules(showDialogs): utils.log("Creating timer " + aJob.name) aJob.next_run = self.calcNextRun(aJob.expression, self.last_run) self.schedules.append(aJob) # release the lock self.lock = False utils.log("Created " + str(len(self.schedules)) + " schedules", xbmc.LOGDEBUG) # show any notifications self.showNotify(not forceUpdate)
if (params['mode'] == 'backup'): mode = 0 elif (params['mode'] == 'restore'): mode = 1 # if mode wasn't passed in as arg, get from user if (mode == -1): # by default, Backup,Restore,Open Settings options = [ utils.getString(30016), utils.getString(30017), utils.getString(30099) ] # find out if we're using the advanced editor if (utils.getSettingInt('backup_selection_type') == 1): options.append(utils.getString(30125)) # figure out if this is a backup or a restore from the user mode = xbmcgui.Dialog().select( utils.getString(30010) + " - " + utils.getString(30023), options) # check if program should be run if (mode != -1): # run the profile backup backup = XbmcBackup() if (mode == 2): # open the settings dialog utils.openSettings() elif (mode == 3 and utils.getSettingInt('backup_selection_type') == 1):