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