Commits

Andriy Kornatskyy committed 8a2a3a4

Added one_of, relative_date and relative_datetime rules

  • Participants
  • Parent commits 2f4a5fe

Comments (0)

Files changed (4)

File i18n/en/LC_MESSAGES/validation.po

 msgid "The value '%s' is not in one of supported formats."
 msgstr "The value '%s' is not in one of supported formats."
 
-#: src/wheezy/validation/rules.py:25
+#: src/wheezy/validation/rules.py:25 src/wheezy/validation/rules.py:26
 msgid "Required field cannot be left blank."
 msgstr "Required field cannot be left blank."
 
-#: src/wheezy/validation/rules.py:95 src/wheezy/validation/rules.py:98
+#: src/wheezy/validation/rules.py:96 src/wheezy/validation/rules.py:98
 #, python-format
 msgid "Required to be a minimum of %(min)d characters in length."
 msgstr "Required to be a minimum of %(min)d characters in length."
 
-#: src/wheezy/validation/rules.py:100 src/wheezy/validation/rules.py:103
+#: src/wheezy/validation/rules.py:101 src/wheezy/validation/rules.py:103
 #, python-format
 msgid "The length must fall within the range %(min)d - %(max)d characters."
 msgstr "The length must fall within the range %(min)d - %(max)d characters."
 
-#: src/wheezy/validation/rules.py:107 src/wheezy/validation/rules.py:110
+#: src/wheezy/validation/rules.py:108 src/wheezy/validation/rules.py:110
 #, python-format
 msgid "Exceeds maximum length of %(max)d."
 msgstr "Exceeds maximum length of %(max)d."
 
-#: src/wheezy/validation/rules.py:229 src/wheezy/validation/rules.py:235
+#: src/wheezy/validation/rules.py:230 src/wheezy/validation/rules.py:235
 #, python-format
 msgid "The value failed equality comparison with \"%(comparand)s\"."
 msgstr "The value failed equality comparison with \"%(comparand)s\"."
 
-#: src/wheezy/validation/rules.py:290 src/wheezy/validation/rules.py:298
+#: src/wheezy/validation/rules.py:291 src/wheezy/validation/rules.py:298
 msgid "Required to match validation pattern."
 msgstr "Required to match validation pattern."
 
-#: src/wheezy/validation/rules.py:320 src/wheezy/validation/rules.py:330
+#: src/wheezy/validation/rules.py:321 src/wheezy/validation/rules.py:330
 msgid ""
 "Invalid slug. The value must consist of letters, digits, underscopes and/or "
 "hyphens."
 "Invalid slug. The value must consist of letters, digits, underscopes and/or "
 "hyphens."
 
-#: src/wheezy/validation/rules.py:350 src/wheezy/validation/rules.py:362
+#: src/wheezy/validation/rules.py:351 src/wheezy/validation/rules.py:362
 msgid "Required to be a valid email address."
 msgstr "Required to be a valid email address."
 
-#: src/wheezy/validation/rules.py:396 src/wheezy/validation/rules.py:410
+#: src/wheezy/validation/rules.py:397 src/wheezy/validation/rules.py:410
 #, python-format
 msgid "Required to be greater or equal to %(min)s."
 msgstr "Required to be greater or equal to %(min)s."
 
-#: src/wheezy/validation/rules.py:400 src/wheezy/validation/rules.py:414
+#: src/wheezy/validation/rules.py:401 src/wheezy/validation/rules.py:414
 #, python-format
 msgid "The value must fall within the range %(min)s - %(max)s"
 msgstr "The value must fall within the range %(min)s - %(max)s"
 
-#: src/wheezy/validation/rules.py:407 src/wheezy/validation/rules.py:421
+#: src/wheezy/validation/rules.py:408 src/wheezy/validation/rules.py:421
 #, python-format
 msgid "Exceeds maximum allowed value of %(max)s."
 msgstr "Exceeds maximum allowed value of %(max)s."
+
+#: src/wheezy/validation/rules.py:624 src/wheezy/validation/rules.py:625
+msgid "The value does not belong to the list of known items."
+msgstr "The value does not belong to the list of known items."
+
+#: src/wheezy/validation/rules.py:655
+msgid "Required to be above a minimum allowed."
+msgstr "Required to be above a minimum allowed."
+
+#: src/wheezy/validation/rules.py:659
+msgid "Must fall within a valid range."
+msgstr "Must fall within a valid range."
+
+#: src/wheezy/validation/rules.py:665
+msgid "Exceeds maximum allowed."
+msgstr "Exceeds maximum allowed."

File i18n/ru/LC_MESSAGES/validation.po

 #, python-format
 msgid "Exceeds maximum allowed value of %(max)s."
 msgstr "Превышает максимально допустимое значение %(max)s."
+
+#: src/wheezy/validation/rules.py:624 src/wheezy/validation/rules.py:625
+msgid "The value does not belong to the list of known items."
+msgstr "Значение не входит в список известных элементов."
+
+#: src/wheezy/validation/rules.py:655
+msgid "Required to be above a minimum allowed."
+msgstr "Обязательно должно быть выше минимально допустимого значения."
+
+#: src/wheezy/validation/rules.py:659
+msgid "Must fall within a valid range."
+msgstr "Должно находиться в пределах допустимого диапазона."
+
+#: src/wheezy/validation/rules.py:665
+msgid "Exceeds maximum allowed."
+msgstr "Превышает допустимый максимум."

File i18n/validation.po

 msgid "The value '%s' is not in one of supported formats."
 msgstr "The value '%s' is not in one of supported formats."
 
-#: src/wheezy/validation/rules.py:25
+#: src/wheezy/validation/rules.py:25 src/wheezy/validation/rules.py:26
 msgid "Required field cannot be left blank."
 msgstr "Required field cannot be left blank."
 
-#: src/wheezy/validation/rules.py:95 src/wheezy/validation/rules.py:98
+#: src/wheezy/validation/rules.py:96 src/wheezy/validation/rules.py:98
 #, python-format
 msgid "Required to be a minimum of %(min)d characters in length."
 msgstr "Required to be a minimum of %(min)d characters in length."
 
-#: src/wheezy/validation/rules.py:100 src/wheezy/validation/rules.py:103
+#: src/wheezy/validation/rules.py:101 src/wheezy/validation/rules.py:103
 #, python-format
 msgid "The length must fall within the range %(min)d - %(max)d characters."
 msgstr "The length must fall within the range %(min)d - %(max)d characters."
 
-#: src/wheezy/validation/rules.py:107 src/wheezy/validation/rules.py:110
+#: src/wheezy/validation/rules.py:108 src/wheezy/validation/rules.py:110
 #, python-format
 msgid "Exceeds maximum length of %(max)d."
 msgstr "Exceeds maximum length of %(max)d."
 
-#: src/wheezy/validation/rules.py:229 src/wheezy/validation/rules.py:235
+#: src/wheezy/validation/rules.py:230 src/wheezy/validation/rules.py:235
 #, python-format
 msgid "The value failed equality comparison with \"%(comparand)s\"."
 msgstr "The value failed equality comparison with \"%(comparand)s\"."
 
-#: src/wheezy/validation/rules.py:290 src/wheezy/validation/rules.py:298
+#: src/wheezy/validation/rules.py:291 src/wheezy/validation/rules.py:298
 msgid "Required to match validation pattern."
 msgstr "Required to match validation pattern."
 
-#: src/wheezy/validation/rules.py:320 src/wheezy/validation/rules.py:330
+#: src/wheezy/validation/rules.py:321 src/wheezy/validation/rules.py:330
 msgid ""
 "Invalid slug. The value must consist of letters, digits, underscopes and/or "
 "hyphens."
 "Invalid slug. The value must consist of letters, digits, underscopes and/or "
 "hyphens."
 
-#: src/wheezy/validation/rules.py:350 src/wheezy/validation/rules.py:362
+#: src/wheezy/validation/rules.py:351 src/wheezy/validation/rules.py:362
 msgid "Required to be a valid email address."
 msgstr "Required to be a valid email address."
 
-#: src/wheezy/validation/rules.py:396 src/wheezy/validation/rules.py:410
+#: src/wheezy/validation/rules.py:397 src/wheezy/validation/rules.py:410
 #, python-format
 msgid "Required to be greater or equal to %(min)s."
 msgstr "Required to be greater or equal to %(min)s."
 
-#: src/wheezy/validation/rules.py:400 src/wheezy/validation/rules.py:414
+#: src/wheezy/validation/rules.py:401 src/wheezy/validation/rules.py:414
 #, python-format
 msgid "The value must fall within the range %(min)s - %(max)s"
 msgstr "The value must fall within the range %(min)s - %(max)s"
 
-#: src/wheezy/validation/rules.py:407 src/wheezy/validation/rules.py:421
+#: src/wheezy/validation/rules.py:408 src/wheezy/validation/rules.py:421
 #, python-format
 msgid "Exceeds maximum allowed value of %(max)s."
 msgstr "Exceeds maximum allowed value of %(max)s."
+
+#: src/wheezy/validation/rules.py:624 src/wheezy/validation/rules.py:625
+msgid "The value does not belong to the list of known items."
+msgstr "The value does not belong to the list of known items."
+
+#: src/wheezy/validation/rules.py:655
+msgid "Required to be above a minimum allowed."
+msgstr "Required to be above a minimum allowed."
+
+#: src/wheezy/validation/rules.py:659
+msgid "Must fall within a valid range."
+msgstr "Must fall within a valid range."
+
+#: src/wheezy/validation/rules.py:665
+msgid "Exceeds maximum allowed."
+msgstr "Exceeds maximum allowed."

File src/wheezy/validation/rules.py

 from datetime import date
 from datetime import datetime
 from datetime import time
+from datetime import timedelta
 
 from wheezy.validation.comp import ref_getter
 from wheezy.validation.comp import regex_pattern
                     break
         return succeed
 
+
+class OneOfRule(object):
+    """ Value must match at least one element from ``items``.
+
+        >>> result = []
+        >>> r = one_of([1, 2, 3])
+        >>> r.validate(3, None, None, result, _)
+        True
+        >>> r.validate(7, None, None, result, _)
+        False
+    """
+
+    def __init__(self, items, message_template=None):
+        """
+        """
+        self.items = tuple(items)
+        self.message_template = message_template or _(
+                'The value does not belong to the list of known items.')
+
+    def validate(self, value, name, model, result, gettext):
+        """ Check whenever value belongs to ``self.items``.
+        """
+        if value not in self.items:
+            result.append(gettext(self.message_template))
+            return False
+        return True
+
+
+class RelativeDeltaRule(object):
+    """ Check if value is in relative date/time range.
+
+        >>> r = RelativeDeltaRule()
+        >>> r.now() # doctest: +ELLIPSIS
+        Traceback (most recent call last):
+            ...
+        NotImplementedError: ...
+    """
+
+    def __init__(self, min=None, max=None, message_template=None):
+        """
+        """
+        if min:
+            self.min = min
+            if not max:
+                self.min = min
+                self.check = self.check_min
+                self.message_template = message_template or _(
+                        'Required to be above a minimum allowed.')
+            else:
+                self.max = max
+                self.message_template = message_template or _(
+                        'Must fall within a valid range.')
+        else:
+            if max:
+                self.max = max
+                self.check = self.check_max
+                self.message_template = message_template or _(
+                        'Exceeds maximum allowed.')
+            else:
+                self.check = self.succeed
+
+    def now(self):
+        raise NotImplementedError('Subclasses must override method now()')
+
+    def succeed(self, value, name, model, result, gettext):
+        return True
+
+    def check_min(self, value, name, model, result, gettext):
+        if value < self.now() + self.min:
+            result.append(gettext(self.message_template)
+                    % {'min': self.min})
+            return False
+        return True
+
+    def check_max(self, value, name, model, result, gettext):
+        if value > self.now() + self.max:
+            result.append(gettext(self.message_template)
+                    % {'max': self.max})
+            return False
+        return True
+
+    def check(self, value, name, model, result, gettext):
+        now = self.now()
+        if value < now + self.min or value > now + self.max:
+            result.append(gettext(self.message_template)
+                    % {'min': self.min, 'max': self.max})
+            return False
+        return True
+
+    def validate(self, value, name, model, result, gettext):
+        """
+        """
+        return value is None or self.check(value, name, model,
+                result, gettext)
+
+
+class RelativeDateDeltaRule(RelativeDeltaRule):
+    """
+        No range succeed.
+
+        >>> result = []
+        >>> r = relative_date()
+        >>> r.validate(date.today(), None, None, result, _)
+        True
+
+        Min range strategy
+
+        >>> result = []
+        >>> r = relative_date(min=timedelta(days=-7))
+        >>> r.validate(date.today(), None, None, result, _)
+        True
+        >>> d = date.today() - timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+
+        Max range strategy
+
+        >>> r = relative_date(max=timedelta(days=7))
+        >>> r.validate(date.today(), None, None, result, _)
+        True
+        >>> d = date.today() + timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+
+        Min - Max range strategy
+
+        >>> result = []
+        >>> r = relative_date(min=timedelta(days=-7), max=timedelta(days=7))
+        >>> r.validate(date.today(), None, None, result, _)
+        True
+        >>> d = date.today() - timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+        >>> d = date.today() + timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+    """
+
+    def now(self):
+        return date.today()
+
+
+class RelativeDateTimeDeltaRule(RelativeDeltaRule):
+    """
+        No range succeed.
+
+        >>> result = []
+        >>> r = relative_datetime()
+        >>> r.validate(datetime.today(), None, None, result, _)
+        True
+
+        Min range strategy
+
+        >>> result = []
+        >>> r = relative_datetime(min=timedelta(days=-7))
+        >>> r.validate(datetime.today(), None, None, result, _)
+        True
+        >>> d = datetime.today() - timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+
+        Max range strategy
+
+        >>> r = relative_datetime(max=timedelta(days=7))
+        >>> r.validate(datetime.today(), None, None, result, _)
+        True
+        >>> d = datetime.today() + timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+
+        Min - Max range strategy
+
+        >>> result = []
+        >>> r = relative_datetime(min=timedelta(days=-7),
+        ...                     max=timedelta(days=7))
+        >>> r.validate(datetime.today(), None, None, result, _)
+        True
+        >>> d = datetime.today() - timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+        >>> d = datetime.today() + timedelta(days=8)
+        >>> r.validate(d, None, None, result, _)
+        False
+    """
+
+    def now(self):
+        return datetime.now()
+
+
 required = RequiredRule()
 length = LengthRule
 compare = CompareRule
 and_ = AndRule
 or_ = OrRule
 iterator = IteratorRule
+one_of = OneOfRule
+relative_date = RelativeDateDeltaRule
+relative_datetime = RelativeDateTimeDeltaRule