Search This Blog

Saturday, October 24, 2009

Send an HTML email with embedded image and plain text alternate

Recipe 473810: Send an HTML email with embedded image and plain text alternate




HTML is the method of choice for those wishing to send emails with rich text, layout and graphics. Often it is desirable to embed the graphics within the message so recipients can display the message directly, without further downloads.

Some mail agents don't support HTML or their users prefer to receive plain text messages. Senders of HTML messages should include a plain text message as an alternate for these users.

This recipe sends a short HTML message with a single embedded image and an alternate plain text message.





Python
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Send an HTML email with an embedded image and a plain text message for
# email clients that don't want to display the HTML.

from email.MIMEMultipart import MIMEMultipart

from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage

# Define these once; use them twice!
strFrom = 'from@example.com'
strTo = 'to@example.com'

# Create the root message and fill in the from, to, and subject headers

msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message'

msgRoot['From'] = strFrom
msgRoot['To'] = strTo

msgRoot.preamble = 'This is a multi-part message in MIME format.'

# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')

msgRoot.attach(msgAlternative)

msgText = MIMEText('This is the alternative plain text message.')

msgAlternative.attach(msgText)

# We reference the image in the IMG SRC attribute by the ID we give it below
msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>Nifty!', 'html')

msgAlternative.attach(msgText)

# This example assumes the image is in the current directory
fp = open('test.jpg', 'rb')

msgImage = MIMEImage(fp.read())
fp.close()

# Define the image's ID as referenced above
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)

# Send the email (this example assumes SMTP authentication is required)
import smtplib
smtp = smtplib.SMTP()
smtp.connect('smtp.example.com')

smtp.login('exampleuser', 'examplepass')
smtp.sendmail(strFrom, strTo, msgRoot.as_string())

smtp.quit()




Discussion



While the practice of embedding images within the message provides a better experience for many users than linking to web-hosted images does it is important to consider the impact this has on message size and consequently on message download time.

An alternative implementation for sending HTML messages is provided in this recipe http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/67083, though it doesn't address embedding images and was written before the email package was incorporated into Python. The email package and its MIME-handling capabilities significantly reduce the amount of code required.



Thursday, October 8, 2009

CAPTCHA: "Completely Automated Public Turing test to Tell Computers and Humans Apart"

CAPTCHA: Telling Humans and Computers Apart Automatically


A CAPTCHA is a program that protects websites against bots by generating and grading tests that humans can pass but current computer programs cannot. For example, humans can read distorted text as the one shown below, but current computer programs can't:


The term CAPTCHA (for Completely Automated Public Turing Test To Tell Computers and Humans Apart) was coined in 2000 by Luis von Ahn, Manuel Blum, Nicholas Hopper and John Langford of Carnegie Mellon University.


Get a Free CAPTCHA For Your Site


A free, secure and accessible CAPTCHA implementation is available from the reCAPTCHA project. Easy to install plugins and controls are available for WordPress, MediaWiki, PHP, ASP.NET, Perl, Python, Java, and many other environments. reCAPTCHA also comes with an audio test to ensure that blind users can freely navigate your site. reCAPTCHA is our officially recommended CAPTCHA implementation.

Test Drive a CAPTCHA

  • reCAPTCHA. Stop spam and help digitize books at the same time! The words shown come directly from old books that are being digitized.
  • SQUIGL-PIX. Our newest CAPTCHA!
  • ESP-PIX. A CAPTCHA script that's close to our hearts. Instead of typing letters, you authenticate yourself as a human by recognizing what object is common in a set of images. This was the first example of a CAPTCHA based on image recognition.

    Below is an example for Embedding a sample Captcha in a CGi FIle.


    #!/usr/bin/env python

    ######### don't change the following three lines: ###########
    import cgi
    import cgitb;cgitb.enable()
    import time
    from recaptcha.client import captcha

    publickey = "<publickey>"
    privatekey = "<privatekey>"


    print "Content-Type: text/html\n\n"
    print '''
    <html>
    <head>
    <title>NO BOTS</title>
    </head>
    <body>
    <form action="<ur cgi validator>" method="post">
    <h2>Prove you are not a BOT</h2>
    <script type="text/javascript" src="http://api.recaptcha.net/challenge?k=''' + publickey + '''"></script>
    <noscript>
    <iframe src="http://api.recaptcha.net/noscript?k=''' + publickey + '''" height="300" width="500" frameborder="0"></iframe><br>
    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
    </textarea>
    <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
    </noscript>
    <input type = "submit" value = "Go">
    </form>
    </body>
    </html>
    '''


    Below is an example for validating a Captcha in a CGi FIle.


    #!/usr/bin/env python

    ######### don't change the following three lines: ###########
    import cgi
    import cgitb;cgitb.enable()
    import time
    from recaptcha.client import captcha


    publickey = "<publickey>"
    privatekey = "<privatekey>"

    print "Content-Type: text/html\n\n"
    form = cgi.FieldStorage()

    response = captcha.submit(
            form.getvalue("recaptcha_challenge_field"),
            form.getvalue('recaptcha_response_field'),
            privatekey,
            "192.168.20.68",
            )

    if not response.is_valid:
            print '''
            <html>
                    <head>
                            <title>U BOTS</title>
                    </head>
                    <body>
                            <form action="<cgi captcha validator>" method="post">
                            <h2>YOU ARE A BOT!!!!!!!!!!!!!!</h2>
                            <h3>Else Try Again</h3>
                            <script type="text/javascript" src="http://api.recaptcha.net/challenge?k=''' + publickey + '''"></script>
                            <noscript>
                                    <iframe src="http://api.recaptcha.net/noscript?k=''' + publickey + '''" height="300" width="500" frameborder="0"></iframe><br>
                                    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
                                    </textarea>
                                    <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
                            </noscript>
                            <input type = "submit" value = "Go">
                            </form>
                    </body>
            </html>
            '''
    else:
            print '''
            <html>
                    <head>
                            <title>Hurray ur not a BOT </title>
                    </head>
                    <body>
                            <form action="<cgi captcha validator>" method="post">
                            <h2>Hurray!!!!!!!!!!!!!!<br> :) you are A Human ;-)</h2>
                            <h3>You can Try Again Human</h3>
                            <script type="text/javascript" src="http://api.recaptcha.net/challenge?k=''' + publickey + '''"></script>
                            <noscript>
                                    <iframe src="http://api.recaptcha.net/noscript?k=''' + publickey + '''" height="300" width="500" frameborder="0"></iframe><br>
                                    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
                                    </textarea>
                                    <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
                            </noscript>
                            <input type = "submit" value = "Go">
                            </form>
                    </body>
            </html>
            '''