##// END OF EJS Templates
test 3.0
test 3.0

File last commit:

r1187:66a3db7e736d
r1222:8e3e1ad5000f v3.0-devel
Show More
admin.py
505 lines | 15.1 KiB | text/x-python | PythonLexer
Alarm working ok
r1130 """
The admin module contains all administrative classes relating to the schain python api.
Miguel Valdez
r681
The main role of this module is to send some reports. It contains a
notification class and a standard error handing class.
$Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
"""
Juan C. Espinoza
test alarm
r1126 import os
import sys
import time
Miguel Valdez
SChainError class has been added
r688 import traceback
Miguel Valdez
r681 import smtplib
Juan C. Espinoza
Review MP changes, three types of operations: self, other and external
r1177 if sys.version[0] == '3':
from configparser import ConfigParser
else:
from ConfigParser import ConfigParser
George Yong
Python 2to3, Spectra (all operations) working
r1167 import io
Juan C. Espinoza
test alarm
r1126 from threading import Thread
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 from multiprocessing import Process
Miguel Valdez
r681 from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
Alarm working ok
r1130 import schainpy
Juan C. Espinoza
test alarm
r1126 from schainpy.utils import log
Juan C. Espinoza
New plotting architecture with buffering/throttle capabilities
r1187 from schainpy.model.graphics.jroplot_base import popup
Juan C. Espinoza
test alarm
r1126
def get_path():
'''
Return schainpy path
'''
try:
root = __file__
if os.path.islink(root):
root = os.path.realpath(root)
return os.path.dirname(os.path.abspath(root))
except:
log.error('I am sorry, but something is wrong... __file__ not found')
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 class Alarm(Process):
Juan C. Espinoza
test alarm
r1126 '''
sound, email & popup alarm
r1128 modes:
0 - All
Alarm working ok
r1130 1 - Send email
2 - Popup message
3 - Sound alarm
sound, email & popup alarm
r1128 4 - Send to alarm system TODO
Juan C. Espinoza
test alarm
r1126 '''
Alarm working ok
r1130 def __init__(self, modes=[], **kwargs):
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 Process.__init__(self)
self.modes = modes
self.kwargs = kwargs
@staticmethod
sound, email & popup alarm
r1128 def play_sound():
sound = os.path.join(get_path(), 'alarm1.oga')
if os.path.exists(sound):
for __ in range(2):
os.system('paplay {}'.format(sound))
time.sleep(0.5)
else:
log.warning('Unable to play alarm, sound file not found', 'ADMIN')
Juan C. Espinoza
test alarm
r1126
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 @staticmethod
sound, email & popup alarm
r1128 def send_email(**kwargs):
notifier = SchainNotify()
George Yong
Python 2to3, Spectra (all operations) working
r1167 print(kwargs)
sound, email & popup alarm
r1128 notifier.notify(**kwargs)
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 @staticmethod
Alarm working ok
r1130 def show_popup(message):
if isinstance(message, list):
message = message[-1]
sound, email & popup alarm
r1128 popup(message)
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 @staticmethod
sound, email & popup alarm
r1128 def send_alarm():
pass
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 @staticmethod
sound, email & popup alarm
r1128 def get_kwargs(kwargs, keys):
ret = {}
for key in keys:
ret[key] = kwargs[key]
return ret
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 def run(self):
tasks = {
1 : self.send_email,
Alarm working ok
r1130 2 : self.show_popup,
3 : self.play_sound,
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 4 : self.send_alarm,
}
tasks_args = {
1: ['email', 'message', 'subject', 'subtitle', 'filename'],
Alarm working ok
r1130 2: ['message'],
3: [],
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 4: [],
}
procs = []
for mode in self.modes:
if 0 in self.modes:
for x in tasks:
t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x]))
t.start()
procs.append(t)
break
else:
t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode]))
sound, email & popup alarm
r1128 t.start()
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 procs.append(t)
for t in procs:
t.join()
Juan C. Espinoza
test alarm
r1126
class SchainConfigure():
Miguel Valdez
r681
sound, email & popup alarm
r1128 __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe"
Miguel Valdez
r681 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
Miguel Valdez
admin.py: Login to email server added
r683 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
__DEFAULT_SENDER_PASS = ""
Miguel Valdez
r681
__SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
__SCHAIN_EMAIL_SERVER = "MAILSERVER"
__SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
Miguel Valdez
admin.py: Login to email server added
r683 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
Miguel Valdez
r681
def __init__(self, initFile = None):
# Set configuration file
if (initFile == None):
self.__confFilePath = "/etc/schain.conf"
else:
self.__confFilePath = initFile
# open configuration file
try:
self.__confFile = open(self.__confFilePath, "r")
except IOError:
# can't read from file - use all hard-coded values
self.__initFromHardCode()
return
# create Parser using standard module ConfigParser
Juan C. Espinoza
Review MP changes, three types of operations: self, other and external
r1177 self.__parser = ConfigParser()
Miguel Valdez
r681
# read conf file into a StringIO with "[madrigal]\n" section heading prepended
George Yong
Python 2to3, Spectra (all operations) working
r1167 strConfFile = io.StringIO("[schain]\n" + self.__confFile.read())
Miguel Valdez
r681
# parse StringIO configuration file
self.__parser.readfp(strConfFile)
# read information from configuration file
self.__readConfFile()
# close conf file
self.__confFile.close()
def __initFromHardCode(self):
self.__sender_email = self.__DEFAULT_SENDER_EMAIL
Miguel Valdez
admin.py: Login to email server added
r683 self.__sender_pass = self.__DEFAULT_SENDER_PASS
Miguel Valdez
r681 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
self.__email_server = self.__DEFAULT_EMAIL_SERVER
def __readConfFile(self):
"""__readConfFile is a private helper function that reads information from the parsed config file.
Inputs: None
Returns: Void.
Affects: Initializes class member variables that are found in the config file.
Exceptions: MadrigalError thrown if any key not found.
"""
# get the sender email
try:
self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
except:
self.__sender_email = self.__DEFAULT_SENDER_EMAIL
Miguel Valdez
admin.py: Login to email server added
r683
# get the sender password
try:
self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
except:
self.__sender_pass = self.__DEFAULT_SENDER_PASS
Miguel Valdez
r681 # get the administrator email
try:
self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
except:
self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
# get the server email
try:
self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
except:
self.__email_server = self.__DEFAULT_EMAIL_SERVER
def getEmailServer(self):
return self.__email_server
def getSenderEmail(self):
return self.__sender_email
Miguel Valdez
admin.py: Login to email server added
r683 def getSenderPass(self):
return self.__sender_pass
Miguel Valdez
r681 def getAdminEmail(self):
return self.__admin_email
class SchainNotify:
"""SchainNotify is an object used to send messages to an administrator about a Schain software.
This object provides functions needed to send messages to an administrator about a Schain , for now
only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
Usage example:
import schainpy.admin
try:
adminObj = schainpy.admin.SchainNotify()
adminObj.sendAlert('This is important!', 'Important Message')
except schainpy.admin.SchainError, e:
print e.getExceptionStr()
Non-standard Python modules used:
None
Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
throwing exceptions, since this is the class that will generally be called when there is a problem.
Change history:
Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
"""
#constants
def __init__(self):
"""__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
this is the class that will generally be called when there is a problem.
Inputs: Existing SchainDB object, by default = None.
Returns: void
Affects: Initializes self.__binDir.
Exceptions: None.
"""
Miguel Valdez
SChainError class has been added
r688
Miguel Valdez
r681 # note that the main configuration file is unavailable
# the best that can be done is send an email to root using localhost mailserver
confObj = SchainConfigure()
self.__emailFromAddress = confObj.getSenderEmail()
Miguel Valdez
admin.py: Login to email server added
r683 self.__emailPass = confObj.getSenderPass()
Miguel Valdez
r681 self.__emailToAddress = confObj.getAdminEmail()
self.__emailServer = confObj.getEmailServer()
def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129
Miguel Valdez
Skip email notification if email or server are empty
r733 if not email_to:
return 0
if not self.__emailServer:
return 0
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 log.success('Sending email to {}...'.format(email_to), 'System')
Miguel Valdez
r681 msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = "(Python SChain API): " + email_from
msg['Reply-to'] = email_from
msg['To'] = email_to
# That is what u see if dont have an email reader:
msg.preamble = 'SChainPy'
if html_format:
message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
message = "<html>\n" + message + '</html>'
# This is the textual part:
part = MIMEText(message, "html")
else:
message = subject + "\n" + subtitle + "\n" + message
part = MIMEText(message)
msg.attach(part)
Juan C. Espinoza
test alarm
r1126 if filename and os.path.isfile(filename):
Miguel Valdez
r681 # This is the binary part(The Attachment):
part = MIMEApplication(open(filename,"rb").read())
part.add_header('Content-Disposition',
'attachment',
filename=os.path.basename(filename))
msg.attach(part)
# Create an instance in SMTP server
Miguel Valdez
admin.py: Login to email server added
r683 try:
smtp = smtplib.SMTP(self.__emailServer)
except:
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 log.error('Could not connect to server {}'.format(self.__emailServer), 'System')
Miguel Valdez
admin.py: Login to email server added
r683 return 0
Miguel Valdez
r681 # Start the server:
Juan C. Espinoza
test alarm
r1126 # smtp.ehlo()
Miguel Valdez
admin.py: Login to email server added
r683 if self.__emailPass:
smtp.login(self.__emailFromAddress, self.__emailPass)
Miguel Valdez
r681
# Send the email
Miguel Valdez
admin.py: Catching error sending email.
r692 try:
smtp.sendmail(msg['From'], msg['To'], msg.as_string())
except:
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 log.error('Could not send the email to {}'.format(msg['To']), 'System')
Miguel Valdez
admin.py: Catching error sending email.
r692 smtp.quit()
return 0
Miguel Valdez
r681 smtp.quit()
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129
log.success('Email sent ', 'System')
Miguel Valdez
r681
Miguel Valdez
admin.py: Login to email server added
r683 return 1
Miguel Valdez
r681
def sendAlert(self, message, subject = "", subtitle="", filename=""):
"""sendAlert sends an email with the given message and optional title.
Inputs: message (string), and optional title (string)
Returns: void
Affects: none
Exceptions: None.
"""
Miguel Valdez
minor changes
r738
if not self.__emailToAddress:
return 0
George Yong
Python 2to3, Spectra (all operations) working
r1167 print("***** Sending alert to %s *****" %self.__emailToAddress)
Miguel Valdez
r681 # set up message
Miguel Valdez
admin.py: Login to email server added
r683 sent=self.sendEmail(email_from=self.__emailFromAddress,
email_to=self.__emailToAddress,
subject=subject,
message=message,
subtitle=subtitle,
filename=filename)
Miguel Valdez
r681
Miguel Valdez
minor changes
r738 if not sent:
return 0
Miguel Valdez
r681
Miguel Valdez
minor changes
r738 return 1
Miguel Valdez
r681
def notify(self, email, message, subject = "", subtitle="", filename=""):
"""notify sends an email with the given message and title to email.
Inputs: email (string), message (string), and subject (string)
Returns: void
Affects: none
Exceptions: None.
"""
sound, email & popup alarm
r1128 if email is None:
email = self.__emailToAddress
Miguel Valdez
r681
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 self.sendEmail(
email_from=self.__emailFromAddress,
email_to=email,
subject=subject,
message=message,
subtitle=subtitle,
filename=filename
)
Miguel Valdez
r681
Miguel Valdez
SChainError class has been added
r688 class SchainError(Exception):
"""SchainError is an exception class that is thrown for all known errors using Schain Py lib.
Miguel Valdez
r681
Usage example:
import sys, traceback
import schainpy.admin
try:
test = open('ImportantFile.txt', 'r')
except:
raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2]))
"""
Miguel Valdez
SChainError class has been added
r688 def __init__(self, strInterpretation, exceptionList=None):
Miguel Valdez
r681 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
Miguel Valdez
SChainError class has been added
r688 Inputs:
strIntepretation - A string representing the programmer's interpretation of
why the exception occurred
Miguel Valdez
r681
exceptionList - a list of strings completely describing the exception.
Generated by traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2])
Returns: Void.
Affects: Initializes class member variables _strInterp, _strExcList.
Exceptions: None.
"""
Miguel Valdez
SChainError class has been added
r688 if not exceptionList:
exceptionList = traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2])
Miguel Valdez
r681 self._strInterp = strInterpretation
self._strExcList = exceptionList
def getExceptionStr(self):
""" getExceptionStr returns a formatted string ready for printing completely describing the exception.
Inputs: None
Returns: A formatted string ready for printing completely describing the exception.
Affects: None
Exceptions: None.
"""
Miguel Valdez
SChainError class has been added
r688 excStr = ''
Miguel Valdez
r681 excStr = excStr + self._strInterp + '\n\n'
if self._strExcList != None:
for item in self._strExcList:
excStr = excStr + str(item) + '\n'
return excStr
def __str__(self):
Miguel Valdez
SChainError class has been added
r688
Miguel Valdez
r681 return(self.getExceptionStr())
def getExceptionHtml(self):
""" getExceptionHtml returns an Html formatted string completely describing the exception.
Inputs: None
Returns: A formatted string ready for printing completely describing the exception.
Affects: None
Exceptions: None.
"""
excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
excStr = excStr + self._strInterp + '\n<BR>\n'
if self._strExcList != None:
for item in self._strExcList:
excStr = excStr + str(item) + '\n<BR>'
return excStr
Now alarm is a process, add SchainWarning exception for handling non-stop exceptions
r1129 class SchainWarning(Exception):
pass
Miguel Valdez
r681 if __name__ == '__main__':
Miguel Valdez
SChainError class has been added
r688
Miguel Valdez
r681 test = SchainNotify()
test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
George Yong
Python 2to3, Spectra (all operations) working
r1167 print('Hopefully message sent - check.')