##// 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 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 __DEFAULT_ADMINISTRATOR_EMAIL = "miguel.urco@jro.igp.gob.pe"
20 __DEFAULT_ADMINISTRATOR_EMAIL = ""
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 if not email_to:
181 181 return 0
182 182
183 183 if not self.__emailServer:
184 184 return 0
185 185
186 186 msg = MIMEMultipart()
187 187 msg['Subject'] = subject
188 188 msg['From'] = "(Python SChain API): " + email_from
189 189 msg['Reply-to'] = email_from
190 190 msg['To'] = email_to
191 191
192 192 # That is what u see if dont have an email reader:
193 193 msg.preamble = 'SChainPy'
194 194
195 195 if html_format:
196 196 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
197 197 message = "<html>\n" + message + '</html>'
198 198
199 199 # This is the textual part:
200 200 part = MIMEText(message, "html")
201 201 else:
202 202 message = subject + "\n" + subtitle + "\n" + message
203 203 part = MIMEText(message)
204 204
205 205 msg.attach(part)
206 206
207 207 if os.path.isfile(filename):
208 208 # This is the binary part(The Attachment):
209 209 part = MIMEApplication(open(filename,"rb").read())
210 210 part.add_header('Content-Disposition',
211 211 'attachment',
212 212 filename=os.path.basename(filename))
213 213 msg.attach(part)
214 214
215 215 # Create an instance in SMTP server
216 216 try:
217 217 smtp = smtplib.SMTP(self.__emailServer)
218 218 except:
219 219 print "***** Could not connect to server %s *****" %self.__emailServer
220 220 return 0
221 221
222 222 # Start the server:
223 223 # smtp.ehlo()
224 224 if self.__emailPass:
225 225 smtp.login(self.__emailFromAddress, self.__emailPass)
226 226
227 227 # Send the email
228 228 try:
229 229 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
230 230 except:
231 231 print "***** Could not send the email to %s *****" %msg['To']
232 232 smtp.quit()
233 233 return 0
234 234
235 235 smtp.quit()
236 236
237 237 return 1
238 238
239 239 def sendAlert(self, message, subject = "", subtitle="", filename=""):
240 240 """sendAlert sends an email with the given message and optional title.
241 241
242 242 Inputs: message (string), and optional title (string)
243 243
244 244 Returns: void
245 245
246 246 Affects: none
247 247
248 248 Exceptions: None.
249 249 """
250 250
251 251 if not self.__emailToAddress:
252 252 return 0
253 253
254 254 print "***** Sending alert to %s *****" %self.__emailToAddress
255 255 # set up message
256 256
257 257 sent=self.sendEmail(email_from=self.__emailFromAddress,
258 258 email_to=self.__emailToAddress,
259 259 subject=subject,
260 260 message=message,
261 261 subtitle=subtitle,
262 262 filename=filename)
263 263
264 264 if not sent:
265 265 return 0
266 266
267 267 print "***** Your system administrator has been notified *****"
268 268
269 269 return 1
270 270
271 271 def notify(self, email, message, subject = "", subtitle="", filename=""):
272 272 """notify sends an email with the given message and title to email.
273 273
274 274 Inputs: email (string), message (string), and subject (string)
275 275
276 276 Returns: void
277 277
278 278 Affects: none
279 279
280 280 Exceptions: None.
281 281 """
282 282
283 283 print "Notifying to %s ..." %email
284 284
285 285 self.sendEmail(email_from=self.__emailFromAddress,
286 286 email_to=email,
287 287 subject=subject,
288 288 message=message,
289 289 subtitle=subtitle,
290 290 filename=filename)
291 291
292 292 print "***** Your system administrator has been notified *****"
293 293
294 294 class SchainError(Exception):
295 295 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
296 296
297 297 Usage example:
298 298
299 299 import sys, traceback
300 300 import schainpy.admin
301 301
302 302 try:
303 303
304 304 test = open('ImportantFile.txt', 'r')
305 305
306 306 except:
307 307
308 308 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
309 309 traceback.format_exception(sys.exc_info()[0],
310 310 sys.exc_info()[1],
311 311 sys.exc_info()[2]))
312 312 """
313 313
314 314
315 315 def __init__(self, strInterpretation, exceptionList=None):
316 316 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
317 317
318 318 Inputs:
319 319 strIntepretation - A string representing the programmer's interpretation of
320 320 why the exception occurred
321 321
322 322 exceptionList - a list of strings completely describing the exception.
323 323 Generated by traceback.format_exception(sys.exc_info()[0],
324 324 sys.exc_info()[1],
325 325 sys.exc_info()[2])
326 326
327 327 Returns: Void.
328 328
329 329 Affects: Initializes class member variables _strInterp, _strExcList.
330 330
331 331 Exceptions: None.
332 332 """
333 333
334 334 if not exceptionList:
335 335 exceptionList = traceback.format_exception(sys.exc_info()[0],
336 336 sys.exc_info()[1],
337 337 sys.exc_info()[2])
338 338
339 339 self._strInterp = strInterpretation
340 340 self._strExcList = exceptionList
341 341
342 342
343 343 def getExceptionStr(self):
344 344 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
345 345
346 346 Inputs: None
347 347
348 348 Returns: A formatted string ready for printing completely describing the exception.
349 349
350 350 Affects: None
351 351
352 352 Exceptions: None.
353 353 """
354 354 excStr = ''
355 355 excStr = excStr + self._strInterp + '\n\n'
356 356
357 357 if self._strExcList != None:
358 358 for item in self._strExcList:
359 359 excStr = excStr + str(item) + '\n'
360 360
361 361 return excStr
362 362
363 363 def __str__(self):
364 364
365 365 return(self.getExceptionStr())
366 366
367 367
368 368 def getExceptionHtml(self):
369 369 """ getExceptionHtml returns an Html formatted string completely describing the exception.
370 370
371 371 Inputs: None
372 372
373 373 Returns: A formatted string ready for printing completely describing the exception.
374 374
375 375 Affects: None
376 376
377 377 Exceptions: None.
378 378 """
379 379
380 380 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
381 381 excStr = excStr + self._strInterp + '\n<BR>\n'
382 382
383 383 if self._strExcList != None:
384 384 for item in self._strExcList:
385 385 excStr = excStr + str(item) + '\n<BR>'
386 386
387 387 return excStr
388 388
389 389 if __name__ == '__main__':
390 390
391 391 test = SchainNotify()
392 392
393 393 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
394 394
395 395 print 'Hopefully message sent - check.'
General Comments 0
You need to be logged in to leave comments. Login now