def run(self, run_datetime): logger = self.config.logger if self.config.test_mode: logger.warning('You are running Automatic Emails cron app ' 'in test mode') delay = datetime.timedelta(days=self.config.delay_between_emails) params = { 'start_date': run_datetime - datetime.timedelta(hours=1), 'end_date': run_datetime, 'delayed_date': run_datetime - delay, 'products': tuple(self.config.restrict_products) } # Find the indexes to use to optimize the elasticsearch query. indexes = self.generate_list_of_indexes( params['start_date'], params['end_date'], self.config.elasticsearch.elasticsearch_index ) # Create and configure the search object. connection = SuperS().es( urls=self.config.elasticsearch.elasticsearch_urls, timeout=self.config.elasticsearch.elasticsearch_timeout, ) search = ( connection.indexes(*indexes).doctypes( self.config.elasticsearch.elasticsearch_doctype ).order_by('processed_crash.email') ) # Create filters. args_and = { 'processed_crash.date_processed__lt': params['end_date'], 'processed_crash.date_processed__gt': params['start_date'], 'processed_crash.product': [x.lower() for x in params['products']], } args_not = { 'processed_crash.email__missing': None, } filters = elasticutils.F(**args_and) filters &= ~elasticutils.F(**args_not) search = search.filter(filters) count = search.count() # Total number of results. search = search[:count] # Get the recently sent emails emails = self.get_list_of_emails(params, connection) validation_rules = TransformRuleSystem() validation_rules.load_rules(( (verify_email, (), {}, sanitize_email, (), {}), (verify_email, (), {}, False, (), {}), ( verify_email_last_sending, (), {'emails_list': emails}, True, (), {} ), )) template_rules = TransformRuleSystem() template_rules.load_rules(( ( verify_support_classification, ('bitguard',), {}, set_email_template, ('socorro_bitguard_en',), {} ), # If no other rule passed, fall back to the default template. ( True, (), {}, set_email_template, (self.config.email_template,), {} ), )) for hit in search.values_dict( 'processed_crash.email', 'processed_crash.classifications.support.classification', ): res = validation_rules.apply_until_predicate_fails(hit) if res is None: # All predicates succeeded! # Now apply all template rules to find which email template # to use. template_rules.apply_until_action_succeeds(hit) if not hit['email_template']: # Bug 965610 - If the email template is empty, do not send # an email. Setting the default email template to '' means # no generic email will be sent anymore. continue email = hit['processed_crash.email'] self.send_email(hit) self.update_user(email, run_datetime, connection.get_es()) emails[email] = run_datetime # logger.info('Automatic Email sent to %s', email) # Make sure the next run will have updated data, to avoid sending an # email several times. connection.get_es().refresh()
def run(self, run_datetime): logger = self.config.logger if self.config.test_mode: logger.warning('You are running Automatic Emails cron app ' 'in test mode') delay = datetime.timedelta(days=self.config.delay_between_emails) params = { 'start_date': run_datetime - datetime.timedelta(hours=1), 'end_date': run_datetime, 'delayed_date': run_datetime - delay, 'products': tuple(self.config.restrict_products) } # Find the indexes to use to optimize the elasticsearch query. indexes = self.generate_list_of_indexes( params['start_date'], params['end_date'], self.config.elasticsearch.elasticsearch_index ) # Create and configure the search object. connection = SuperS().es( urls=self.config.elasticsearch.elasticsearch_urls, timeout=self.config.elasticsearch.elasticsearch_timeout, ) search = (connection.indexes(*indexes) .doctypes( self.config.elasticsearch.elasticsearch_doctype ) .order_by('processed_crash.email')) # Create filters. args_and = { 'processed_crash.date_processed__lt': params['end_date'], 'processed_crash.date_processed__gt': params['start_date'], 'processed_crash.product': [x.lower() for x in params['products']], } args_not = { 'processed_crash.email__missing': None, } filters = elasticutils.F(**args_and) filters &= ~elasticutils.F(**args_not) search = search.filter(filters) count = search.count() # Total number of results. search = search[:count] # Get the recently sent emails emails = self.get_list_of_emails(params, connection) validation_rules = TransformRuleSystem() validation_rules.load_rules(( (verify_email, (), {}, sanitize_email, (), {}), (verify_email, (), {}, False, (), {}), ( verify_email_last_sending, (), {'emails_list': emails}, True, (), {} ), )) template_rules = TransformRuleSystem() template_rules.load_rules(( ( verify_support_classification, ('bitguard',), {}, set_email_template, ('socorro_bitguard_en',), {} ), # If no other rule passed, fall back to the default template. ( True, (), {}, set_email_template, (self.config.email_template,), {} ), )) for hit in search.values_dict( 'processed_crash.email', 'processed_crash.classifications.support.classification', ): res = validation_rules.apply_until_predicate_fails(hit) if res is None: # All predicates succeeded! # Now apply all template rules to find which email template # to use. template_rules.apply_until_action_succeeds(hit) email = hit['processed_crash.email'] self.send_email(hit) self.update_user(email, run_datetime, connection.get_es()) emails[email] = run_datetime # logger.info('Automatic Email sent to %s', email) # Make sure the next run will have updated data, to avoid sending an # email several times. connection.get_es().refresh()