Пример #1
0
async def manage_schedule(context, conn, app):
    username = context["username"]
    if context["schedule"] or context["window"]:
        await set_schedule(username, conn, context.get("schedule"),
                           context.get("window"))
        schedule, window = await get_schedule(username, conn)
        print("New schedule for user %s: %s (within %s hour(s))" %
              (username, get_description(schedule), window))
        regenerate_reminder_for_user(
            schedule,
            username,
            window,
            datetime.now(pytz.timezone(context["timezone"])),
            app,
        )
    else:
        row = await get_schedule(username, conn)
        if not row:
            print(
                "User %s has no schedule. Set one with e.g. "
                '/phb schedule --username %s --schedule "0 9 * * 1-5" --window 3'
                % (username, username))
            return
        schedule, window = row
        print("User %s's schedule: %s (within %d hour(s))" %
              (username, get_description(schedule), window))
Пример #2
0
    def test_second_minutes_hours_intervals(self):

        self.assertEqual(("Seconds 5 through 10 past the minute, "
                          "minutes 30 through 35 past the hour, "
                          "between 10:00 AM and 12:59 PM"),
                         get_description("5-10 30-35 10-12 * * *",
                                         self.options))
Пример #3
0
    def cron_translate(self, cron_slices):
        '''Translates cron job into human redable'''

        raw_result = get_description(cron_slices)
        final_result = [x.strip() for x in raw_result.split(',')]

        return final_result
Пример #4
0
    def test_day_of_week_modifier_with_sunday_start_one(self):

        options = Options()
        options.day_of_week_start_index_zero = False

        self.assertEqual("At 12:23 PM, on the second Sunday of the month",
                         get_description("23 12 * * 1#2", options))
Пример #5
0
    def test_between_with_interval(self):

        self.assertEqual((
            "Every 03 minutes, minutes 02 through 59 past the hour, "
            "at 01:00 AM, 09:00 AM, and 10:00 PM, between day 11 and 26 of the month, "
            "January through June"),
                         get_description("2-59/3 1,9,22 11-26 1-6 ?"))
Пример #6
0
    def test_every_2_day_of_the_week_in_range_with_sunday_start_one(self):
        options = Options()
        options.day_of_week_start_index_zero = False

        self.assertEqual(
            "Every second, every 2 days of the week, Monday through Friday",
            get_description("* * * ? * 2-6/2", options))
Пример #7
0
def get_schedule(service_type):
    import json
    import pandas as pd
    from cron_descriptor import get_description

    data = []
    for key, info in gramex.conf.get(service_type, {}).items():
        entry = dict(info)
        entry['name'] = key
        entry['args'] = json.dumps(entry.get('args', []))
        entry['kwargs'] = json.dumps(entry.get('kwargs', {}))
        entry['schedule'] = ''
        if key not in gramex.service[service_type]:
            entry['schedule'] = 'NA'
            data.append(entry)
            continue
        schedule = gramex.service[service_type][key]
        entry['next'] = schedule.next * 1000 if schedule.next else None
        if hasattr(schedule, 'cron_str'):
            cron = schedule.cron_str
            # cron_descriptor requires year to start with a number
            if cron.endswith(' *'):
                cron = cron[:-2]
            entry['schedule'] = get_description(cron)
            entry['schedule'] += ' UTC' if schedule.utc else ''
        entry['startup'] = 'Y' if entry.get('startup', False) else ''
        entry['thread'] = 'Y' if entry.get('thread', False) else ''
        data.append(entry)
    return pd.DataFrame(data)
Пример #8
0
    def test_minutes_past_the_hour_range(self):

        self.assertEqual(("At 30 minutes past the hour, "
                          "between 10:00 AM and 01:59 PM, "
                          "only on Wednesday and Friday"),
                         get_description("0 30 10-13 ? * WED,FRI",
                                         self.options))
Пример #9
0
def activate_cron_job(cronjob_from_request, cron_job):
    cronjob_raw_expression = cron_job.expression
    cronjob_converted_expression = get_description(cronjob_raw_expression)
    script_command = cron_job.command
    if (cronjob_from_request['log']['logFile']
            & cronjob_from_request['log']['sendMail']):
        command = MyCronTab.cmd_woutput_log_mail(
            script_command, str(cron_job.id),
            cronjob_from_request['description'])
    elif (cronjob_from_request['log']['sendMail']):
        command = MyCronTab.cmd_woutput_mail(
            script_command, cronjob_from_request['description'])
    elif (cronjob_from_request['log']['logFile']):
        command = MyCronTab.cmd_woutput_log(script_command, str(cron_job.id))

    status = "On Hold"

    if (platform.system() == 'Windows'):
        cron = CronTab()
        script_path = ''
    else:
        cron = CronTab(user='******')
        script_body = MyCronTab.create_cron_shell_script(cron_job.id, command)
        script_path = MyCronTab.write_cron_shell_file(cron_job.id, script_body)

        job = cron.new(command='/bin/bash {0}'.format(script_path),
                       comment=str(cron_job.id))
        job.setall(cronjob_raw_expression)
        print("job: ", job)
        print("job.is_valid? ", job.is_valid())
        if job.is_valid():
            status = "Enabled"
            cron.write(user='******')
            nextRun = datetime.datetime.now().strftime("%Y-%m-%d")
    return status
Пример #10
0
    def hf_schedule(self) -> str:
        sch = self.schedule_as_string
        if "seconds" in sch and self.seconds:
            result = f"Every {self.seconds // 60} minutes"
        else:
            result = get_description(sch)

        result = result.replace("00:00 AM", "midnight")
        return result
Пример #11
0
def convert_cron_job():
    cronjob_from_request = request.get_json()
    cronjob_to_convert = cronjob_from_request['expression']
    print("cronjob_to_convert", cronjob_to_convert)
    try:
        converted = get_description(cronjob_to_convert)
        return jsonify(converted_cron_job=converted, status="ok")
    except Exception:
        return jsonify(converted_cron_job="", status="error")
Пример #12
0
    def get_readable_cron(self):
        """If the job is scheduled, return the cron syntax and a human readable version of the cron syntax."""
        periodic_task = self.get_periodic_task()
        if periodic_task:
            crontab_lst = str(periodic_task.crontab).split(" ")
            crontab = " ".join(crontab_lst[:len(crontab_lst) - 2])

            return crontab, get_description(crontab)
        else:
            return "", "Manual"
Пример #13
0
async def get_all_schedules(context, conn):
    async with conn.execute(
            "SELECT username, schedule, window FROM schedule", ) as cur:
        schedules = await cur.fetchall()
    if not schedules:
        print("No users registered.")
    print("Standup schedules: ")
    for username, schedule, window in schedules:
        print("  * %s: %s (within %d hour(s))" %
              (username, get_description(schedule), window))
Пример #14
0
 def post(self):
     try:
         cron_expression = request.form.get('expression', None)
         if cron_expression:
             expression = get_description(cron_expression,
                                          options=self.options)
             return {'description': str(expression)}, 200
         else:
             return make_response(('', 200))
     except Exception as e:
         return {'err': 'not valid %s' % e}, 500
Пример #15
0
    def checktimeplan(self):
        """Checks timeplan and prints description"""

        valid = crontab.CronSlices.is_valid(self.jobtimeplan)
        if valid:
            timedesc = get_description(self.jobtimeplan)
            lineprint("Your timeplan will run " + timedesc)
        else:
            lineprint("Timeplan is not valid..")

        return valid
Пример #16
0
def validate_cron(cron_str):
    valid_chars = '-/,*0123456789 '
    e = t('Невалидная нотация. Строка должна содержать только знаки {0}'
          ', и четыре одинарных пробела. Удобно настроить и скопировать строку'
          ' можно здесь{1}')
    e = e.format(valid_chars, ' - https://crontab.guru/')
    try:
        pycron.is_now(cron_str)
        cron_descriptor.get_description(cron_str)
    except Exception:
        raise ValidationError(e)
    spaces_counter = 0
    for char in cron_str:
        if char == ' ':
            spaces_counter += 1
        if char not in valid_chars:
            raise ValidationError(e)
    if spaces_counter != 4:
        raise ValidationError(e)
    return cron_str
Пример #17
0
def build_schedule_html(html_top: str = "<div>",
                        html_bottom: str = "</div>") -> str:
    """Create a basic HTML table with the currently scheduled jobs.

    Args:
        html_top (str, optional): HTML to go before the table. Defaults to "<div>".
        html_bottom (str, optional): HTML to go at hte end of the table. Defaults to
        "</div>".

    Returns:
        str: HTML code.
    """

    # Ensure scheduler is shut down, then re-add jobs and retrieve scheduled jobs from okr/scrapers/scheduler.py
    scheduler.setup()
    scheduler.scheduler.shutdown()
    scheduler.add_jobs()
    jobs_list = scheduler.scheduler.get_jobs()

    options = Options()
    options.locale_code = "de_DE"
    options.use_24hour_time_format = True

    # parse and convert job information into list
    table_lines = []
    for job in jobs_list:
        cron_expression = " ".join(map(str, reversed(job.trigger.fields[1:])))
        table_lines.append([
            parse_job_info_method(job),
            get_description(cron_expression, options=options),
        ])

    # sort list by module and reformat to a module.method format (instead of library.module.method)
    formatted_list = sorted(table_lines, key=itemgetter(0))
    for entry in formatted_list:
        args_idx = entry[0].index("(")
        path = entry[0][:args_idx]
        rest = entry[0][args_idx:]

        path = ".".join(path.split(".")[-2:])
        entry[0] = f"{path}{rest}"

    # convert jobs list into HTML table
    table_contents = tabulate(
        formatted_list,
        headers=["Aufgerufene Methode", "Zeitschema"],
        tablefmt="html",
    )

    return str(html_top + table_contents + html_bottom)
Пример #18
0
    def cron_check(self, setall_string, command):
        desc = None
        is_valid = False
        try:
            desc = get_description(setall_string)
            if desc:
                is_valid = True

            if not command.startswith('curl'):
                error = 'Only curl allowed!'
        except Exception:
            pass

        return is_valid, desc
Пример #19
0
    def handle(self, arguments, user, **kwargs):
        if not arguments:
            raise exceptions.HandleError(
                'You need to provide a crontab expression such as `1 * 2 * *`',
                code='missing_arg')
            tz = arguments

        try:
            description = cron_descriptor.get_description(arguments)
        except cron_descriptor.FormatException as e:
            raise exceptions.HandleError(
                '{0} is not a valid crontab expression: {1}'.format(
                    arguments, str(e)),
                code='invalid_arg')
        return {'description': description, 'crontab': arguments}
Пример #20
0
def describe_cron(request):
    cron_str = request.GET.get('cron_str', '')
    try:
        err = ''
        res = cron_descriptor.get_description(cron_str)
    except Exception as e:
        err = e
        res = 'Невалидный крон'
    return JsonResponse({
        "e": str(err),
        "cron_verb": res
    },
                        safe=False,
                        json_dumps_params={
                            'indent': 4,
                            'ensure_ascii': False
                        })
Пример #21
0
    def get_scheduled_jobs(self):
        # Grab job templates
        run_list = self.get('/jobs/list')['jobs']

        # Filter all the jobs that have a schedule defined
        scheduled_jobs = filter(lambda x: x['settings'].has_key('schedule'),
                                run_list)
        jobs_list = []
        for x in scheduled_jobs:
            y = dict()
            y['creator_user_name'] = x['creator_user_name']
            y['job_id'] = x['job_id']
            y['job_name'] = x['settings']['name']
            y['created_time'] = datetime.datetime.fromtimestamp(
                x['created_time'] / 1000.0).strftime('%Y-%m-%d %H:%M:%S.%f')
            y['schedule'] = get_description(
                x['settings']['schedule']['quartz_cron_expression'])
            jobs_list.append(y)
        return jobs_list
Пример #22
0
def parse_cron(expression: str) -> Tuple[str, str]:
    if '?' in expression:
        raise InvalidCronException(f"Cannot parse the cron expression: '?' symbols are not allowed\n"
                                   f"Please use https://crontab.guru/#{expression.replace(' ', '_')} as a reference.")
    try:
        human_readable_description = get_description(expression)
        aws_cron = _cron_to_aws_cron(expression)
    except FormatException as e:
        raise InvalidCronException(f"Cannot parse the cron expression: {str(e)}\n You can find out what part of your "
                                   "expression is not written in a standard notation by following this link "
                                   f"https://crontab.guru/#{expression.replace(' ', '_')}.")
    except ValueError as e:
        if 'too many values to unpack (expected 5)' in str(e):
            raise InvalidCronException("Currently we support only cron expressions that consist of 5 parts. "
                                       "Your expression had more. "
                                       "If you have any questions please shoot an email at [email protected]")
        else:
            raise e
    return aws_cron, human_readable_description
Пример #23
0
def format_trigger(trigger: Union[CronTrigger, DateTrigger]) -> Text:
    """
    Format a trigger to human readable format.
    """
    if isinstance(trigger, CronTrigger):
        trigger_fields = {field.name: str(field) for field in trigger.fields}
        description = remove_first_cap(
            cron_descriptor.get_description(
                f"{trigger_fields['minute']} {trigger_fields['hour']} {trigger_fields['day']} "
                f"{trigger_fields['month']} {trigger_fields['day_of_week']}").
            replace("only on", "every"))
        if trigger_fields["day"] == "*" and trigger_fields[
                "day_of_week"] == "*":
            description = f"{description}, every day"
        elif trigger_fields["week"].startswith("*/"):
            week_interval = int(trigger_fields["week"][2:])
            week_interval_ordinal = ("other" if week_interval == 2 else
                                     format_ordinal(week_interval))
            description = f"{description}, every {week_interval_ordinal} week"

        return description

    return trigger.run_date.strftime("on %A %B %-d at %I:%M %p")
def generate_cron_job(session, cronjob_to_save, status, nextRun):

    if cronjob_to_save["creationDate"] is None:
        cronjob_to_save["creationDate"] = datetime.datetime.now().strftime(
            "%Y-%m-%d, %H:%M:%S")
    nextRun = datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S")
    #expression = cronjob_to_save["minute"]+" "+ cronjob_to_save["hour"]+" "+cronjob_to_save["day"]+" "+cronjob_to_save["month"]+" "+cronjob_to_save["weekDay"]
    expression = cronjob_to_save["expression"]
    schedule = get_description(expression)
    cron_job = CronJob(
        datetime.datetime.now(),
        cronjob_to_save["command"],
        cronjob_to_save["type"],
        schedule,
        expression,
        cronjob_to_save["lastRun"],
        status,
        nextRun,
    )

    session.add(cron_job)
    session.flush()
    print(cron_job.id)
    return cron_job, ' was scheduled successfully', True
Пример #25
0
    def get_message(self, session, item):
        failed_task_attachments = None

        if isinstance(item, WorkflowInstance):
            item_type = 'Workflow'
            name = item.workflow_name

            failed_tasks = session.query(TaskInstance)\
                .filter(TaskInstance.workflow_instance_id == item.id,
                        TaskInstance.status == 'failed')\
                .all()

            failed_task_attachments = []
            for failed_task in failed_tasks:
                failed_task_attachments.append({
                    'title':
                    'Failed Workflow Task',
                    'color':
                    '#ff0000',
                    'fields': [{
                        'title': 'Task',
                        'value': failed_task.task_name
                    }, {
                        'title': 'ID',
                        'value': failed_task.id
                    }, {
                        'title': 'Number of Attempts',
                        'value': failed_task.attempts
                    }, {
                        'title': 'Logs',
                        'value': self.get_log_url(failed_task)
                    }]
                })
        else:
            item_type = 'Task'
            name = item.task_name

        attachments = [{
            'title':
            '{} Failure'.format(item_type),
            'text':
            '<!channel> A {} in Taskflow failed'.format(item_type.lower()),
            'color':
            '#ff0000',
            'fields': [{
                'title': item_type,
                'value': name,
                'short': False
            }, {
                'title': 'ID',
                'value': item.id
            }, {
                'title': 'Priority',
                'value': item.priority
            }, {
                'title': 'Scheduled Run Time',
                'value': '{:%Y-%m-%d %H:%M:%S}'.format(item.run_at)
            }, {
                'title': 'Start Time',
                'value': '{:%Y-%m-%d %H:%M:%S}'.format(item.started_at)
            }, {
                'title': 'Failure Time',
                'value': '{:%Y-%m-%d %H:%M:%S}'.format(item.ended_at)
            }]
        }]

        if item.scheduled:
            if isinstance(item, WorkflowInstance):
                schedulable = self.taskflow.get_workflow(item.workflow_name)
            else:
                schedulable = self.taskflow.get_task(item.task_name)
            attachments[0]['fields'].append({
                'title':
                'Schedule',
                'value':
                '{} ({})'.format(get_description(schedulable.schedule),
                                 schedulable.schedule)
            })

        if failed_task_attachments:
            attachments += failed_task_attachments
        else:
            attachments[0]['fields'].append({
                'title': 'Number of Attempts',
                'value': item.attempts
            })
            attachments[0]['fields'].append({
                'title': 'Logs',
                'value': self.get_log_url(item)
            })

        return {'attachments': attachments}
Пример #26
0
 def schedule(self):
     # FIXME this is a mess
     om = get_omega(self.args)
     name = self.args.get('<name>')
     at = self.args.get('--at')
     # get interval specs
     if at:
         hour, minute = at.split(':')
     else:
         hour = self.args.get('--hour')
         minute = self.args.get('--minute')
     weekday = self.args.get('--weekday')
     monthday = self.args.get('--monthday')
     month = self.args.get('--month')
     delete = self.args.get('delete')
     show = self.args.get('show')
     spec = self.args.get('--cron')
     next_n = self.args.get('--next')
     interval = self.args.get('<interval>')
     # by default we show if no interval is specified
     show = show or not any(s for s in (weekday, monthday, month, hour, minute, interval, spec))
     # print current schedule and triggers
     run_at, triggers = om.jobs.get_schedule(name, only_pending=True)
     if run_at:
         human_sched = get_description(run_at)
         self.logger.info("Currently {name} is scheduled at {human_sched}".format(**locals()))
         if next_n:
             self.logger.info("Given this existing interval, next {next_n} times would be:".format(**locals()))
             for time in om.jobs.Schedule.from_cron(run_at).next_times(int(next_n)):
                 self.logger.info("  {}".format(time))
     else:
         self.logger.info("Currently {name} is not scheduled".format(**locals()))
     # show current triggers
     if triggers:
         trigger = triggers[-1]
         if trigger['status'] == 'PENDING':
             event = trigger['event']
             self.logger.info("{name} is scheduled to run next at {event}".format(**locals()))
     # delete if currently scheduled
     if delete:
         if run_at or triggers:
             answer = self.ask("Do you want to delete this schedule?", options='Y/n', default='y')
             should_drop = answer.lower().startswith('y')
             return om.jobs.drop_schedule(name) if should_drop else None
     # create new schedule
     if not (show or delete):
         if interval:
             try:
                 # nlp text-like
                 spec = om.jobs.Schedule(interval).cron
             except Exception as e:
                 self.logger.info(f"Cannot parse {interval}, error was {e}")
                 raise
         if not spec:
             cron_repr = ('{0._orig_minute} {0._orig_hour} {0._orig_day_of_month} '
                          '{0._orig_month_of_year} {0._orig_day_of_week}')
             sched = om.jobs.Schedule(minute=minute or '*',
                                      hour=hour or '*',
                                      monthday=monthday or '*',
                                      weekday=weekday or '*',
                                      month=month or '*')
             cron_sched = sched.cron
         else:
             cron_sched = spec
         human_sched = get_description(cron_sched)
         if next_n:
             self.logger.info("Given this new interval, next {next_n} times would be:".format(**locals()))
             for time in om.jobs.Schedule.from_cron(cron_sched).next_times(int(next_n)):
                 self.logger.info("  {}".format(time))
         text = "Do you want to schedule {name} at {human_sched}?".format(**locals())
         answer = self.ask(text, options="Y/n", default='y')
         if answer.lower().startswith('n'):
             self.logger.info('Ok, not scheduled. Try again.')
             return
         self.logger.info('{name} will be scheduled to run {human_sched}'.format(**locals()))
         om.jobs.schedule(name, run_at=cron_sched, last_run=datetime.datetime.now())
Пример #27
0
 def crontab_humanized(self) -> str:
     return get_description(self.crontab)
Пример #28
0
 def text(self):
     """ return the human readable representation of the schedule """
     from cron_descriptor import get_description
     return get_description(self.cron)
Пример #29
0
def handle_command(user, command, channel):
    """
        Executes bot command if the command is known

        Args:
            user: Slack user ID
            command: Command string
            channel: Originating Slack channel
    """
    # Default response is help text for the user
    default_response = "Sorry, I am not sure what you mean. Try _*@Xarvis help*_ to see what I can help you with\n"

    # Finds and executes the given command, filling in response
    response = None
    # This is where you start to implement more commands!
    if command.lower().startswith("schedule "):
        command_split = command.split("schedule ")
        if command_split[1].lower().startswith("list"):
            response = "*Scheduled jobs*\n"
            for key in JOBS:
                response += "- " + JOBS[key]["title"] + "\n"
        else:
            partial_reponse = ""
            for key in JOBS:
                description = pretty_cron.prettify_cron(JOBS[key]["sequence"])
                if description == JOBS[key]["sequence"]:
                    description = get_description(description)
                description = description[0].lower() + description[1:]
                if command_split[1].lower() in JOBS[key]["title"].lower(
                ) or JOBS[key]["title"].lower() in command_split[1].lower():
                    partial_reponse += "*" + JOBS[key]["title"] + "*\n" \
                                                                  "- Runs " + description + " (ET)\n"
            if len(partial_reponse) > 0:
                response = "Job scheduled time(s)\n" + partial_reponse
    elif command.lower().startswith("help"):
        response = "Hey there, following are the queries that I am trained to help you with as of now,\n" \
                   "- *schedule list* - _Get a list of cron pattern based scheduled jobs stored_\n" \
                   "- *schedule <job_name>* - _Get the scheduled time of a specific job_\n" \
                   "- *holidays* - _Get the list of US holidays for the year_\n" \
                   "- *calc <expression>* - _Do a calculation_\n" \
                   "- *execute <job_name> <optional parameters>* - _Execute a predifined job_\n" \
                   "Use *@Xarvis _command_* to ask me something"
    elif command.lower().startswith("holidays"):
        now = datetime.datetime.now()
        response = "US public holidays\n"
        for date, name in sorted(holidays.US(years=now.year).items()):
            response += "- " + "*" + date.strftime(
                "%A") + "*, " + date.strftime("%B %d ") + date.strftime(
                    ", %Y") + ": " + name + "\n"
    elif "thank" in command.lower() or "thanks" in command.lower():
        response = "You are welcome <@" + user + ">"
    elif command.lower().startswith("calc "):
        command_split = command.split("calc ")
        try:
            result = eval(command_split[1])
            if isinstance(result, numbers.Real):
                response = "<@" + user + ">, result: " + str(result)
            else:
                response = "<@" + user + ">, invalid mathematical expression"
        except:
            response = "<@" + user + ">, invalid mathematical expression"
    elif "hi" in command.lower() or "hey" in command.lower():
        response = "Hey <@" + user + ">, Try _*@Xarvis help*_ to see what I can help you with"
    elif command.lower().startswith("execute"):
        response = handlers.tasks.execute_task(
            command.lower().strip()[8:].split(" "), TASKS)

    # Sends the response back to the channel
    SLACK_CLIENT.api_call("chat.postMessage",
                          channel=channel,
                          text=response or default_response)
Пример #30
0
 def text(self):
     from cron_descriptor import get_description
     return get_description(self.cron)