Beispiel #1
0
 def test_match(self):
     self.assertTrue(
         croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 0, 0, 0)))
     self.assertFalse(
         croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 1, 0, 0)))
     self.assertTrue(
         croniter.match("31 * * * *", datetime(2019, 1, 14, 1, 31, 0, 0)))
Beispiel #2
0
 def test_match(self):
     self.assertTrue(
         croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 0, 0, 0)))
     self.assertFalse(
         croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 1, 0, 0)))
     self.assertTrue(
         croniter.match("31 * * * *", datetime(2019, 1, 14, 1, 31, 0, 0)))
     self.assertTrue(
         croniter.match("0 0 10 * wed",
                        datetime(2020, 6, 10, 0, 0, 0, 0),
                        day_or=True))
     self.assertTrue(
         croniter.match("0 0 10 * fri",
                        datetime(2020, 6, 10, 0, 0, 0, 0),
                        day_or=True))
     self.assertTrue(
         croniter.match("0 0 10 * fri",
                        datetime(2020, 6, 12, 0, 0, 0, 0),
                        day_or=True))
     self.assertTrue(
         croniter.match("0 0 10 * wed",
                        datetime(2020, 6, 10, 0, 0, 0, 0),
                        day_or=False))
     self.assertFalse(
         croniter.match("0 0 10 * fri",
                        datetime(2020, 6, 10, 0, 0, 0, 0),
                        day_or=False))
     self.assertFalse(
         croniter.match("0 0 10 * fri",
                        datetime(2020, 6, 12, 0, 0, 0, 0),
                        day_or=False))
Beispiel #3
0
 def check(self,
           text_preprocessing_result: BaseTextPreprocessingResult,
           user: BaseUser,
           params: Dict[str, Any] = None) -> bool:
     message_time_dict = user.message.payload['meta']['time']
     message_timestamp_sec = message_time_dict['timestamp'] // 1000
     message_datetime = datetime.fromtimestamp(message_timestamp_sec)
     return croniter.match(self.match_cron, message_datetime)
Beispiel #4
0
 async def tick(self):
     current = self._now()
     for k, v in self.userdata.items():
         if croniter.match(v["schedule"], current):
             cmd = v["command"]
             ch = self.bot.get_channel(v["channel_id"])
             await ch.send(f"{cmd}")
             logger.debug(f"Runned `{cmd}`.")
     presence_type = ActivityType.listening
     await self.bot.change_presence(activity=Activity(type=presence_type,
                                                      name="Cron"),
                                    status=None)
     logger.debug("tick")
Beispiel #5
0
    def timer_active_check(cls, time_spec, now):
        """Check if the given time matches the time specification."""
        results = {"+": [], "-": []}
        for entry in time_spec if isinstance(time_spec, list) else [time_spec]:
            this_match = False
            negate = False
            active_str = entry.strip()
            if active_str.startswith("not"):
                negate = True
                active_str = active_str.replace("not ", "")

            cron_match = re.match(r"cron\((?P<cron_expr>.*)\)", active_str)
            range_expr = re.match(r"range\(([^,]+),\s?([^,]+)\)", active_str)
            if cron_match:
                if not croniter.is_valid(cron_match.group("cron_expr")):
                    _LOGGER.error("Invalid cron expression: %s", cron_match)
                    return False

                this_match = croniter.match(cron_match.group("cron_expr"), now)

            elif range_expr:
                try:
                    dt_start, dt_end = range_expr.groups()
                except ValueError as exc:
                    _LOGGER.error("Invalid range expression: %s", exc)
                    return False

                start = cls.parse_date_time(dt_start.strip(), 0, now)
                end = cls.parse_date_time(dt_end.strip(), 0, start)

                if start < end:
                    this_match = start <= now <= end
                else:  # Over midnight
                    this_match = now >= start or now <= end

            if negate:
                results["-"].append(not this_match)
            else:
                results["+"].append(this_match)

        # An empty spec, or only neg specs, is True
        result = any(
            results["+"]) if results["+"] else True and all(results["-"])

        return result
Beispiel #6
0
    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
Beispiel #7
0
    def handle(self, *args, **options):
        # wait until :00 second
        now = timezone.localtime()
        wait_secs = 59 - now.second
        print('Current time: %s, wait for %s seconds' %
              (now.isoformat(), wait_secs))
        sleep(wait_secs)

        while True:
            # query every minute
            now = timezone.localtime()
            print('Current time: %s, check tasks..' % now.isoformat())

            tasks = Task.objects.filter(enabled=True)
            for task in tasks:
                if croniter.match(task.cron, now):
                    # play task
                    print('  task %s (%s) matches, text=%s' %
                          (task.id, task.cron, task.text))
                    play_mp3(task.voice_file())

            sleep(60)
Beispiel #8
0
def launch_scheduled_runs_for_schedule(
    instance,
    logger,
    schedule_state,
    repo_location,
    end_datetime_utc,
    max_catchup_runs,
    debug_crash_flags=None,
):
    check.inst_param(instance, "instance", DagsterInstance)
    check.inst_param(schedule_state, "schedule_state", ScheduleState)
    check.inst_param(end_datetime_utc, "end_datetime_utc", datetime.datetime)
    check.inst_param(repo_location, "repo_location", RepositoryLocation)

    latest_tick = instance.get_latest_tick(schedule_state.schedule_origin_id)

    if not latest_tick:
        start_timestamp_utc = schedule_state.start_timestamp
    elif latest_tick.status == ScheduleTickStatus.STARTED:
        # Scheduler was interrupted while performing this tick, re-do it
        start_timestamp_utc = latest_tick.timestamp
    else:
        start_timestamp_utc = latest_tick.timestamp + 1

    schedule_name = schedule_state.name

    repo_dict = repo_location.get_repositories()
    check.invariant(
        len(repo_dict) == 1, "Reconstructed repository location should have exactly one repository",
    )
    external_repo = next(iter(repo_dict.values()))

    external_schedule = external_repo.get_external_schedule(schedule_name)

    timezone_str = external_schedule.execution_timezone
    if not timezone_str:
        logger.error(
            "Scheduler could not run for {schedule_name} as it did not specify "
            "an execution_timezone in its definition.".format(schedule_name=schedule_name)
        )
        return

    end_datetime = end_datetime_utc.in_tz(timezone_str)
    start_datetime = pendulum.from_timestamp(start_timestamp_utc, tz=timezone_str)

    date_iter = croniter(external_schedule.cron_schedule, start_datetime)
    tick_times = []

    # 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)
        if next_date.timestamp() > end_datetime.timestamp():
            break

        # During DST transitions, croniter returns datetimes that don't actually match the
        # cron schedule, so add a guard here
        if croniter.match(external_schedule.cron_schedule, next_date):
            tick_times.append(next_date)

    if not tick_times:
        logger.info("No new runs for {schedule_name}".format(schedule_name=schedule_name))
        return

    if len(tick_times) > max_catchup_runs:
        logger.warn(
            "{schedule_name} has fallen behind, only launching {max_catchup_runs} runs".format(
                schedule_name=schedule_name, max_catchup_runs=max_catchup_runs
            )
        )
        tick_times = tick_times[-max_catchup_runs:]

    if len(tick_times) == 1:
        logger.info(
            "Launching run for {schedule_name} at {time}".format(
                schedule_name=schedule_name,
                time=tick_times[0].strftime(_SCHEDULER_DATETIME_FORMAT),
            )
        )
    else:
        logger.info(
            "Launching {num_runs} runs for {schedule_name} at the following times: {times}".format(
                num_runs=len(tick_times),
                schedule_name=schedule_name,
                times=", ".join([time.strftime(_SCHEDULER_DATETIME_FORMAT) for time in tick_times]),
            )
        )

    for tick_time in tick_times:
        schedule_time = pendulum.instance(tick_time).in_tz(timezone_str)
        schedule_timestamp = schedule_time.timestamp()

        if latest_tick and latest_tick.timestamp == schedule_timestamp:
            tick = latest_tick
            logger.info("Resuming previously interrupted schedule execution")

        else:
            tick = instance.create_schedule_tick(
                ScheduleTickData(
                    schedule_origin_id=external_schedule.get_origin_id(),
                    schedule_name=schedule_name,
                    timestamp=schedule_timestamp,
                    cron_schedule=external_schedule.cron_schedule,
                    status=ScheduleTickStatus.STARTED,
                )
            )

            _check_for_debug_crash(debug_crash_flags, "TICK_CREATED")

        with ScheduleTickHolder(tick, instance, logger) as tick_holder:

            _check_for_debug_crash(debug_crash_flags, "TICK_HELD")

            _schedule_run_at_time(
                instance,
                logger,
                repo_location,
                external_repo,
                external_schedule,
                schedule_time,
                tick_holder,
                debug_crash_flags,
            )
Beispiel #9
0
 def test_issue151(self):
     """."""
     self.assertTrue(
         croniter.match("* * * * *", datetime(2019, 1, 14, 11, 0, 59, 999999)))
Beispiel #10
0
 def should_execute(self):
     if not self.is_active:
         return False
     return croniter.match(self.schedule, datetime.utcnow())
Beispiel #11
0
def matchCron(t, cron):
    return croniter.match(cron, t)