Example #1
0
 def setUp(self):
     options = {
         "test": True,
         "host": "localhost",
         "port": 25,
         "sender": "*****@*****.**"
     }
     self.emailer = Emailer(options)
Example #2
0
class EmailerTests(unittest.TestCase):
    def setUp(self):
        options = {
            "test": True,
            "host": "localhost",
            "port": 25,
            "sender": "*****@*****.**"
        }
        self.emailer = Emailer(options)

    def test_recipient_format(self):
        # Test that we require at least one of "to", "cc" or "bcc" to send an email.
        recipients = {"fail": "*****@*****.**"}
        self.assertRaises(NotifyError, self.emailer.format, recipients, u"This is the subject!", u"This is the body!")

    def test_recipient_dict_format(self):
        # Test that recipients must be a dict.
        recipients = "fail"
        self.assertRaises(NotifyError, self.emailer.format, recipients, u"This is the subject!", u"This is the body!")

    def test_basic_format(self):
        # Test the basic case of formatting the email correctly.
        recipients = {"to": "*****@*****.**"}
        recipient_addrs, message = self.emailer.format(recipients, u"This is the subject!", u"This is the body!")

        self.assertEqual(recipient_addrs, ['*****@*****.**'])

        expected_msg = u"From: [email protected]\r\nTo: [email protected]\r\nSubject: This is the subject!\r\n\r\nThis is the body!"
        self.assertEqual(message, expected_msg)

    def test_advanced_format(self):
        # Make sure we can handle all of the input formats we accept.
        recipients = {
            "to": "*****@*****.**",
            "cc": ["*****@*****.**", "*****@*****.**"],
            "bcc": "[email protected], [email protected],[email protected]"
        }
        recipient_addrs, message = self.emailer.format(recipients, u"This is the subject!", u"This is the body!")

        expected_recipient_addrs = ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**']
        self.assertEqual(recipient_addrs, expected_recipient_addrs)

        expected_msg = u"From: [email protected]\r\nCc: [email protected], [email protected]\r\nTo: [email protected]\r\nSubject: This is the subject!\r\n\r\nThis is the body!"
        self.assertEqual(message, expected_msg)
Example #3
0
def main():
    # Deal with the command line arguments
    current_dir = os.path.dirname(os.path.realpath(__file__))
    settings_path = sys.argv[1] if len(sys.argv) >= 2 else '{0}/settings.json'.format(current_dir)
    log_path = sys.argv[2] if len(sys.argv) >= 3 else '{0}/flmx-validator.log'.format(current_dir)

    # First off set up the logging.
    logger = logging.getLogger('flmx-logger')
    logger.setLevel(logging.DEBUG)

    handler = logging.handlers.RotatingFileHandler(log_path, maxBytes=104857600, backupCount=3)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    try:
        # Load json settings, either from command line argument or default location.
        settings = JsonSettings(settings_path)
        logger.info("Settings loaded from {0}".format(settings_path))

        # Setup validator, emailer and feeds.
        validator = Validator(**settings.json_data['validator'])
        logger.info("Validator at endpoint {0} initialised".format(validator.endpoint))

        feeds = []
        for feed in settings.json_data['feeds']:
            f = Feed(**feed)
            feeds.append(f)
            logger.info("Feed at endpoint {0} initialised".format(f.endpoint))

        emailer = Emailer(settings.json_data['email'])

        # Start validation loop.
        while (True):
            for feed in feeds:
                # If feed is not currently being validated, and it was last validated longer than [next_try] ago, start validation.
                if feed.validation_start_time is None and (feed.last_validated is None or datetime.now() > feed.last_validated + feed.next_try):
                    logger.info("Sending validation request for {0} [{1}] to {2}".format(feed.name, feed.endpoint, validator.endpoint))
                    validator.start(feed)

                # Else if the validation must have started
                elif feed.validation_start_time is not None:
                    logger.info("Polling validation results for {0} [{1}] from {2}".format(feed.name, feed.endpoint, validator.endpoint))
                    completed, success, total_issues, response_json = validator.poll_results(feed)

                    # If the process has completed and the result was a failure, send an email notification.
                    if completed:
                        if not success:
                            logger.info("Validation for {0} [{1}] resulted in errors, sending email to {2}".format(feed.name, feed.endpoint, feed.failure_email))

                            title = u'Validation failed for {feed} [{endpoint}] ({total_issues} {issues})'.format(
                                    feed = feed.name,
                                    endpoint = feed.endpoint,
                                    total_issues = total_issues,
                                    issues = "Issues" if total_issues > 1 else "Issue")
                            body = json.dumps(response_json, indent=4, separators=(',', ': '), sort_keys=True)
                            emailer.send(feed.failure_email, title, body)

                            logger.info("Email sent to {0}".format(feed.failure_email))
                        else:
                            logger.info("Validation completed successfully for {0} [{1}]".format(feed.name, feed.endpoint))

                    # Check to make sure we haven't hit some weird behaviour and have been stuck polling for > 6 hours.
                    elif feed.last_validated is not None and datetime.now() > feed.last_validated + timedelta(hours=6):
                        # If we have then let's just kick off another validation request.
                        feed.validation_start_time = None
                        logger.debug("Have been polling {0} for > 6 hours, must be a problem lets rinse and repeat.".format(feed.name))
                        break

            time.sleep(300) # Wait for a bit to try again, hopefully this should account for most differences in time between the executing and validation server too.

    except Exception as e:
        logger.debug("Unhandled exception occured: {0}".format(e))
        logger.debug(traceback.format_exc())
        logger.debug("Closing application.")

        sys.exit()