#!/usr/bin/env python\r
# -*- coding: utf-8 -*-\r
\r
-'''A process wrapper class that maintains the text output and execution status of a process\r
-or a list of other process wrappers which carry such data.'''\r
+"""\r
+A process wrapper class that maintains the text output and execution status\r
+of a process or a list of other process wrappers which carry such data.\r
+"""\r
\r
import os\r
import sys\r
import traceback\r
\r
+\r
def readText(textFile):\r
- if( textFile != "" ):\r
+ if (textFile != ""):\r
fp = open(textFile, 'rb')\r
# Create a text/plain message\r
text = (fp.read())\r
fp.close()\r
return text\r
+\r
+\r
# readText\r
\r
def writeText(text, textFile):\r
- if( textFile != "" ):\r
+ if (textFile != ""):\r
fp = open(textFile, 'wb')\r
# Create a text/plain message\r
fp.write(text)\r
fp.close()\r
return text\r
+\r
+\r
# readText\r
\r
class Process:\r
- "A process with logged output"\r
-\r
- def __init__(self, description=None, cmd=None, args=[], cwd=None, env=None, batchWrapper=False):\r
- "Initialize the standard class variables"\r
+ """\r
+ A process with logged output\r
+ """\r
+\r
+ def __init__(self,\r
+ description=None,\r
+ cmd=None,\r
+ args=[],\r
+ cwd=None,\r
+ env=None,\r
+ batchWrapper=False):\r
+ """Initialize the standard class variables"""\r
self.cmd = cmd\r
if not description:\r
self.description = cmd\r
self.env = env\r
self.batchWrapper = batchWrapper\r
self.processKeys = []\r
+\r
# __init__\r
\r
def getElapsedSeconds(self):\r
import math\r
+\r
if self.end and self.start:\r
delta = (self.end - self.start)\r
- formatted = "%s.%s" % (delta.days * 86400 + delta.seconds, int(math.floor(delta.microseconds/1e3)))\r
+ formatted = "%s.%s" % (delta.days * 86400 + delta.seconds,\r
+ int(math.floor(delta.microseconds / 1e3)))\r
else:\r
formatted = None\r
return formatted\r
+\r
# getElapsedtime\r
\r
def writeKey(self, writeDict, key=None, value=None, startStop=None):\r
"Write a key, value pair in a supported format"\r
if key != None and (value != None or startStop != None):\r
- indent = '\t'*writeDict['indentationLevel']\r
+ indent = '\t' * writeDict['indentationLevel']\r
if writeDict['format'] == 'xml':\r
if startStop == 'start':\r
- writeDict['logHandle'].write( "%s<%s>\n" % (indent, key) )\r
+ writeDict['logHandle'].write("%s<%s>\n" % (indent, key))\r
elif startStop == 'stop':\r
- writeDict['logHandle'].write( "%s</%s>\n" % (indent, key) )\r
+ writeDict['logHandle'].write("%s</%s>\n" % (indent, key))\r
else:\r
- writeDict['logHandle'].write( "%s<%s>%s</%s>\n" % (indent, key, value, key) )\r
- else: # writeDict['format'] == 'txt':\r
- writeDict['logHandle'].write( "%s%40s : %s\n" % (indent, key, value) )\r
+ writeDict['logHandle'].write(\r
+ "%s<%s>%s</%s>\n" % (indent, key, value, key))\r
+ else: # writeDict['format'] == 'txt':\r
+ writeDict['logHandle'].write(\r
+ "%s%40s : %s\n" % (indent, key, value))\r
\r
def writeLogHeader(self, writeDict):\r
import platform\r
except:\r
user = "unknown_user"\r
try:\r
- (sysname, nodename, release, version, machine, processor) = platform.uname()\r
+ (sysname, nodename, release, version, machine,\r
+ processor) = platform.uname()\r
except:\r
- (sysname, nodename, release, version, machine, processor) = ("unknown_sysname", "unknown_nodename", "unknown_release", "unknown_version", "unknown_machine", "unknown_processor")\r
+ (sysname, nodename, release, version, machine, processor) = (\r
+ "unknown_sysname", "unknown_nodename", "unknown_release",\r
+ "unknown_version", "unknown_machine", "unknown_processor")\r
try:\r
hostname = platform.node()\r
except:\r
hostname = "unknown_hostname"\r
\r
- self.writeKey(writeDict, 'process', None, 'start' )\r
+ self.writeKey(writeDict, 'process', None, 'start')\r
writeDict['indentationLevel'] += 1\r
\r
- self.writeKey(writeDict, 'description', self.description )\r
- self.writeKey(writeDict, 'cmd', self.cmd )\r
- if self.args: self.writeKey(writeDict, 'args', ' '.join(self.args) )\r
- self.writeKey(writeDict, 'start', self.start )\r
- self.writeKey(writeDict, 'end', self.end )\r
- self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds() )\r
-\r
- self.writeKey(writeDict, 'user', user )\r
- self.writeKey(writeDict, 'sysname', sysname )\r
- self.writeKey(writeDict, 'nodename', nodename )\r
- self.writeKey(writeDict, 'release', release )\r
- self.writeKey(writeDict, 'version', version )\r
- self.writeKey(writeDict, 'machine', machine )\r
- self.writeKey(writeDict, 'processor', processor )\r
+ self.writeKey(writeDict, 'description', self.description)\r
+ self.writeKey(writeDict, 'cmd', self.cmd)\r
+ if self.args: self.writeKey(writeDict, 'args', ' '.join(self.args))\r
+ self.writeKey(writeDict, 'start', self.start)\r
+ self.writeKey(writeDict, 'end', self.end)\r
+ self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds())\r
+\r
+ self.writeKey(writeDict, 'user', user)\r
+ self.writeKey(writeDict, 'sysname', sysname)\r
+ self.writeKey(writeDict, 'nodename', nodename)\r
+ self.writeKey(writeDict, 'release', release)\r
+ self.writeKey(writeDict, 'version', version)\r
+ self.writeKey(writeDict, 'machine', machine)\r
+ self.writeKey(writeDict, 'processor', processor)\r
\r
if len(self.processKeys) > 0:\r
- self.writeKey(writeDict, 'processKeys', None, 'start' )\r
+ self.writeKey(writeDict, 'processKeys', None, 'start')\r
for pair in self.processKeys:\r
(key, value) = pair\r
writeDict['indentationLevel'] += 1\r
- self.writeKey(writeDict, key, value )\r
+ self.writeKey(writeDict, key, value)\r
writeDict['indentationLevel'] -= 1\r
- self.writeKey(writeDict, 'processKeys', None, 'stop' )\r
+ self.writeKey(writeDict, 'processKeys', None, 'stop')\r
+\r
+ self.writeKey(writeDict, 'status', self.status)\r
\r
- self.writeKey(writeDict, 'status', self.status )\r
# writeLogHeader\r
\r
def writeLogFooter(self, writeDict):\r
writeDict['indentationLevel'] -= 1\r
- self.writeKey(writeDict, 'process', None, 'stop' )\r
+ self.writeKey(writeDict, 'process', None, 'stop')\r
+\r
# writeLogFooter\r
\r
- def writeLog(self, logHandle=sys.stdout, indentationLevel=0,format='xml'):\r
- "Write logging information to the specified handle"\r
- \r
+ def writeLog(self, logHandle=sys.stdout, indentationLevel=0, format='xml'):\r
+ """\r
+ Write logging information to the specified handle\r
+ """\r
+\r
writeDict = {}\r
writeDict['logHandle'] = logHandle\r
writeDict['indentationLevel'] = indentationLevel\r
writeDict['format'] = format\r
- \r
+\r
if logHandle:\r
self.writeLogHeader(writeDict)\r
- \r
+\r
if self.log:\r
- self.writeKey(writeDict, 'output', None, 'start' )\r
+ self.writeKey(writeDict, 'output', None, 'start')\r
if format == 'xml':\r
- logHandle.write( "<![CDATA[\n" )\r
+ logHandle.write("<![CDATA[\n")\r
for line in self.log:\r
- logHandle.write( '%s%s\n' % ("", line) )\r
+ logHandle.write('%s%s\n' % ("", line))\r
if format == 'xml':\r
- logHandle.write( "]]>\n" )\r
- self.writeKey(writeDict, 'output', None, 'stop' )\r
+ logHandle.write("]]>\n")\r
+ self.writeKey(writeDict, 'output', None, 'stop')\r
\r
self.writeLogFooter(writeDict)\r
+\r
# writeLog\r
\r
def writeLogToDisk(self, logFilename=None, format='xml', header=None):\r
- if logFilename: \r
+ if logFilename:\r
try:\r
# This also doesn't seem like the best structure...\r
# 3.1\r
try:\r
- logHandle = open( logFilename, mode='wt', encoding="utf-8")\r
+ logHandle = open(logFilename, mode='wt', encoding="utf-8")\r
# 2.6\r
except:\r
- logHandle = open( logFilename, mode='wt')\r
+ logHandle = open(logFilename, mode='wt')\r
except:\r
- print( "Couldn't open log : %s" % logFilename )\r
+ print("Couldn't open log : %s" % logFilename)\r
logHandle = None\r
\r
if logHandle:\r
if header:\r
if format == 'xml':\r
- logHandle.write( "<![CDATA[\n" )\r
- logHandle.write( header )\r
+ logHandle.write("<![CDATA[\n")\r
+ logHandle.write(header)\r
if format == 'xml':\r
- logHandle.write( "]]>\n" )\r
+ logHandle.write("]]>\n")\r
self.writeLog(logHandle)\r
logHandle.close()\r
+\r
# writeLogToDisk\r
\r
def logLine(self, line):\r
"Add a line of text to the log"\r
- self.log.append( line.rstrip() )\r
+ self.log.append(line.rstrip())\r
if self.echo:\r
- print( "%s" % line.rstrip() )\r
+ print("%s" % line.rstrip())\r
+\r
# logLine\r
\r
def execute(self):\r
- "Execute this process"\r
+ """\r
+ Execute this process\r
+ """\r
import re\r
import datetime\r
import traceback\r
- \r
+\r
try:\r
import subprocess as sp\r
except:\r
\r
cmdargs = [self.cmd]\r
cmdargs.extend(self.args)\r
- \r
+\r
if self.echo:\r
if sp:\r
- print( "\n%s : %s\n" % (self.__class__, sp.list2cmdline(cmdargs)) )\r
+ print(\r
+ "\n%s : %s\n" % (self.__class__, sp.list2cmdline(cmdargs)))\r
else:\r
- print( "\n%s : %s\n" % (self.__class__, " ".join(cmdargs)) )\r
+ print("\n%s : %s\n" % (self.__class__, " ".join(cmdargs)))\r
\r
# intialize a few variables that may or may not be set later\r
process = None\r
cmd = " ".join(cmdargs)\r
tmpWrapper = os.path.join(self.cwd, "process.bat")\r
writeText(cmd, tmpWrapper)\r
- print( "%s : Running process through wrapper %s\n" % (self.__class__, tmpWrapper) )\r
- process = sp.Popen([tmpWrapper], stdout=sp.PIPE, stderr=sp.STDOUT, \r
- cwd=self.cwd, env=self.env)\r
+ print("%s : Running process through wrapper %s\n" % (\r
+ self.__class__, tmpWrapper))\r
+ process = sp.Popen([tmpWrapper], stdout=sp.PIPE,\r
+ stderr=sp.STDOUT,\r
+ cwd=self.cwd, env=self.env)\r
else:\r
- process = sp.Popen(cmdargs, stdout=sp.PIPE, stderr=sp.STDOUT, \r
- cwd=self.cwd, env=self.env)\r
+ process = sp.Popen(cmdargs, stdout=sp.PIPE,\r
+ stderr=sp.STDOUT,\r
+ cwd=self.cwd, env=self.env)\r
\r
# using os.popen4\r
else:\r
if self.env:\r
os.environ = self.env\r
if self.cwd:\r
- os.chdir( self.cwd )\r
- \r
- stdin, stdout = os.popen4( cmdargs, 'r')\r
+ os.chdir(self.cwd)\r
+\r
+ stdin, stdout = os.popen4(cmdargs, 'r')\r
except:\r
- print( "Couldn't execute command : %s" % cmdargs[0] )\r
+ print("Couldn't execute command : %s" % cmdargs[0])\r
traceback.print_exc()\r
\r
# Using subprocess\r
if sp:\r
if process != None:\r
- #pid = process.pid\r
- #log.logLine( "process id %s\n" % pid )\r
+ # pid = process.pid\r
+ # log.logLine("process id %s\n" % pid)\r
\r
try:\r
- # This is more proper python, and resolves some issues with a process ending before all\r
- # of its output has been processed, but it also seems to stall when the read buffer\r
- # is near or over it's limit. this happens relatively frequently with processes\r
- # that generate lots of print statements.\r
- #\r
+ # This is more proper python, and resolves some issues with\r
+ # a process ending before all of its output has been\r
+ # processed, but it also seems to stall when the read\r
+ # buffer is near or over it's limit. this happens\r
+ # relatively frequently with processes that generate lots\r
+ # of print statements.\r
for line in process.stdout:\r
self.logLine(line)\r
#\r
break\r
# 3.1\r
try:\r
- self.logLine( str(line, encoding="utf-8") )\r
+ self.logLine(str(line, encoding="utf-8"))\r
# 2.6\r
except:\r
- self.logLine( line )\r
+ self.logLine(line)\r
except:\r
- self.logLine( "Logging error : %s" % sys.exc_info()[0] )\r
+ self.logLine("Logging error : %s" % sys.exc_info()[0])\r
\r
self.status = process.returncode\r
- \r
+\r
if self.batchWrapper and tmpWrapper:\r
try:\r
os.remove(tmpWrapper)\r
except:\r
- print( "Couldn't remove temp wrapper : %s" % tmpWrapper )\r
+ print("Couldn't remove temp wrapper : %s" % tmpWrapper)\r
traceback.print_exc()\r
\r
# Using os.popen4\r
else:\r
exitCode = -1\r
try:\r
- #print( "reading stdout lines" )\r
+ # print("reading stdout lines")\r
stdoutLines = stdout.readlines()\r
exitCode = stdout.close()\r
\r
if self.env:\r
os.environ = parentenv\r
if self.cwd:\r
- os.chdir( parentcwd )\r
- \r
- if len( stdoutLines ) > 0:\r
+ os.chdir(parentcwd)\r
+\r
+ if len(stdoutLines) > 0:\r
for line in stdoutLines:\r
self.logLine(line)\r
\r
if not exitCode:\r
exitCode = 0\r
except:\r
- self.logLine( "Logging error : %s" % sys.exc_info()[0] )\r
+ self.logLine("Logging error : %s" % sys.exc_info()[0])\r
\r
self.status = exitCode\r
- \r
+\r
self.end = datetime.datetime.now()\r
- #execute\r
+ # execute\r
+\r
+\r
# Process\r
\r
class ProcessList(Process):\r
- "A list of processes with logged output"\r
+ """\r
+ A list of processes with logged output\r
+ """\r
\r
def __init__(self, description, blocking=True, cwd=None, env=None):\r
Process.__init__(self, description, None, None, cwd, env)\r
"Initialize the standard class variables"\r
self.processes = []\r
self.blocking = blocking\r
+\r
# __init__\r
\r
def generateReport(self, writeDict):\r
- "Generate a log based on the success of the child processes"\r
+ """\r
+ Generate a log based on the success of the child processes\r
+ """\r
if self.processes:\r
_status = True\r
- indent = '\t'*(writeDict['indentationLevel']+1)\r
- \r
+ indent = '\t' * (writeDict['indentationLevel'] + 1)\r
+\r
self.log = []\r
- \r
+\r
for child in self.processes:\r
if isinstance(child, ProcessList):\r
child.generateReport(writeDict)\r
- \r
+\r
childResult = ""\r
key = child.description\r
value = child.status\r
if writeDict['format'] == 'xml':\r
- childResult = ( "%s<result description=\"%s\">%s</result>" % (indent, key, value) )\r
- else: # writeDict['format'] == 'txt':\r
- childResult = ( "%s%40s : %s" % (indent, key, value) )\r
- self.log.append( childResult )\r
- \r
+ childResult = (\r
+ "%s<result description=\"%s\">%s</result>" % (\r
+ indent, key, value))\r
+ else: # writeDict['format'] == 'txt':\r
+ childResult = ("%s%40s : %s" % (indent, key, value))\r
+ self.log.append(childResult)\r
+\r
if child.status != 0:\r
_status = False\r
if not _status:\r
self.status = -1\r
\r
def writeLogHeader(self, writeDict):\r
- self.writeKey(writeDict, 'processList', None, 'start' )\r
+ self.writeKey(writeDict, 'processList', None, 'start')\r
writeDict['indentationLevel'] += 1\r
\r
- self.writeKey(writeDict, 'description', self.description )\r
- self.writeKey(writeDict, 'start', self.start )\r
- self.writeKey(writeDict, 'end', self.end )\r
- self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds() )\r
+ self.writeKey(writeDict, 'description', self.description)\r
+ self.writeKey(writeDict, 'start', self.start)\r
+ self.writeKey(writeDict, 'end', self.end)\r
+ self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds())\r
\r
self.generateReport(writeDict)\r
\r
- self.writeKey(writeDict, 'status', self.status )\r
+ self.writeKey(writeDict, 'status', self.status)\r
+\r
# writeLogHeader\r
\r
def writeLogFooter(self, writeDict):\r
writeDict['indentationLevel'] -= 1\r
- self.writeKey(writeDict, 'processList', None, 'stop' )\r
+ self.writeKey(writeDict, 'processList', None, 'stop')\r
+\r
# writeLogFooter\r
\r
- def writeLog(self, logHandle=sys.stdout, indentationLevel=0,format='xml'):\r
- "Write logging information to the specified handle"\r
- \r
+ def writeLog(self, logHandle=sys.stdout, indentationLevel=0, format='xml'):\r
+ """\r
+ Write logging information to the specified handle\r
+ """\r
+\r
writeDict = {}\r
writeDict['logHandle'] = logHandle\r
writeDict['indentationLevel'] = indentationLevel\r
writeDict['format'] = format\r
- \r
+\r
if logHandle:\r
self.writeLogHeader(writeDict)\r
- \r
+\r
if self.log:\r
- self.writeKey(writeDict, 'output', None, 'start' )\r
+ self.writeKey(writeDict, 'output', None, 'start')\r
for line in self.log:\r
- logHandle.write( '%s%s\n' % ("", line) )\r
- self.writeKey(writeDict, 'output', None, 'stop' )\r
+ logHandle.write('%s%s\n' % ("", line))\r
+ self.writeKey(writeDict, 'output', None, 'stop')\r
\r
if self.processes:\r
- self.writeKey(writeDict, 'processes', None, 'start' )\r
+ self.writeKey(writeDict, 'processes', None, 'start')\r
for child in self.processes:\r
- child.writeLog( logHandle, indentationLevel + 1, format )\r
- self.writeKey(writeDict, 'processes', None, 'stop' )\r
+ child.writeLog(logHandle, indentationLevel + 1, format)\r
+ self.writeKey(writeDict, 'processes', None, 'stop')\r
\r
self.writeLogFooter(writeDict)\r
+\r
# writeLog\r
\r
def execute(self):\r
- "Execute this list of processes"\r
+ """\r
+ Execute this list of processes\r
+ """\r
import datetime\r
\r
self.start = datetime.datetime.now()\r
try:\r
child.execute()\r
except:\r
- print( "%s : caught exception in child class %s" % (self.__class__, child.__class__) )\r
+ print("%s : caught exception in child class %s" % (\r
+ self.__class__, child.__class__))\r
traceback.print_exc()\r
child.status = -1\r
\r
if self.blocking and child.status != 0:\r
- print( "%s : child class %s finished with an error" % (self.__class__, child.__class__) )\r
+ print("%s : child class %s finished with an error" % (\r
+ self.__class__, child.__class__))\r
self.status = -1\r
break\r
\r
self.end = datetime.datetime.now()\r
- # execute\r
+ # execute\r
+\r
+\r
# ProcessList\r
\r
def main():\r
import optparse\r
\r
p = optparse.OptionParser(description='A process logging script',\r
- prog='process',\r
- version='process 0.1',\r
- usage='%prog [options] [options for the logged process]')\r
+ prog='process',\r
+ version='process 0.1',\r
+ usage=('%prog [options] '\r
+ '[options for the logged process]'))\r
p.add_option('--cmd', '-c', default=None)\r
p.add_option('--log', '-l', default=None)\r
\r
argsStart = sys.argv.index('--') + 1\r
args = sys.argv[argsStart:]\r
except:\r
- argsStart = len(sys.argv)+1\r
+ argsStart = len(sys.argv) + 1\r
args = []\r
\r
if cmd == None:\r
- print( "process: No command specified" )\r
- \r
+ print("process: No command specified")\r
+\r
#\r
# Test regular logging\r
#\r
- process = Process(description="a process",cmd=cmd, args=args)\r
+ process = Process(description="a process", cmd=cmd, args=args)\r
\r
#\r
# Test report generation and writing a log\r
#\r
processList = ProcessList("a process list")\r
- processList.processes.append( process )\r
+ processList.processes.append(process)\r
processList.echo = True\r
processList.execute()\r
- \r
+\r
processList.writeLogToDisk(logFilename)\r
+\r
# main\r
\r
if __name__ == '__main__':\r