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