def acquired_rules(self): # Short circuit if this is the root of the portal if ISiteRoot.providedBy(self.context): return [] in_use = set([r['id'] for r in self.assigned_rules()]) storage = getUtility(IRuleStorage) events = self._events() assignments = [] context = aq_parent(aq_inner(self.context)) while context is not None: assignable = IRuleAssignmentManager(context, None) if assignable is not None: for key, assignment in assignable.items(): if key not in in_use and assignment.bubbles: rule = storage.get(key, None) if rule is not None: assignments.append(dict(id=key, title=rule.title, description=rule.description, trigger=events.get(rule.event, "Unknown"), url=context.absolute_url() + '/@@manage-content-rules', enabled=(assignment.enabled and rule.enabled), )) if ISiteRoot.providedBy(context): context = None else: context = aq_parent(context) return assignments
def container_moved(container, event): if event.oldParent is None or event.newParent is None or \ event.oldName is None: return assignable = IRuleAssignmentManager(container, None) storage = queryUtility(IRuleStorage) if assignable is None or storage is None: return old_path = '{0}/{1}'.format( '/'.join(event.oldParent.getPhysicalPath()), event.oldName, ) new_path = '/'.join(container.getPhysicalPath()) if aq_base(event.object) is not aq_base(container): new_path_of_moved = '/'.join(event.object.getPhysicalPath()) old_path = old_path + new_path[len(new_path_of_moved):] for rule_name in assignable.keys(): rule = storage.get(rule_name, None) if rule is not None: assignments = get_assignments(rule) if old_path in assignments: assignments.remove(old_path) assignments.insert(new_path)
def _activate_rule(rule_id, context=None): assignable = IRuleAssignmentManager(context) assignment = assignable.get(rule_id, None) if not assignment: assignment = assignable[rule_id] = RuleAssignment(rule_id) assignment.enabled = True assignment.bubbles = True apirules.assign_rule(context, assignment.__name__)
def __call__(self, event, bubbled=False, rule_filter=None): assignments = IRuleAssignmentManager(self.context) for rule in assignments.getRules(event, bubbled=bubbled): if rule_filter is None or rule_filter(self.context, rule, event) == True: executable = getMultiAdapter((self.context, rule, event), IExecutable) executable() if rule.stop: raise StopRule(rule)
def _activate_rule(rule_id, context=None): storage = component.getUtility(IRuleStorage) rule = storage.get(rule_id) assignable = IRuleAssignmentManager(context) assignment = assignable.get(rule_id, None) if not assignment: assignment = assignable[rule_id] = RuleAssignment(rule_id) assignment.enabled = True assignment.bubbles = True get_assignments(rule).insert('/'.join(context.getPhysicalPath()))
def __call__(self): context = aq_inner(self.context) request = aq_inner(self.request) form = request.form status = IStatusMessage(self.request) operation = request.get('operation', None) if operation == 'move_up': assignable = IRuleAssignmentManager(context) rule_id = request.get('rule_id') keys = list(assignable.keys()) idx = keys.index(rule_id) del keys[idx] keys.insert(idx - 1, rule_id) assignable.updateOrder(keys) elif operation == 'move_down': assignable = IRuleAssignmentManager(context) rule_id = request.get('rule_id') keys = list(assignable.keys()) idx = keys.index(rule_id) del keys[idx] keys.insert(idx + 1, rule_id) assignable.updateOrder(keys) elif 'form.button.AddAssignment' in form: rule_id = form.get('rule_id') api.assign_rule(self.context, rule_id) elif 'form.button.Delete' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: api.unassign_rule(self.context, r) status.addStatusMessage(_(u'Assignments deleted.'), type='info') elif 'form.button.Enable' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: api.edit_rule_assignment(context, r, enabled=True) status.addStatusMessage(_(u'Assignments enabled.'), type='info') elif 'form.button.Disable' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: api.edit_rule_assignment(context, r, enabled=False) status.addStatusMessage(_(u'Assignments disabled.'), type='info') elif 'form.button.Bubble' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: api.edit_rule_assignment( context, r, bubbles=True, enabled=True) status.addStatusMessage(_(u'Changes saved.'), type='info') elif 'form.button.NoBubble' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: api.edit_rule_assignment(context, r, bubbles=False) status.addStatusMessage(_(u'Changes saved.'), type='info') return self.template()
def edit_rule_assignment(container, rule_id, bubbles=None, enabled=None): """Change a property of an assigned rule @param object container @param string rule_id @param bool enabled @param bool bubbles (apply in subfolders) """ assignable = IRuleAssignmentManager(container) assignment = assignable.get(rule_id, None) if bubbles is not None: assignment.bubbles = bool(bubbles) if enabled is not None: assignment.enabled = bool(enabled)
def container_removed(container, event): assignable = IRuleAssignmentManager(container, None) storage = queryUtility(IRuleStorage) if assignable is None or storage is None: return path = '/'.join(container.getPhysicalPath()) for rule_name in assignable.keys(): rule = storage.get(rule_name, None) if rule is not None: assignments = get_assignments(rule) if path in assignments: assignments.remove(path)
def setUp(self): self.portal = self.layer['portal'] self.request = self.layer['request'] login(self.portal, TEST_USER_NAME) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Folder', 'f1') self.folder = self.portal['f1'] self.folder.invokeFactory('Document', 'd1') self.portal.invokeFactory('Folder', 'target') self.folder.invokeFactory('Folder', 'f1') self.folder.f1.invokeFactory('Folder', 'f11') self.folder.f1.invokeFactory('Folder', 'f12') self.storage = getUtility(IRuleStorage) self.storage['r1'] = Rule() self.storage['r2'] = Rule() self.storage['r3'] = Rule() self.f11a = IRuleAssignmentManager(self.folder.f1.f11) self.f11a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f11.getPhysicalPath())) self.f12a = IRuleAssignmentManager(self.folder.f1.f12) self.f12a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f12.getPhysicalPath())) self.f12a['r2'] = RuleAssignment('r2', bubbles=True) insert_assignment(self.storage['r2'], '/'.join(self.folder.f1.f12.getPhysicalPath()))
def assignContentRulesToContainer(container, storage, bubbles): '''Assign the standard EDRN content events to the given container.''' assignmentManager = IRuleAssignmentManager(container, None) if assignmentManager is None: # This container doesn't support content rules, so skip it. return for eventName in _edrnContentEvents: assignment = assignmentManager.get(eventName, None) if assignment is None: # Brand new assignment assignment = assignmentManager[eventName] = RuleAssignment(eventName) if not assignment.enabled: assignment.enabled = True if assignment.bubbles != bubbles: assignment.bubbles = bubbles path = '/'.join(container.getPhysicalPath()) get_assignments(storage[eventName]).insert(path)
def apply_rule(folder, event): """ Apply content rule to execute a transition from new to pending """ name = "rule-transition-registration" storage = getUtility(IRuleStorage) # Assignment assignable = IRuleAssignmentManager(folder, None) if assignable is None: return assignment = assignable.get(name, None) if assignment is None: assignment = assignable[name] = RuleAssignment(name) assignment.enabled = True assignment.bubbles = False path = "/".join(folder.getPhysicalPath()) get_assignments(storage[name]).insert(path)
def assigned_rules(self): assignable = IRuleAssignmentManager(self.context) storage = getUtility(IRuleStorage) events = self._events() assignments = [] for key, assignment in assignable.items(): rule = storage.get(key, None) if rule is not None: assignments.append(dict(id=key, title=rule.title, description=rule.description, trigger=events.get(rule.event, "Unknown"), url=self._rule_url(key), bubbles=assignment.bubbles, enabled=assignment.enabled, global_enabled=rule.enabled, )) return assignments
def setup_contentrules_registration(registrations): assignable = IRuleAssignmentManager(registrations, None) if assignable is None: return None storage = getUtility(IRuleStorage) path = '/'.join(registrations.getPhysicalPath()) names = [ 'registration-rule-transition', 'registration-new', 'registration-confirmed', ] for name in names: assignment = assignable.get(name, None) if assignment is None: assignment = assignable[name] = RuleAssignment(name) assignment.enabled = True assignment.bubbles = True get_assignments(storage[name]).insert(path)
def setup_contentrules_program(program): assignable = IRuleAssignmentManager(program, None) if assignable is None: return None storage = getUtility(IRuleStorage) path = '/'.join(program.getPhysicalPath()) names = [ 'talk-submited', 'talk-accepted', 'training-submited', 'training-accepted', ] for name in names: assignment = assignable.get(name, None) if assignment is None: assignment = assignable[name] = RuleAssignment(name) assignment.enabled = True assignment.bubbles = True get_assignments(storage[name]).insert(path)
def assign_rule(container, rule_id, enabled=True, bubbles=True, insert_before=None): """Assign @param string rule_id rule to @param object container with options @param bool enabled @param bool bubbles (apply in subfolders) @param string insert-before """ storage = queryUtility(IRuleStorage) if storage is None: return assignable = IRuleAssignmentManager(container, None) if assignable is None: return assignment = assignable.get(rule_id, None) if assignment is None: assignable[rule_id] = RuleAssignment(rule_id) assignable[rule_id].enabled = bool(enabled) assignable[rule_id].bubbles = bool(bubbles) path = '/'.join(container.getPhysicalPath()) insert_assignment(storage[rule_id], path) if insert_before: position = None keys = list(assignable.keys()) if insert_before == "*": position = 0 elif insert_before in keys: position = keys.index(insert_before) if position is not None: keys.remove(rule_id) keys.insert(position, rule_id) assignable.updateOrder(keys)
def __call__(self, event, bubbled=False, rule_filter=None): assignments = IRuleAssignmentManager(self.context) for rule in assignments.getRules(event, bubbled=bubbled): # for each rule assigned in this context - bubbled means rule apply on subfolders if rule_filter is None or rule_filter(self.context, rule, event) == True: # execute the rule if it is not filtered, for exemple, # it has not been executed on the same content but from an other context # in the same request # we store cascading option in the filter. if true, this will allow # rules to be executed because of the actions ran by this rule. if rule_filter is not None: cascade_before = getattr(rule_filter, 'cascade', False) rule_filter.cascade = rule.cascading executable = getMultiAdapter((self.context, rule, event), IExecutable) executable() if rule_filter is not None: rule_filter.cascade = cascade_before if rule.stop: # stop rule execution if 'Stop rules after' option has been selected raise StopRule(rule)
def afterSetUp(self): self.folder.invokeFactory('Folder', 'f1') self.folder.f1.invokeFactory('Folder', 'f11') self.folder.f1.invokeFactory('Folder', 'f12') self.storage = getUtility(IRuleStorage) self.storage['r1'] = Rule() self.storage['r2'] = Rule() self.storage['r3'] = Rule() self.f11a = IRuleAssignmentManager(self.folder.f1.f11) self.f11a['r1'] = RuleAssignment('r1', bubbles=True) get_assignments(self.storage['r1']).insert('/'.join(self.folder.f1.f11.getPhysicalPath())) self.f12a = IRuleAssignmentManager(self.folder.f1.f12) self.f12a['r1'] = RuleAssignment('r1', bubbles=True) get_assignments(self.storage['r1']).insert('/'.join(self.folder.f1.f12.getPhysicalPath())) self.f12a['r2'] = RuleAssignment('r2', bubbles=True) get_assignments(self.storage['r2']).insert('/'.join(self.folder.f1.f12.getPhysicalPath()))
def testAssignmentOrdering(self): assignable = IRuleAssignmentManager(self.portal.news) self.assertEquals([u'test1'], assignable.keys())
class TestRuleAssignmentMapping(ContentRulesTestCase): def afterSetUp(self): self.folder.invokeFactory('Folder', 'f1') self.folder.f1.invokeFactory('Folder', 'f11') self.folder.f1.invokeFactory('Folder', 'f12') self.storage = getUtility(IRuleStorage) self.storage['r1'] = Rule() self.storage['r2'] = Rule() self.storage['r3'] = Rule() self.f11a = IRuleAssignmentManager(self.folder.f1.f11) self.f11a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f11.getPhysicalPath())) self.f12a = IRuleAssignmentManager(self.folder.f1.f12) self.f12a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f12.getPhysicalPath())) self.f12a['r2'] = RuleAssignment('r2', bubbles=True) insert_assignment(self.storage['r2'], '/'.join(self.folder.f1.f12.getPhysicalPath())) def testRuleRemoved(self): self.assertTrue('r1' in self.f11a) self.assertTrue('r1' in self.f12a) del self.storage['r1'] self.assertFalse('r1' in self.f11a) self.assertFalse('r1' in self.f12a) def testContainerMoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder.f1.manage_renameObject('f12', 'f12a') f12apath = '/'.join(self.folder.f1.f12a.getPhysicalPath()) self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) def testParentOfContainerMoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder.manage_renameObject('f1', 'f1a') f12apath = '/'.join(self.folder.f1a.f12.getPhysicalPath()) self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) def testContainerRemoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder._delObject('f1') self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) def testRuleAssignmentRemovedAPI(self): self.assertTrue('r1' in self.f11a) self.assertTrue('r1' in self.f12a) api.unassign_rule(self.folder.f1.f11, 'r1') self.assertFalse('r1' in self.f11a) self.assertTrue('r1' in self.f12a) def testRuleAssignmentEditedAPI(self): self.assertTrue(self.f11a['r1'].bubbles) self.assertTrue(self.f11a['r1'].enabled) api.edit_rule_assignment(self.folder.f1.f11, 'r1', bubbles=False, enabled=False) self.assertFalse(self.f11a['r1'].bubbles) self.assertFalse(self.f11a['r1'].enabled) api.edit_rule_assignment(self.folder.f1.f11, 'r1', bubbles=True, enabled=True) self.assertTrue(self.f11a['r1'].bubbles) self.assertTrue(self.f11a['r1'].enabled) def testRuleAssignmentAddedAPI(self): api.assign_rule(self.folder.f1.f11, 'r2', enabled=True, bubbles=True) self.assertTrue('r2' in self.f11a) self.assertTrue(self.f11a['r2'].enabled) self.assertTrue(self.f11a['r2'].bubbles) api.assign_rule(self.folder.f1.f11, 'r3', enabled=True, bubbles=False, insert_before='r2') self.assertTrue('r3' in self.f11a) self.assertTrue(self.f11a['r3'].enabled) self.assertFalse(self.f11a['r3'].bubbles) self.assertEqual(self.f11a.keys(), ['r1', 'r3', 'r2'])
def __call__(self): context = aq_inner(self.context) request = aq_inner(self.request) form = request.form path = '/'.join(context.getPhysicalPath()) status = IStatusMessage(self.request) assignable = IRuleAssignmentManager(context) storage = getUtility(IRuleStorage) operation = request.get('operation', None) if operation == 'move_up': rule_id = request.get('rule_id') keys = list(assignable.keys()) idx = keys.index(rule_id) del keys[idx] keys.insert(idx-1, rule_id) assignable.updateOrder(keys) elif operation == 'move_down': rule_id = request.get('rule_id') keys = list(assignable.keys()) idx = keys.index(rule_id) del keys[idx] keys.insert(idx+1, rule_id) assignable.updateOrder(keys) elif 'form.button.AddAssignment' in form: rule_id = form.get('rule_id') assignable[rule_id] = RuleAssignment(rule_id) get_assignments(storage[rule_id]).insert(path) elif 'form.button.Delete' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: del assignable[r] get_assignments(storage[r]).remove(path) status.addStatusMessage(_(u"Assignments deleted."), type='info') elif 'form.button.Enable' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: assignment = assignable.get(r, None) if assignment is not None: assignment.enabled = True status.addStatusMessage(_(u"Assignments enabled."), type='info') elif 'form.button.Disable' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: assignment = assignable.get(r, None) if assignment is not None: assignment.enabled = False status.addStatusMessage(_(u"Assignments disabled."), type='info') elif 'form.button.Bubble' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: assignment = assignable.get(r, None) if assignment is not None: assignment.bubbles = True status.addStatusMessage(_(u"Changes saved."), type='info') elif 'form.button.NoBubble' in form: rule_ids = form.get('rule_ids', ()) for r in rule_ids: assignment = assignable.get(r, None) if assignment is not None: assignment.bubbles = False status.addStatusMessage(_(u"Changes saved."), type='info') return self.template()
def testAssignmentOrdering(self): assignable = IRuleAssignmentManager(self.portal.news) self.assertEqual(set([u'test3', u'test2', u'test1']), set(assignable.keys()))
def _initRules(self, node): """Import rules from the given node """ site = self.environ.getSite() storage = queryUtility(IRuleStorage) if storage is None: return for child in node.childNodes: if child.nodeName == 'rule': rule = None name = child.getAttribute('name') if name: rule = storage.get(name, None) if rule is None: rule = Rule() if not name: chooser = INameChooser(storage) name = chooser.chooseName(None, rule) storage[name] = rule else: # Clear out conditions and actions since we're expecting new ones del rule.conditions[:] del rule.actions[:] rule.title = child.getAttribute('title') rule.description = child.getAttribute('description') event_name = child.getAttribute('event') rule.event = _resolveDottedName(event_name) if not rule.event: raise ImportError("Can not import %s" % event_name) rule.enabled = as_bool(child.getAttribute('enabled'), True) rule.stop = as_bool(child.getAttribute('stop-after')) # Aq-wrap to enable complex setters for elements below # to work rule = rule.__of__(site) for rule_config_node in child.childNodes: if rule_config_node.nodeName == 'conditions': for condition_node in rule_config_node.childNodes: if not condition_node.nodeName == 'condition': continue type_ = condition_node.getAttribute('type') element_type = getUtility(IRuleCondition, name=type_) if element_type.factory is None: continue condition = element_type.factory() # Aq-wrap in case of complex setters condition = condition.__of__(rule) handler = IRuleElementExportImportHandler(condition) handler.import_element(condition_node) rule.conditions.append(aq_base(condition)) elif rule_config_node.nodeName == 'actions': for action_node in rule_config_node.childNodes: if not action_node.nodeName == 'action': continue type_ = action_node.getAttribute('type') element_type = getUtility(IRuleAction, name=type_) if element_type.factory is None: continue action = element_type.factory() # Aq-wrap in case of complex setters action = action.__of__(rule) handler = IRuleElementExportImportHandler(action) handler.import_element(action_node) rule.actions.append(aq_base(action)) elif child.nodeName == 'assignment': location = child.getAttribute('location') if location.startswith("/"): location = location[1:] try: container = site.unrestrictedTraverse(str(location)) except KeyError: continue assignable = IRuleAssignmentManager(container, None) if assignable is None: continue name = child.getAttribute('name') assignment = assignable.get(name, None) if assignment is None: assignment = assignable[name] = RuleAssignment(name) assignment.enabled = as_bool(child.getAttribute('enabled')) assignment.bubbles = as_bool(child.getAttribute('bubbles')) insert_before = child.getAttribute('insert-before') if insert_before: position = None keys = list(assignable.keys()) if insert_before == "*": position = 0 elif insert_before in keys: position = keys.index(insert_before) if position is not None: keys.remove(name) keys.insert(position, name) assignable.updateOrder(keys) path = '/'.join(container.getPhysicalPath()) get_assignments(storage[name]).insert(path)
class TestRuleAssignmentMapping(unittest.TestCase): layer = PLONE_APP_CONTENTRULES_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.request = self.layer['request'] login(self.portal, TEST_USER_NAME) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Folder', 'f1') self.folder = self.portal['f1'] self.folder.invokeFactory('Document', 'd1') self.portal.invokeFactory('Folder', 'target') self.folder.invokeFactory('Folder', 'f1') self.folder.f1.invokeFactory('Folder', 'f11') self.folder.f1.invokeFactory('Folder', 'f12') self.storage = getUtility(IRuleStorage) self.storage['r1'] = Rule() self.storage['r2'] = Rule() self.storage['r3'] = Rule() self.f11a = IRuleAssignmentManager(self.folder.f1.f11) self.f11a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f11.getPhysicalPath())) self.f12a = IRuleAssignmentManager(self.folder.f1.f12) self.f12a['r1'] = RuleAssignment('r1', bubbles=True) insert_assignment(self.storage['r1'], '/'.join(self.folder.f1.f12.getPhysicalPath())) self.f12a['r2'] = RuleAssignment('r2', bubbles=True) insert_assignment(self.storage['r2'], '/'.join(self.folder.f1.f12.getPhysicalPath())) def testRuleRemoved(self): self.assertTrue('r1' in self.f11a) self.assertTrue('r1' in self.f12a) del self.storage['r1'] self.assertFalse('r1' in self.f11a) self.assertFalse('r1' in self.f12a) def testContainerMoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder.f1.manage_renameObject('f12', 'f12a') f12apath = '/'.join(self.folder.f1.f12a.getPhysicalPath()) self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) def testParentOfContainerMoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder.manage_renameObject('f1', 'f1a') f12apath = '/'.join(self.folder.f1a.f12.getPhysicalPath()) self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) self.assertTrue(f12apath in get_assignments(self.storage['r1'])) def testContainerRemoved(self): f12path = '/'.join(self.folder.f1.f12.getPhysicalPath()) self.assertTrue(f12path in get_assignments(self.storage['r1'])) self.assertTrue(f12path in get_assignments(self.storage['r2'])) transaction.savepoint(1) self.folder._delObject('f1') self.assertFalse(f12path in get_assignments(self.storage['r1'])) self.assertFalse(f12path in get_assignments(self.storage['r2'])) def testRuleAssignmentRemovedAPI(self): self.assertTrue('r1' in self.f11a) self.assertTrue('r1' in self.f12a) api.unassign_rule(self.folder.f1.f11, 'r1') self.assertFalse('r1' in self.f11a) self.assertTrue('r1' in self.f12a) def testRuleAssignmentEditedAPI(self): self.assertTrue(self.f11a['r1'].bubbles) self.assertTrue(self.f11a['r1'].enabled) api.edit_rule_assignment(self.folder.f1.f11, 'r1', bubbles=False, enabled=False) self.assertFalse(self.f11a['r1'].bubbles) self.assertFalse(self.f11a['r1'].enabled) api.edit_rule_assignment(self.folder.f1.f11, 'r1', bubbles=True, enabled=True) self.assertTrue(self.f11a['r1'].bubbles) self.assertTrue(self.f11a['r1'].enabled) def testRuleAssignmentAddedAPI(self): api.assign_rule(self.folder.f1.f11, 'r2', enabled=True, bubbles=True) self.assertTrue('r2' in self.f11a) self.assertTrue(self.f11a['r2'].enabled) self.assertTrue(self.f11a['r2'].bubbles) api.assign_rule(self.folder.f1.f11, 'r3', enabled=True, bubbles=False, insert_before='r2') self.assertTrue('r3' in self.f11a) self.assertTrue(self.f11a['r3'].enabled) self.assertFalse(self.f11a['r3'].bubbles) self.assertEqual(self.f11a.keys(), ['r1', 'r3', 'r2'])
def _extractRules(self): """Extract rules to a document fragment """ site = self.environ.getSite() storage = queryUtility(IRuleStorage) if storage is None: return fragment = self._doc.createDocumentFragment() assignment_paths = set() for name, rule in storage.items(): rule_node = self._doc.createElement('rule') rule_node.setAttribute('name', name) rule_node.setAttribute('title', rule.title) rule_node.setAttribute('description', rule.description) rule_node.setAttribute('event', _getDottedName(rule.event)) rule_node.setAttribute('enabled', str(rule.enabled)) rule_node.setAttribute('stop-after', str(rule.stop)) rule_node.setAttribute('cascading', str(rule.cascading)) # Aq-wrap so that exporting fields with clever getters or # vocabularies will work. We also aq-wrap conditions and # actions below. rule = rule.__of__(site) # Add conditions conditions_node = self._doc.createElement('conditions') for condition in rule.conditions: condition_data = IRuleElementData(condition) condition = condition.__of__(rule) condition_node = self._doc.createElement('condition') condition_node.setAttribute('type', condition_data.element) handler = IRuleElementExportImportHandler(condition) handler.export_element(self._doc, condition_node) conditions_node.appendChild(condition_node) rule_node.appendChild(conditions_node) # Add actions actions_node = self._doc.createElement('actions') for action in rule.actions: action_data = IRuleElementData(action) action = action.__of__(rule) action_node = self._doc.createElement('action') action_node.setAttribute('type', action_data.element) handler = IRuleElementExportImportHandler(action) handler.export_element(self._doc, action_node) actions_node.appendChild(action_node) rule_node.appendChild(actions_node) fragment.appendChild(rule_node) assignment_paths.update(get_assignments(rule)) # Export assignments last - this is necessary to ensure they # are orderd properly site_path_length = len('/'.join(site.getPhysicalPath())) for path in assignment_paths: try: container = site.unrestrictedTraverse(path) except KeyError: continue assignable = IRuleAssignmentManager(container, None) if assignable is None: continue location = path[site_path_length:] for name, assignment in assignable.items(): assignment_node = self._doc.createElement('assignment') assignment_node.setAttribute('location', location) assignment_node.setAttribute('name', name) assignment_node.setAttribute('enabled', str(assignment.enabled)) assignment_node.setAttribute('bubbles', str(assignment.bubbles)) fragment.appendChild(assignment_node) return fragment