Repository: tonioo/sievelib

Issue:
Factory: add support for currentdate test
Make the factory module understand the currendate test.

Discussion:

Patch:
diff --git a/sievelib/commands.py b/sievelib/commands.py
index d26bcb5..c2db5a4 100644
--- a/sievelib/commands.py
+++ b/sievelib/commands.py
@@ -962,6 +962,22 @@ class CurrentdateCommand(TestCommand):
          "required": True}
     ]
 
+    def args_as_tuple(self):
+        """Return arguments as a list."""
+        result = ("currentdate", )
+        result += (
+            ":zone",
+            self.arguments["zone"].strip('"'),
+            self.arguments["match-type"],
+            self.arguments["date-part"].strip('"')
+        )
+        if self.arguments["key-list"].startswith("["):
+            result = result + tuple(
+                tools.to_list(self.arguments["key-list"]))
+        else:
+            result = result + (self.arguments["key-list"].strip('"'),)
+        return result
+
 
 class VacationCommand(ActionCommand):
     args_definition = [
diff --git a/sievelib/factory.py b/sievelib/factory.py
index eb9b32e..8c065aa 100644
--- a/sievelib/factory.py
+++ b/sievelib/factory.py
@@ -215,6 +215,23 @@ class FiltersSet(object):
                     "stringlist",
                     "[%s]" % (",".join('"%s"' % val for val in c[3:]))
                 )
+            elif cname == "currentdate":
+                cmd = commands.get_command_instance(
+                    "currentdate", ifcontrol, False)
+                self.require(cmd.extension)
+                cmd.check_next_arg("tag", c[1])
+                cmd.check_next_arg("string", self.__quote_if_necessary(c[2]))
+                if c[3].startswith(":not"):
+                    comp_tag = c[3].replace("not", "")
+                    negate = True
+                else:
+                    comp_tag = c[3]
+                cmd.check_next_arg("tag", comp_tag)
+                cmd.check_next_arg("string", self.__quote_if_necessary(c[4]))
+                cmd.check_next_arg(
+                    "stringlist",
+                    "[%s]" % (",".join('"%s"' % val for val in c[5:]))
+                )
             else:
                 # header command fallback
                 if c[1].startswith(':not'):
@@ -356,7 +373,8 @@ class FiltersSet(object):
                                    commands.SizeCommand,
                                    commands.ExistsCommand,
                                    commands.BodyCommand,
-                                   commands.EnvelopeCommand)):
+                                   commands.EnvelopeCommand,
+                                   commands.CurrentdateCommand)):
                 args = node.args_as_tuple()
                 if negate:
                     if node.name in ["header", "envelope"]:
@@ -367,6 +385,12 @@ class FiltersSet(object):
                             (":not{}".format(args[2][1:]),) +
                             args[3:]
                         )
+                    elif node.name == "currentdate":
+                        args = (
+                            args[:3] +
+                            (":not{}".format(args[3][1:]),) +
+                            args[4:]
+                        )
                     elif node.name == "exists":
                         args = ("not{}".format(args[0]),) + args[1:]
                     negate = False


Test patch:
diff --git a/sievelib/tests/test_factory.py b/sievelib/tests/test_factory.py
index 42b3964..e2e602d 100644
--- a/sievelib/tests/test_factory.py
+++ b/sievelib/tests/test_factory.py
@@ -68,6 +68,17 @@ class FactoryTestCase(unittest.TestCase):
         conditions = self.fs.get_filter_conditions("ruleC")
         self.assertEqual(orig_conditions, conditions)
 
+        orig_conditions = [(
+            "currentdate", ":zone", "+0100", ":notis", "date", "2019-02-26"
+        )]
+        self.fs.addfilter(
+            "ruleD",
+            orig_conditions,
+            [("fileinto", "INBOX")]
+        )
+        conditions = self.fs.get_filter_conditions("ruleD")
+        self.assertEqual(orig_conditions, conditions)
+
     def test_get_filter_matchtype(self):
         """Test get_filter_matchtype method."""
         self.fs.addfilter(
@@ -298,6 +309,21 @@ if anyof (not envelope :is ["From"] ["hello"]) {
 }
 """)
 
+    def test_add_currentdate_filter(self):
+        """Add a currentdate filter."""
+        self.fs.addfilter(
+            "test",
+            [("currentdate", ":zone", "+0100", ":is", "date", "2019-02-26")],
+            [("fileinto", "INBOX")]
+        )
+        self.assertEqual("{}".format(self.fs), """require ["date", "fileinto"];
+
+# Filter: test
+if anyof (currentdate :zone "+0100" :is "date" ["2019-02-26"]) {
+    fileinto "INBOX";
+}
+""")
+
 
 if __name__ == "__main__":
     unittest.main()