Skip to content

Commit

Permalink
Merge pull request #113 from sambrightman/assorted-fixes
Browse files Browse the repository at this point in the history
Assorted fixes
  • Loading branch information
tonioo authored Jan 8, 2025
2 parents ef8e990 + 84c5835 commit 76122b6
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 15 deletions.
12 changes: 8 additions & 4 deletions sievelib/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, name: str):
self.name = name

def __str__(self):
return "unknown command %s" % self.name
return "unknown command '%s'" % self.name


class BadArgument(CommandError):
Expand Down Expand Up @@ -224,7 +224,7 @@ def tosieve(self, indentlevel: int = 0, target=sys.stdout):
if not value.startswith('"') and not value.startswith("["):
target.write("\n")
else:
target.write(value)
target.write(str(value))

if not self.accept_children:
if self.get_type() != "test":
Expand Down Expand Up @@ -998,6 +998,7 @@ def args_as_tuple(self):


class VacationCommand(ActionCommand):
extension = "vacation"
args_definition = [
{
"name": "subject",
Expand Down Expand Up @@ -1093,11 +1094,14 @@ def get_command_instance(
"""
cname = "%sCommand" % name.lower().capitalize()
gl = globals()
condition = cname not in gl or (
condition = cname not in gl
if condition:
raise UnknownCommand(name)
condition = (
checkexists
and gl[cname].extension
and gl[cname].extension not in RequireCommand.loaded_extensions
)
if condition:
raise UnknownCommand(name)
raise ExtensionNotLoaded(gl[cname].extension)
return gl[cname](parent)
31 changes: 21 additions & 10 deletions sievelib/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,14 @@ def __build_condition(
tag = condition[1]
cmd = commands.get_command_instance("header", parent)
cmd.check_next_arg("tag", tag)
cmd.check_next_arg("string", self.__quote_if_necessary(condition[0]))
cmd.check_next_arg("string", self.__quote_if_necessary(condition[2]))
if isinstance(condition[0], list):
cmd.check_next_arg("stringlist", [self.__quote_if_necessary(c) for c in condition[0]])
else:
cmd.check_next_arg("string", self.__quote_if_necessary(condition[0]))
if isinstance(condition[2], list):
cmd.check_next_arg("stringlist", [self.__quote_if_necessary(c) for c in condition[2]])
else:
cmd.check_next_arg("string", self.__quote_if_necessary(condition[2]))
return cmd

def __create_filter(
Expand Down Expand Up @@ -188,7 +194,7 @@ def __create_filter(
ifcontrol = commands.get_command_instance("if")
mtypeobj = commands.get_command_instance(matchtype, ifcontrol)
for c in conditions:
if c[0].startswith("not"):
if not isinstance(c[0], list) and c[0].startswith("not"):
negate = True
cname = c[0].replace("not", "", 1)
else:
Expand Down Expand Up @@ -281,7 +287,11 @@ def __create_filter(
self.require(action.extension)
for arg in actdef[1:]:
self.check_if_arg_is_extension(arg)
if arg.startswith(":"):
if isinstance(arg, int):
atype = "number"
elif isinstance(arg, list):
atype = "stringlist"
elif arg.startswith(":"):
atype = "tag"
else:
atype = "string"
Expand Down Expand Up @@ -563,7 +573,7 @@ def movefilter(self, name: str, direction: str) -> bool:
cpt += 1
return False # raise not found

def dump(self):
def dump(self, target=sys.stdout):
"""Dump this object
Available for debugging purposes
Expand All @@ -572,13 +582,14 @@ def dump(self):
cmd = self.__gen_require_command()
if cmd:
print("Dumping requirements")
cmd.dump()
print
cmd.dump(target=target)
target.write("\n")

for f in self.filters:
print("Filter Name: %s" % f["name"])
print("Filter Description: %s" % f["description"])
f["content"].dump()
target.write("Filter Name: %s\n" % f["name"])
if "description" in f:
target.write("Filter Description: %s\n" % f["description"])
f["content"].dump(target=target)

def tosieve(self, target=sys.stdout):
"""Generate the sieve syntax corresponding to this filters set
Expand Down
63 changes: 63 additions & 0 deletions sievelib/tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,69 @@ def test_add_currentdate_filter(self):
""",
)

def test_vacation(self):
self.fs.addfilter(
"test",
[("Subject", ":matches", "*")],
[("vacation", ":subject", "Example Autoresponder Subject", ":days", 7, ":mime", "Example Autoresponder Body")],
)
output = io.StringIO()
self.fs.tosieve(output)
self.assertEqual(
output.getvalue(),
"""require ["vacation"];
# Filter: test
if anyof (header :matches "Subject" "*") {
vacation :subject "Example Autoresponder Subject" :days 7 :mime "Example Autoresponder Body";
}
""",
)

def test_dump(self):
self.fs.addfilter(
"test",
[("Subject", ":matches", "*")], [("vacation", ":subject", "Example Autoresponder Subject", ":days", 7, ":mime", "Example Autoresponder Body")]
)
output = io.StringIO()
self.fs.dump(output)
self.assertEqual(
output.getvalue(),
"""require (type: control)
[vacation]
Filter Name: test
if (type: control)
anyof (type: test)
header (type: test)
:matches
"Subject"
"*"
vacation (type: action)
:subject
"Example Autoresponder Subject"
:days
7
:mime
"Example Autoresponder Body"
""",
)

def test_stringlist_condition(self):
self.fs.addfilter(
"test",
[(["X-Foo", "X-Bar"], ":contains", ["bar", "baz"])],
[],
)
output = io.StringIO()
self.fs.tosieve(output)
self.assertEqual(
output.getvalue(),
"""# Filter: test
if anyof (header :contains ["X-Foo", "X-Bar"] ["bar", "baz"]) {
}
"""
)

if __name__ == "__main__":
unittest.main()
13 changes: 12 additions & 1 deletion sievelib/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,18 @@ def test_fileinto_create_without_fileinto(self):
}
"""
)
self.assertEqual(self.parser.error, "line 4: unknown command fileinto")
self.assertEqual(self.parser.error, "line 4: extension 'fileinto' not loaded")

def test_unknown_command(self):
self.compilation_ko(
b"""require ["mailbox"];
if header :is "Sender" "[email protected]"
{
foobar :create "filter"; # move to "filter" mailbox
}
"""
)
self.assertEqual(self.parser.error, "line 4: unknown command 'foobar'")

def test_exists_get_string_or_list(self):
self.compilation_ok(
Expand Down

0 comments on commit 76122b6

Please sign in to comment.