Exemplo n.º 1
0
    def second_minute(self, expr, prefix):
        """ sec/min expressions (n : Number, s: String)
        *
        nn (1~59)
        nn-nn
        nn/nn
        nn-nn/nn
        */nn
        nn,nn,nn (Maximum 24 elements)
        """
        mi, mx = (0, 59)
        if re.fullmatch(r"\d{1,2}$", expr):
            self.check_range(expr=expr, mi=mi, mx=mx, prefix=prefix)

        elif re.search(r"[-*,/]", expr):
            if '*' == expr:
                pass

            elif re.fullmatch(r"\d{1,2}-\d{1,2}$", expr):
                parts = expr.split("-")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=parts[0], ed=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}-\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                fst_parts = parts[0].split("-")
                self.check_range(expr=fst_parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=fst_parts[0], ed=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\*/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range('interval', expr=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"^\d{1,2}(,\d{1,2})+", expr):
                limit = 60
                expr_ls = expr.split(",")
                if len(expr_ls) > limit:
                    msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix,
                                                                                                            limit, len(
                            expr_ls))
                    raise FormatException(msg)
                else:
                    for n in expr_ls:
                        self.check_range(expr=n, mi=mi, mx=mx, prefix=prefix)
            else:
                msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
                raise FormatException(msg)

        else:
            msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
            raise FormatException(msg)
Exemplo n.º 2
0
    def year(self, expr, prefix):
        """ Year - valid expression (n : Number)
        *
        nnnn(1970~2099) - 4 digits number
        nnnn-nnnn(1970~2099)
        nnnn/nnn(0~129)
        */nnn(0~129)
        nnnn,nnnn,nnnn(1970~2099) - maximum 86 elements
        """
        mi, mx = (1970, 2099)
        if re.fullmatch(r"\d{4}$", expr):
            self.check_range(expr=expr, mi=mi, mx=mx, prefix=prefix)

        elif re.search(r"[-*,/]", expr):

            if '*' == expr:
                pass

            elif re.fullmatch(r"\d{4}-\d{4}$", expr):
                parts = expr.split("-")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=parts[0], ed=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{4}/\d{1,3}$", expr):
                parts = expr.split("/")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=129, prefix=prefix)

            elif re.fullmatch(r"\d{4}-\d{4}/\d{1,3}$", expr):
                parts = expr.split("/")
                fst_parts = parts[0].split("-")
                self.check_range(expr=fst_parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=fst_parts[0], ed=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=129, prefix=prefix)

            elif re.fullmatch(r"\*/\d{1,3}$", expr):
                parts = expr.split("/")
                self.check_range('interval', expr=parts[1], mi=0, mx=129, prefix=prefix)

            elif re.fullmatch(r"^\d{4}(,\d{4})+", expr):
                limit = 84
                expr_ls = expr.split(",")
                if len(expr_ls) > limit:
                    msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix,
                                                                                                            limit, len(
                            expr_ls))
                    raise FormatException(msg)
                else:
                    for year in expr_ls:
                        self.check_range(expr=year, mi=mi, mx=mx, prefix=prefix)
            else:
                msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
                raise FormatException(msg)
        else:
            msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
            raise FormatException(msg)
Exemplo n.º 3
0
    def parse(self):
        """Parses the cron expression string
        Returns:
            A 7 part string array, one part for each component of the cron expression (seconds, minutes, etc.)
        Raises:
            MissingFieldException: if _expression is empty or None
            FormatException: if _expression has wrong format
        """
        # Initialize all elements of parsed array to empty strings
        parsed = ['', '', '', '', '', '', '']

        if self._expression is None or len(self._expression) == 0:
            raise MissingFieldException("ExpressionDescriptor.expression")
        else:
            expression_parts_temp = self._expression.split()
            expression_parts_temp_length = len(expression_parts_temp)
            if expression_parts_temp_length < 5:
                raise FormatException(
                    "Error: Expression only has {0} parts.  At least 5 part are required."
                    .format(expression_parts_temp_length))
            elif expression_parts_temp_length == 5:
                # 5 part cron so shift array past seconds element
                for i, expression_part_temp in enumerate(
                        expression_parts_temp):
                    parsed[i + 1] = expression_part_temp
            elif expression_parts_temp_length == 6:
                # If last element ends with 4 digits, a year element has been
                # supplied and no seconds element
                year_regex = re.compile("\d{4}$")
                if year_regex.search(expression_parts_temp[5]) is not None:
                    for i, expression_part_temp in enumerate(
                            expression_parts_temp):
                        parsed[i + 1] = expression_part_temp
                else:
                    for i, expression_part_temp in enumerate(
                            expression_parts_temp):
                        parsed[i] = expression_part_temp
            elif expression_parts_temp_length == 7:
                parsed = expression_parts_temp
            else:
                raise FormatException(
                    "Error: Expression has too many parts ({0}).  Expression must not have more than 7 parts."
                    .format(expression_parts_temp_length))
        self.normalize_expression(parsed)

        return parsed
Exemplo n.º 4
0
 def compare_range(self, type=None, **kwargs):
     """ check 2 expression values size
     does not allow {st} value to be greater than {ed} value
     """
     prefix = kwargs["prefix"]
     st = kwargs["st"]
     ed = kwargs["ed"]
     mi = kwargs["mi"]
     mx = kwargs["mx"]
     if int(st) > int(ed):
         if type is None:
             msg = "({0}) Invalid range '{1}-{2}'. Accepted range is {3}-{4}".format(prefix, st, ed, mi, mx)
         elif type == 'dow':
             msg = "({0}) Invalid range '{1}-{2}'. Accepted range is {3}-{4}".format(prefix,
                                                                                     self._cron_days[st],
                                                                                     self._cron_days[ed], mi, mx)
         raise FormatException(msg)
Exemplo n.º 5
0
 def check_range(self, type=None, **kwargs):
     """
     check if expression value within range of specified limit
     """
     prefix = kwargs["prefix"]
     mi = kwargs["mi"]
     mx = kwargs["mx"]
     expr = kwargs["expr"]
     if int(expr) < mi or mx < int(expr):
         if type is None:
             msg = "{0} values must be between {1} and {2} but '{3}' is provided".format(prefix, mi, mx, expr)
         elif type == "interval":
             msg = "({0}) Accepted increment value range is {1}~{2} but '{3}' is provided".format(prefix,
                                                                                                  mi, mx, expr)
         elif type == 'dow':
             msg = "({0}) Accepted week value is {1}~{2} but '{3}' is provided".format(prefix, mi, mx, expr)
         raise FormatException(msg)
     else:
         pass
Exemplo n.º 6
0
    def dayofweek(self, expr, prefix):
        """ DAYOfWeek expressions (n : Number, s: String)
        *
        ?
        n (0~7) - 0 and 7 used interchangeable as Sunday
        sss (SUN~SAT)
        n/n
        n-n/n
        */n
        n-n
        sss-sss
        n|sss,n|sss,n|sss (maximum 7 elements)
        nL
        n#n
        """
        mi, mx = (0, 7)

        if '*' == expr:
            pass

        elif '?' == expr:
            pass

        elif re.fullmatch(r"\d{1}$", expr):
            self.check_range(expr=expr, mi=mi, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\D{3}", expr):
            cron_days = {v: k for (k, v) in self._cron_days.items()}
            if expr.upper() in cron_days:
                pass
            else:
                msg = "Invalid DayOfWeek value '{}'".format(expr)
                raise FormatException(msg)

        elif re.fullmatch(r"\d{1}/\d{1}$", expr):
            parts = expr.split("/")
            self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
            self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\d{1}-\d{1}/\d{1}$", expr):
            parts = expr.split("/")
            fst_parts = parts[0].split("-")
            self.check_range(expr=fst_parts[0], mi=mi, mx=mx, prefix=prefix)
            self.check_range(expr=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
            self.compare_range(st=fst_parts[0], ed=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
            self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

        elif re.fullmatch(r"[*]/\d{1}$", expr):
            parts = expr.split("/")
            self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\d{1}-\d{1}$", expr):
            parts = expr.split("-")
            self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
            self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
            self.compare_range(st=parts[0], ed=parts[1], mi=mi, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\D{3}-\D{3}$", expr):
            parts = expr.split("-")
            cron_days = {v: k for (k, v) in self._cron_days.items()}
            try:
                st_day = cron_days[parts[0].upper()]
                ed_day = cron_days[parts[1].upper()]
            except KeyError:
                msg = "({0}) Invalid DayOfWeek value '{1}'".format(prefix, expr)
                raise FormatException(msg)
            self.compare_range(st=st_day, ed=ed_day, mi=mi, mx=mx, prefix=prefix, type='dow')

        elif re.fullmatch(r"^(\d{1}|\D{3})((,\d{1})+|(,\D{3})*)*", expr):
            limit = 7
            expr_ls = expr.split(",")
            if len(expr_ls) > limit:
                msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix, limit,
                                                                                                        len(expr_ls))
                raise FormatException(msg)
            else:
                cron_days = {v: k for (k, v) in self._cron_days.items()}
                for day in expr_ls:
                    day = cron_days[day.upper()] + 1 if len(day) == 3 else day  # syncronize by add 1 to cron_days index
                    self.check_range(expr=day, mi=mi, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\d{1}(l|L)", expr):
            self.check_range(expr=expr[0], mi=mi, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\d{1}#\d{1}", expr):
            parts = expr.split('#')
            self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
            self.check_range(expr=parts[1], mi=mi, mx=5, prefix=prefix, type='dow')
        else:
            msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
            raise FormatException(msg)
Exemplo n.º 7
0
    def month(self, expr, prefix):
        """ month expressions (n : Number, s: String)
        *
        nn (1~12)
        sss (JAN~DEC)
        nn-nn
        sss-sss
        nn/nn
        nn-nn/nn
        */nn
        nn,nn,nn (Maximum 12 elements)
        """
        mi, mx = (1, 12)
        if re.fullmatch(r"\d{1,2}$", expr):
            self.check_range(expr=expr, mi=mi, mx=mx, prefix=prefix)

        elif re.fullmatch(r"\D{3}", expr):
            matched_month = [m for m in self._cron_months.values() if expr == m]
            if len(matched_month) == 0:
                msg = "Invalid Month value '{}'".format(expr)
                raise FormatException(msg)

        elif re.search(r"[-*,/]", expr):
            if '*' == expr:
                pass

            elif re.fullmatch(r"\d{1,2}-\d{1,2}$", expr):
                parts = expr.split("-")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=parts[0], ed=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\D{3}-\D{3}$", expr):
                parts = expr.split("-")
                cron_months = {v: k for (k, v) in self._cron_months.items()}
                st_not_exist = parts[0] not in cron_months
                ed_not_exist = parts[1] not in cron_months
                if st_not_exist or ed_not_exist:
                    msg = "Invalid Month value '{}'".format(expr)
                    raise FormatException(msg)
                self.compare_range(st=cron_months[parts[0]], ed=cron_months[parts[1]], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}-\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                fst_parts = parts[0].split("-")
                self.check_range(expr=fst_parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=fst_parts[0], ed=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=12, prefix=prefix)

            elif re.fullmatch(r"\*/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range('interval', expr=parts[1], mi=0, mx=12, prefix=prefix)

            elif re.fullmatch(r"^\d{1,2}(,\d{1,2})+", expr):
                limit = 12
                expr_ls = expr.split(",")
                if len(expr_ls) > limit:
                    msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix,
                                                                                                            limit, len(
                            expr_ls))
                    raise FormatException(msg)
                else:
                    for month in expr_ls:
                        self.check_range(expr=month, mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"^(\d{1,2}|\D{3})((,\d{1,2})+|(,\D{3})*)*", expr):
                limit = 12
                expr_ls = expr.split(",")
                if len(expr_ls) > limit:
                    msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix,
                                                                                                            limit, len(
                            expr_ls))
                    raise FormatException(msg)
                else:
                    cron_months = {v: k for (k, v) in self._cron_months.items()}
                    for month in expr_ls:
                        month = cron_months[month.upper()] if len(month) == 3 else month
                        self.check_range(expr=month, mi=mi, mx=mx, prefix=prefix)
            else:
                msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
                raise FormatException(msg)
        else:
            msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
            raise FormatException(msg)
Exemplo n.º 8
0
    def dayofmonth(self, expr, prefix):
        """ DAYOfMonth expressions (n : Number, s: String)
        *
        ?
        nn (1~31)
        nn-nn
        nn/nn
        nn-nn/nn
        */nn
        nn,nn,nn (Maximum 31 elements)
        L-nn
        LW
        nW
        """
        mi, mx = (1, 31)
        if re.fullmatch(r"\d{1,2}$", expr):
            self.check_range(expr=expr, mi=mi, mx=mx, prefix=prefix)
        elif re.search(r"[-*,/?]", expr):
            if '*' == expr:
                pass

            elif '?' == expr:
                pass

            elif re.fullmatch(r"\d{1,2}-\d{1,2}$", expr):
                parts = expr.split("-")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=parts[0], ed=parts[1], mi=mi, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range(expr=parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\d{1,2}-\d{1,2}/\d{1,2}$", expr):
                parts = expr.split("/")
                fst_parts = parts[0].split("-")
                self.check_range(expr=fst_parts[0], mi=mi, mx=mx, prefix=prefix)
                self.check_range(expr=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.compare_range(st=fst_parts[0], ed=fst_parts[1], mi=mi, mx=mx, prefix=prefix)
                self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

            elif re.fullmatch(r"\*/\d{1,2}$", expr):
                parts = expr.split("/")
                self.check_range('interval', expr=parts[1], mi=0, mx=mx, prefix=prefix)

            elif re.fullmatch(r"^\d{1,2}(,\d{1,2})+", expr):
                limit = 31
                expr_ls = expr.split(",")
                if len(expr_ls) > 31:
                    msg = "({0}) Exceeded maximum number({1}) of specified value. '{2}' is provided".format(prefix,
                                                                                                            limit, len(
                            expr_ls))
                    raise FormatException(msg)
                else:
                    for dayofmonth in expr_ls:
                        self.check_range(expr=dayofmonth, mi=mi, mx=mx, prefix=prefix)
            elif re.fullmatch(r"^(L|l)-(\d{1,2})$", expr):
                parts = expr.split("-")
                self.check_range(expr=parts[1], mi=mi, mx=mx, prefix=prefix)
            else:
                msg = "Illegal Expression Format '{0}'".format(expr)
                raise FormatException(msg)

        elif re.fullmatch(r"^(L|l)(W|w)?$", expr):
            pass

        elif re.fullmatch(r"^(\d{1,2})(w{1}|W{1})$", expr):
            self.check_range(expr=expr[:-1], mi=mi, mx=mx, prefix=prefix)

        else:
            msg = "({0}) Illegal Expression Format '{1}'".format(prefix, expr)
            raise FormatException(msg)