diff --git a/mailosaur/models/__init__.py b/mailosaur/models/__init__.py index e7a053a..f6466f9 100644 --- a/mailosaur/models/__init__.py +++ b/mailosaur/models/__init__.py @@ -1,6 +1,7 @@ from .spam_assassin_rule import SpamAssassinRule from .spam_filter_results import SpamFilterResults from .spam_analysis_result import SpamAnalysisResult +from .deliverability_report import DeliverabilityReport from .mailosaur_exception import MailosaurException from .message_address import MessageAddress from .link import Link @@ -37,6 +38,7 @@ 'SpamAssassinRule', 'SpamFilterResults', 'SpamAnalysisResult', + 'DeliverabilityReport', 'MailosaurException', 'MessageAddress', 'Link', diff --git a/mailosaur/models/block_list_result.py b/mailosaur/models/block_list_result.py new file mode 100644 index 0000000..b4d89ab --- /dev/null +++ b/mailosaur/models/block_list_result.py @@ -0,0 +1,20 @@ +from .result_enum import ResultEnum + +class BlockListResult(object): + """BlockListResult. + + :param id: + :type id: string + :param name: + :type name: string + :param result: + :type result: ~mailosaur.models.ResultEnum + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.id = data.get('id', None) + self.name = data.get('name', None) + self.result = ResultEnum(data.get('result', None)) diff --git a/mailosaur/models/content.py b/mailosaur/models/content.py new file mode 100644 index 0000000..b53b8f2 --- /dev/null +++ b/mailosaur/models/content.py @@ -0,0 +1,37 @@ + +class Content(object): + """Content. + + :param embed: + :type embed: boolean + :param iframe: + :type iframe: boolean + :param object: + :type object: boolean + :param script: + :type script: boolean + :param short_urls: + :type short_urls: boolean + :param text_size: + :type text_size: int + :param total_size: + :type total_size: int + :param missing_alt: + :type missing_alt: boolean + :param missing_list_unsubscribe: + :type missing_list_unsubscribe: boolean + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.embed = data.get('embed', None) + self.iframe = data.get('iframe', None) + self.object = data.get('object', None) + self.script = data.get('script', None) + self.short_urls = data.get('shortUrls', None) + self.text_size = data.get('textSize', None) + self.total_size = data.get('totalSize', None) + self.missing_alt = data.get('missingAlt', None) + self.missing_list_unsubscribe = data.get('missingListUnsubscribe', None) \ No newline at end of file diff --git a/mailosaur/models/deliverability_report.py b/mailosaur/models/deliverability_report.py new file mode 100644 index 0000000..c028482 --- /dev/null +++ b/mailosaur/models/deliverability_report.py @@ -0,0 +1,36 @@ +from .email_authentication_result import EmailAuthenticationResult +from .block_list_result import BlockListResult +from .content import Content +from .dns_records import DnsRecords +from .spam_assassin_result import SpamAssassinResult + +class DeliverabilityReport(object): + """DeliverabilityReport. + + :param spf: + :type spf: ~mailosaur.models.EmailAuthenticationResult + :param dkim: + :type dkim: list[~mailosaur.models.EmailAuthenticationResult] + :param dmarc: + :type dmarc: ~mailosaur.models.EmailAuthenticationResult + :param block_list: + :type block_lists: list[~mailosaur.models.BlockListResult] + :param content: + :type content: ~mailosaur.models.Content + :param dns_records: + :type dns_records: ~mailosaur.models.DnsRecords + :param spam_assassin: + :type spam_assassin: ~mailosaur.models.SpamAssassinResult + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.spf = EmailAuthenticationResult(data.get('spf', None)) + self.dkim = [EmailAuthenticationResult(i) for i in data.get('dkim', None)] + self.dmarc = EmailAuthenticationResult(data.get('dmarc', None)) + self.block_lists = [BlockListResult(i) for i in data.get('blockLists', None)] + self.content = Content(data.get('content', None)) + self.dns_records = DnsRecords(data.get('dnsRecords', None)) + self.spam_assassin = SpamAssassinResult(data.get('spamAssassin', None)) diff --git a/mailosaur/models/dns_records.py b/mailosaur/models/dns_records.py new file mode 100644 index 0000000..011e061 --- /dev/null +++ b/mailosaur/models/dns_records.py @@ -0,0 +1,20 @@ +from .spam_assassin_rule import SpamAssassinRule + +class DnsRecords(object): + """DnsRecords. + + :param a: + :type a: list[string] + :param mx: + :type mx: list[string] + :param ptr: + :type ptr: list[string] + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.a = [a for a in data.get('a', None)] + self.mx = [mx for mx in data.get('mx', None)] + self.ptr = [ptr for ptr in data.get('ptr', None)] \ No newline at end of file diff --git a/mailosaur/models/email_authentication_result.py b/mailosaur/models/email_authentication_result.py new file mode 100644 index 0000000..965a034 --- /dev/null +++ b/mailosaur/models/email_authentication_result.py @@ -0,0 +1,24 @@ +from .spam_filter_results import SpamFilterResults +from .result_enum import ResultEnum + +class EmailAuthenticationResult(object): + """EmailAuthenticationResult. + + :param result: + :type result: ~mailosaur.models.ResultEnum + :param description: + :type description: string + :param raw_value: + :type raw_value: string + :param tags: + :type tags: dict + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.result = ResultEnum(data.get('result', None)) + self.description = data.get('description', None) + self.raw_value = data.get('rawValue', None) + self.tags = data.get('tags', None) diff --git a/mailosaur/models/result_enum.py b/mailosaur/models/result_enum.py new file mode 100644 index 0000000..c816a43 --- /dev/null +++ b/mailosaur/models/result_enum.py @@ -0,0 +1,7 @@ +from enum import Enum + +class ResultEnum(Enum): + Pass = "Pass" + Warning = "Warning" + Fail = "Fail" + Timeout = "Timeout" \ No newline at end of file diff --git a/mailosaur/models/spam_assassin_result.py b/mailosaur/models/spam_assassin_result.py new file mode 100644 index 0000000..dfc2f95 --- /dev/null +++ b/mailosaur/models/spam_assassin_result.py @@ -0,0 +1,21 @@ +from .spam_assassin_rule import SpamAssassinRule +from .result_enum import ResultEnum + +class SpamAssassinResult(object): + """SpamAssassinResult. + + :param score: + :type score: float + :param result: + :type result: ~mailosaur.models.ResultEnum + :param rules: + :type rules: list[~mailosaur.models.SpamAssassinRule] + """ + + def __init__(self, data=None): + if data is None: + data = {} + + self.score = data.get('score', 0.0) + self.result = ResultEnum(data.get('result', None)) + self.rules = [SpamAssassinRule(i) for i in data.get('rules', None)] diff --git a/mailosaur/operations/analysis_operations.py b/mailosaur/operations/analysis_operations.py index cb2cdc0..7864eb8 100644 --- a/mailosaur/operations/analysis_operations.py +++ b/mailosaur/operations/analysis_operations.py @@ -1,5 +1,6 @@ from ..models import SpamAnalysisResult from ..models import MailosaurException +from ..models import DeliverabilityReport class AnalysisOperations(object): """AnalysisOperations operations. @@ -32,3 +33,27 @@ def spam(self, email): data = response.json() return SpamAnalysisResult(data) + + def deliverability(self, email): + """Perform a deliverability test. + + Perform deliverability testing on the specified email. + + :param email: The identifier of the email to be analyzed. + :type email: str + :return: DeliverabilityReport + :rtype: ~mailosaur.models.DeliverabilityReport + :raises: + :class:`MailosaurException` + """ + url = "%sapi/analysis/deliverability/%s" % (self.base_url, email) + response = self.session.get(url) + + if response.status_code not in [200]: + self.handle_http_error(response) + return + + data = response.json() + + return DeliverabilityReport(data) + diff --git a/tests/emails_test.py b/tests/emails_test.py index 1f5d651..36f5339 100644 --- a/tests/emails_test.py +++ b/tests/emails_test.py @@ -150,6 +150,39 @@ def test_spam_analysis(self): self.assertIsNotNone(rule.rule) self.assertIsNotNone(rule.description) + def test_deliverability_report(self): + target_id = self.emails[0].id + result = self.client.analysis.deliverability(target_id) + + self.assertIsNotNone(result) + + self.assertIsNotNone(result.spf) + + self.assertIsNotNone(result.dmarc) + for dkim in result.dkim: + self.assertIsNotNone(dkim) + + self.assertIsNotNone(result.dmarc) + + self.assertIsNotNone(result.block_lists) + for block_list in result.block_lists: + self.assertIsNotNone(block_list.id) + self.assertIsNotNone(block_list.name) + + self.assertIsNotNone(result.content) + + self.assertIsNotNone(result.dns_records) + self.assertIsNotNone(result.dns_records.a) + self.assertIsNotNone(result.dns_records.mx) + self.assertIsNotNone(result.dns_records.ptr) + + self.assertIsNotNone(result.spam_assassin) + self.assertIsNotNone(result.spam_assassin.result) + self.assertIsNotNone(result.spam_assassin.score) + for rule in result.spam_assassin.rules: + self.assertIsNotNone(rule.rule) + self.assertIsNotNone(rule.description) + def test_delete(self): target_email_id = self.emails[4].id