##// END OF EJS Templates
made auth type optional in constructor
marcink -
r1583:8e77c75b beta
parent child Browse files
Show More
@@ -1,165 +1,165 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.smtp_mailer
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Simple smtp mailer used in RhodeCode
7 7
8 8 :created_on: Sep 13, 2010
9 9 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 10 :license: GPLv3, see COPYING for more details.
11 11 """
12 12 # This program is free software: you can redistribute it and/or modify
13 13 # it under the terms of the GNU General Public License as published by
14 14 # the Free Software Foundation, either version 3 of the License, or
15 15 # (at your option) any later version.
16 16 #
17 17 # This program is distributed in the hope that it will be useful,
18 18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 20 # GNU General Public License for more details.
21 21 #
22 22 # You should have received a copy of the GNU General Public License
23 23 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 24
25 25 import logging
26 26 import smtplib
27 27 import mimetypes
28 28 from socket import sslerror
29 29
30 30 from email.mime.multipart import MIMEMultipart
31 31 from email.mime.image import MIMEImage
32 32 from email.mime.audio import MIMEAudio
33 33 from email.mime.base import MIMEBase
34 34 from email.mime.text import MIMEText
35 35 from email.utils import formatdate
36 36 from email import encoders
37 37
38 38
39
40 39 class SmtpMailer(object):
41 40 """SMTP mailer class
42 41
43 mailer = SmtpMailer(mail_from, user, passwd, mail_server,
42 mailer = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth
44 43 mail_port, ssl, tls)
45 44 mailer.send(recipients, subject, body, attachment_files)
46 45
47 46 :param recipients might be a list of string or single string
48 47 :param attachment_files is a dict of {filename:location}
49 48 it tries to guess the mimetype and attach the file
50 49
51 50 """
52 51
53 def __init__(self, mail_from, user, passwd, mail_server,smtp_auth,
54 mail_port=None, ssl=False, tls=False, debug=False):
52 def __init__(self, mail_from, user, passwd, mail_server, smtp_auth=None,
53 mail_port=None, ssl=False, tls=False, debug=False):
55 54
56 55 self.mail_from = mail_from
57 56 self.mail_server = mail_server
58 57 self.mail_port = mail_port
59 58 self.user = user
60 59 self.passwd = passwd
61 60 self.ssl = ssl
62 61 self.tls = tls
63 62 self.debug = debug
64 63 self.auth = smtp_auth
65 64
66 65 def send(self, recipients=[], subject='', body='', attachment_files=None):
67 66
68 67 if isinstance(recipients, basestring):
69 68 recipients = [recipients]
70 69 if self.ssl:
71 70 smtp_serv = smtplib.SMTP_SSL(self.mail_server, self.mail_port)
72 71 else:
73 72 smtp_serv = smtplib.SMTP(self.mail_server, self.mail_port)
74 73
75 74 if self.tls:
76 75 smtp_serv.ehlo()
77 76 smtp_serv.starttls()
78 77
79 78 if self.debug:
80 79 smtp_serv.set_debuglevel(1)
81 80
82 81 smtp_serv.ehlo()
83 82 if self.auth:
84 83 smtp_serv.esmtp_features["auth"] = self.auth
85 84
86 #if server requires authorization you must provide login and password
87 #but only if we have them
85 # if server requires authorization you must provide login and password
86 # but only if we have them
88 87 if self.user and self.passwd:
89 88 smtp_serv.login(self.user, self.passwd)
90 89
91 90 date_ = formatdate(localtime=True)
92 91 msg = MIMEMultipart()
93 92 msg.set_type('multipart/alternative')
94 93 msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
95 94
96 95 text_msg = MIMEText(body)
97 96 text_msg.set_type('text/plain')
98 97 text_msg.set_param('charset', 'UTF-8')
99 98
100 99 msg['From'] = self.mail_from
101 100 msg['To'] = ','.join(recipients)
102 101 msg['Date'] = date_
103 102 msg['Subject'] = subject
104 103
105 104 msg.attach(text_msg)
106 105
107 106 if attachment_files:
108 107 self.__atach_files(msg, attachment_files)
109 108
110 109 smtp_serv.sendmail(self.mail_from, recipients, msg.as_string())
111 110 logging.info('MAIL SEND TO: %s' % recipients)
112 111
113 112 try:
114 113 smtp_serv.quit()
115 114 except sslerror:
116 115 # sslerror is raised in tls connections on closing sometimes
117 116 pass
118 117
119 118 def __atach_files(self, msg, attachment_files):
120 119 if isinstance(attachment_files, dict):
121 120 for f_name, msg_file in attachment_files.items():
122 121 ctype, encoding = mimetypes.guess_type(f_name)
123 122 logging.info("guessing file %s type based on %s", ctype,
124 123 f_name)
125 124 if ctype is None or encoding is not None:
126 125 # No guess could be made, or the file is encoded
127 126 # (compressed), so use a generic bag-of-bits type.
128 127 ctype = 'application/octet-stream'
129 128 maintype, subtype = ctype.split('/', 1)
130 129 if maintype == 'text':
131 130 # Note: we should handle calculating the charset
132 131 file_part = MIMEText(self.get_content(msg_file),
133 132 _subtype=subtype)
134 133 elif maintype == 'image':
135 134 file_part = MIMEImage(self.get_content(msg_file),
136 135 _subtype=subtype)
137 136 elif maintype == 'audio':
138 137 file_part = MIMEAudio(self.get_content(msg_file),
139 138 _subtype=subtype)
140 139 else:
141 140 file_part = MIMEBase(maintype, subtype)
142 141 file_part.set_payload(self.get_content(msg_file))
143 142 # Encode the payload using Base64
144 143 encoders.encode_base64(msg)
145 144 # Set the filename parameter
146 145 file_part.add_header('Content-Disposition', 'attachment',
147 146 filename=f_name)
148 147 file_part.add_header('Content-Type', ctype, name=f_name)
149 148 msg.attach(file_part)
150 149 else:
151 150 raise Exception('Attachment files should be'
152 151 'a dict in format {"filename":"filepath"}')
153 152
154 153 def get_content(self, msg_file):
155 154 """Get content based on type, if content is a string do open first
156 155 else just read because it's a probably open file object
157 156
158 157 :param msg_file:
159 158 """
160 159 if isinstance(msg_file, str):
161 160 return open(msg_file, "rb").read()
162 161 else:
163 #just for safe seek to 0
162 # just for safe seek to 0
164 163 msg_file.seek(0)
165 164 return msg_file.read()
165
General Comments 0
You need to be logged in to leave comments. Login now