comparison pylons_app/lib/smtp_mailer.py @ 474:a3d9d24acbec celery

Implemented password reset(forms/models/ tasks) and mailing tasks. Added smtp mailer, configurations, cleaned user model
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 13 Sep 2010 01:27:41 +0200
parents
children
comparison
equal deleted inserted replaced
473:6b934c9607e7 474:a3d9d24acbec
1 import logging
2 import smtplib
3 import mimetypes
4 from email.mime.multipart import MIMEMultipart
5 from email.mime.image import MIMEImage
6 from email.mime.audio import MIMEAudio
7 from email.mime.base import MIMEBase
8 from email.mime.text import MIMEText
9 from email.utils import formatdate
10 from email import encoders
11
12 class SmtpMailer(object):
13 """simple smtp mailer class
14
15 mailer = SmtpMailer(mail_from, user, passwd, mail_server, mail_port, ssl, tls)
16 mailer.send(recipients, subject, body, attachment_files)
17
18 :param recipients might be a list of string or single string
19 :param attachment_files is a dict of {filename:location}
20 it tries to guess the mimetype and attach the file
21 """
22
23 def __init__(self, mail_from, user, passwd, mail_server,
24 mail_port=None, ssl=False, tls=False):
25
26 self.mail_from = mail_from
27 self.mail_server = mail_server
28 self.mail_port = mail_port
29 self.user = user
30 self.passwd = passwd
31 self.ssl = ssl
32 self.tls = tls
33 self.debug = False
34
35 def send(self, recipients=[], subject='', body='', attachment_files={}):
36
37 if isinstance(recipients, basestring):
38 recipients = [recipients]
39 if self.ssl:
40 smtp_serv = smtplib.SMTP_SSL(self.mail_server, self.mail_port)
41 else:
42 smtp_serv = smtplib.SMTP(self.mail_server, self.mail_port)
43
44 if self.tls:
45 smtp_serv.starttls()
46
47 if self.debug:
48 smtp_serv.set_debuglevel(1)
49
50 smtp_serv.ehlo("mailer")
51
52 #if server requires authorization you must provide login and password
53 smtp_serv.login(self.user, self.passwd)
54
55 date_ = formatdate(localtime=True)
56 msg = MIMEMultipart()
57 msg['From'] = self.mail_from
58 msg['To'] = ','.join(recipients)
59 msg['Date'] = date_
60 msg['Subject'] = subject
61 msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
62
63 msg.attach(MIMEText(body))
64
65 if attachment_files:
66 self.__atach_files(msg, attachment_files)
67
68 smtp_serv.sendmail(self.mail_from, recipients, msg.as_string())
69 logging.info('MAIL SEND TO: %s' % recipients)
70 smtp_serv.quit()
71
72
73 def __atach_files(self, msg, attachment_files):
74 if isinstance(attachment_files, dict):
75 for f_name, msg_file in attachment_files.items():
76 ctype, encoding = mimetypes.guess_type(f_name)
77 logging.info("guessing file %s type based on %s" , ctype, f_name)
78 if ctype is None or encoding is not None:
79 # No guess could be made, or the file is encoded (compressed), so
80 # use a generic bag-of-bits type.
81 ctype = 'application/octet-stream'
82 maintype, subtype = ctype.split('/', 1)
83 if maintype == 'text':
84 # Note: we should handle calculating the charset
85 file_part = MIMEText(self.get_content(msg_file),
86 _subtype=subtype)
87 elif maintype == 'image':
88 file_part = MIMEImage(self.get_content(msg_file),
89 _subtype=subtype)
90 elif maintype == 'audio':
91 file_part = MIMEAudio(self.get_content(msg_file),
92 _subtype=subtype)
93 else:
94 file_part = MIMEBase(maintype, subtype)
95 file_part.set_payload(self.get_content(msg_file))
96 # Encode the payload using Base64
97 encoders.encode_base64(msg)
98 # Set the filename parameter
99 file_part.add_header('Content-Disposition', 'attachment',
100 filename=f_name)
101 file_part.add_header('Content-Type', ctype, name=f_name)
102 msg.attach(file_part)
103 else:
104 raise Exception('Attachment files should be'
105 'a dict in format {"filename":"filepath"}')
106
107 def get_content(self, msg_file):
108 '''
109 Get content based on type, if content is a string do open first
110 else just read because it's a probably open file object
111 @param msg_file:
112 '''
113 if isinstance(msg_file, str):
114 return open(msg_file, "rb").read()
115 else:
116 #just for safe seek to 0
117 msg_file.seek(0)
118 return msg_file.read()