def test_body_type_is_passed_to_set_content(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) body = '<p>Test body</p>' email = emails.Email(self.smtp_config, body=body, body_type='html') email.send(self.recipients) sent_message = smtp_mock.send_message.call_args[0][0] self.assertEqual(sent_message.get_content().strip(), body) self.assertIn('text/html', sent_message['Content-Type'])
def test_smtp_is_called_correctly(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config) email.send(self.recipients) smtp_mock.assert_called_once_with(self.smtp_config['host'], self.smtp_config['port']) smtp_mock.__enter__.assert_called_once() smtp_mock.starttls.assert_called_once() smtp_mock.send_message.assert_called_once() smtp_mock.__exit__.assert_called_once()
def test_sent_message_is_constructed_correctly(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) e = emails.Email(self.smtp_config, self.subject, self.body) e.send(self.recipients) sent_message = smtp_mock.send_message.call_args[0][0] self.assertEqual(sent_message['From'], self.smtp_config['sender']) self.assertEqual(sent_message['To'], ', '.join(self.recipients)) self.assertEqual(sent_message['Subject'], self.subject) self.assertEqual(sent_message.get_content().strip(), self.body)
def test_attachment_mimetype_is_used_if_specified(self, add_attachment_mock, smtp_mock): self._prepare_smtp_mock(smtp_mock) attachment = { 'filename': 'README', 'content': b'example readme', 'mime_type': 'text/plain' } email = emails.Email(self.smtp_config, attachments=[attachment]) email.send(self.recipients) add_attachment_mock.assert_called_once_with(b'example readme', maintype='text', subtype='plain', filename='README')
def test_attachments_are_added(self, add_attachment_mock, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config, attachments=self.attachments) email.send(self.recipients) expected_calls = [] for attachment in self.attachments: content = attachment['content'] filename = attachment['filename'] mime_type = mimetypes.guess_type(filename) maintype, subtype = mime_type[0].split('/') expected_calls.append(call(content, maintype=maintype, subtype=subtype, filename=filename)) self.assertEqual(add_attachment_mock.mock_calls, expected_calls)
def get_domain_from_email(self, email_address, elastic_output): global domain_list email1 = emails.Email(email_address) email1.google() email1.haveibeenpwned() email1.check_username() whoxy = email1.whoxy(conf['keys']['whoxy'], elastic_output) new_domains = [] if whoxy[email_address]: for i, j in whoxy[email_address].items(): new_domains.append(j['domain_name']) domain_list.append([j['domain_name']]) return new_domains
def parse_enron(relations, wiki_words): """Parse the enron.xml file, updating the relations list with relevant emails.""" print "Parsing enron.xml" with open("data/enron.xml", "r") as f: line = f.readline() while len(line) > 0: line = line.strip() # Grab the message id, ignoring the one junk email in enron.xml. try: email = emails.Email(line.split()[1].split("/")[2], wiki_words) except IndexError: # Skip through the junk email. line = f.readline() while not re.match(r"^<DOC>", line) and len(line) > 0: line = f.readline() continue # Find the subject. line = f.readline() subject_match = re.match(r"^Subject: (.*)", line) while not subject_match and len(line) > 0: line = f.readline() subject_match = re.match(r"^Subject: (.*)", line) email.subject = subject_match.group(1) if subject_match else None # Find the start of the text body. line = f.readline() while line != "\n": line = f.readline() # Eat the text data. line = f.readline() while not re.match(r"^</DOC>", line): line.strip() email.add_line(line) line = f.readline() # Finally, add the email set to anyone who's involved. for relation in relations: if email.id in relation.from_info.node.outs_ids: relation.emails.add_email(email) # Move onto the next document. line = f.readline()
def test_raises_if_attachment_mimetype_cannot_be_guessed_and_was_not_specified(self): attachment = {'filename': 'LICENSE', 'content': b'MIT License'} with self.assertRaises(emails._src.MimeTypeNotSpecifiedError): email = emails.Email(self.smtp_config, attachments=[attachment])
def test_can_use_recipient_as_string_instead_of_list(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config) email.send('*****@*****.**') sent_message = smtp_mock.send_message.call_args[0][0] self.assertEqual(sent_message['To'], '*****@*****.**')
def test_constructor(self): email = emails.Email(self.smtp_config, self.subject, self.body, self.body_type, self.attachments) self.assert_email_is_built_correctly(email)
def test_constructor_raises_if_host_not_specified(self): self.smtp_config.pop('host') with self.assertRaises(emails._src.InvalidSmtpConfigError): email = emails.Email(self.smtp_config)
def test_does_not_exceed_retry_attempt_threshold(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) smtp_mock.send_message.side_effect = [socket.timeout, socket.timeout, socket.timeout] email = emails.Email(self.smtp_config) with self.assertRaises(socket.timeout): email.send(self.recipients)
def test_can_specify_retry_threshold(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) smtp_mock.send_message.side_effect = [socket.timeout, socket.timeout, socket.timeout, None] email = emails.Email(self.smtp_config) email.send(self.recipients, max_retries=3) self.assertEqual(smtp_mock.send_message.call_count, 4)
def test_defaults_to_port_25_if_not_specified(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) self.smtp_config.pop('port') email = emails.Email(self.smtp_config) email.send(self.recipients) smtp_mock.assert_called_once_with(self.smtp_config['host'], 25)
def test_retries_on_timeout(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) smtp_mock.send_message.side_effect = [socket.timeout, socket.timeout, None] email = emails.Email(self.smtp_config) email.send(self.recipients) self.assertEqual(smtp_mock.send_message.call_count, 3)
def test_smtp_authenticates_if_auth_specified_in_config(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config) email.send(self.recipients) smtp_mock.login.assert_called_once_with(self.smtp_config['sender'], self.smtp_config['password'])
import emails if __name__ == '__main__': # Simple Form ########################################## smtp_config = { 'sender': '<your email address>', 'host': 'smtp.example.com' } email = emails.Email(smtp_config, subject='Hi', body='Lunch tomorrow?') email.send('<your recipients>' ) # recipients can be a string or a string-yielding iterable # Long Form ########################################## sender = '<your email address>' smtp_config = { 'sender': sender, 'host': 'smtp.example.com', 'port': 587, # defaults to 25 if not specified 'password': input(f'Password for {sender}: ') # Omit password if not needed } with open('README.md', 'rb') as fp: attachment = { 'filename': 'readme.md', 'content': fp.read(), 'mime_type': 'text/markdown' # If not specified, emails will try to guess based on the filename }
def test_smtp_does_not_attempt_to_authenticate_if_password_not_specified_in_config(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) self.smtp_config.pop('password') email = emails.Email(self.smtp_config) email.send(self.recipients) smtp_mock.login.assert_not_called()
def test_unspecified_subject_does_not_generate_header(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config, body=self.body) email.send(self.recipients) sent_message = smtp_mock.send_message.call_args[0][0] self.assertNotIn('Subject', sent_message.keys())
def test_unspecified_body_does_not_raise_exception(self, smtp_mock): self._prepare_smtp_mock(smtp_mock) email = emails.Email(self.smtp_config, self.subject) email.send(self.recipients)