any easy way to author HTML email? Yes: found that I can do so in both in and in thunderbird.
Questions I have:
https://news.ycombinator.com/item?id=6169040 -> https://github.com/charlierguo/gmail
git clone https://github.com/charlierguo/gmail.git
To install:
pip install git+https://github.com/charlierguo/gmail.git
/Users/raymondyee/C/src/gmail
to use -- I will create a specific password for this use at https://accounts.google.com/b/0/IssuedAuthSubTokens?hl=en
SMTP
specialized gmail library in Python
creating Evernote notes in a series of examples with a rising level of complexity:
Question: what aspects of the conversion from HTML to ENML + resources can be handled by emailing HTML email to evernote? Specifically:
In [ ]:
from settings import (gmail_username, gmail_password, evernote_email)
import gmail
def gmail_sent_to_myself(gmail_username, gmail_password):
g = gmail.login(gmail_username, gmail_password)
assert g.logged_in # Should be True, AuthenticationError if login fails
emails = g.inbox().mail(fr=gmail_username, prefetch=True)
return emails
In [ ]:
emails = gmail_sent_to_myself(gmail_username, gmail_password)
email = emails[0]
email.subject, email.body
how are attachments handled? mimetypes? Come back to look at http://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example-with-gmail/
to send email: https://github.com/paulchakravarti/gmail-sender
In [ ]:
# based on http://stackoverflow.com/a/9274387/7782
from email.header import Header
from email.mime.text import MIMEText
from smtplib import SMTP_SSL
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def simple_email_send(host, login, password, text, subject, from_, to, encoding='utf-8', port=465, timeout=10,
debug_level=0):
"""
e.g., host smtp.gmail.com
login, to are email addresses
"""
# create message
msg = MIMEText(subject, _charset=encoding)
msg['Subject'] = Header(subject, encoding)
msg['From'] = from_
msg['To'] = to
s = SMTP_SSL(host, port, timeout=timeout)
s.set_debuglevel(debug_level)
try:
s.login(login, password)
s.sendmail(msg['From'], msg['To'], msg.as_string())
finally:
s.quit()
In [ ]:
simple_email_send('smtp.gmail.com', gmail_username, gmail_password,
text = """You're in luck, my friend.""",
subject='Hello from your friendly Nigerian prince',
from_ = gmail_username,
to = gmail_username)
time to study the email standard module: http://docs.python.org/2/library/email
Maybe a good place to also read -- http://my.safaribooksonline.com/book/programming/python/9781449398712/13dot-client-side-scripting/id4144723
In [ ]:
def send_email_text_html(host, login, password, text, subject, from_, to, html=None, encoding='utf-8', port=465, timeout=10,
debug_level=0):
"""
e.g., host smtp.gmail.com
login, to are email addresses
"""
# create message
if html is not None:
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
else:
msg = MIMEText(subject, _charset=encoding)
msg['Subject'] = Header(subject, encoding)
msg['From'] = from_
msg['To'] = to
if html is not None:
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain', _charset=encoding)
part2 = MIMEText(html, 'html', _charset=encoding)
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
s = SMTP_SSL(host, port, timeout=timeout)
s.set_debuglevel(debug_level)
try:
s.login(login, password)
s.sendmail(msg['From'], msg['To'], msg.as_string())
finally:
s.quit()
In [ ]:
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"
html = """\
<html>
<head>
<title>An email</title>
</head>
<body>
<p>Hi!<br/>
How are you?<br/>
<span style="color:red">styled span</span><br/>
Here is the <a href="http://www.python.org">link</a> you wanted.
</p>
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Johann_Sebastian_Bach.jpg/220px-Johann_Sebastian_Bach.jpg"/>
</body>
</html>
"""
send_email_text_html('smtp.gmail.com', gmail_username, gmail_password,
text = text,
subject='send_email_text_html TEST',
from_ = gmail_username,
to = gmail_username,
html = html)
In [ ]:
# this routine works when html is None too
send_email_text_html('smtp.gmail.com', gmail_username, gmail_password,
text = """You're in luck, my friend.""",
subject='Hello from your friendly Nigerian prince',
from_ = gmail_username,
to = gmail_username,
html=None)
In [ ]:
# next question: inlining of CSS done for us by Evernote? Answer is NO.
Working conclusion: we have to do our own CSS inlining for email and for Evernote
In [ ]:
!pip freeze | grep pynliner
In [ ]:
# http://pythonhosted.org/pynliner/
# pip install pynliner
import pynliner
html = u'<style>h1 { color:#ffcc00; }</style><h1>Hello World!</h1>'
output = pynliner.fromString(html)
output
In [ ]:
from pynliner import Pynliner
html = "<h1>Hello World!</h1>"
css = "h1 { color:#ffcc00; }"
p = Pynliner()
p.from_string(html).with_cssString(css)
p.run()
In [ ]:
# Python 2
from urllib2 import urlopen
url = 'http://mashupguide.net/1.0/html/'
fallback_encoding = 'UTF-8'
response = urlopen(url)
the_page = response.read()
encoding = response.headers.getparam("charset")
if encoding is None:
encoding = fallback_encoding
content = the_page.decode(encoding)
print (encoding, type(content), content[:100])
In [ ]:
import requests
url = 'http://mashupguide.net/1.0/html/'
r = requests.get(url)
r.headers
In [ ]:
from pynliner import Pynliner
p = Pynliner()
p.from_url('http://mashupguide.net/1.0/html/')
html = p.run()
In [ ]:
send_email_text_html('smtp.gmail.com', gmail_username, gmail_password,
text = text,
subject='mashupguide toc',
from_ = gmail_username,
to = evernote_email,
html = html)
https://github.com/peterbe/premailer
pip install premailer
In [ ]:
!pip freeze | grep premailer
In [ ]:
from premailer import transform
print transform("""
<html>
<style type="text/css">
h1 { border:1px solid black }
p { color:red;}
p::first-letter { float:left; }
</style>
<h1 style="font-weight:bolder">Peter</h1>
<p>Hej</p>
</html>""")
In [ ]:
url = "http://mashupguide.net/1.0/html/"
import requests
r = requests.get(url=url)
r
In [ ]:
r.text.encode('ascii', 'ignore')
In [ ]:
import requests
from premailer import transform
url = "http://mashupguide.net/1.0/html/"
r = requests.get(url=url)
# transforming to ascii to get around what seems to be a bug in premailer
t = transform(r.text.encode('ascii', 'ignore'), base_url=url)
print t
In [ ]:
# based on http://docs.python.org/2/library/email-examples.html
import smtplib
from smtplib import SMTP_SSL
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# me == my email address
# you == recipient's email address
from settings import (gmail_username, gmail_password, evernote_email)
me = gmail_username
you = evernote_email
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
text = url
import requests
from premailer import transform
url = "http://mashupguide.net/1.0/html/"
r = requests.get(url=url)
# work around to do ascii decoding
html = transform(r.text.encode('ascii', 'ignore'), base_url=url)
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
login, password = gmail_username, gmail_password
# send it via gmail
s = SMTP_SSL('smtp.gmail.com', 465, timeout=10)
s.set_debuglevel(0)
try:
s.login(login, password)
s.sendmail(msg['From'], msg['To'], msg.as_string())
finally:
s.quit()
problem: although the relative URIs are converted to absolute URIs, premailer
doesn't handle external CSS files: https://github.com/peterbe/premailer/issues/6
Solution: come back to parse HTML and turn external CSS references to embedded style: http://lxml.de/parsing.html
In [ ]:
# based on http://docs.python.org/2/library/email-examples.html
import smtplib
from smtplib import SMTP_SSL
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# me == my email address
# you == recipient's email address
from settings import (gmail_username, gmail_password, evernote_email)
me = gmail_username
you = evernote_email
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
text = url
import requests
from premailer import transform
mashupsource = open("mashupguidetoc.html").read()
html = transform(mashupsource, base_url=url)
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
login, password = gmail_username, gmail_password
# send it via gmail
s = SMTP_SSL('smtp.gmail.com', 465, timeout=10)
s.set_debuglevel(0)
try:
s.login(login, password)
s.sendmail(msg['From'], msg['To'], msg.as_string())
finally:
s.quit()
In [ ]:
print html
In [ ]: