##// END OF EJS Templates
minor changes
Miguel Valdez -
r738:6e5e8c0c4528
parent child
Show More
@@ -1,388 +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 = "miguel.urco@jro.igp.gob.pe"
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
251 if not self.__emailToAddress:
252 return 0
253
250 print "***** Sending alert to %s *****" %self.__emailToAddress
254 print "***** Sending alert to %s *****" %self.__emailToAddress
251 # set up message
255 # set up message
252
256
253 sent=self.sendEmail(email_from=self.__emailFromAddress,
257 sent=self.sendEmail(email_from=self.__emailFromAddress,
254 email_to=self.__emailToAddress,
258 email_to=self.__emailToAddress,
255 subject=subject,
259 subject=subject,
256 message=message,
260 message=message,
257 subtitle=subtitle,
261 subtitle=subtitle,
258 filename=filename)
262 filename=filename)
259
263
260 if sent:
264 if not sent:
261 print "***** Your system administrator has been notified *****"
265 return 0
262
266
267 print "***** Your system administrator has been notified *****"
268
269 return 1
263
270
264 def notify(self, email, message, subject = "", subtitle="", filename=""):
271 def notify(self, email, message, subject = "", subtitle="", filename=""):
265 """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.
266
273
267 Inputs: email (string), message (string), and subject (string)
274 Inputs: email (string), message (string), and subject (string)
268
275
269 Returns: void
276 Returns: void
270
277
271 Affects: none
278 Affects: none
272
279
273 Exceptions: None.
280 Exceptions: None.
274 """
281 """
275
282
276 print "Notifying to %s ..." %email
283 print "Notifying to %s ..." %email
277
284
278 self.sendEmail(email_from=self.__emailFromAddress,
285 self.sendEmail(email_from=self.__emailFromAddress,
279 email_to=email,
286 email_to=email,
280 subject=subject,
287 subject=subject,
281 message=message,
288 message=message,
282 subtitle=subtitle,
289 subtitle=subtitle,
283 filename=filename)
290 filename=filename)
284
291
285 print "***** Your system administrator has been notified *****"
292 print "***** Your system administrator has been notified *****"
286
293
287 class SchainError(Exception):
294 class SchainError(Exception):
288 """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.
289
296
290 Usage example:
297 Usage example:
291
298
292 import sys, traceback
299 import sys, traceback
293 import schainpy.admin
300 import schainpy.admin
294
301
295 try:
302 try:
296
303
297 test = open('ImportantFile.txt', 'r')
304 test = open('ImportantFile.txt', 'r')
298
305
299 except:
306 except:
300
307
301 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
308 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
302 traceback.format_exception(sys.exc_info()[0],
309 traceback.format_exception(sys.exc_info()[0],
303 sys.exc_info()[1],
310 sys.exc_info()[1],
304 sys.exc_info()[2]))
311 sys.exc_info()[2]))
305 """
312 """
306
313
307
314
308 def __init__(self, strInterpretation, exceptionList=None):
315 def __init__(self, strInterpretation, exceptionList=None):
309 """ __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().
310
317
311 Inputs:
318 Inputs:
312 strIntepretation - A string representing the programmer's interpretation of
319 strIntepretation - A string representing the programmer's interpretation of
313 why the exception occurred
320 why the exception occurred
314
321
315 exceptionList - a list of strings completely describing the exception.
322 exceptionList - a list of strings completely describing the exception.
316 Generated by traceback.format_exception(sys.exc_info()[0],
323 Generated by traceback.format_exception(sys.exc_info()[0],
317 sys.exc_info()[1],
324 sys.exc_info()[1],
318 sys.exc_info()[2])
325 sys.exc_info()[2])
319
326
320 Returns: Void.
327 Returns: Void.
321
328
322 Affects: Initializes class member variables _strInterp, _strExcList.
329 Affects: Initializes class member variables _strInterp, _strExcList.
323
330
324 Exceptions: None.
331 Exceptions: None.
325 """
332 """
326
333
327 if not exceptionList:
334 if not exceptionList:
328 exceptionList = traceback.format_exception(sys.exc_info()[0],
335 exceptionList = traceback.format_exception(sys.exc_info()[0],
329 sys.exc_info()[1],
336 sys.exc_info()[1],
330 sys.exc_info()[2])
337 sys.exc_info()[2])
331
338
332 self._strInterp = strInterpretation
339 self._strInterp = strInterpretation
333 self._strExcList = exceptionList
340 self._strExcList = exceptionList
334
341
335
342
336 def getExceptionStr(self):
343 def getExceptionStr(self):
337 """ 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.
338
345
339 Inputs: None
346 Inputs: None
340
347
341 Returns: A formatted string ready for printing completely describing the exception.
348 Returns: A formatted string ready for printing completely describing the exception.
342
349
343 Affects: None
350 Affects: None
344
351
345 Exceptions: None.
352 Exceptions: None.
346 """
353 """
347 excStr = ''
354 excStr = ''
348 excStr = excStr + self._strInterp + '\n\n'
355 excStr = excStr + self._strInterp + '\n\n'
349
356
350 if self._strExcList != None:
357 if self._strExcList != None:
351 for item in self._strExcList:
358 for item in self._strExcList:
352 excStr = excStr + str(item) + '\n'
359 excStr = excStr + str(item) + '\n'
353
360
354 return excStr
361 return excStr
355
362
356 def __str__(self):
363 def __str__(self):
357
364
358 return(self.getExceptionStr())
365 return(self.getExceptionStr())
359
366
360
367
361 def getExceptionHtml(self):
368 def getExceptionHtml(self):
362 """ getExceptionHtml returns an Html formatted string completely describing the exception.
369 """ getExceptionHtml returns an Html formatted string completely describing the exception.
363
370
364 Inputs: None
371 Inputs: None
365
372
366 Returns: A formatted string ready for printing completely describing the exception.
373 Returns: A formatted string ready for printing completely describing the exception.
367
374
368 Affects: None
375 Affects: None
369
376
370 Exceptions: None.
377 Exceptions: None.
371 """
378 """
372
379
373 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
380 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
374 excStr = excStr + self._strInterp + '\n<BR>\n'
381 excStr = excStr + self._strInterp + '\n<BR>\n'
375
382
376 if self._strExcList != None:
383 if self._strExcList != None:
377 for item in self._strExcList:
384 for item in self._strExcList:
378 excStr = excStr + str(item) + '\n<BR>'
385 excStr = excStr + str(item) + '\n<BR>'
379
386
380 return excStr
387 return excStr
381
388
382 if __name__ == '__main__':
389 if __name__ == '__main__':
383
390
384 test = SchainNotify()
391 test = SchainNotify()
385
392
386 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')
387
394
388 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