def __build_condition(self, condition, parent, tag=None): """Translate a condition to a valid sievelib Command. :param list condition: condition's definition :param ``Command`` parent: the parent :param str tag: tag to use instead of the one included into :keyword:`condition` :rtype: Command :return: the generated command """ #print("condition, parent, tag", condition, parent, tag) #condition = condition[2:] + condition[:2] if tag is None: tag = condition[0] #print("condition, parent, tag", condition, parent, tag) cmd = get_command_instance("header", parent) #print("tag",tag) #print("cond",condition) #print("cmd",cmd) cmd.check_next_arg("tag", tag) #cmd.check_next_arg("string", condition[0])#.strip('"')) cmd.check_next_arg("string", self.__quote_if_necessary(condition[1])) cmd.check_next_arg("string", self.__quote_if_necessary(condition[2])) #cmd.check_next_arg("string", condition[2].strip('"')) #print("Cmd++",cmd) #cmd.tosieve() return cmd
def __command(self, ttype, tvalue): """Command parsing method Entry point for command parsing. Here is expected behaviour: * Handle command beginning if detected, * Call the appropriate sub-method (specified by __cstate) to handle the body, * Handle command ending or block opening if detected. Syntax: identifier arguments (";" / block) :param ttype: current token type :param tvalue: current token value :return: False if an error is encountered, True otherwise """ if self.__cstate is None: if ttype == "right_cbracket": self.__up() self.__opened_blocks -= 1 self.__cstate = None return True if ttype != "identifier": return False command = get_command_instance(tvalue.decode("ascii"), self.__curcommand) if command.get_type() == "test": raise ParseError("%s may not appear as a first command" % command.name) if command.get_type() == "control" and command.accept_children \ and command.has_arguments(): self.__set_expected("identifier") if self.__curcommand is not None: if not self.__curcommand.addchild(command): raise ParseError("%s unexpected after a %s" % (tvalue, self.__curcommand.name)) self.__curcommand = command self.__cstate = self.__arguments return True if self.__cstate(ttype, tvalue): return True if ttype == "left_cbracket": self.__opened_blocks += 1 self.__cstate = None return True if ttype == "semicolon": self.__cstate = None if not self.__check_command_completion(testsemicolon=False): return False self.__curcommand.complete_cb() self.__up() return True return False
def __command(self, ttype, tvalue): """Command parsing method Entry point for command parsing. Here is expected behaviour: * Handle command beginning if detected, * Call the appropriate sub-method (specified by __cstate) to handle the body, * Handle command ending or block opening if detected. Syntax: identifier arguments (";" / block) :param ttype: current token type :param tvalue: current token value :return: False if an error is encountered, True otherwise """ if self.__cstate is None: if ttype == "right_cbracket": self.__up() self.__opened_blocks -= 1 self.__cstate = None return True if ttype != "identifier": return False command = get_command_instance( tvalue.decode("ascii"), self.__curcommand) if command.get_type() == "test": raise ParseError( "%s may not appear as a first command" % command.name) if command.get_type() == "control" and command.accept_children \ and command.has_arguments(): self.__set_expected("identifier") if self.__curcommand is not None: if not self.__curcommand.addchild(command): raise ParseError("%s unexpected after a %s" % (tvalue, self.__curcommand.name)) self.__curcommand = command self.__cstate = self.__arguments return True if self.__cstate(ttype, tvalue): return True if ttype == "left_cbracket": self.__opened_blocks += 1 self.__cstate = None return True if ttype == "semicolon": self.__cstate = None if not self.__check_command_completion(testsemicolon=False): return False self.__curcommand.complete_cb() self.__up() return True return False
def __gen_require_command(self): """Internal method to create a RequireCommand based on requirements Called just before this object is going to be dumped. """ if not len(self.requires): return None reqcmd = get_command_instance("require") reqcmd.check_next_arg("stringlist", self.requires) return reqcmd
def __gen_require_command(self): """Internal method to create a RequireCommand based on requirements Called just before this object is going to be dumped. """ if not len(self.requires): return None reqcmd = commands.get_command_instance("require") reqcmd.check_next_arg("stringlist", self.requires) return reqcmd
def disablefilter(self, name): """Disable a filter Instead of commenting the filter, we just surround it with a "if false { }" test. :param name: the filter's name :return: True if filter was disabled, False otherwise """ ifcontrol = get_command_instance("if") falsecmd = get_command_instance("false", ifcontrol) ifcontrol.check_next_arg("test", falsecmd) for f in self.filters: if f["name"] != name: continue ifcontrol.addchild(f["content"]) f["content"] = ifcontrol f["enabled"] = False return True return False
def disablefilter(self, name): """Disable a filter Instead of commenting the filter, we just surround it with a "if false { }" test. :param name: the filter's name :return: True if filter was disabled, False otherwise """ name = self._unicode_filter_name(name) ifcontrol = get_command_instance("if") falsecmd = get_command_instance("false", ifcontrol) ifcontrol.check_next_arg("test", falsecmd) for f in self.filters: if f["name"] != name: continue ifcontrol.addchild(f["content"]) f["content"] = ifcontrol f["enabled"] = False return True return False
def __build_condition(self, condition, parent, tag=None): """Translate a condition to a valid sievelib Command. :param list condition: condition's definition :param ``Command`` parent: the parent :param str tag: tag to use instead of the one included into :keyword:`condition` :rtype: Command :return: the generated command """ if tag is None: 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])) return cmd
def __arguments(self, ttype, tvalue): """Arguments parsing method Entry point for command arguments parsing. The parser must call this method for each parsed command (either a control, action or test). Syntax: *argument [ test / test-list ] :param ttype: current token type :param tvalue: current token value :return: False if an error is encountered, True otherwise """ if ttype == "identifier": test = get_command_instance(tvalue.decode("ascii"), self.__curcommand) self.__curcommand.check_next_arg("test", test) self.__expected = test.get_expected_first() self.__curcommand = test return self.__check_command_completion(testsemicolon=False) if ttype == "left_parenthesis": self.__push_expected_bracket("right_parenthesis", b')') self.__set_expected("identifier") return True if ttype == "comma": self.__set_expected("identifier") return True if ttype == "right_parenthesis": self.__pop_expected_bracket(ttype, tvalue) self.__up() return True if self.__argument(ttype, tvalue): return self.__check_command_completion(testsemicolon=False) return False
def __arguments(self, ttype, tvalue): """Arguments parsing method Entry point for command arguments parsing. The parser must call this method for each parsed command (either a control, action or test). Syntax: *argument [ test / test-list ] :param ttype: current token type :param tvalue: current token value :return: False if an error is encountered, True otherwise """ if ttype == "identifier": test = get_command_instance(tvalue, self.__curcommand) self.__curcommand.check_next_arg("test", test) self.__expected = test.get_expected_first() self.__curcommand = test return self.__check_command_completion(testsemicolon=False) if ttype == "left_parenthesis": self.__set_expected("identifier") return True if ttype == "comma": self.__set_expected("identifier") return True if ttype == "right_parenthesis": self.__up() return True if self.__argument(ttype, tvalue): return self.__check_command_completion(testsemicolon=False) return False
def __create_filter(self, conditions, actions, matchtype="anyof"): """Create a new filter A filter is composed of: * a name * one or more conditions (tests) combined together using ``matchtype`` * one or more actions A condition must be given as a 3-uple of the form:: (test's name, operator, value) An action must be given as a 2-uple of the form:: (action's name, value) It uses the "header" test to generate the sieve syntax corresponding to the given conditions. :param conditions: the list of conditions :param actions: the list of actions :param matchtype: "anyof" or "allof" """ ifcontrol = get_command_instance("if") mtypeobj = get_command_instance(matchtype, ifcontrol) for c in conditions: if c[0].startswith("not"): negate = True cname = c[0].replace("not", "", 1) else: negate = False cname = c[0] if cname in ("true", "false"): cmd = get_command_instance(c[0], ifcontrol) elif cname == "size": cmd = get_command_instance("size", ifcontrol) cmd.check_next_arg("tag", c[1]) cmd.check_next_arg("number", c[2]) elif cname == "exists": cmd = get_command_instance("exists", ifcontrol) cmd.check_next_arg( "stringlist", "[%s]" % (",".join('"%s"' % val for val in c[1:]))) else: if c[1].startswith(':not'): cmd = self.__build_condition(c, ifcontrol, c[1].replace("not", "", 1)) not_cmd = get_command_instance("not", ifcontrol) not_cmd.check_next_arg("test", cmd) cmd = not_cmd else: cmd = self.__build_condition(c, ifcontrol) if negate: not_cmd = get_command_instance("not", ifcontrol) not_cmd.check_next_arg("test", cmd) cmd = not_cmd mtypeobj.check_next_arg("test", cmd) ifcontrol.check_next_arg("test", mtypeobj) for actdef in actions: action = get_command_instance(actdef[0], ifcontrol, False) if action.is_extension: self.require(actdef[0]) for arg in actdef[1:]: self.check_if_arg_is_extension(arg) if arg.startswith(":"): atype = "tag" else: atype = "string" arg = self.__quote_if_necessary(arg) action.check_next_arg(atype, arg, check_extension=False) ifcontrol.addchild(action) return ifcontrol
def __create_filter(self, conditions, actions, matchtype="anyof"): """Create a new filter A filter is composed of: * a name * one or more conditions (tests) combined together using ``matchtype`` * one or more actions A condition must be given as a 3-uple of the form:: (test's name, operator, value) An action must be given as a 2-uple of the form:: (action's name, value) It uses the "header" test to generate the sieve syntax corresponding to the given conditions. :param conditions: the list of conditions :param actions: the list of actions :param matchtype: "anyof" or "allof" """ ifcontrol = commands.get_command_instance("if") mtypeobj = commands.get_command_instance(matchtype, ifcontrol) for c in conditions: if c[0].startswith("not"): negate = True cname = c[0].replace("not", "", 1) else: negate = False cname = c[0] if cname in ("true", "false"): cmd = commands.get_command_instance(c[0], ifcontrol) elif cname == "size": cmd = commands.get_command_instance("size", ifcontrol) cmd.check_next_arg("tag", c[1]) cmd.check_next_arg("number", c[2]) elif cname == "exists": cmd = commands.get_command_instance("exists", ifcontrol) cmd.check_next_arg( "stringlist", "[%s]" % (",".join('"%s"' % val for val in c[1:])) ) elif cname == "envelope": cmd = commands.get_command_instance( "envelope", ifcontrol, False) self.require("envelope") if c[1].startswith(":not"): comp_tag = c[1].replace("not", "") negate = True else: comp_tag = c[1] cmd.check_next_arg("tag", comp_tag) cmd.check_next_arg( "stringlist", "[{}]".format(",".join('"{}"'.format(val) for val in c[2])) ) cmd.check_next_arg( "stringlist", "[{}]".format(",".join('"{}"'.format(val) for val in c[3])) ) elif cname == "body": cmd = commands.get_command_instance("body", ifcontrol, False) self.require(cmd.extension) cmd.check_next_arg("tag", c[1]) if c[2].startswith(":not"): comp_tag = c[2].replace("not", "") negate = True else: comp_tag = c[2] cmd.check_next_arg("tag", comp_tag) cmd.check_next_arg( "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, check_extension=False) next_arg_pos = 4 if comp_tag == ":value": self.require("relational") cmd.check_next_arg( "string", self.__quote_if_necessary(c[next_arg_pos])) next_arg_pos += 1 cmd.check_next_arg( "string", self.__quote_if_necessary(c[next_arg_pos])) next_arg_pos += 1 cmd.check_next_arg( "stringlist", "[%s]" % (",".join('"%s"' % val for val in c[next_arg_pos:])) ) else: # header command fallback if c[1].startswith(':not'): cmd = self.__build_condition( c, ifcontrol, c[1].replace("not", "", 1)) negate = True else: cmd = self.__build_condition(c, ifcontrol) if negate: not_cmd = commands.get_command_instance("not", ifcontrol) not_cmd.check_next_arg("test", cmd) cmd = not_cmd mtypeobj.check_next_arg("test", cmd) ifcontrol.check_next_arg("test", mtypeobj) for actdef in actions: action = commands.get_command_instance(actdef[0], ifcontrol, False) if action.extension is not None: self.require(action.extension) for arg in actdef[1:]: self.check_if_arg_is_extension(arg) if arg.startswith(":"): atype = "tag" else: atype = "string" arg = self.__quote_if_necessary(arg) action.check_next_arg(atype, arg, check_extension=False) ifcontrol.addchild(action) return ifcontrol
def __create_filter(self, conditions, actions, matchtype="anyof"): """Create a new filter A filter is composed of: * a name * one or more conditions (tests) combined together using ``matchtype`` * one or more actions A condition must be given as a 3-uple of the form:: (test's name, operator, value) An action must be given as a 2-uple of the form:: (action's name, value) It uses the "header" test to generate the sieve syntax corresponding to the given conditions. :param conditions: the list of conditions :param actions: the list of actions :param matchtype: "anyof" or "allof" """ ifcontrol = get_command_instance("if") mtypeobj = get_command_instance(matchtype, ifcontrol) for c in conditions: if c[0].startswith("not"): negate = True cname = c[0].replace("not", "", 1) else: negate = False cname = c[0] if cname in ("true", "false"): cmd = get_command_instance(c[0], ifcontrol) elif cname == "size": cmd = get_command_instance("size", ifcontrol) cmd.check_next_arg("tag", c[1]) cmd.check_next_arg("number", c[2]) elif cname == "exists": cmd = get_command_instance("exists", ifcontrol) cmd.check_next_arg( "stringlist", "[%s]" % (",".join('"%s"' % val for val in c[1:])) ) else: if c[1].startswith(':not'): cmd = self.__build_condition(c, ifcontrol, c[1].replace("not", "", 1)) not_cmd = get_command_instance("not", ifcontrol) not_cmd.check_next_arg("test", cmd) cmd = not_cmd else: cmd = self.__build_condition(c, ifcontrol) if negate: not_cmd = get_command_instance("not", ifcontrol) not_cmd.check_next_arg("test", cmd) cmd = not_cmd mtypeobj.check_next_arg("test", cmd) ifcontrol.check_next_arg("test", mtypeobj) for actdef in actions: action = get_command_instance(actdef[0], ifcontrol, False) if action.is_extension: self.require(actdef[0]) for arg in actdef[1:]: action.check_next_arg("string", self.__quote_if_necessary(arg)) ifcontrol.addchild(action) return ifcontrol