Mercurial > kallithea
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() |