##// END OF EJS Templates
email notification is not sent by default. Now it is necessary to set an email account in /etc/schain.conf
Miguel Valdez -
r796:a6015faf3805
parent child
Show More
@@ -1,395 +1,395
1 """The admin module contains all administrative classes relating to the schain python api.
1 """The admin module contains all administrative classes relating to the schain python api.
2
2
3 The main role of this module is to send some reports. It contains a
3 The main role of this module is to send some reports. It contains a
4 notification class and a standard error handing class.
4 notification class and a standard error handing class.
5
5
6 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
6 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
7 """
7 """
8 import os, sys
8 import os, sys
9 import traceback
9 import traceback
10 import smtplib
10 import smtplib
11 import ConfigParser
11 import ConfigParser
12 import StringIO
12 import StringIO
13
13
14 from email.mime.text import MIMEText
14 from email.mime.text import MIMEText
15 from email.mime.application import MIMEApplication
15 from email.mime.application import MIMEApplication
16 from email.mime.multipart import MIMEMultipart
16 from email.mime.multipart import MIMEMultipart
17
17
18 class SchainConfigure():
18 class SchainConfigure():
19
19
20 __DEFAULT_ADMINISTRATOR_EMAIL = "miguel.urco@jro.igp.gob.pe"
20 __DEFAULT_ADMINISTRATOR_EMAIL = ""
21 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
21 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
22 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
22 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
23 __DEFAULT_SENDER_PASS = ""
23 __DEFAULT_SENDER_PASS = ""
24
24
25 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
25 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
26 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
26 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
27 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
27 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
28 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
28 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
29
29
30 def __init__(self, initFile = None):
30 def __init__(self, initFile = None):
31
31
32 # Set configuration file
32 # Set configuration file
33 if (initFile == None):
33 if (initFile == None):
34 self.__confFilePath = "/etc/schain.conf"
34 self.__confFilePath = "/etc/schain.conf"
35 else:
35 else:
36 self.__confFilePath = initFile
36 self.__confFilePath = initFile
37
37
38 # open configuration file
38 # open configuration file
39 try:
39 try:
40 self.__confFile = open(self.__confFilePath, "r")
40 self.__confFile = open(self.__confFilePath, "r")
41 except IOError:
41 except IOError:
42 # can't read from file - use all hard-coded values
42 # can't read from file - use all hard-coded values
43 self.__initFromHardCode()
43 self.__initFromHardCode()
44 return
44 return
45
45
46 # create Parser using standard module ConfigParser
46 # create Parser using standard module ConfigParser
47 self.__parser = ConfigParser.ConfigParser()
47 self.__parser = ConfigParser.ConfigParser()
48
48
49 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
49 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
50 strConfFile = StringIO.StringIO("[schain]\n" + self.__confFile.read())
50 strConfFile = StringIO.StringIO("[schain]\n" + self.__confFile.read())
51
51
52 # parse StringIO configuration file
52 # parse StringIO configuration file
53 self.__parser.readfp(strConfFile)
53 self.__parser.readfp(strConfFile)
54
54
55 # read information from configuration file
55 # read information from configuration file
56 self.__readConfFile()
56 self.__readConfFile()
57
57
58 # close conf file
58 # close conf file
59 self.__confFile.close()
59 self.__confFile.close()
60
60
61
61
62 def __initFromHardCode(self):
62 def __initFromHardCode(self):
63
63
64 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
64 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
65 self.__sender_pass = self.__DEFAULT_SENDER_PASS
65 self.__sender_pass = self.__DEFAULT_SENDER_PASS
66 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
66 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
67 self.__email_server = self.__DEFAULT_EMAIL_SERVER
67 self.__email_server = self.__DEFAULT_EMAIL_SERVER
68
68
69 def __readConfFile(self):
69 def __readConfFile(self):
70 """__readConfFile is a private helper function that reads information from the parsed config file.
70 """__readConfFile is a private helper function that reads information from the parsed config file.
71
71
72 Inputs: None
72 Inputs: None
73
73
74 Returns: Void.
74 Returns: Void.
75
75
76 Affects: Initializes class member variables that are found in the config file.
76 Affects: Initializes class member variables that are found in the config file.
77
77
78 Exceptions: MadrigalError thrown if any key not found.
78 Exceptions: MadrigalError thrown if any key not found.
79 """
79 """
80
80
81 # get the sender email
81 # get the sender email
82 try:
82 try:
83 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
83 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
84 except:
84 except:
85 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
85 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
86
86
87 # get the sender password
87 # get the sender password
88 try:
88 try:
89 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
89 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
90 except:
90 except:
91 self.__sender_pass = self.__DEFAULT_SENDER_PASS
91 self.__sender_pass = self.__DEFAULT_SENDER_PASS
92
92
93 # get the administrator email
93 # get the administrator email
94 try:
94 try:
95 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
95 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
96 except:
96 except:
97 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
97 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
98
98
99 # get the server email
99 # get the server email
100 try:
100 try:
101 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
101 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
102 except:
102 except:
103 self.__email_server = self.__DEFAULT_EMAIL_SERVER
103 self.__email_server = self.__DEFAULT_EMAIL_SERVER
104
104
105 def getEmailServer(self):
105 def getEmailServer(self):
106
106
107 return self.__email_server
107 return self.__email_server
108
108
109 def getSenderEmail(self):
109 def getSenderEmail(self):
110
110
111 return self.__sender_email
111 return self.__sender_email
112
112
113 def getSenderPass(self):
113 def getSenderPass(self):
114
114
115 return self.__sender_pass
115 return self.__sender_pass
116
116
117 def getAdminEmail(self):
117 def getAdminEmail(self):
118
118
119 return self.__admin_email
119 return self.__admin_email
120
120
121 class SchainNotify:
121 class SchainNotify:
122 """SchainNotify is an object used to send messages to an administrator about a Schain software.
122 """SchainNotify is an object used to send messages to an administrator about a Schain software.
123
123
124 This object provides functions needed to send messages to an administrator about a Schain , for now
124 This object provides functions needed to send messages to an administrator about a Schain , for now
125 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
125 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
126
126
127 Usage example:
127 Usage example:
128
128
129 import schainpy.admin
129 import schainpy.admin
130
130
131 try:
131 try:
132
132
133 adminObj = schainpy.admin.SchainNotify()
133 adminObj = schainpy.admin.SchainNotify()
134 adminObj.sendAlert('This is important!', 'Important Message')
134 adminObj.sendAlert('This is important!', 'Important Message')
135
135
136 except schainpy.admin.SchainError, e:
136 except schainpy.admin.SchainError, e:
137
137
138 print e.getExceptionStr()
138 print e.getExceptionStr()
139
139
140
140
141 Non-standard Python modules used:
141 Non-standard Python modules used:
142 None
142 None
143
143
144 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
144 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
145 throwing exceptions, since this is the class that will generally be called when there is a problem.
145 throwing exceptions, since this is the class that will generally be called when there is a problem.
146
146
147 Change history:
147 Change history:
148
148
149 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
149 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
150 """
150 """
151
151
152 #constants
152 #constants
153
153
154 def __init__(self):
154 def __init__(self):
155 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
155 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
156
156
157 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
157 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
158 this is the class that will generally be called when there is a problem.
158 this is the class that will generally be called when there is a problem.
159
159
160 Inputs: Existing SchainDB object, by default = None.
160 Inputs: Existing SchainDB object, by default = None.
161
161
162 Returns: void
162 Returns: void
163
163
164 Affects: Initializes self.__binDir.
164 Affects: Initializes self.__binDir.
165
165
166 Exceptions: None.
166 Exceptions: None.
167 """
167 """
168
168
169 # note that the main configuration file is unavailable
169 # note that the main configuration file is unavailable
170 # the best that can be done is send an email to root using localhost mailserver
170 # the best that can be done is send an email to root using localhost mailserver
171 confObj = SchainConfigure()
171 confObj = SchainConfigure()
172
172
173 self.__emailFromAddress = confObj.getSenderEmail()
173 self.__emailFromAddress = confObj.getSenderEmail()
174 self.__emailPass = confObj.getSenderPass()
174 self.__emailPass = confObj.getSenderPass()
175 self.__emailToAddress = confObj.getAdminEmail()
175 self.__emailToAddress = confObj.getAdminEmail()
176 self.__emailServer = confObj.getEmailServer()
176 self.__emailServer = confObj.getEmailServer()
177
177
178 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
178 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
179
179
180 if not email_to:
180 if not email_to:
181 return 0
181 return 0
182
182
183 if not self.__emailServer:
183 if not self.__emailServer:
184 return 0
184 return 0
185
185
186 msg = MIMEMultipart()
186 msg = MIMEMultipart()
187 msg['Subject'] = subject
187 msg['Subject'] = subject
188 msg['From'] = "(Python SChain API): " + email_from
188 msg['From'] = "(Python SChain API): " + email_from
189 msg['Reply-to'] = email_from
189 msg['Reply-to'] = email_from
190 msg['To'] = email_to
190 msg['To'] = email_to
191
191
192 # That is what u see if dont have an email reader:
192 # That is what u see if dont have an email reader:
193 msg.preamble = 'SChainPy'
193 msg.preamble = 'SChainPy'
194
194
195 if html_format:
195 if html_format:
196 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
196 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
197 message = "<html>\n" + message + '</html>'
197 message = "<html>\n" + message + '</html>'
198
198
199 # This is the textual part:
199 # This is the textual part:
200 part = MIMEText(message, "html")
200 part = MIMEText(message, "html")
201 else:
201 else:
202 message = subject + "\n" + subtitle + "\n" + message
202 message = subject + "\n" + subtitle + "\n" + message
203 part = MIMEText(message)
203 part = MIMEText(message)
204
204
205 msg.attach(part)
205 msg.attach(part)
206
206
207 if os.path.isfile(filename):
207 if os.path.isfile(filename):
208 # This is the binary part(The Attachment):
208 # This is the binary part(The Attachment):
209 part = MIMEApplication(open(filename,"rb").read())
209 part = MIMEApplication(open(filename,"rb").read())
210 part.add_header('Content-Disposition',
210 part.add_header('Content-Disposition',
211 'attachment',
211 'attachment',
212 filename=os.path.basename(filename))
212 filename=os.path.basename(filename))
213 msg.attach(part)
213 msg.attach(part)
214
214
215 # Create an instance in SMTP server
215 # Create an instance in SMTP server
216 try:
216 try:
217 smtp = smtplib.SMTP(self.__emailServer)
217 smtp = smtplib.SMTP(self.__emailServer)
218 except:
218 except:
219 print "***** Could not connect to server %s *****" %self.__emailServer
219 print "***** Could not connect to server %s *****" %self.__emailServer
220 return 0
220 return 0
221
221
222 # Start the server:
222 # Start the server:
223 # smtp.ehlo()
223 # smtp.ehlo()
224 if self.__emailPass:
224 if self.__emailPass:
225 smtp.login(self.__emailFromAddress, self.__emailPass)
225 smtp.login(self.__emailFromAddress, self.__emailPass)
226
226
227 # Send the email
227 # Send the email
228 try:
228 try:
229 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
229 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
230 except:
230 except:
231 print "***** Could not send the email to %s *****" %msg['To']
231 print "***** Could not send the email to %s *****" %msg['To']
232 smtp.quit()
232 smtp.quit()
233 return 0
233 return 0
234
234
235 smtp.quit()
235 smtp.quit()
236
236
237 return 1
237 return 1
238
238
239 def sendAlert(self, message, subject = "", subtitle="", filename=""):
239 def sendAlert(self, message, subject = "", subtitle="", filename=""):
240 """sendAlert sends an email with the given message and optional title.
240 """sendAlert sends an email with the given message and optional title.
241
241
242 Inputs: message (string), and optional title (string)
242 Inputs: message (string), and optional title (string)
243
243
244 Returns: void
244 Returns: void
245
245
246 Affects: none
246 Affects: none
247
247
248 Exceptions: None.
248 Exceptions: None.
249 """
249 """
250
250
251 if not self.__emailToAddress:
251 if not self.__emailToAddress:
252 return 0
252 return 0
253
253
254 print "***** Sending alert to %s *****" %self.__emailToAddress
254 print "***** Sending alert to %s *****" %self.__emailToAddress
255 # set up message
255 # set up message
256
256
257 sent=self.sendEmail(email_from=self.__emailFromAddress,
257 sent=self.sendEmail(email_from=self.__emailFromAddress,
258 email_to=self.__emailToAddress,
258 email_to=self.__emailToAddress,
259 subject=subject,
259 subject=subject,
260 message=message,
260 message=message,
261 subtitle=subtitle,
261 subtitle=subtitle,
262 filename=filename)
262 filename=filename)
263
263
264 if not sent:
264 if not sent:
265 return 0
265 return 0
266
266
267 print "***** Your system administrator has been notified *****"
267 print "***** Your system administrator has been notified *****"
268
268
269 return 1
269 return 1
270
270
271 def notify(self, email, message, subject = "", subtitle="", filename=""):
271 def notify(self, email, message, subject = "", subtitle="", filename=""):
272 """notify sends an email with the given message and title to email.
272 """notify sends an email with the given message and title to email.
273
273
274 Inputs: email (string), message (string), and subject (string)
274 Inputs: email (string), message (string), and subject (string)
275
275
276 Returns: void
276 Returns: void
277
277
278 Affects: none
278 Affects: none
279
279
280 Exceptions: None.
280 Exceptions: None.
281 """
281 """
282
282
283 print "Notifying to %s ..." %email
283 print "Notifying to %s ..." %email
284
284
285 self.sendEmail(email_from=self.__emailFromAddress,
285 self.sendEmail(email_from=self.__emailFromAddress,
286 email_to=email,
286 email_to=email,
287 subject=subject,
287 subject=subject,
288 message=message,
288 message=message,
289 subtitle=subtitle,
289 subtitle=subtitle,
290 filename=filename)
290 filename=filename)
291
291
292 print "***** Your system administrator has been notified *****"
292 print "***** Your system administrator has been notified *****"
293
293
294 class SchainError(Exception):
294 class SchainError(Exception):
295 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
295 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
296
296
297 Usage example:
297 Usage example:
298
298
299 import sys, traceback
299 import sys, traceback
300 import schainpy.admin
300 import schainpy.admin
301
301
302 try:
302 try:
303
303
304 test = open('ImportantFile.txt', 'r')
304 test = open('ImportantFile.txt', 'r')
305
305
306 except:
306 except:
307
307
308 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
308 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
309 traceback.format_exception(sys.exc_info()[0],
309 traceback.format_exception(sys.exc_info()[0],
310 sys.exc_info()[1],
310 sys.exc_info()[1],
311 sys.exc_info()[2]))
311 sys.exc_info()[2]))
312 """
312 """
313
313
314
314
315 def __init__(self, strInterpretation, exceptionList=None):
315 def __init__(self, strInterpretation, exceptionList=None):
316 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
316 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
317
317
318 Inputs:
318 Inputs:
319 strIntepretation - A string representing the programmer's interpretation of
319 strIntepretation - A string representing the programmer's interpretation of
320 why the exception occurred
320 why the exception occurred
321
321
322 exceptionList - a list of strings completely describing the exception.
322 exceptionList - a list of strings completely describing the exception.
323 Generated by traceback.format_exception(sys.exc_info()[0],
323 Generated by traceback.format_exception(sys.exc_info()[0],
324 sys.exc_info()[1],
324 sys.exc_info()[1],
325 sys.exc_info()[2])
325 sys.exc_info()[2])
326
326
327 Returns: Void.
327 Returns: Void.
328
328
329 Affects: Initializes class member variables _strInterp, _strExcList.
329 Affects: Initializes class member variables _strInterp, _strExcList.
330
330
331 Exceptions: None.
331 Exceptions: None.
332 """
332 """
333
333
334 if not exceptionList:
334 if not exceptionList:
335 exceptionList = traceback.format_exception(sys.exc_info()[0],
335 exceptionList = traceback.format_exception(sys.exc_info()[0],
336 sys.exc_info()[1],
336 sys.exc_info()[1],
337 sys.exc_info()[2])
337 sys.exc_info()[2])
338
338
339 self._strInterp = strInterpretation
339 self._strInterp = strInterpretation
340 self._strExcList = exceptionList
340 self._strExcList = exceptionList
341
341
342
342
343 def getExceptionStr(self):
343 def getExceptionStr(self):
344 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
344 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
345
345
346 Inputs: None
346 Inputs: None
347
347
348 Returns: A formatted string ready for printing completely describing the exception.
348 Returns: A formatted string ready for printing completely describing the exception.
349
349
350 Affects: None
350 Affects: None
351
351
352 Exceptions: None.
352 Exceptions: None.
353 """
353 """
354 excStr = ''
354 excStr = ''
355 excStr = excStr + self._strInterp + '\n\n'
355 excStr = excStr + self._strInterp + '\n\n'
356
356
357 if self._strExcList != None:
357 if self._strExcList != None:
358 for item in self._strExcList:
358 for item in self._strExcList:
359 excStr = excStr + str(item) + '\n'
359 excStr = excStr + str(item) + '\n'
360
360
361 return excStr
361 return excStr
362
362
363 def __str__(self):
363 def __str__(self):
364
364
365 return(self.getExceptionStr())
365 return(self.getExceptionStr())
366
366
367
367
368 def getExceptionHtml(self):
368 def getExceptionHtml(self):
369 """ getExceptionHtml returns an Html formatted string completely describing the exception.
369 """ getExceptionHtml returns an Html formatted string completely describing the exception.
370
370
371 Inputs: None
371 Inputs: None
372
372
373 Returns: A formatted string ready for printing completely describing the exception.
373 Returns: A formatted string ready for printing completely describing the exception.
374
374
375 Affects: None
375 Affects: None
376
376
377 Exceptions: None.
377 Exceptions: None.
378 """
378 """
379
379
380 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
380 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
381 excStr = excStr + self._strInterp + '\n<BR>\n'
381 excStr = excStr + self._strInterp + '\n<BR>\n'
382
382
383 if self._strExcList != None:
383 if self._strExcList != None:
384 for item in self._strExcList:
384 for item in self._strExcList:
385 excStr = excStr + str(item) + '\n<BR>'
385 excStr = excStr + str(item) + '\n<BR>'
386
386
387 return excStr
387 return excStr
388
388
389 if __name__ == '__main__':
389 if __name__ == '__main__':
390
390
391 test = SchainNotify()
391 test = SchainNotify()
392
392
393 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
393 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
394
394
395 print 'Hopefully message sent - check.'
395 print 'Hopefully message sent - check.'
General Comments 0
You need to be logged in to leave comments. Login now