Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16699 manish.sha 1
from email import encoders
2
from email.mime.audio import MIMEAudio
3
from email.mime.base import MIMEBase
4
from email.mime.image import MIMEImage
5
from email.mime.multipart import MIMEMultipart
6
from email.mime.text import MIMEText
7
import mimetypes
8
import os
9
import re
10
import smtplib
11
 
12
class Email:
13
    """
14
    This class handles the creation and sending of email messages
15
    via SMTP.  This class also handles attachments and can send
16
    HTML messages.  The code comes from various places around
17
    the net and from my own brain.
18
    """
19
    def __init__(self, smtpServer):
20
        """
21
        Create a new empty email message object.
22
 
23
        @param smtpServer: The address of the SMTP server
24
        @type smtpServer: String
25
        """
26
        self._textBody = None
27
        self._htmlBody = None
28
        self._subject = ""
29
        self._smtpServer = smtpServer
30
        self._reEmail = re.compile("^([\\w \\._]+\\<[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\>|[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)$")
31
        self.clearRecipients()
32
        self.clearAttachments()
33
 
34
    def send(self):
35
        """
36
        Send the email message represented by this object.
37
        """
38
        # Validate message
39
        if self._textBody is None and self._htmlBody is None:
40
            raise Exception("Error! Must specify at least one body type (HTML or Text)")
41
        if len(self._to) == 0:
42
            raise Exception("Must specify at least one recipient")
43
 
44
        # Create the message part
45
        if self._textBody is not None and self._htmlBody is None:
46
            msg = MIMEText(self._textBody, "plain")
47
        elif self._textBody is None and self._htmlBody is not None:
48
            msg = MIMEText(self._htmlBody, "html")
49
        else:
50
            msg = MIMEMultipart("alternative")
51
            msg.attach(MIMEText(self._textBody, "plain"))
52
            msg.attach(MIMEText(self._htmlBody, "html"))
53
        # Add attachments, if any
54
        if len(self._attach) != 0:
55
            tmpmsg = msg
56
            msg = MIMEMultipart()
57
            msg.attach(tmpmsg)
58
        for fname,attachname in self._attach:
59
            if not os.path.exists(fname):
60
                print "File '%s' does not exist.  Not attaching to email." % fname
61
                continue
62
            if not os.path.isfile(fname):
63
                print "Attachment '%s' is not a file.  Not attaching to email." % fname
64
                continue
65
            # Guess at encoding type
66
            ctype, encoding = mimetypes.guess_type(fname)
67
            if ctype is None or encoding is not None:
68
                # No guess could be made so use a binary type.
69
                ctype = 'application/octet-stream'
70
            maintype, subtype = ctype.split('/', 1)
71
            if maintype == 'text':
72
                fp = open(fname)
73
                attach = MIMEText(fp.read(), _subtype=subtype)
74
                fp.close()
75
            elif maintype == 'image':
76
                fp = open(fname, 'rb')
77
                attach = MIMEImage(fp.read(), _subtype=subtype)
78
                fp.close()
79
            elif maintype == 'audio':
80
                fp = open(fname, 'rb')
81
                attach = MIMEAudio(fp.read(), _subtype=subtype)
82
                fp.close()
83
            else:
84
                fp = open(fname, 'rb')
85
                attach = MIMEBase(maintype, subtype)
86
                attach.set_payload(fp.read())
87
                fp.close()
88
                # Encode the payload using Base64
89
                encoders.encode_base64(attach)
90
            # Set the filename parameter
91
            if attachname is None:
92
                filename = os.path.basename(fname)
93
            else:
94
                filename = attachname
95
            attach.add_header('Content-Disposition', 'attachment', filename=filename)
96
            msg.attach(attach)
97
        # Some header stuff
98
        msg['Subject'] = self._subject
99
        msg['From'] = self._from
100
        msg['To'] = ", ".join(self._to)
101
        msg.preamble = "You need a MIME enabled mail reader to see this message"
102
        # Send message
103
        msg = msg.as_string()
104
        server = smtplib.SMTP(self._smtpServer)
105
        server.sendmail(self._from, self._to, msg)
106
        server.quit()
107
 
108
    def setSubject(self, subject):
109
        """
110
        Set the subject of the email message.
111
        """
112
        self._subject = subject
113
 
114
    def setFrom(self, address):
115
        """
116
        Set the email sender.
117
        """
118
        if not self.validateEmailAddress(address):
119
            raise Exception("Invalid email address '%s'" % address)
120
        self._from = address
121
 
122
    def clearRecipients(self):
123
        """
124
        Remove all currently defined recipients for
125
        the email message.
126
        """
127
        self._to = []
128
 
129
    def addRecipient(self, address):
130
        """
131
        Add a new recipient to the email message.
132
        """
133
        if not self.validateEmailAddress(address):
134
            raise Exception("Invalid email address '%s'" % address)
135
        self._to.append(address)
136
 
137
    def setTextBody(self, body):
138
        """
139
        Set the plain text body of the email message.
140
        """
141
        self._textBody = body
142
 
143
    def setHtmlBody(self, body):
144
        """
145
        Set the HTML portion of the email message.
146
        """
147
        self._htmlBody = body
148
 
149
    def clearAttachments(self):
150
        """
151
        Remove all file attachments.
152
        """
153
        self._attach = []
154
 
155
    def addAttachment(self, fname, attachname=None):
156
        """
157
        Add a file attachment to this email message.
158
 
159
        @param fname: The full path and file name of the file
160
                      to attach.
161
        @type fname: String
162
        @param attachname: This will be the name of the file in
163
                           the email message if set.  If not set
164
                           then the filename will be taken from
165
                           the fname parameter above.
166
        @type attachname: String
167
        """
168
        if fname is None:
169
            return
170
        self._attach.append( (fname, attachname) )
171
 
172
    def validateEmailAddress(self, address):
173
        """
174
        Validate the specified email address.
175
 
176
        @return: True if valid, False otherwise
177
        @rtype: Boolean
178
        """
179
        if self._reEmail.search(address) is None:
180
            return False
181
        return True