def is_cron(string): try: croniter(string) except ValueError: raise ValueError("please provide a valid cron entry") else: return string
def time_to_action(start_sched, stop_sched, state, id1, lgr, Instcsv_file): now = datetime.datetime.now() try: if start_sched != None: startcron = croniter.croniter(start_sched, now) nextstart = startcron.get_next(datetime.datetime) prevstart = startcron.get_prev(datetime.datetime) lgr.debug( "%s, Now: %s, NextStart: %s, PrevStart: %s " % (id1, now, nextstart, prevstart)) if stop_sched != None: stopcron = croniter.croniter(stop_sched, now) nextstop = stopcron.get_next(datetime.datetime) prevstop = stopcron.get_prev(datetime.datetime) lgr.debug( "%s, Now: %s, NextStop: %s and PrevStop: %s " % (id1, now, nextstop, prevstop)) if (state =='stopped'): if (stop_sched != None): tstop = (prevstart <= prevstop <= now) ret = (prevstart<= now <=nextstop) and (tstop != True) else: ret = False elif (state =='running'): if (start_sched != None): tstart = (prevstop <= prevstart <= now) ret = (prevstop <= now <= nextstart) and (tstart != True) else: ret = False else: ret = False except Exception, e: lgr.info( "Caught Exception: %s" % (e)) lgr.info( "Instance-id %s state will remain the same [%s]" % (id1, state)) ret = False
def validate_cron_trigger_input(pattern, first_time, count): if not (first_time or pattern): raise exc.InvalidModelException( 'Pattern or first_execution_time must be specified.' ) if first_time: valid_min_time = datetime.datetime.utcnow() + datetime.timedelta(0, 60) if valid_min_time > first_time: raise exc.InvalidModelException( 'first_execution_time must be at least 1 minute in the future.' ) if not pattern and count and count > 1: raise exc.InvalidModelException( 'Pattern must be provided if count is superior to 1.' ) if pattern: try: croniter.croniter(pattern) except (ValueError, KeyError): raise exc.InvalidModelException( 'The specified pattern is not valid: {}'.format(pattern) )
def testPrevMinute(self): base = datetime(2010, 8, 25, 15, 56) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) self.assertEqual(base.year, prev.year) self.assertEqual(base.month, prev.month) self.assertEqual(base.day, prev.day) self.assertEqual(base.hour, prev.hour) self.assertEqual(base.minute, prev.minute + 1) base = datetime(2010, 8, 25, 15, 0) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) self.assertEqual(base.year, prev.year) self.assertEqual(base.month, prev.month) self.assertEqual(base.day, prev.day) self.assertEqual(base.hour, prev.hour + 1) self.assertEqual(59, prev.minute) base = datetime(2010, 8, 25, 0, 0) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) self.assertEqual(base.year, prev.year) self.assertEqual(base.month, prev.month) self.assertEqual(base.day, prev.day + 1) self.assertEqual(23, prev.hour) self.assertEqual(59, prev.minute)
def testPrevMinute(self): base = datetime(2010, 8, 25, 15, 56) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) base.year == prev.year base.month == prev.month base.day == prev.day base.hour == prev.hour base.minute, prev.minute + 1 base = datetime(2010, 8, 25, 15, 0) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) base.year == prev.year base.month == prev.month base.day == prev.day base.hour == prev.hour + 1 59 == prev.minute base = datetime(2010, 8, 25, 0, 0) itr = croniter('*/1 * * * *', base) prev = itr.get_prev(datetime) base.year == prev.year base.month == prev.month base.day == prev.day + 1 23 == prev.hour 59 == prev.minute
def addJob(self,job): try: #verify the cron expression here, throws ValueError if wrong croniter(job.expression) except: #didn't work return False #set the addon id if there isn't one if(job.addon == None): job.addon = utils.addon_id() self._refreshJobs() if(job.id >= 0): #replace existing job self.jobs[job.id] = job else: #add a new job self.jobs.append(job) #write the file self._writeCronFile() return True
def testNthWeekDay(self): base = datetime(2010, 2, 25) itr = croniter('0 0 * * sat#1', base) n1 = itr.get_next(datetime) self.assertEqual(n1.isoweekday(), 6) self.assertEqual(n1.day, 6) self.assertEqual(n1.month, 3) n2 = itr.get_next(datetime) self.assertEqual(n2.isoweekday(), 6) self.assertEqual(n2.day, 3) self.assertEqual(n2.month, 4) base = datetime(2010, 1, 25) itr = croniter('0 0 * * wed#5', base) n1 = itr.get_next(datetime) self.assertEqual(n1.month, 3) self.assertEqual(n1.day, 31) self.assertEqual(n1.year, 2010) n2 = itr.get_next(datetime) self.assertEqual(n2.month, 6) self.assertEqual(n2.day, 30) self.assertEqual(n2.year, 2010) n3 = itr.get_next(datetime) self.assertEqual(n3.month, 9) self.assertEqual(n3.day, 29) self.assertEqual(n3.year, 2010)
def testBug57(self): base = datetime(2012, 2, 24, 0, 0, 0) itr = croniter('0 4/6 * * *', base) n1 = itr.get_next(datetime) self.assertEqual(n1.hour, 4) self.assertEqual(n1.minute, 0) self.assertEqual(n1.month, 2) self.assertEqual(n1.day, 24) n1 = itr.get_prev(datetime) self.assertEqual(n1.hour, 22) self.assertEqual(n1.minute, 0) self.assertEqual(n1.month, 2) self.assertEqual(n1.day, 23) itr = croniter('0 0/6 * * *', base) n1 = itr.get_next(datetime) self.assertEqual(n1.hour, 6) self.assertEqual(n1.minute, 0) self.assertEqual(n1.month, 2) self.assertEqual(n1.day, 24) n1 = itr.get_prev(datetime) self.assertEqual(n1.hour, 0) self.assertEqual(n1.minute, 0) self.assertEqual(n1.month, 2) self.assertEqual(n1.day, 24)
def validate(self, value): verrors = ValidationErrors() for attr in self.attrs.values(): if attr.name in value: try: attr.validate(value[attr.name]) except ValidationErrors as e: verrors.add_child(self.name, e) for v in value: if v not in Cron.FIELDS: verrors.add(self.name, f'Unexpected {v} value') if verrors: raise verrors cron_expression = '' for field in Cron.FIELDS: cron_expression += value.get(field) + ' ' if value.get(field) else '* ' try: croniter(cron_expression) except Exception as e: verrors.add(self.name, 'Please ensure fields match cron syntax - ' + str(e)) if verrors: raise verrors
def testMinute(self): # minute asterisk base = datetime(2010, 1, 23, 12, 18) itr = croniter('*/1 * * * *', base) n1 = itr.get_next(datetime) # 19 base.year == n1.year base.month == n1.month base.day == n1.day base.hour == n1.hour base.minute == n1.minute - 1 for i in range(39): # ~ 58 itr.get_next() n2 = itr.get_next(datetime) n2.minute == 59 n3 = itr.get_next(datetime) n3.minute == 0 n3.hour == 13 itr = croniter('*/5 * * * *', base) n4 = itr.get_next(datetime) n4.minute == 20 for i in range(6): itr.get_next() n5 = itr.get_next(datetime) n5.minute == 55 n6 = itr.get_next(datetime) n6.minute == 0 n6.hour == 13
def testWeekDay(self): base = datetime(2010, 2, 25) itr = croniter('0 0 * * sat', base) n1 = itr.get_next(datetime) self.assertEqual(n1.isoweekday(), 6) self.assertEqual(n1.day, 27) n2 = itr.get_next(datetime) self.assertEqual(n2.isoweekday(), 6) self.assertEqual(n2.day, 6) self.assertEqual(n2.month, 3) base = datetime(2010, 1, 25) itr = croniter('0 0 1 * wed', base) n1 = itr.get_next(datetime) self.assertEqual(n1.month, 1) self.assertEqual(n1.day, 27) self.assertEqual(n1.year, 2010) n2 = itr.get_next(datetime) self.assertEqual(n2.month, 2) self.assertEqual(n2.day, 1) self.assertEqual(n2.year, 2010) n3 = itr.get_next(datetime) self.assertEqual(n3.month, 2) self.assertEqual(n3.day, 3) self.assertEqual(n3.year, 2010)
def testDay(self): base = datetime(2010, 2, 24, 12, 9) itr = croniter('0 0 */3 * *', base) n1 = itr.get_next(datetime) n1.day == 27 n2 = itr.get_next(datetime) n2.day == 3 # test leap year base = datetime(1996, 2, 27) itr = croniter('0 0 * * *', base) n1 = itr.get_next(datetime) n1.day == 28 n1.month == 2 n2 = itr.get_next(datetime) n2.day == 29 n2.month == 2 base2 = datetime(2000, 2, 27) itr2 = croniter('0 0 * * *', base2) n3 = itr2.get_next(datetime) n3.day == 28 n3.month == 2 n4 = itr2.get_next(datetime) n4.day == 29 n4.month == 2
def testWeekDay(self): base = datetime(2010, 2, 25) itr = croniter('0 0 * * sat', base) n1 = itr.get_next(datetime) n1.isoweekday() == 6 n1.day == 27 n2 = itr.get_next(datetime) n2.isoweekday() == 6 n2.day == 6 n2.month == 3 base = datetime(2010, 1, 25) itr = croniter('0 0 1 * wed', base) n1 = itr.get_next(datetime) n1.month == 1 n1.day == 27 n1.year == 2010 n2 = itr.get_next(datetime) n2.month == 2 n2.day == 1 n2.year == 2010 n3 = itr.get_next(datetime) n3.month == 2 n3.day == 3 n3.year == 2010
def testMinute(self): # minute asterisk base = datetime(2010, 1, 23, 12, 18) itr = croniter('*/1 * * * *', base) n1 = itr.get_next(datetime) # 19 self.assertEqual(base.year, n1.year) self.assertEqual(base.month, n1.month) self.assertEqual(base.day, n1.day) self.assertEqual(base.hour, n1.hour) self.assertEqual(base.minute, n1.minute - 1) for i in range(39): # ~ 58 itr.get_next() n2 = itr.get_next(datetime) self.assertEqual(n2.minute, 59) n3 = itr.get_next(datetime) self.assertEqual(n3.minute, 0) self.assertEqual(n3.hour, 13) itr = croniter('*/5 * * * *', base) n4 = itr.get_next(datetime) self.assertEqual(n4.minute, 20) for i in range(6): itr.get_next() n5 = itr.get_next(datetime) self.assertEqual(n5.minute, 55) n6 = itr.get_next(datetime) self.assertEqual(n6.minute, 0) self.assertEqual(n6.hour, 13)
def testDay(self): base = datetime(2010, 2, 24, 12, 9) itr = croniter('0 0 */3 * *', base) n1 = itr.get_next(datetime) # 1 4 7 10 13 16 19 22 25 28 self.assertEqual(n1.day, 25) n2 = itr.get_next(datetime) self.assertEqual(n2.day, 28) n3 = itr.get_next(datetime) self.assertEqual(n3.day, 1) self.assertEqual(n3.month, 3) # test leap year base = datetime(1996, 2, 27) itr = croniter('0 0 * * *', base) n1 = itr.get_next(datetime) self.assertEqual(n1.day, 28) self.assertEqual(n1.month, 2) n2 = itr.get_next(datetime) self.assertEqual(n2.day, 29) self.assertEqual(n2.month, 2) base2 = datetime(2000, 2, 27) itr2 = croniter('0 0 * * *', base2) n3 = itr2.get_next(datetime) self.assertEqual(n3.day, 28) self.assertEqual(n3.month, 2) n4 = itr2.get_next(datetime) self.assertEqual(n4.day, 29) self.assertEqual(n4.month, 2)
def next_occurrence(self, start_datetime): '''Gets the next date-time occurrence starting from start_datetime according to the crontab style rules. :param start_datetime: Current date-time :type start_datetime: datetime.datetime :return: The next date-time occurrence :rtype: datetime.datetime ''' today = start_datetime.replace(hour=0, minute=0) iter_today_end = croniter(self.time_daylight_end, today) today_end = iter_today_end.get_next(datetime) #print 'Debug - next_occurrence.start_datetime:', start_datetime #print 'Debug - next_occurrence.today_end:', today_end if start_datetime <= today_end: next_datetime = start_datetime + timedelta(seconds=self.time_period) iter_today_begin = croniter(self.time_daylight_begin, today) today_begin = iter_today_begin.get_next(datetime) #print 'Debug - next_occurrence.today_begin:', today_begin if next_datetime < today_begin: next_datetime = today_begin if next_datetime <= today_end: #print 'Debug - next_occurrence.next_datetime:', next_datetime return next_datetime # the current date-time is greater than daylight end time: # increment the day nextday = today + timedelta(days=1) iter_nextday_begin = croniter(self.time_daylight_begin, nextday) next_datetime = iter_nextday_begin.get_next(datetime) #print 'Debug - next_occurrence.next_datetime:', next_datetime return next_datetime
def cron_validator(value): try: croniter(value) except KeyError as ke: raise ValidationError('Invalid value: ' + ke.message) except ValueError as ve: raise ValidationError(ve.message)
def clean_cron_string(self): try: croniter.croniter(self.cron_string) except ValueError as e: raise ValidationError({ 'cron_string': ValidationError( _(str(e)), code='invalid') })
def validate_cron(form, field): try: croniter(field.data) except (ValueError, AttributeError): raise ValidationError( 'Invalid cron format: given {}' .format(field.data) )
def validate(self): errors = [] if not self.expression: errors.append("Plan schedule is missing expression") else: try: croniter(self.expression) except (ValueError, KeyError), e: errors.append("Plan schedule has an invalid expression (%s): " "%s" % (self.expression, str(e)))
def cron_task(cron_spec): """Decorator for a task that executes on a cron-like schedule""" # test the cron spec before the function is called croniter.croniter(cron_spec) def get_next_time(last_run): ci = croniter.croniter(cron_spec, last_run) return ci.get_next(datetime) return _task_decorator(get_next_time, "cron: %s" % cron_spec)
def test_next_when_now_satisfies_cron(self): ts_a = datetime(2018, 5, 21, 0, 3, 0) ts_b = datetime(2018, 5, 21, 0, 4, 20) test_cron = '4 * * * *' next_a = croniter(test_cron, start_time=ts_a).get_next() next_b = croniter(test_cron, start_time=ts_b).get_next() self.assertTrue(next_b > next_a)
def check_time_format(cls, pattern): if not pattern: msg = (_("The trigger pattern is None")) raise exception.InvalidInput(msg) try: croniter(pattern) except Exception: msg = (_("The trigger pattern(%s) is invalid") % pattern) raise exception.InvalidInput(msg)
def validate(self, value, context, template=None): if not value: return True try: croniter.croniter(value) return True except Exception as ex: self._error_message = _( 'Invalid CRON expression: %s') % six.text_type(ex) return False
def calcInterval(self, cron_format): """ "*/5 * * * *" :return 5 * 60 :param format: :return: seconds """ first = cron.croniter(cron_format, datetime.now()).get_next(datetime) second = cron.croniter(cron_format, first).get_next(datetime) return (second - first).total_seconds()
def validate_schedule(self, field): """Ensure that `schedule` is accepted by `croniter`.""" if not field.data: return try: croniter(field.data) except Exception: # May be TypeError/KeyError/AttributeError, who knows what else # Let's play it safe. six.reraise(ValidationError, *sys.exc_info()[1:])
def cron_task(cron_spec): """Decorator for a task that executes on a cron-like schedule""" # test the cron spec before the function is called croniter.croniter(cron_spec) def runnable_now(task, now): last_run = max(j.created_at for j in task.jobs) if task.jobs else None ci = croniter.croniter(cron_spec, last_run) return now >= ci.get_next(datetime) return _task_decorator(runnable_now, "cron: %s" % cron_spec)
def testTimezone(self): base = datetime(2013, 3, 4, 12, 15) itr = croniter('* * * * *', base) n1 = itr.get_next(datetime) self.assertEqual(n1.tzinfo, None) tokyo = pytz.timezone('Asia/Tokyo') itr2 = croniter('* * * * *', tokyo.localize(base)) n2 = itr2.get_next(datetime) self.assertEqual(n2.tzinfo.zone, 'Asia/Tokyo')
def __init__(self, fn, interval, start=True, clock=None, args=None, kwargs=None): super(CronScheduler, self).__init__(fn, clock, args, kwargs) self.fn = fn from croniter import croniter if clock: self.iter = croniter(interval, clock.seconds()) else: self.iter = croniter(interval) if start: self.schedule()
def process_edits(uid, tb_file, using_local_file, old_tab): crontab = [] jobs = [] old_jobs = api.get_jobs_for_user(uid) with open(tb_file, "r") as tab: for line in tab: line = line.strip() crontab.append(line) # Ignore newlines and full line comments if line and (line[0] != "#"): split = line.split() interval = " ".join(split[:5]) cmd = " ".join(split[5:]) try: # Ensure the crontab line is valid croniter(interval) if not cmd: raise ValueError except (KeyError, ValueError): # Otherwise prompt user to edit crontab e_str = "The crontab you entered has invalid entries, " "would you like to edit it again? (y/n) " while True: cnt = _input(e_str) if (cnt == "n") or (cnt == "N"): if using_local_file is False: os.unlink(tb_file) sys.exit(1) elif (cnt == "y") or (cnt == "Y"): return False e_str = "Please enter y or n: " # Check if job was already there job = None if line in old_tab: for old_job in old_jobs: if old_job.interval == interval and old_job.command == cmd: job = old_job old_jobs.remove(old_job) break if not job: old_tab.discard(line) job = api.Job(interval, cmd, uid, datetime.now()) jobs.append(job) if using_local_file is False: os.unlink(tb_file) api.set_crontab("\n".join(crontab), uid) api.set_jobs(jobs, uid) return True
def wait_on_cron_schedule(creationDate, schedule): if schedule: if croniter.is_valid(schedule): cron = croniter(schedule, creationDate) nextdate = cron.get_next(datetime) while True: now = datetime.now().astimezone() # needs to be tz-aware to compare if now >= nextdate: print("finally reached!") break print("current time: " + now.strftime("%m/%d/%Y, %H:%M:%S")) print("didn't reach " + nextdate.strftime("%m/%d/%Y, %H:%M:%S")) time.sleep(5) else: print("invalid cron schedule") else: print("no cron schedule passed via env variables")
def get_next_schedule(base_datetime, schedule_type, schedule): if schedule_type == ScheduleType.CRONTAB: itr = croniter(schedule, base_datetime) next_schedule = itr.get_next(datetime) elif schedule_type == ScheduleType.INTERVAL: count, unit_name = schedule # count is the "number of units" and unit_name is the "unit name of interval" # which is inverse from what rrule calls them rule = rrule.rrule( freq=SCHEDULE_INTERVAL_MAP[unit_name], interval=count, dtstart=base_datetime, count=2) if rule[0] > base_datetime: next_schedule = rule[0] else: next_schedule = rule[1] else: raise NotImplementedError('unknown schedule_type') return next_schedule
def backupIfNeeded(self, cluster_object: V1MongoClusterConfiguration) -> bool: """ Checks whether a backup is needed for the cluster, backing it up if necessary. :param cluster_object: The cluster object from the YAML file. :return: Whether a backup was created or not. """ now = self._utcNow() cluster_key = (cluster_object.metadata.name, cluster_object.metadata.namespace) last_backup = self._last_backups.get(cluster_key) next_backup = croniter(cluster_object.spec.backups.cron, last_backup, datetime).get_next() \ if last_backup else now if next_backup <= now: self.backup(cluster_object, now) self._last_backups[cluster_key] = now return True logging.info("Cluster %s @ ns/%s will need a backup at %s.", cluster_object.metadata.name, cluster_object.metadata.namespace, next_backup.isoformat()) return False
def schedule_next_reboot(self, instances): for ec2inst in instances: ec2tags = self.taglist_to_dict(ec2inst['Tags']) if TAG_REBOOT_SCHEDULE in ec2tags.keys() and len(ec2tags[TAG_REBOOT_SCHEDULE]) >= 1: try: nextscheduledreboot = croniter( ec2tags[TAG_REBOOT_SCHEDULE], self.reference_time).get_next(datetime) # Create/Update tag if doesn't exist or is invalid if TAG_NEXT_SCHEDULED_REBOOT not in ec2tags.keys() or len(ec2tags[TAG_NEXT_SCHEDULED_REBOOT]) < 1 or nextscheduledreboot != ec2tags[TAG_NEXT_SCHEDULED_REBOOT]: self.client.create_tags( Resources=[ec2inst['InstanceId']], Tags=[ { 'Key': TAG_NEXT_SCHEDULED_REBOOT, 'Value': nextscheduledreboot.strftime("%Y-%m-%d %H:%M:%S UTC") } ] ) except ValueError: log.info("Instance {instance} has invalid cron syntax: {cron}".format( instance=ec2inst['InstanceId'], cron=ec2tags[TAG_REBOOT_SCHEDULE]))
def test_issue_142_dow(self): ret = [] for i in range(1, 31): ret.append((i, croniter('35 * 0-l/8 * *', datetime(2020, 1, i), ret_type=datetime).get_next()) ) i += 1 self.assertEqual( ret, [(1, datetime(2020, 1, 1, 0, 35)), (2, datetime(2020, 1, 8, 0, 35)), (3, datetime(2020, 1, 8, 0, 35)), (4, datetime(2020, 1, 8, 0, 35)), (5, datetime(2020, 1, 8, 0, 35)), (6, datetime(2020, 1, 8, 0, 35)), (7, datetime(2020, 1, 8, 0, 35)), (8, datetime(2020, 1, 8, 0, 35)), (9, datetime(2020, 1, 16, 0, 35)), (10, datetime(2020, 1, 16, 0, 35)), (11, datetime(2020, 1, 16, 0, 35)), (12, datetime(2020, 1, 16, 0, 35)), (13, datetime(2020, 1, 16, 0, 35)), (14, datetime(2020, 1, 16, 0, 35)), (15, datetime(2020, 1, 16, 0, 35)), (16, datetime(2020, 1, 16, 0, 35)), (17, datetime(2020, 1, 24, 0, 35)), (18, datetime(2020, 1, 24, 0, 35)), (19, datetime(2020, 1, 24, 0, 35)), (20, datetime(2020, 1, 24, 0, 35)), (21, datetime(2020, 1, 24, 0, 35)), (22, datetime(2020, 1, 24, 0, 35)), (23, datetime(2020, 1, 24, 0, 35)), (24, datetime(2020, 1, 24, 0, 35)), (25, datetime(2020, 2, 1, 0, 35)), (26, datetime(2020, 2, 1, 0, 35)), (27, datetime(2020, 2, 1, 0, 35)), (28, datetime(2020, 2, 1, 0, 35)), (29, datetime(2020, 2, 1, 0, 35)), (30, datetime(2020, 2, 1, 0, 35))])
def handle(self, *args, **options): utc = pytz.UTC for job in Job.objects.due(): for node in job.nodes.all(): '''spawn process for each node''' p = Process(target=ExecuteJob, kwargs={ 'node': node, 'job': job }) p.start() for node_group in job.node_groups.all(): for node in node_group.get_node_list(): '''spawn a process for each node''' p = Process(target=ExecuteJob, kwargs={ 'node': node, 'job': job }) p.start() job.last_run = datetime.utcnow().replace(tzinfo=timezone.utc) cron_string = "%s %s %s %s %s" % (job.minute, job.hour, job.day_of_week, job.month, job.day_of_month) frequency = croniter( cron_string, timezone.make_naive(job.last_run, timezone.get_current_timezone())) naive_next_run = frequency.get_next(datetime) tz = pytz.timezone('US/Central') d_tz = tz.normalize(tz.localize(naive_next_run)) utc = pytz.timezone('UTC') d_utc = d_tz.astimezone(utc) job.next_run = d_utc job.save()
def execution_time_iterator(self, start_timestamp): check.float_param(start_timestamp, "start_timestamp") timezone_str = ( self.execution_timezone if self.execution_timezone else pendulum.now().timezone.name ) start_datetime = pendulum.from_timestamp(start_timestamp, tz=timezone_str) date_iter = croniter(self.cron_schedule, start_datetime) # Go back one iteration so that the next iteration is the first time that is >= start_datetime # and matches the cron schedule date_iter.get_prev(datetime.datetime) while True: next_date = pendulum.instance(date_iter.get_next(datetime.datetime)).in_tz(timezone_str) # During DST transitions, croniter returns datetimes that don't actually match the # cron schedule, so add a guard here if croniter.match(self.cron_schedule, next_date): yield next_date
def _put(self, job, next_t=None, last_t=None): if next_t is None and not isinstance(job.interval, str): next_t = job.interval if next_t is None: raise ValueError('next_t is None') if isinstance(next_t, datetime.datetime): next_t = (next_t - datetime.datetime.now()).total_seconds() next_t += last_t or time.time() elif isinstance(next_t, datetime.time): next_datetime = datetime.datetime.combine(datetime.date.today(), next_t) if datetime.datetime.now().time() > next_t: next_datetime += datetime.timedelta(days=1) next_t = (next_datetime - datetime.datetime.now()).total_seconds() next_t += last_t or time.time() elif isinstance(next_t, datetime.timedelta): next_t = next_t.total_seconds() next_t += last_t or time.time() elif isinstance(job.interval, str): base = self._now() dt = croniter(job.interval, base).get_next(datetime.datetime) next_t = datetime.datetime.timestamp(dt) else: next_t += last_t or time.time() self.logger.debug('Putting job %s with t=%f', job.name, next_t) self._queue.put((next_t, job)) # Wake up the loop if this job should be executed next self._set_next_peek(next_t)
def main(): args = ARGS current_time = datetime.now() repo_path = os.path.expanduser(args.repo_path) config_dir = f'{repo_path}config/' config_file_list = get_config_list(config_dir) bash_command_list = [] for config_file_path in config_file_list: with open(config_file_path) as config_file: config_list = yaml.safe_load(config_file)['config'] for config in config_list: for schedule in config['schedules']: cron = croniter(schedule, current_time) prev_schedule_time = datetime.utcfromtimestamp( cron.get_prev()) next_schedule_time = datetime.utcfromtimestamp( cron.get_next()) if abs(prev_schedule_time.timestamp() - current_time.timestamp()) < abs( next_schedule_time.timestamp() - current_time.timestamp()): schedule_time_to_use = prev_schedule_time else: schedule_time_to_use = next_schedule_time if (current_time - timedelta(minutes=2) ).timestamp() < schedule_time_to_use.timestamp( ) <= current_time.timestamp(): bash_command_list.append(config['bash_command']) pool = Pool(processes=20) results = pool.map(execute_bash_command, bash_command_list) pool.close() pool.join()
def BuildAmortization(self): """Conditionally run by AddAccount in GeneralLedger.""" if not self.start_date: logging.warn( '%s: Cannot build an amortization schedule without a start date', self.name) return if self.value > 0: logging.warn( '%s: Accounts with start date are expected to be loans and have a ' 'negative value.', self.name) return monthly_rate = self.rate / 12 # Balance is negative, we want P&I in positive. balance = -self.value if self.loan_months: numerator = monthly_rate * balance * ( 1 + monthly_rate)**self.loan_months denominator = (1 + monthly_rate)**self.loan_months - 1 self._payment = numerator / denominator start_epoch = int(self.start_date.strftime('%s')) # Duplicate self.timespec but with a start date. Building a non-monthly # scheduled could be done, but requires more thought. monthly = croniter.croniter(' '.join(self.timespec.exprs), start_epoch) for _ in xrange(self.loan_months): #build a schedule current = monthly.get_current(datetime.datetime).date() interest = monthly_rate * balance principle = self._payment - interest balance -= principle self._amortization[current] = (interest, principle) monthly.get_next() else: # No timeframe, assume interest only self._payment = balance * monthly_rate