##// END OF EJS Templates
mailer: bit of code cleanup
marcink -
r2933:3df7f0a4 default
parent child Browse files
Show More
@@ -1,119 +1,120 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2018 RhodeCode GmbH
3 # Copyright (C) 2013-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Simple smtp mailer used in RhodeCode
22 Simple smtp mailer used in RhodeCode
23 """
23 """
24
24
25 import time
25 import time
26 import logging
26 import logging
27 from socket import sslerror
27 import socket
28 from email.utils import formatdate
28 from email.utils import formatdate
29
29 from rhodecode.lib.rcmail.message import Message
30 from rhodecode.lib.rcmail.message import Message
30 from rhodecode.lib.rcmail.utils import DNS_NAME
31 from rhodecode.lib.rcmail.utils import DNS_NAME
31
32
32 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
33
34
34
35
35 class SmtpMailer(object):
36 class SmtpMailer(object):
36 """
37 """
37 SMTP mailer class
38 SMTP mailer class
38
39
39 mailer = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth
40 mailer = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth
40 mail_port, ssl, tls)
41 mail_port, ssl, tls)
41 mailer.send(recipients, subject, body, attachment_files)
42 mailer.send(recipients, subject, body, attachment_files)
42
43
43 :param recipients might be a list of string or single string
44 :param recipients might be a list of string or single string
44 :param attachment_files is a dict of {filename:location}
45 :param attachment_files is a dict of {filename:location}
45 it tries to guess the mimetype and attach the file
46 it tries to guess the mimetype and attach the file
46
47
47 """
48 """
48
49
49 def __init__(self, mail_from, user, passwd, mail_server, smtp_auth=None,
50 def __init__(self, mail_from, user, passwd, mail_server, smtp_auth=None,
50 mail_port=None, ssl=False, tls=False, debug=False):
51 mail_port=None, ssl=False, tls=False, debug=False):
51
52
52 self.mail_from = mail_from
53 self.mail_from = mail_from
53 self.mail_server = mail_server
54 self.mail_server = mail_server
54 self.mail_port = mail_port
55 self.mail_port = mail_port
55 self.user = user
56 self.user = user
56 self.passwd = passwd
57 self.passwd = passwd
57 self.ssl = ssl
58 self.ssl = ssl
58 self.tls = tls
59 self.tls = tls
59 self.debug = debug
60 self.debug = debug
60 self.auth = smtp_auth
61 self.auth = smtp_auth
61
62
62 def _get_smptlib(self):
63 def _get_smptlib(self):
63 #patch the output
64 # patch the output
64 import smtplib
65 import smtplib
65
66
66 class StderrLogger(object):
67 class StderrLogger(object):
67
68
68 def write(self, message):
69 def write(self, message):
69 log.debug(message)
70 log.debug(message)
70
71
71 org_stderr = smtplib.stderr
72 org_stderr = smtplib.stderr
72 smtplib.stderr = StderrLogger()
73 smtplib.stderr = StderrLogger()
73 return smtplib
74 return smtplib
74
75
75 def send(self, recipients=None, subject='', body='', html='',
76 def send(self, recipients=None, subject='', body='', html='',
76 attachment_files=None):
77 attachment_files=None):
77 recipients = recipients or []
78 recipients = recipients or []
78 if isinstance(recipients, basestring):
79 if isinstance(recipients, basestring):
79 recipients = [recipients]
80 recipients = [recipients]
80 headers = {
81 headers = {
81 'Date': formatdate(time.time())
82 'Date': formatdate(time.time())
82 }
83 }
83 msg = Message(subject, recipients, body, html, self.mail_from,
84 msg = Message(subject, recipients, body, html, self.mail_from,
84 recipients_separator=", ", extra_headers=headers)
85 recipients_separator=", ", extra_headers=headers)
85 raw_msg = msg.to_message()
86 raw_msg = msg.to_message()
86
87
87 # patched smtplib without stderr
88 # patched smtplib without stderr
88 smtplib = self._get_smptlib()
89 smtplib = self._get_smptlib()
89 if self.ssl:
90 if self.ssl:
90 smtp_serv = smtplib.SMTP_SSL(self.mail_server, self.mail_port,
91 smtp_serv = smtplib.SMTP_SSL(self.mail_server, self.mail_port,
91 local_hostname=DNS_NAME.get_fqdn())
92 local_hostname=DNS_NAME.get_fqdn())
92 else:
93 else:
93 smtp_serv = smtplib.SMTP(self.mail_server, self.mail_port,
94 smtp_serv = smtplib.SMTP(self.mail_server, self.mail_port,
94 local_hostname=DNS_NAME.get_fqdn())
95 local_hostname=DNS_NAME.get_fqdn())
95
96
96 if self.tls:
97 if self.tls:
97 smtp_serv.ehlo()
98 smtp_serv.ehlo()
98 smtp_serv.starttls()
99 smtp_serv.starttls()
99
100
100 if self.debug:
101 if self.debug:
101 smtp_serv.set_debuglevel(1)
102 smtp_serv.set_debuglevel(1)
102
103
103 smtp_serv.ehlo()
104 smtp_serv.ehlo()
104 if self.auth:
105 if self.auth:
105 smtp_serv.esmtp_features["auth"] = self.auth
106 smtp_serv.esmtp_features["auth"] = self.auth
106
107
107 # if server requires authorization you must provide login and password
108 # if server requires authorization you must provide login and password
108 # but only if we have them
109 # but only if we have them
109 if self.user and self.passwd:
110 if self.user and self.passwd:
110 smtp_serv.login(self.user, self.passwd)
111 smtp_serv.login(self.user, self.passwd)
111
112
112 smtp_serv.sendmail(msg.sender, msg.send_to, raw_msg.as_string())
113 smtp_serv.sendmail(msg.sender, msg.send_to, raw_msg.as_string())
113 log.info('email sent to: %s' % recipients)
114 log.info('email sent to: %s' % recipients)
114
115
115 try:
116 try:
116 smtp_serv.quit()
117 smtp_serv.quit()
117 except sslerror:
118 except socket.sslerror:
118 # sslerror is raised in tls connections on closing sometimes
119 # sslerror is raised in tls connections on closing sometimes
119 smtp_serv.close()
120 smtp_serv.close()
General Comments 0
You need to be logged in to leave comments. Login now