Skip to content

Commit

Permalink
Something more like a real initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
abkfenris committed Sep 28, 2017
1 parent d2bfcf0 commit f01d442
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 1 deletion.
69 changes: 68 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,74 @@ Simplyify sending HTML emails
Features
--------

* TODO
The built in Python modules for sending email are powerful, but require a lot of
boilerplate to write an HTML formatted email.

.. code-block:: python
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
message = MIMEMultipart('alternative')
message['Subject'] = 'Test'
message['From'] = '[email protected]'
message['To'] = '[email protected]'
message.attach(MIMEText('# A Heading\nSomething else in the body', 'plain')
message.attach(MIMEText('<h1 style="color: blue">A Heading</a><p>Something else in the body</p>', 'html')
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login('[email protected]', 'password')
server.sendmail('[email protected]', '[email protected]', message.as_string())
server.quit()
With ``email_to`` sending a simple email becomes much more succint.
.. code-block:: python
import email_to
server = email_to.EmailServer('smtp.gmail.com', 587, '[email protected]', 'password')
server.quick_email('[email protected]', 'Test',
['# A Heading', 'Something else in the body'],
style='h1 {color: blue}')
``email_to`` also supports building a message up, line by line. This is
especially useful for monitoring scripts where there may be several different
conditions of interest.
.. code-block:: python
import email_to
server = email_to.EmailServer('smtp.gmail.com', 587, '[email protected]', 'password')
message = server.message()
message.add('# Oh boy, something went wrong!')
message.add('- The server had a hiccup')
message.add('- The power went out')
message.add('- Blame it on a rogue backhoe')
message.style = 'h1 { color: red}'
message.send('[email protected]', 'Things did not occur as expected')
Additionally if the server details are not known at the beginning of the message,
that can be handled easily too.
.. code-block:: python
import email_to
message = email_to.Message('# Every thing is ok')
message.add('Everything has been running fine for days.')
message.add('Probably time to build something new and break everything')
message.style = 'h1 { color: green }'
server = email_to.EmailServer('smtp.gmail.com', 587, '[email protected]', 'password')
server.send_message(message, '[email protected]', 'Things are awesome')
Credits
---------
Expand Down
2 changes: 2 additions & 0 deletions email_to/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

"""Top-level package for Email To."""

from email_to.email_to import EmailServer, Message

__author__ = """Alex Kerney"""
__email__ = '[email protected]'
__version__ = '0.1.0'
112 changes: 112 additions & 0 deletions email_to/email_to.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,115 @@
# -*- coding: utf-8 -*-

"""Main module."""

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib

import markdown
import premailer


class Message(object):
""" A simple email message made of Markdown strings
A Message is a simplified version of a MIMEMultipart email message.
Instead of having to seperately construct HTML and text version of
an email, you can build a Message by adding lines of Markdown formatted
strings.
"""
def __init__(self, body=None, style=None, server=None):
"""
Args:
body (str, bytes, iterable of strings): The body of the email.
It does not need to be complete, as you can add to it later.
style (str): CSS formatting to be applied to HTML formatted verion
of email.
server (EmailServer): An EmailServer instance allowing a message
to be sent directly from it's `send` method.
"""
if body is None:
self.body = []
else:
if any((isinstance(body, str), isinstance(body, bytes))):
body = [body]
self.body = body
self.style = style
self.server = server

def add(self, line):
""" Adds a new Markdown formatted line to the current email body """
self.body.append(line)

@property
def html(self):
""" Returns HTML formatted and styled version of body """
html = markdown.markdown('\n'.join(self.body))
if self.style:
return premailer.transform('<style>\n' + self.style +
'\n</style>\n' + html)
return html

def __str__(self):
return '\n'.join(self.body)

def __repr__(self):
return '<Message: {0} and {1} more lines>'.format(
self.body[0], (len(self.body) - 1))

def mime(self):
""" Returns a MIMEMultipart message """
msg = MIMEMultipart('alternative')

msg.attach(MIMEText(str(self), 'plain'))
msg.attach(MIMEText(self.html, 'html'))

return msg

def send(self, to, subject):
""" Sends the formatted message to given recripient
args:
to (:obj:str, iterable of :obj:`str`): Email addresses to send to
subject (str): Subject line of email to send
"""
self.server.send_message(self, to, subject)


class EmailServer(object):
def __init__(self, url, port, email, password):
self.url = url
self.port = port
self.email_address = email
self.password = password

def _login(self):
self.server = smtplib.SMTP(self.url, self.port)
self.server.starttls()
self.server.login(self.email_address, self.password)

def _logout(self):
self.server.quit()

def quick_email(self, to, subject, body, style=None):
message = Message(body, style=style)

self.send_message(message, to, subject)

def send_message(self, message, to, subject):
message = message.mime()

message['From'] = self.email_address
message['To'] = to

message['Subject'] = subject

self._login()
self.server.sendmail(self.email_address, to, message.as_string())
self._logout()

def message(self, body=None, style=None):
return Message(body=body, style=style, server=self)
Empty file modified setup.py
100644 → 100755
Empty file.

0 comments on commit f01d442

Please sign in to comment.