mail.py
author Julien Cristau <julien.cristau@logilab.fr>
Fri, 17 Oct 2014 12:14:58 +0200
changeset 10045 0a49d61c8cca
parent 9362 2f0129d17fa9
child 10326 03d98646d57c
permissions -rw-r--r--
Add custom checker for Password values We override the default converter to pass Binary values through, but don't do anything about the checker. This worked previously because yams allowed StringIO instances, although its converter didn't do the right thing for them. Fixing this in yams requires that we properly register a checker.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8599
4fabc81cd924 docstring typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8056
diff changeset
     1
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
8599
4fabc81cd924 docstring typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8056
diff changeset
    18
"""Common utilies to format / send emails."""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
2879
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    22
from base64 import b64encode, b64decode
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    23
from time import time
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    24
from email.mime.multipart import MIMEMultipart
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    25
from email.mime.text import MIMEText
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    26
from email.mime.image import MIMEImage
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    27
from email.header import Header
8056
8909800a8c51 [cleanup] drop some appengine support junk
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    28
from socket import gethostname
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
def header(ustring):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    return Header(ustring.encode('UTF-8'), 'UTF-8')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
def addrheader(uaddr, uname=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    # even if an email address should be ascii, encode it using utf8 since
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2172
diff changeset
    35
    # automatic tests may generate non ascii email address
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1977
diff changeset
    36
    addr = uaddr.encode('UTF-8')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
    if uname:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
        return '%s <%s>' % (header(uname).encode(), addr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    return addr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
2879
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    42
def construct_message_id(appid, eid, withtimestamp=True):
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    43
    if withtimestamp:
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    44
        addrpart = 'eid=%s&timestamp=%.10f' % (eid, time())
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    45
    else:
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    46
        addrpart = 'eid=%s' % eid
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    47
    # we don't want any equal sign nor trailing newlines
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    48
    leftpart = b64encode(addrpart, '.-').rstrip().rstrip('=')
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    49
    return '<%s@%s.%s>' % (leftpart, appid, gethostname())
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    50
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    51
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    52
def parse_message_id(msgid, appid):
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    53
    if msgid[0] == '<':
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    54
        msgid = msgid[1:]
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    55
    if msgid[-1] == '>':
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    56
        msgid = msgid[:-1]
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    57
    try:
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    58
        values, qualif = msgid.split('@')
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    59
        padding = len(values) % 4
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    60
        values = b64decode(str(values + '='*padding), '.-')
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    61
        values = dict(v.split('=') for v in values.split('&'))
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    62
        fromappid, host = qualif.split('.', 1)
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5736
diff changeset
    63
    except Exception:
2879
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    64
        return None
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    65
    if appid != fromappid or host != gethostname():
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    66
        return None
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    67
    return values
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    68
ae26a80c0635 move base NotificationView to cw.common.mail, we may want to use it to send notification from the web ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
    69
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
def format_mail(uinfo, to_addrs, content, subject="",
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
                cc_addrs=(), msgid=None, references=(), config=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
    """Sends an Email to 'e_addr' with content 'content', and subject 'subject'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
    to_addrs and cc_addrs are expected to be a list of email address without
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
    name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    assert type(content) is unicode, repr(content)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    msg = MIMEText(content.encode('UTF-8'), 'plain', 'UTF-8')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    # safety: keep only the first newline
5579
297b2002a083 fix 978144: exception with view send-email if empty subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    80
    try:
297b2002a083 fix 978144: exception with view send-email if empty subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    81
        subject = subject.splitlines()[0]
297b2002a083 fix 978144: exception with view send-email if empty subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    82
        msg['Subject'] = header(subject)
297b2002a083 fix 978144: exception with view send-email if empty subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    83
    except IndexError:
297b2002a083 fix 978144: exception with view send-email if empty subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    84
        pass # no subject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
    if uinfo.get('email'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        email = uinfo['email']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    elif config and config['sender-addr']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        email = unicode(config['sender-addr'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        email = u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    if uinfo.get('name'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        name = uinfo['name']
9362
2f0129d17fa9 [mail] format_mail copy/paste fix: we want to test sender-name, not sender-addr
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8931
diff changeset
    93
    elif config and config['sender-name']:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        name = unicode(config['sender-name'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        name = u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
    msg['From'] = addrheader(email, name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    if config and config['sender-addr'] and config['sender-addr'] != email:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        appaddr = addrheader(config['sender-addr'], config['sender-name'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        msg['Reply-to'] = '%s, %s' % (msg['From'], appaddr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    elif email:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
        msg['Reply-to'] = msg['From']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    if config is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        msg['X-CW'] = config.appid
425
cc9e8986d55e sort email addresses and remove doubled ones before sending the email
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   105
    unique_addrs = lambda addrs: sorted(set(addr for addr in addrs if addr is not None))
cc9e8986d55e sort email addresses and remove doubled ones before sending the email
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   106
    msg['To'] = ', '.join(addrheader(addr) for addr in unique_addrs(to_addrs))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    if cc_addrs:
425
cc9e8986d55e sort email addresses and remove doubled ones before sending the email
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   108
        msg['Cc'] = ', '.join(addrheader(addr) for addr in unique_addrs(cc_addrs))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    if msgid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        msg['Message-id'] = msgid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
    if references:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        msg['References'] = ', '.join(references)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    return msg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
class HtmlEmail(MIMEMultipart):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    def __init__(self, subject, textcontent, htmlcontent,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
                 sendermail=None, sendername=None, recipients=None, ccrecipients=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        MIMEMultipart.__init__(self, 'related')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        self['Subject'] = header(subject)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        self.preamble = 'This is a multi-part message in MIME format.'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        # Attach alternative text message
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
        alternative = MIMEMultipart('alternative')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        self.attach(alternative)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
        msgtext = MIMEText(textcontent.encode('UTF-8'), 'plain', 'UTF-8')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        alternative.attach(msgtext)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        # Attach html message
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
        msghtml = MIMEText(htmlcontent.encode('UTF-8'), 'html', 'UTF-8')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        alternative.attach(msghtml)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
        if sendermail or sendername:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            self['From'] = addrheader(sendermail, sendername)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        if recipients:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
            self['To'] = ', '.join(addrheader(addr) for addr in recipients if addr is not None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        if ccrecipients:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
            self['Cc'] = ', '.join(addrheader(addr) for addr in ccrecipients if addr is not None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
    def attach_image(self, data, htmlId):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        image = MIMEImage(data)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        image.add_header('Content-ID', '<%s>' % htmlId)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        self.attach(image)