Ejemplo n.º 1
0
 def test_none_cron_expression_error(self):
     options = Options()
     options.throw_exception_on_parse_error = False
     ceh = ExpressionDescriptor(None, options)
     self.assertEqual(
         "Field 'ExpressionDescriptor.expression' not found.",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 2
0
 def test_inline_import(self):
     from cron_descriptor import Options, DescriptionTypeEnum, ExpressionDescriptor
     options = Options()
     options.use_24hour_time_format = True
     ceh = ExpressionDescriptor("* * * * *", options)
     self.assertEqual("Every minute",
                      ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 3
0
 def test_invalid_cron_expression_error(self):
     options = Options()
     options.throw_exception_on_parse_error = False
     ceh = ExpressionDescriptor("INVALID CRON", options)
     self.assertEqual(
         "Error: Expression only has 2 parts.  At least 5 part are required.",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 4
0
 def test_invalid_cron_expression_error(self):
     options = Options()
     options.throw_exception_on_parse_error = False
     ceh = ExpressionDescriptor("INVALID CRON", options)
     self.assertEqual(
         "Error: Expression only has 2 parts.  At least 5 part are required.",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 5
0
 def test_title_casing(self):
     options = Options()
     options.casing_type = CasingTypeEnum.Title
     ceh = ExpressionDescriptor("* * * * *", options)
     self.assertEqual(
         "Every Minute",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 6
0
def get_pretty(expression):
    import sys

    # By default the module is installed in the 2.7 branch, pyotherside uses python 3
    # We use a custom location
    sys.path.append("/usr/share/harbour-sailcron/python/")
    # https://github.com/Salamek/cron-descriptor
    from cron_descriptor import Options, CasingTypeEnum, DescriptionTypeEnum, ExpressionDescriptor
    import subprocess

    # get proper 24/12 hour notation and strip output
    output = subprocess.check_output("/usr/bin/dconf read /sailfish/i18n/lc_timeformat24h", shell=True)
    output = str(output).replace("'", "").replace('b"', "").replace('\\n"', "").strip()
    if output == "24":
        is24h = True
    else:
        is24h = False

    # set options
    options = Options()
    options.throw_exception_on_parse_error = False
    options.casing_type = CasingTypeEnum.Sentence
    options.use_24hour_time_format = is24h
    descripter = ExpressionDescriptor(expression, options)
    human_format = descripter.get_description(DescriptionTypeEnum.FULL)

    return human_format
Ejemplo n.º 7
0
 def test_full(self):
     options = Options()
     options.use_24hour_time_format = True
     ceh = ExpressionDescriptor("* * * * *", options)
     self.assertEqual(
         "Every minute",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 8
0
 def test_lower_casing(self):
     options = Options()
     options.casing_type = CasingTypeEnum.LowerCase
     ceh = ExpressionDescriptor("* * * * *", options)
     self.assertEqual(
         "every minute",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 9
0
 def test_inline_import(self):
     from cron_descriptor import Options, DescriptionTypeEnum, ExpressionDescriptor
     options = Options()
     options.use_24hour_time_format = True
     ceh = ExpressionDescriptor("* * * * *", options)
     self.assertEqual(
         "Every minute",
         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 10
0
    def test_full_import(self):
        from cron_descriptor.Options import Options
        from cron_descriptor.DescriptionTypeEnum import DescriptionTypeEnum
        from cron_descriptor.ExpressionDescriptor import ExpressionDescriptor

        options = Options()
        options.use_24hour_time_format = True
        ceh = ExpressionDescriptor("* * * * *", options)
        self.assertEqual('Every minute',
                         ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 11
0
    def test_full_import(self):
        from cron_descriptor.Options import Options
        from cron_descriptor.DescriptionTypeEnum import DescriptionTypeEnum
        from cron_descriptor.ExpressionDescriptor import ExpressionDescriptor

        options = Options()
        options.use_24hour_time_format = True
        ceh = ExpressionDescriptor("* * * * *", options)
        self.assertEqual(
            'Every minute',
            ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 12
0
def cronIntervalToDescription(interval):
    """
    Convert a crontab interval to a human readable format
    :param interval:        crontab interval
    :type interval:         str
    :return:                readable format or None
    :rtype:                 str|None
    """
    try:
        descriptor = ExpressionDescriptor(interval,
                                          use_24hour_time_format=True)
        return descriptor.get_description()
    except:
        return None
Ejemplo n.º 13
0
    def description(self, **kw):
        """
        Returns a description of the crontab's schedule (if available)

        **kw - Keyword arguments to pass to cron_descriptor (see docs)
        """
        try:
            from cron_descriptor import ExpressionDescriptor
        except ImportError:
            raise ImportError("cron_descriptor not available. Please install"\
              "cron_descriptor python module via pip or your package manager")

        exdesc = ExpressionDescriptor(self.slices.clean_render(), **kw)
        return exdesc.get_description()
Ejemplo n.º 14
0
    def description(self, **kw):
        """
        Returns a description of the crontab's schedule (if available)

        **kw - Keyword arguments to pass to cron_descriptor (see docs)
        """
        try:
            from cron_descriptor import ExpressionDescriptor
        except ImportError:
            raise ImportError("cron_descriptor not available. Please install"\
              "cron_descriptor python module via pip or your package manager")

        exdesc = ExpressionDescriptor(self.slices.clean_render(), **kw)
        return exdesc.get_description()
Ejemplo n.º 15
0
    def __init__(self, cron: str, timezone: Timezone) -> None:
        self._expression = cron_presets.get(cron, cron)
        self._timezone = timezone

        descriptor = ExpressionDescriptor(expression=self._expression,
                                          casing_type=CasingTypeEnum.Sentence,
                                          use_24hour_time_format=True)
        try:
            # checking for more than 5 parameters in Cron and avoiding evaluation for now,
            # as Croniter has inconsistent evaluation with other libraries
            if len(croniter(self._expression).expanded) > 5:
                raise FormatException()
            interval_description = descriptor.get_description()
        except (CroniterBadCronError, FormatException, MissingFieldException):
            interval_description = ""
        self.description = interval_description
Ejemplo n.º 16
0
def format_cron_syntax_filter(
        cron_syntax: Union[str, None]) -> Union[str, None]:
    if cron_syntax:
        expression_descriptor = ExpressionDescriptor(cron_syntax)
        return str(expression_descriptor)

    return None
Ejemplo n.º 17
0
    def create_modal(self, pcron, parsed_command):
        # explanation of parts you can use
        parts = table(
                tbody(
                    tr(th('*'), td("any value")),
                    tr(th(','), td("value list separator")),
                    tr(th('-'), td("range of values")),
                    tr(th('/'), td("step values")),
                    tr(th('0-9'), td("numbers"))
                ), _style="padding:0px;"
            )

        return str(Modal("modal_"+str(self.count), div(
            strong('explanation:'),
            div(ExpressionDescriptor(pcron, _options), _id="hr"+str(self.count), _class="human-readable"),
            strong('cron:'),
            input(_class="in_cron", _id="in_cron"+str(self.count), _type="text", _value=pcron),
            strong('command:'),
            input(_id="in_comm"+str(self.count), _type="text", _value=escape(parsed_command)),
            parts,
            button("Save"),
            button("Cancel", _class="del"),
            _class="text-editor"
            )
        ))
Ejemplo n.º 18
0
 def render_frequency(record):
     """Create the cron description."""
     if not record.frequency:
         return ''
     return str(
         ExpressionDescriptor(record.frequency,
                              casing_type=CasingTypeEnum.LowerCase))
Ejemplo n.º 19
0
 def test_to_kargs(self):
     self.assertEqual(
         "At 17:17",
         str(
             ExpressionDescriptor("17 17 * * *",
                                  self.options,
                                  use_24hour_time_format=True)))
Ejemplo n.º 20
0
async def home(request):
    ctab = CrontabRenderer(str(crontab("-l")))
    # last_edit = str(crontab("-v")) # try/catch
    htmlcal = calendar.HTMLCalendar(calendar.SUNDAY)
    cal = htmlcal.formatyear(2020,1)
    upt = str(uptime())
    page = article(
        script(_src="/assets/js/later.min.js"),
        script(_src=domonic.JS_MASTER),
        link(_rel="stylesheet", _type="text/css", _href=domonic.CSS_STYLE),
        div(
            sub(str(date()), " ", a("🔄", _href="/")),
            h1("📅 ezcron"),
            _style="text-align:center;"
        ),
        div(
            div(ExpressionDescriptor("* * * * *", _options), _id="hr0", _class="human-readable"),
            input(_class="in_cron", _id="in_cron0", _type="text", _value="* * * * *"),
            _class="cron-input"
        ),
        h5(f"{ctab.count} cron jobs detected:"),
        div(str(ctab())),
        button("Add another"),
        h5("When the cron jobs are scheduled to run:"),
        div(cal),
        p(strong("uptime : "), upt),
        h5("Useful Links:"),
        a( "crontab guru", _href="https://crontab.guru/", _target="_blank")
        )

    return response.html( render( Webpage(page, _dark_mode) ) )
Ejemplo n.º 21
0
 def test_empty_cron_expression_exception(self):
     self.options.throw_exception_on_parse_error = True
     ceh = ExpressionDescriptor('', self.options)
     self.assertRaises(
         MissingFieldException,
         ceh.get_description,
         DescriptionTypeEnum.FULL)
Ejemplo n.º 22
0
 def test_invalid_syntax_exception(self):
     self.options.throw_exception_on_parse_error = True
     ceh = ExpressionDescriptor("* $ * * *", self.options)
     self.assertRaises(
         FormatException,
         ceh.get_description,
         DescriptionTypeEnum.FULL)
Ejemplo n.º 23
0
 def test_locale_de(self):
     options = Options()
     options.locale_code = 'de_DE'
     options.use_24hour_time_format = True
     self.assertEqual(
         "Jede Minute",
         ExpressionDescriptor("* * * * *", options).get_description())
Ejemplo n.º 24
0
 def parse_expression(self):
     options = Options()
     options.throw_exception_on_parse_error = True
     options.casing_type = CasingTypeEnum.Sentence
     options.use_24hour_time_format = True
     return ExpressionDescriptor(self.expression, options).get_description(
         DescriptionTypeEnum.FULL)
Ejemplo n.º 25
0
def get_pretty(line_nbr, expression):
    """Get a human readable string for the cron expression"""
    import sys
    import subprocess
    import pyotherside
    # By default the module is installed in the 2.7 branch, pyotherside uses python 3
    # We use a custom location
    sys.path.append("/usr/share/harbour-sailcron/python/")
    # https://github.com/Salamek/cron-descriptor
    from cron_descriptor import Options, CasingTypeEnum, DescriptionTypeEnum, ExpressionDescriptor

    # get proper 24/12 hour notation and strip output
    output = subprocess.check_output(
        "/usr/bin/dconf read /sailfish/i18n/lc_timeformat24h", shell=True)
    output = str(output).replace("'", "").replace('b"',
                                                  "").replace('\\n"',
                                                              "").strip()
    is24h = bool(output == "24")
    SPECIALS = {
        "reboot": '@reboot',
        "hourly": '0 * * * *',
        "daily": '0 0 * * *',
        "weekly": '0 0 * * 0',
        "monthly": '0 0 1 * *',
        "yearly": '0 0 1 1 *',
        "annually": '0 0 1 1 *',
        "midnight": '0 0 * * *'
    }

    key = expression.lstrip('@').rstrip(' ').lower()
    if key in SPECIALS.keys():
        expression = SPECIALS[key]
    # set options
    options = Options()
    options.throw_exception_on_parse_error = False
    options.casing_type = CasingTypeEnum.Sentence
    options.use_24hour_time_format = is24h
    if expression == "@reboot":
        pyotherside.send('result', line_nbr, expression)
        human_format = "reboot"
    else:
        descripter = ExpressionDescriptor(expression, options)
        human_format = descripter.get_description(DescriptionTypeEnum.FULL)

        pyotherside.send('result', line_nbr, human_format)
    return human_format
Ejemplo n.º 26
0
    def validate(self) -> bool:
        rv = Form.validate(self)
        if not rv:
            return False

        project_name_exists = PullMirror.query.filter_by(
            project_name=self.project_name.data).first()
        if project_name_exists:
            self.project_name.errors.append(
                gettext('Project name %(project_name)s already exists.',
                        project_name=self.project_name.data))
            return False

        project_mirror_exists = PullMirror.query.filter_by(
            project_mirror=self.project_mirror.data).first()
        if project_mirror_exists:
            self.project_mirror.errors.append(
                gettext('Project mirror %(project_mirror)s already exists.',
                        project_mirror=self.project_mirror.data))
            return False

        if not GitRemote.detect_vcs_type(self.project_mirror.data):
            self.project_mirror.errors.append(
                gettext('Unknown VCS type or detection failed.'))
            return False

        if not self.group.data:
            self.group.errors.append(
                gettext(
                    'You have to select GitLab group where mirrored project will be created.'
                ))
            return False

        try:
            check_project_visibility_in_group(self.visibility.data,
                                              self.group.data)
        except VisibilityError as e:
            self.visibility.errors.append(gettext(str(e)))
            return False

        if check_project_exists(self.project_name.data, self.group.data):
            if not self.is_force_create.data:
                self.project_name.errors.append(
                    gettext(
                        'Project with name %(project_name)s already exists in selected group and "Create project in GitLab even if it already exists." is not checked in "Advanced options"',
                        project_name=self.project_name.data))
                return False

        if self.periodic_sync.data:
            try:
                ExpressionDescriptor(self.periodic_sync.data,
                                     throw_exception_on_parse_error=True)
            except (MissingFieldException, FormatException):
                self.periodic_sync.errors.append(
                    gettext('Wrong cron expression.'))

        return True
Ejemplo n.º 27
0
def format_poll_data(poll: Poll):
    options = Options()
    options.locale_code = "ru_RU"
    return (poll.question or "Нет",
            ("\n\t\\- " +
             "\n\t\\- ".join(poll.answers)) if poll.answers else "Нет",
            "Да" if poll.is_anonymous else "Нет",
            "Да" if poll.is_multiple else "Нет",
            str(ExpressionDescriptor(poll.schedule, options))
            if poll.schedule else "Не установлено")
Ejemplo n.º 28
0
def create_timedelta_string(
    ftime: datetime,
    frequency: str,
    utime: Optional[datetime] = None,
) -> Optional[str]:
    """Create a string rendering a time delta between now and the given one.

    The rendering proceeds gradually to see if the words days, hours, minutes
    etc. are needed.

    :param ftime: datetime object (may be in the past)
    :param frequency: string with the cron frequency (or empty)
    :param utime: until datetime object
    :return: String rendering
    """
    diagnostic_msg = models.ScheduledOperation.validate_times(
        ftime, frequency, utime)
    if diagnostic_msg:
        return None

    now = datetime.now(pytz.timezone(settings.TIME_ZONE))

    if ftime and not frequency and not utime:
        # Single execution
        if ftime < now and not utime:
            return None

        return ftime.strftime('%H:%M:%S %z %Y/%b/%d')

    # Repeating execution.
    result = str(
        ExpressionDescriptor(frequency, casing_type=CasingTypeEnum.LowerCase))
    if not ftime and not utime:
        return result

    if ftime:
        # Has start time
        result = (ugettext('Starting at ') +
                  ftime.strftime('%H:%M:%S %z %Y/%b/%d') + ', ' + result)

    if utime:
        # Has finish time
        result = result + ', until ' + utime.strftime('%H:%M:%S %z %Y/%b/%d')

    return result
Ejemplo n.º 29
0
def get_item_value_dictionary(sch_obj: models.ScheduledOperation) -> Dict:
    """Get a dictionary with the values in the time."""
    result = model_to_dict(sch_obj)
    result['operation_type'] = models.Log.LOG_TYPES[result['operation_type']]
    if result['frequency']:
        result['frequency'] = str(ExpressionDescriptor(result['frequency']))
    result['workflow'] = str(sch_obj.workflow)
    result['action'] = str(sch_obj.action)
    result['payload'] = json.dumps(result['payload'], indent=2)
    result.pop('id')
    result.pop('user')
    result = {
        models.ScheduledOperation._meta.get_field(key).verbose_name.title():
        val
        for key, val in result.items()
    }

    return result
Ejemplo n.º 30
0
    def __init__(self, cronfile):
        """Initialize CrontabReader

        Args:
            cronfile: Path to cronfile
        Returns:
            None
        """
        options = Options()
        options.day_of_week_start_index_zero = False
        options.use_24hour_time_format = True
        with open(cronfile) as f:
            for line in f.readlines():
                parsed_line = self.parse_cron_line(line)
                if parsed_line:
                    print("{} -> {}".format(
                        parsed_line,
                        ExpressionDescriptor(parsed_line, options)))
Ejemplo n.º 31
0
    def validate(self) -> bool:
        rv = Form.validate(self)
        if not rv:
            return False

        project_name_exists = PullMirror.query.filter(
            PullMirror.project_name == self.project_name.data,
            PullMirror.id != self.id.data).first()
        if project_name_exists:
            self.project_name.errors.append(
                gettext('Project name %(project_name)s already exists.',
                        project_name=self.project_name.data))
            return False

        project_mirror_exists = PullMirror.query.filter(
            PullMirror.project_mirror == self.project_mirror.data,
            PullMirror.id != self.id.data).first()
        if project_mirror_exists:
            self.project_mirror.errors.append(
                gettext('Project mirror %(project_mirror)s already exists.',
                        project_mirror=self.project_mirror.data))
            return False

        if not GitRemote.detect_vcs_type(self.project_mirror.data):
            self.project_mirror.errors.append(
                gettext('Unknown VCS type or detection failed.'))
            return False

        try:
            check_project_visibility_in_group(self.visibility.data,
                                              self.group.data)
        except VisibilityError as e:
            self.visibility.errors.append(gettext(str(e)))
            return False

        if self.periodic_sync.data:
            try:
                ExpressionDescriptor(self.periodic_sync.data,
                                     throw_exception_on_parse_error=True)
            except (MissingFieldException, FormatException):
                self.periodic_sync.errors.append(
                    gettext('Wrong cron expression.'))

        return True
Ejemplo n.º 32
0
 def print_line(self, parsed_line, parsed_command, line_number):
     hex = self.random_color()
     ref = 'modal_'+str(self.count) # the target modal
     return str(
             div(
             strong( parsed_line, _style=f'color:{hex};', _class="thecron"),
             " Runs: " + str(ExpressionDescriptor(parsed_line, _options)),
             " ", pre( escape(parsed_command) ),
             " ",button( "✏️ EDIT", **{'_data-ref':ref}, _class='open btn-sm' ),
             " ",button( "X DELETE", _class='del btn-sm', **{'_data-ref':ref}, _onclick="alert('Not Yet Implmented!');" ),
             " ",button( "🏃 RUN NOW", _class='go btn-sm', **{'_data-ref':ref}, _onclick=f"execute_order_66({line_number})"),
             div( "Next one will run at : "+self.get_next(parsed_line) ),
             strong( "Countdown:" ),
             div( _id="countdown"+str(self.count) ),
             # notice im changing the js interval var dynamicaly by appending the count to the id
             script(f'const timer{str(self.count)} = setInterval(showRemaining, 1000, "{self.get_next(parsed_line)}", "countdown{str(self.count)}", "timer{str(self.count)}" );'),
             hr()
             )
         )
Ejemplo n.º 33
0
 def test_lower_casing(self):
     self.options.casing_type = CasingTypeEnum.LowerCase
     ceh = ExpressionDescriptor("* * * * *", self.options)
     self.assertEqual("every minute",
                      ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 34
0
 def test_title_casing(self):
     self.options.casing_type = CasingTypeEnum.Title
     ceh = ExpressionDescriptor("* * * * *", self.options)
     self.assertEqual("Every Minute",
                      ceh.get_description(DescriptionTypeEnum.FULL))
Ejemplo n.º 35
0
 def test_to_repr(self):
     self.assertIsInstance(ExpressionDescriptor("* * * * *"), ExpressionDescriptor)
Ejemplo n.º 36
0
 def test_to_str(self):
     self.assertEqual(
         "Every minute",
         str(ExpressionDescriptor("* * * * *")))
Ejemplo n.º 37
0
 def test_default(self):
     self.assertEqual(
         "Every minute",
         ExpressionDescriptor("* * * * *").get_description())
Ejemplo n.º 38
0
 def get_descricao(self, cron_expressao):
     descripter = ExpressionDescriptor(cron_expressao, self.options)
     return descripter.get_description()