-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Something more like a real initial commit
- Loading branch information
Showing
4 changed files
with
182 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
--------- | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |