def test_rule_grouping_and_types(self): sheet_data = \ [RuleFactoryTest.header, \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '1', '', ''], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '1', '', ''], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '1', '', ''], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '2', 'ifany', 'if'], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '2', '', 'any'], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '3', '', ''], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '4', 'ifelse', ''], \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '4', 'ifelse', '', '']] # final group sizes should be 3, 2, 1, 2 # types are ifelse, ifany, single, ifany rf = RuleFactory(sheet_data) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(4, len(rule_groups)) self.assertEqual(3, len(rule_groups[0])) self.assertEqual(2, len(rule_groups[1])) self.assertEqual(1, len(rule_groups[2])) self.assertEqual(2, len(rule_groups[3])) self.assertTrue(isinstance(rule_groups[0], IfElseRuleGroup)) self.assertTrue(isinstance(rule_groups[1], IfAnyRuleGroup)) self.assertTrue(isinstance(rule_groups[2], SingleRuleGroup)) self.assertTrue(isinstance(rule_groups[3], IfElseRuleGroup))
def test_throw_for_bad_setup(self): # Throw for no inboxes passed when we try to create redirect rules sheet_data = \ [RuleFactoryTest.header, \ ['redirect- wont be created since we dont specify inboxes', 'apply', 'tyler', 'automation', '', '', '', 'redirect', 'value_exp', 'finder_expr', 'dest_expr', '1', '']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data) # Bad action name sheet_data = \ [RuleFactoryTest.header, \ ['match anything', 'apply', '', '', '', '', '', 'I dont know how to create an action for this string', 'value expression', '', 'dest expresssion', '2', '', '', '']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data) # no rule user specified sheet_data = \ [RuleFactoryTest.header, \ ['match anything', '', '', '', '', '', '', 'draft', 'value expression', '', 'dest expresssion', '2', '', '', '']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data) # group number does down sheet_data = \ [RuleFactoryTest.header, \ ['match anything', '', '', '', '', '', '', 'draft', 'value expression', '', 'dest expresssion', '2', '', ''], \ ['match anything', '', '', '', '', '', '', 'draft', 'value expression', '', 'dest expresssion', '1', '', '', '']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data) # group number not interpretable as float sheet_data = \ [RuleFactoryTest.header, \ ['match anything', '', '', '', '', '', '', 'draft', 'value expression', '', 'dest expresssion', '2.a', '', '', '']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data)
def test_create_rules(self): sheet_data = \ [RuleFactoryTest.header, \ ['remove automation', 'apply', '', 'automation', '', '', 'not thread.has_existing_draft()', 'unlabel', '"automation"', '', '', '0', '', '', ''], \ ['subject match, draft action', 'apply', '', '', 'sregex', '', '', 'draft', 'value expression', '', 'dest expresssion', '1', '', '', ''], \ ['match anything', 'apply', '', '', '', '', '', 'draft', 'value expression', '', 'dest expresssion', '2', '', '', '']] rf = RuleFactory(sheet_data) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(3, len(rule_groups)) group = rule_groups[0] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, ComboMatcher)) self.assertTrue(isinstance(rh.action, LabelAction)) self.assertTrue(rh.action.unset) group = rule_groups[1] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, ComboMatcher)) self.assertTrue(isinstance(rh.action, DraftAction)) self.assertEqual('value expression', rh.action.value) group = rule_groups[2] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, LabelMatcher)) self.assertTrue(isinstance(rh.action, DraftAction)) self.assertEqual('value expression', rh.action.value)
def test_attachement_forward_attachement_label_lookup_creation(self): sheet_data = \ [RuleFactoryTest.header, \ # basic attachment with a filename ['attachment', 'apply', '', '', '', 'body regext', '', 'attachment', '/home/tgaldes/Pictures/*txt', '', 'destination_email', '0', '', '', ''], \ # attach from existing thread attachments ['forward attachment', 'apply', '', '', '', 'body regext', '', 'forward_attachment', '', '', 'destination_email', '0', '', '', ''], \ # label lookup ['remove automation', 'apply', 'tyler', '', '', 'body regext', '', 'label_lookup', 'Schools/.*', 'inbox.query(get_approved_application_name(thread))', '', '0', '', '', '']] inboxes = {'apply': 'apply_inbox', 'tyler': 'tyler_inbox'} rf = RuleFactory(sheet_data, inboxes) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(1, len(rule_groups)) group = rule_groups[0] self.assertEqual(3, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, ComboMatcher)) # body & reverse label self.assertTrue(isinstance(rh.action, AttachmentAction)) rh = group[1] self.assertTrue(isinstance(rh.matcher, ComboMatcher)) self.assertTrue(isinstance(rh.action, ForwardAttachmentAction)) rh = group[2] self.assertTrue(isinstance(rh.matcher, BodyMatcher)) self.assertTrue(isinstance(rh.action, LabelLookupAction))
def test_need_inboxes_for_redirect(self): sheet_data = \ [RuleFactoryTest.header, \ ['redirect- wont be created since we dont specify inboxes', 'apply', 'tyler', 'automation', '', '', '', 'redirect', 'value_exp', 'finder_expr', 'dest_expr', '1']] inboxes = {'apply': 'apply_inbox', 'tyler': 'tyler_inbox'} rf = RuleFactory(sheet_data, inboxes) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(1, len(rule_groups)) group = rule_groups[0] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, LabelMatcher)) self.assertTrue(isinstance(rh.action, RedirectAction)) self.assertEqual('tyler_inbox', rh.action.inbox)
def test_prepend_draft_action(self): sheet_data = \ [RuleFactoryTest.header, \ ['remove automation', 'apply', '', '', '', 'body regext', '', 'prepend_draft', '"automation"', '', 'destination_email', '0', '', '', '']] rf = RuleFactory(sheet_data) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(1, len(rule_groups)) group = rule_groups[0] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, ComboMatcher)) self.assertTrue(isinstance(rh.action, DraftAction)) self.assertTrue(rh.action.prepend)
def test_body_regex_matcher(self): sheet_data = \ [RuleFactoryTest.header, \ ['remove automation', 'apply', '', '', '', 'body regext', '', 'unlabel', '"automation"', '', '', '0', '', '', '']] rf = RuleFactory(sheet_data) rule_groups = rf.get_rule_groups_for_user('apply') self.assertEqual(1, len(rule_groups)) group = rule_groups[0] self.assertEqual(1, len(group)) rh = group[0] self.assertTrue(isinstance(rh.matcher, BodyMatcher)) self.assertTrue(isinstance(rh.action, LabelAction)) self.assertTrue(rh.action.unset)
def test_only_specify_query_on_first_rule_of_rule_group(self): sheet_data = \ [RuleFactoryTest.header, \ ['remove automation', 'apply', '', '', '', 'body regext', '', 'prepend_draft', '"automation"', '', 'destination_email', '0', '', '', 'label:automation'], \ ['remove automation', 'apply', '', '', '', 'body regext', '', 'prepend_draft', '"automation"', '', 'destination_email', '0', '', '', 'label:automation']] with self.assertRaises(Exception): rf = RuleFactory(sheet_data)
def setup(self): self.inboxes = {} for service in self.mail_services: self.inboxes[service.get_user()] = Inbox(service) self.rule_factory = RuleFactory( framework.globals.g_org.get_rule_construction_data(), self.inboxes)
class Main: def __init__(self, mail_services, logger, config): self.logger = logger framework.globals.init(config, self.logger) self.mail_services = mail_services self.config = config def validate_rules(self): BaseValidator.set_validate_mode(True) for rule_group, user in self.rule_factory.get_rule_groups(): inbox = self.inboxes[user] for thread in inbox.query( 'label:automation/dev_test_case/validate'): self.logger.li( 'Processing user {} thread {} in validate mode'.format( thread, user)) rule_group.process(thread) BaseValidator.set_validate_mode(False) def setup(self): self.inboxes = {} for service in self.mail_services: self.inboxes[service.get_user()] = Inbox(service) self.rule_factory = RuleFactory( framework.globals.g_org.get_rule_construction_data(), self.inboxes) def refresh(self): for inbox in self.inboxes: self.inboxes[inbox].refresh() def run_one(self): try: for rule_group, user in self.rule_factory.get_rule_groups(): inbox = self.inboxes[user] threads = inbox.query(rule_group.get_query()) self.logger.li( 'Query: "{}" returned {} threads for user {}'.format( rule_group.get_query(), len(threads), user)) for thread in threads: self.logger.li('Processing user {} thread {}'.format( user, thread)) try: rule_group.process(thread) except bdb.BdbQuit as e: exit(0) except Exception as e: self.logger.le( 'Caught exception while processing: {}. Will continue execution of rules while skipping this thread' .format(thread)) self.logger.le('Trace: {}'.format( traceback.format_exc())) self.logger.le(str(e)) thread.set_label(constants.error_label) inbox.blacklist_id(thread.id()) self.logger.li( 'Refreshing inboxes and default queries for next loop.') self.refresh() return except bdb.BdbQuit as e: exit(0) except Exception as e: self.logger.lw('Caught exception in main. Stack: {}'.format( traceback.format_exc())) self.logger.li('Attempting to refresh again before continuing.') for i in range(10): try: self.refresh() return except bdb.BdbQuit as e: exit(0) except Exception as e: self.logger.lw( 'Caught exception while trying to refresh. Stack: {}'. format(traceback.format_exc())) self.refresh( ) # at this point just let the exception refresh is creating kill the program def run(self): if 'validate' in self.config and self.config['validate']: self.validate_rules() loop_count = 0 while True: self.run_one() loop_count += 1 self.logger.li('Finished iteration {} in main'.format(loop_count)) sleep(60)