def parseRuleRecursively(currentRoot, currentRule): if currentRoot.tag == "not": # get possible elemts orItem = currentRoot.find("or") andItem = currentRoot.find("and") notItem = currentRoot.find("not") sensorItem = currentRoot.find("sensor") weekdayItem = currentRoot.find("weekday") monthdayItem = currentRoot.find("monthday") hourItem = currentRoot.find("hour") minuteItem = currentRoot.find("minute") secondItem = currentRoot.find("second") # check that only one tag is given in not tag # (because only one is allowed) counter = 0 if not orItem is None: counter += 1 if not andItem is None: counter += 1 if not notItem is None: counter += 1 if not sensorItem is None: counter += 1 if not weekdayItem is None: counter += 1 if not monthdayItem is None: counter += 1 if not hourItem is None: counter += 1 if not minuteItem is None: counter += 1 if not secondItem is None: counter += 1 if counter != 1: raise ValueError("Only one tag is valid inside a 'not' tag.") # start parsing the rule if not orItem is None: # create a new "or" rule ruleNew = RuleBoolean() ruleNew.type = "or" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element parseRuleRecursively(orItem, ruleNew) elif not andItem is None: # create a new "and" rule ruleNew = RuleBoolean() ruleNew.type = "and" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element parseRuleRecursively(andItem, ruleNew) elif not notItem is None: # create a new "not" rule ruleNew = RuleBoolean() ruleNew.type = "not" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element parseRuleRecursively(notItem, ruleNew) elif not sensorItem is None: ruleSensorNew = RuleSensor() ruleSensorNew.username = str(sensorItem.attrib["username"]) ruleSensorNew.remoteSensorId = int(sensorItem.attrib[ "remoteSensorId"]) # create a wrapper element around the sensor element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "sensor" ruleElement.element = ruleSensorNew ruleElement.timeTriggeredFor = float( sensorItem.attrib["timeTriggeredFor"]) # add wrapper element to the current rule currentRule.elements.append(ruleElement) elif not weekdayItem is None: ruleWeekdayNew = RuleWeekday() # get time attribute and check if valid ruleWeekdayNew.time = str(weekdayItem.attrib["time"]) if (ruleWeekdayNew.time != "local" and ruleWeekdayNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in weekday tag.") # get weekday attribute and check if valid ruleWeekdayNew.weekday = int(weekdayItem.attrib[ "weekday"]) if (ruleWeekdayNew.weekday < 0 or ruleWeekdayNew.weekday > 6): raise ValueError("No valid value for 'weekday' " + "attribute in weekday tag.") # create a wrapper element around the weekday element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "weekday" ruleElement.element = ruleWeekdayNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) elif not monthdayItem is None: ruleMonthdayNew = RuleMonthday() # get time attribute and check if valid ruleMonthdayNew.time = str(monthdayItem.attrib["time"]) if (ruleMonthdayNew.time != "local" and ruleMonthdayNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in monthday tag.") # get monthday attribute and check if valid ruleMonthdayNew.monthday = int(monthdayItem.attrib[ "monthday"]) if (ruleMonthdayNew.monthday < 1 or ruleMonthdayNew.monthday > 31): raise ValueError("No valid value for 'monthday' " + "attribute in monthday tag.") # create a wrapper element around the monthday element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "monthday" ruleElement.element = ruleMonthdayNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) elif not hourItem is None: ruleHourNew = RuleHour() # get time attribute and check if valid ruleHourNew.time = str(hourItem.attrib["time"]) if (ruleHourNew.time != "local" and ruleHourNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in hour tag.") # get start attribute and check if valid ruleHourNew.start = int(hourItem.attrib[ "start"]) if (ruleHourNew.start < 0 or ruleHourNew.start > 23): raise ValueError("No valid value for 'start' " + "attribute in hour tag.") # get end attribute and check if valid ruleHourNew.end = int(hourItem.attrib[ "end"]) if (ruleHourNew.start < 0 or ruleHourNew.start > 23): raise ValueError("No valid value for 'end' " + "attribute in hour tag.") if ruleHourNew.start > ruleHourNew.end: raise ValueError("'start' attribute not allowed to be " + "greater than 'end' attribute in hour tag.") # create a wrapper element around the hour element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "hour" ruleElement.element = ruleHourNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) elif not minuteItem is None: ruleMinuteNew = RuleMinute() # get start attribute and check if valid ruleMinuteNew.start = int(minuteItem.attrib[ "start"]) if (ruleMinuteNew.start < 0 or ruleMinuteNew.start > 59): raise ValueError("No valid value for 'start' " + "attribute in minute tag.") # get end attribute and check if valid ruleMinuteNew.end = int(minuteItem.attrib[ "end"]) if (ruleMinuteNew.start < 0 or ruleMinuteNew.start > 59): raise ValueError("No valid value for 'end' " + "attribute in minute tag.") if ruleMinuteNew.start > ruleMinuteNew.end: raise ValueError("'start' attribute not allowed to be " + "greater than 'end' attribute in minute tag.") # create a wrapper element around the minute element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "minute" ruleElement.element = ruleMinuteNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) elif not secondItem is None: ruleSecondNew = RuleSecond() # get start attribute and check if valid ruleSecondNew.start = int(secondItem.attrib[ "start"]) if (ruleSecondNew.start < 0 or ruleSecondNew.start > 59): raise ValueError("No valid value for 'start' " + "attribute in second tag.") # get end attribute and check if valid ruleSecondNew.end = int(secondItem.attrib[ "end"]) if (ruleSecondNew.start < 0 or ruleSecondNew.start > 59): raise ValueError("No valid value for 'end' " + "attribute in second tag.") if ruleSecondNew.start > ruleSecondNew.end: raise ValueError("'start' attribute not allowed to be " + "greater than 'end' attribute in second tag.") # create a wrapper element around the second element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "second" ruleElement.element = ruleSecondNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) else: raise ValueError("No valid tag was found.") # NOT is always an invalid rule (ignores all elements inside the # NOT element) return False elif (currentRoot.tag == "and" or currentRoot.tag == "or"): # set the current rule element to invald ruleValid = False # parse all "sensor" tags for item in currentRoot.iterfind("sensor"): ruleSensorNew = RuleSensor() ruleSensorNew.username = str(item.attrib["username"]) ruleSensorNew.remoteSensorId = int(item.attrib["remoteSensorId"]) # create a wrapper element around the sensor element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "sensor" ruleElement.element = ruleSensorNew ruleElement.timeTriggeredFor = float( item.attrib["timeTriggeredFor"]) # add wrapper element to the current rule currentRule.elements.append(ruleElement) # a sensor element always sets the rule to a valid rule ruleValid = True # parse all "weekday" tags for item in currentRoot.iterfind("weekday"): ruleWeekdayNew = RuleWeekday() # get time attribute and check if valid ruleWeekdayNew.time = str(item.attrib["time"]) if (ruleWeekdayNew.time != "local" and ruleWeekdayNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in weekday tag.") # get weekday attribute and check if valid ruleWeekdayNew.weekday = int(item.attrib[ "weekday"]) if (ruleWeekdayNew.weekday < 0 or ruleWeekdayNew.weekday > 6): raise ValueError("No valid value for 'weekday' " + "attribute in weekday tag.") # create a wrapper element around the weekday element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "weekday" ruleElement.element = ruleWeekdayNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse all "monthday" tags for item in currentRoot.iterfind("monthday"): ruleMonthdayNew = RuleMonthday() # get time attribute and check if valid ruleMonthdayNew.time = str(item.attrib["time"]) if (ruleMonthdayNew.time != "local" and ruleMonthdayNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in monthday tag.") # get monthday attribute and check if valid ruleMonthdayNew.monthday = int(item.attrib[ "monthday"]) if (ruleMonthdayNew.monthday < 1 or ruleMonthdayNew.monthday > 31): raise ValueError("No valid value for 'monthday' " + "attribute in monthday tag.") # create a wrapper element around the monthday element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "monthday" ruleElement.element = ruleMonthdayNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse all "hour" tags for item in currentRoot.iterfind("hour"): ruleHourNew = RuleHour() # get time attribute and check if valid ruleHourNew.time = str(item.attrib["time"]) if (ruleHourNew.time != "local" and ruleHourNew.time != "utc"): raise ValueError("No valid value for 'time' attribute " + "in hour tag.") # get start attribute and check if valid ruleHourNew.start = int(item.attrib[ "start"]) if (ruleHourNew.start < 0 or ruleHourNew.start > 23): raise ValueError("No valid value for 'start' " + "attribute in hour tag.") # get end attribute and check if valid ruleHourNew.end = int(item.attrib[ "end"]) if (ruleHourNew.start < 0 or ruleHourNew.start > 23): raise ValueError("No valid value for 'end' " + "attribute in hour tag.") if ruleHourNew.start > ruleHourNew.end: raise ValueError("'start' attribute not allowed to be" + "greater than 'end' attribute in hour tag.") # create a wrapper element around the hour element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "hour" ruleElement.element = ruleHourNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse all "minute" tags for item in currentRoot.iterfind("minute"): ruleMinuteNew = RuleMinute() # get start attribute and check if valid ruleMinuteNew.start = int(item.attrib[ "start"]) if (ruleMinuteNew.start < 0 or ruleMinuteNew.start > 59): raise ValueError("No valid value for 'start' " + "attribute in minute tag.") # get end attribute and check if valid ruleMinuteNew.end = int(item.attrib[ "end"]) if (ruleMinuteNew.start < 0 or ruleMinuteNew.start > 59): raise ValueError("No valid value for 'end' " + "attribute in minute tag.") if ruleMinuteNew.start > ruleMinuteNew.end: raise ValueError("'start' attribute not allowed to be " + "greater than 'end' attribute in minute tag.") # create a wrapper element around the minute element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "minute" ruleElement.element = ruleMinuteNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse all "second" tags for item in currentRoot.iterfind("second"): ruleSecondNew = RuleSecond() # get start attribute and check if valid ruleSecondNew.start = int(item.attrib[ "start"]) if (ruleSecondNew.start < 0 or ruleSecondNew.start > 59): raise ValueError("No valid value for 'start' " + "attribute in second tag.") # get end attribute and check if valid ruleSecondNew.end = int(item.attrib[ "end"]) if (ruleSecondNew.start < 0 or ruleSecondNew.start > 59): raise ValueError("No valid value for 'end' " + "attribute in second tag.") if ruleSecondNew.start > ruleSecondNew.end: raise ValueError("'start' attribute not allowed to be " + "greater than 'end' attribute in second tag.") # create a wrapper element around the second element # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "second" ruleElement.element = ruleSecondNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse all "and" tags for item in currentRoot.iterfind("and"): # create a new "and" rule ruleNew = RuleBoolean() ruleNew.type = "and" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element tempValid = parseRuleRecursively(item, ruleNew) # only set the rule to the result of the recursively parsing # if it is not already valid if not ruleValid: ruleValid = tempValid # parse all "or" tags for item in currentRoot.iterfind("or"): # create a new "or" rule ruleNew = RuleBoolean() ruleNew.type = "or" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element tempValid = parseRuleRecursively(item, ruleNew) # only set the rule to the result of the recursively parsing # if it is not already valid if not ruleValid: ruleValid = tempValid # parse all "not" tags for item in currentRoot.iterfind("not"): # create a new "not" rule ruleNew = RuleBoolean() ruleNew.type = "not" # create a wrapper element around the rule # to have meta information (i.e. triggered, # time when triggered, etc.) ruleElement = RuleElement() ruleElement.type = "boolean" ruleElement.element = ruleNew # add wrapper element to the current rule currentRule.elements.append(ruleElement) # parse rule starting from the new element parseRuleRecursively(item, ruleNew) # return if the current rule is valid return ruleValid else: raise ValueError("No valid tag found in rule.")
"monthday"]) if (ruleMonthdayNew.monthday < 1 or ruleMonthdayNew.monthday > 31): raise ValueError("No valid value for 'monthday' " + "attribute in monthday tag.") # fill wrapper element ruleElement.type = "monthday" ruleElement.element = ruleMonthdayNew # flag current rule as invalid rulesValid.append(False) elif not hourRule is None: ruleHourNew = RuleHour() # get time attribute and check if valid ruleHourNew.time = str(hourRule.attrib["time"]) if (ruleHourNew.time != "local" and ruleHourNew.time != "utc"): raise ValueError("No valid value for 'time' " + "attribute in hour tag.") # get start attribute and check if valid ruleHourNew.start = int(hourRule.attrib[ "start"]) if (ruleHourNew.start < 0 or ruleHourNew.start > 23): raise ValueError("No valid value for 'start' " + "attribute in hour tag.")