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