408f2cbaab1f960c197b33cdfcd1858dd193631d
[plcapi.git] / PLC / sendmail.py
1 import smtplib
2 import string
3 import sys
4 import time
5
6 from PLC.Faults import *
7
8 """
9 used to send out emails - sets up the headers correctly
10 """
11 class sendmail:
12
13     def __init__(self, config):
14
15         self.MAIL_ENABLED = config.PLC_MAIL_ENABLED
16
17         self.SMTP_SERVER= 'localhost'
18     
19         self.X_MAILER= 'PlanetLab API Mailer'
20
21
22     """
23     open up a connect to our mail server, and send out a message.
24
25     the email addresses are not verified before sending out the message.
26
27     to_addr_list, cc_addr_list, and from_addr should be a dictionary, with the keys
28     being the email address and the value being the plain text name of
29     the recipient. only the first key from from_addr will be used, so it should
30     contain only one address.
31
32     subject is not checked for multiple lines - ensure it is only one.
33     """
34     def mail( self, to_addr_list, cc_addr_list, from_addr, subject, content ):
35
36         if self.MAIL_ENABLED == 0:
37             return 1
38         
39         server= smtplib.SMTP(self.SMTP_SERVER)
40
41         str_date= time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
42
43         str_from_addr= self.create_recipient_list(from_addr,1)
44         str_to_addr= self.create_recipient_list(to_addr_list)
45
46         full_message  = ""
47         full_message += "Content-type: text/plain; charset=iso-8859-1\r\n"
48         full_message += "Date: %s\r\n" % str_date
49         full_message += "MIME-Version: 1.0\r\n"
50
51         full_message += "To: %s\r\n" % str_to_addr
52         full_message += "From: %s\r\n" % str_from_addr
53         
54         if cc_addr_list is not None and len(cc_addr_list) > 0:
55             str_cc_addr= self.create_recipient_list(cc_addr_list)
56             full_message += "Cc: %s\r\n" % str_cc_addr
57
58         full_message += "Subject: %s\r\n" % subject
59         full_message += "Reply-To: %s\r\n" % str_from_addr
60         full_message += "X-Mailer: %s\r\n\r\n" % self.X_MAILER        
61         full_message += content
62
63         try:
64             # get just a list of to recipients (needed for envelope). this
65             # needs to include all reciepients, including Cc
66             local_to_list= to_addr_list.copy()
67
68             if cc_addr_list is not None:
69                 local_to_list.update( cc_addr_list )
70                 
71             all_to_addr_list= self.create_recipient_list(local_to_list,
72                                                          return_string=0)
73             
74             # send out the mail!
75             rc= server.sendmail(str_from_addr, all_to_addr_list, full_message )
76
77             return 1
78         
79         except smtplib.SMTPRecipientsRefused, err:
80             sys.stderr.write( "SMTPRecipientsRefused: %s" % repr(err) )
81             return 0
82         
83         except smtplib.SMTPHeloError:
84             sys.stderr.write( "SMTPHeloError: %s" % repr(err) )
85             return 0
86         
87         except smtplib.SMTPSenderRefused:
88             sys.stderr.write( "SMTPSenderRefused: %s" % repr(err) )
89             return 0
90         
91         except smtplib.SMTPDataError:
92             sys.stderr.write( "SMTPDataError: %s" % repr(err) )
93             return 0
94         
95
96
97
98
99     """
100     accepts a list of email recipient as a dictionary in the same format
101     as the mail function, and returns it in a format suitable for use in
102     an email message. for example:
103
104     if limit is specified, only limit number of entries from
105     addr_list is used. which one is used is not defined, so it is really only
106     useful to make sure that the result has a single entry (for from lines)
107
108     for return_string= 1:
109       input: {'user@domain.com': 'A User','test@planet-lab.org': 'PL User'}
110       ouput: 'A User <user@domain.com>, PL User <test@planet-lab.org>'
111     otherwise:
112       input: {'user@domain.com': 'A User','test@planet-lab.org': 'PL User'}
113       ouput: ['A User <user@domain.com>', 'PL User <test@planet-lab.org>']
114   
115     """
116     def create_recipient_list( self, addr_list, return_string= 1, limit= None ):
117         if not isinstance(addr_list,dict):
118             raise PLCAPIError, \
119                   "Internal error, call to create_recipient_list " \
120                   "with non-dict addr_list (%s)." % str(addr_list)
121         
122         if limit == None:
123             limit= len(addr_list.keys())
124
125         if limit <= 0:
126             return ''
127
128         recipients= []
129         total= 0
130         
131         for email in addr_list.keys():
132             recipients = recipients + ['%s <%s>' % (addr_list[email],email)]
133             total= total+1
134             if total == limit:
135                 break
136
137         if return_string == 1:
138             return string.join( recipients, ", " )
139         else:
140             return recipients
141
142     
143         
144