X-Git-Url: http://users.mur.at/ms/git/gitweb/?p=OpenColorIO-Configs.git;a=blobdiff_plain;f=aces_1.0.0%2Fpython%2Faces_ocio%2Fprocess.py;h=db23fc37abc24b4b4d26524560102b65a5b10225;hp=7660c15052f6fd012f779717d024af6f7099d75f;hb=d815605e42c964ddb306e32506caaa077b3cf160;hpb=75d8749d3630921f8ced18c026cd3cf0d9af14b6 diff --git a/aces_1.0.0/python/aces_ocio/process.py b/aces_1.0.0/python/aces_ocio/process.py index 7660c15..db23fc3 100755 --- a/aces_1.0.0/python/aces_ocio/process.py +++ b/aces_1.0.0/python/aces_ocio/process.py @@ -2,8 +2,8 @@ # -*- coding: utf-8 -*- """ -A process wrapper class that maintains the text output and execution status -of a process or a list of other process wrappers which carry such data. +A process wrapper class that maintains the text output and execution status of +a process or a list of other process wrappers which carry such data. """ import os @@ -17,38 +17,58 @@ __maintainer__ = 'ACES Developers' __email__ = 'aces@oscars.org' __status__ = 'Production' -__all__ = ['readText', - 'writeText', +__all__ = ['read_text', + 'write_text', 'Process', 'ProcessList', 'main'] -def readText(textFile): - if (textFile != ""): - fp = open(textFile, 'rb') - # Create a text/plain message - text = (fp.read()) - fp.close() - return text +def read_text(text_file): + """ + Object description. + Parameters + ---------- + parameter : type + Parameter description. -# readText + Returns + ------- + type + Return value description. + """ -def writeText(text, textFile): - if (textFile != ""): - fp = open(textFile, 'wb') - # Create a text/plain message - fp.write(text) - fp.close() + if text_file != '': + with open(text_file, 'rb') as fp: + text = (fp.read()) return text -# readText +def write_text(text, text_file): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + + if text_file != '': + with open(text_file, 'wb') as fp: + fp.write(text) + return text + class Process: """ - A process with logged output + A process with logged output. """ def __init__(self, @@ -57,8 +77,21 @@ class Process: args=[], cwd=None, env=None, - batchWrapper=False): - """Initialize the standard class variables""" + batch_wrapper=False): + """ + Initialize the standard class variables. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + self.cmd = cmd if not description: self.description = cmd @@ -72,169 +105,256 @@ class Process: self.echo = True self.cwd = cwd self.env = env - self.batchWrapper = batchWrapper - self.processKeys = [] + self.batch_wrapper = batch_wrapper + self.process_keys = [] + + def get_elapsed_seconds(self): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. - # __init__ + Returns + ------- + type + Return value description. + """ - def getElapsedSeconds(self): import math if self.end and self.start: delta = (self.end - self.start) - formatted = "%s.%s" % (delta.days * 86400 + delta.seconds, + formatted = '%s.%s' % (delta.days * 86400 + delta.seconds, int(math.floor(delta.microseconds / 1e3))) else: formatted = None return formatted - # getElapsedtime - - def writeKey(self, writeDict, key=None, value=None, startStop=None): - "Write a key, value pair in a supported format" - if key != None and (value != None or startStop != None): - indent = '\t' * writeDict['indentationLevel'] - if writeDict['format'] == 'xml': - if startStop == 'start': - writeDict['logHandle'].write("%s<%s>\n" % (indent, key)) - elif startStop == 'stop': - writeDict['logHandle'].write("%s\n" % (indent, key)) + def write_key(self, write_dict, key=None, value=None, start_stop=None): + """ + Writes a key / value pair in a supported format. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + + if key != None and (value != None or start_stop != None): + indent = '\t' * write_dict['indentationLevel'] + if write_dict['format'] == 'xml': + if start_stop == 'start': + write_dict['logHandle'].write('%s<%s>\n' % (indent, key)) + elif start_stop == 'stop': + write_dict['logHandle'].write('%s\n' % (indent, key)) else: - writeDict['logHandle'].write( - "%s<%s>%s\n" % (indent, key, value, key)) - else: # writeDict['format'] == 'txt': - writeDict['logHandle'].write( - "%s%40s : %s\n" % (indent, key, value)) + write_dict['logHandle'].write( + '%s<%s>%s\n' % (indent, key, value, key)) + else: + write_dict['logHandle'].write( + '%s%40s : %s\n' % (indent, key, value)) + + def write_log_header(self, write_dict): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ - def writeLogHeader(self, writeDict): import platform - # Retrieve operating environment information - user = None try: user = os.getlogin() except: try: - user = os.getenv("USERNAME") - if user == None: - user = os.getenv("USER") + user = os.getenv('USERNAME') + if user is None: + user = os.getenv('USER') except: - user = "unknown_user" + user = 'unknown_user' try: (sysname, nodename, release, version, machine, processor) = platform.uname() except: (sysname, nodename, release, version, machine, processor) = ( - "unknown_sysname", "unknown_nodename", "unknown_release", - "unknown_version", "unknown_machine", "unknown_processor") - try: - hostname = platform.node() - except: - hostname = "unknown_hostname" - - self.writeKey(writeDict, 'process', None, 'start') - writeDict['indentationLevel'] += 1 - - self.writeKey(writeDict, 'description', self.description) - self.writeKey(writeDict, 'cmd', self.cmd) - if self.args: self.writeKey(writeDict, 'args', ' '.join(self.args)) - self.writeKey(writeDict, 'start', self.start) - self.writeKey(writeDict, 'end', self.end) - self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds()) - - self.writeKey(writeDict, 'user', user) - self.writeKey(writeDict, 'sysname', sysname) - self.writeKey(writeDict, 'nodename', nodename) - self.writeKey(writeDict, 'release', release) - self.writeKey(writeDict, 'version', version) - self.writeKey(writeDict, 'machine', machine) - self.writeKey(writeDict, 'processor', processor) - - if len(self.processKeys) > 0: - self.writeKey(writeDict, 'processKeys', None, 'start') - for pair in self.processKeys: + 'unknown_sysname', 'unknown_nodename', 'unknown_release', + 'unknown_version', 'unknown_machine', 'unknown_processor') + + self.write_key(write_dict, 'process', None, 'start') + write_dict['indentationLevel'] += 1 + + self.write_key(write_dict, 'description', self.description) + self.write_key(write_dict, 'cmd', self.cmd) + if self.args: + self.write_key(write_dict, 'args', ' '.join(self.args)) + self.write_key(write_dict, 'start', self.start) + self.write_key(write_dict, 'end', self.end) + self.write_key(write_dict, 'elapsed', self.get_elapsed_seconds()) + + self.write_key(write_dict, 'user', user) + self.write_key(write_dict, 'sysname', sysname) + self.write_key(write_dict, 'nodename', nodename) + self.write_key(write_dict, 'release', release) + self.write_key(write_dict, 'version', version) + self.write_key(write_dict, 'machine', machine) + self.write_key(write_dict, 'processor', processor) + + if len(self.process_keys) > 0: + self.write_key(write_dict, 'processKeys', None, 'start') + for pair in self.process_keys: (key, value) = pair - writeDict['indentationLevel'] += 1 - self.writeKey(writeDict, key, value) - writeDict['indentationLevel'] -= 1 - self.writeKey(writeDict, 'processKeys', None, 'stop') + write_dict['indentationLevel'] += 1 + self.write_key(write_dict, key, value) + write_dict['indentationLevel'] -= 1 + self.write_key(write_dict, 'processKeys', None, 'stop') - self.writeKey(writeDict, 'status', self.status) + self.write_key(write_dict, 'status', self.status) - # writeLogHeader + def write_log_footer(self, write_dict): + """ + Object description. - def writeLogFooter(self, writeDict): - writeDict['indentationLevel'] -= 1 - self.writeKey(writeDict, 'process', None, 'stop') + Parameters + ---------- + parameter : type + Parameter description. - # writeLogFooter + Returns + ------- + type + Return value description. + """ - def writeLog(self, logHandle=sys.stdout, indentationLevel=0, format='xml'): + write_dict['indentationLevel'] -= 1 + self.write_key(write_dict, 'process', None, 'stop') + + def write_log(self, + log_handle=sys.stdout, + indentation_level=0, + format='xml'): """ - Write logging information to the specified handle + Writes logging information to the specified handle. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. """ - writeDict = {} - writeDict['logHandle'] = logHandle - writeDict['indentationLevel'] = indentationLevel - writeDict['format'] = format + write_dict = {} + write_dict['logHandle'] = log_handle + write_dict['indentationLevel'] = indentation_level + write_dict['format'] = format - if logHandle: - self.writeLogHeader(writeDict) + if log_handle: + self.write_log_header(write_dict) if self.log: - self.writeKey(writeDict, 'output', None, 'start') + self.write_key(write_dict, 'output', None, 'start') if format == 'xml': - logHandle.write("\n") - self.writeKey(writeDict, 'output', None, 'stop') + log_handle.write(']]>\n') + self.write_key(write_dict, 'output', None, 'stop') + + self.write_log_footer(write_dict) - self.writeLogFooter(writeDict) + def write_log_to_disk(self, log_filename=None, format='xml', header=None): + """ + Object description. - # writeLog + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ - def writeLogToDisk(self, logFilename=None, format='xml', header=None): - if logFilename: + if log_filename: try: - # This also doesn't seem like the best structure... + # TODO: Review statements. # 3.1 try: - logHandle = open(logFilename, mode='wt', encoding="utf-8") + log_handle = ( + open(log_filename, mode='wt', encoding='utf-8')) # 2.6 except: - logHandle = open(logFilename, mode='wt') + log_handle = open(log_filename, mode='wt') except: - print("Couldn't open log : %s" % logFilename) - logHandle = None + print('Couldn\'t open log : %s' % log_filename) + log_handle = None - if logHandle: + if log_handle: if header: if format == 'xml': - logHandle.write("\n") - self.writeLog(logHandle) - logHandle.close() + log_handle.write(']]>\n') + self.write_log(log_handle) + log_handle.close() - # writeLogToDisk + def log_line(self, line): + """ + Adds a line of text to the log. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ - def logLine(self, line): - "Add a line of text to the log" self.log.append(line.rstrip()) if self.echo: - print("%s" % line.rstrip()) - - # logLine + print('%s' % line.rstrip()) def execute(self): """ - Execute this process + Executes the current process. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. """ - import re + import datetime import traceback @@ -251,28 +371,27 @@ class Process: if self.echo: if sp: print( - "\n%s : %s\n" % (self.__class__, sp.list2cmdline(cmdargs))) + '\n%s : %s\n' % (self.__class__, sp.list2cmdline(cmdargs))) else: - print("\n%s : %s\n" % (self.__class__, " ".join(cmdargs))) + print('\n%s : %s\n' % (self.__class__, ' '.join(cmdargs))) - # intialize a few variables that may or may not be set later process = None - tmpWrapper = None + tmp_wrapper = None stdout = None stdin = None parentenv = os.environ parentcwd = os.getcwd() try: - # Using subprocess + # Using *subprocess*. if sp: - if self.batchWrapper: - cmd = " ".join(cmdargs) - tmpWrapper = os.path.join(self.cwd, "process.bat") - writeText(cmd, tmpWrapper) - print("%s : Running process through wrapper %s\n" % ( - self.__class__, tmpWrapper)) - process = sp.Popen([tmpWrapper], stdout=sp.PIPE, + if self.batch_wrapper: + cmd = ' '.join(cmdargs) + tmp_wrapper = os.path.join(self.cwd, 'process.bat') + write_text(cmd, tmp_wrapper) + print('%s : Running process through wrapper %s\n' % ( + self.__class__, tmp_wrapper)) + process = sp.Popen([tmp_wrapper], stdout=sp.PIPE, stderr=sp.STDOUT, cwd=self.cwd, env=self.env) else: @@ -280,7 +399,7 @@ class Process: stderr=sp.STDOUT, cwd=self.cwd, env=self.env) - # using os.popen4 + # using *os.popen4*. else: if self.env: os.environ = self.env @@ -289,59 +408,59 @@ class Process: stdin, stdout = os.popen4(cmdargs, 'r') except: - print("Couldn't execute command : %s" % cmdargs[0]) + print('Couldn\'t execute command : %s' % cmdargs[0]) traceback.print_exc() - # Using subprocess + # Using *subprocess* if sp: if process != None: # pid = process.pid - # log.logLine("process id %s\n" % pid) + # log.logLine('process id %s\n' % pid) try: # This is more proper python, and resolves some issues with # a process ending before all of its output has been # processed, but it also seems to stall when the read - # buffer is near or over it's limit. this happens + # buffer is near or over its limit. This happens # relatively frequently with processes that generate lots # of print statements. for line in process.stdout: - self.logLine(line) - # - # So we go with the, um, uglier option below + self.log_line(line) - # This is now used to ensure that the process has finished - line = "" - while line != None and process.poll() == None: + # So we go with the, um, uglier option below. + + # This is now used to ensure that the process has finished. + line = '' + while line != None and process.poll() is None: try: line = process.stdout.readline() except: break # 3.1 try: - self.logLine(str(line, encoding="utf-8")) + self.log_line(str(line, encoding='utf-8')) # 2.6 except: - self.logLine(line) + self.log_line(line) except: - self.logLine("Logging error : %s" % sys.exc_info()[0]) + self.log_line('Logging error : %s' % sys.exc_info()[0]) self.status = process.returncode - if self.batchWrapper and tmpWrapper: + if self.batch_wrapper and tmp_wrapper: try: - os.remove(tmpWrapper) + os.remove(tmp_wrapper) except: - print("Couldn't remove temp wrapper : %s" % tmpWrapper) + print( + 'Couldn\'t remove temp wrapper : %s' % tmp_wrapper) traceback.print_exc() - # Using os.popen4 + # Using *os.popen4*. else: - exitCode = -1 + exit_code = -1 try: - # print("reading stdout lines") - stdoutLines = stdout.readlines() - exitCode = stdout.close() + stdout_lines = stdout.readlines() + exit_code = stdout.close() stdout.close() stdin.close() @@ -351,60 +470,79 @@ class Process: if self.cwd: os.chdir(parentcwd) - if len(stdoutLines) > 0: - for line in stdoutLines: - self.logLine(line) + if len(stdout_lines) > 0: + for line in stdout_lines: + self.log_line(line) - if not exitCode: - exitCode = 0 + if not exit_code: + exit_code = 0 except: - self.logLine("Logging error : %s" % sys.exc_info()[0]) + self.log_line('Logging error : %s' % sys.exc_info()[0]) - self.status = exitCode + self.status = exit_code self.end = datetime.datetime.now() - # execute - -# Process class ProcessList(Process): """ - A list of processes with logged output + A list of processes with logged output. """ def __init__(self, description, blocking=True, cwd=None, env=None): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + Process.__init__(self, description, None, None, cwd, env) - "Initialize the standard class variables" + 'Initialize the standard class variables' self.processes = [] self.blocking = blocking - # __init__ - - def generateReport(self, writeDict): + def generate_report(self, write_dict): """ - Generate a log based on the success of the child processes + Generates a log based on the success of the child processes. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. """ + if self.processes: _status = True - indent = '\t' * (writeDict['indentationLevel'] + 1) + indent = '\t' * (write_dict['indentationLevel'] + 1) self.log = [] for child in self.processes: if isinstance(child, ProcessList): - child.generateReport(writeDict) + child.generate_report(write_dict) - childResult = "" key = child.description value = child.status - if writeDict['format'] == 'xml': - childResult = ( - "%s%s" % ( + if write_dict['format'] == 'xml': + child_result = ( + '%s%s' % ( indent, key, value)) - else: # writeDict['format'] == 'txt': - childResult = ("%s%40s : %s" % (indent, key, value)) - self.log.append(childResult) + else: + child_result = ('%s%40s : %s' % (indent, key, value)) + self.log.append(child_result) if child.status != 0: _status = False @@ -413,63 +551,109 @@ class ProcessList(Process): else: self.status = 0 else: - self.log = ["No child processes available to generate a report"] + self.log = ['No child processes available to generate a report'] self.status = -1 - def writeLogHeader(self, writeDict): - self.writeKey(writeDict, 'processList', None, 'start') - writeDict['indentationLevel'] += 1 + def write_log_header(self, write_dict): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + + self.write_key(write_dict, 'processList', None, 'start') + write_dict['indentationLevel'] += 1 - self.writeKey(writeDict, 'description', self.description) - self.writeKey(writeDict, 'start', self.start) - self.writeKey(writeDict, 'end', self.end) - self.writeKey(writeDict, 'elapsed', self.getElapsedSeconds()) + self.write_key(write_dict, 'description', self.description) + self.write_key(write_dict, 'start', self.start) + self.write_key(write_dict, 'end', self.end) + self.write_key(write_dict, 'elapsed', self.get_elapsed_seconds()) - self.generateReport(writeDict) + self.generate_report(write_dict) - self.writeKey(writeDict, 'status', self.status) + self.write_key(write_dict, 'status', self.status) - # writeLogHeader + def write_log_footer(self, write_dict): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. - def writeLogFooter(self, writeDict): - writeDict['indentationLevel'] -= 1 - self.writeKey(writeDict, 'processList', None, 'stop') + Returns + ------- + type + Return value description. + """ - # writeLogFooter + write_dict['indentationLevel'] -= 1 + self.write_key(write_dict, 'processList', None, 'stop') - def writeLog(self, logHandle=sys.stdout, indentationLevel=0, format='xml'): + def write_log(self, + log_handle=sys.stdout, + indentation_level=0, + format='xml'): """ - Write logging information to the specified handle + Writes logging information to the specified handle. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. """ - writeDict = {} - writeDict['logHandle'] = logHandle - writeDict['indentationLevel'] = indentationLevel - writeDict['format'] = format + write_dict = {} + write_dict['logHandle'] = log_handle + write_dict['indentationLevel'] = indentation_level + write_dict['format'] = format - if logHandle: - self.writeLogHeader(writeDict) + if log_handle: + self.write_log_header(write_dict) if self.log: - self.writeKey(writeDict, 'output', None, 'start') + self.write_key(write_dict, 'output', None, 'start') for line in self.log: - logHandle.write('%s%s\n' % ("", line)) - self.writeKey(writeDict, 'output', None, 'stop') + log_handle.write('%s%s\n' % ('', line)) + self.write_key(write_dict, 'output', None, 'stop') if self.processes: - self.writeKey(writeDict, 'processes', None, 'start') + self.write_key(write_dict, 'processes', None, 'start') for child in self.processes: - child.writeLog(logHandle, indentationLevel + 1, format) - self.writeKey(writeDict, 'processes', None, 'stop') + child.write_log(log_handle, indentation_level + 1, format) + self.write_key(write_dict, 'processes', None, 'stop') - self.writeLogFooter(writeDict) - - # writeLog + self.write_log_footer(write_dict) def execute(self): """ - Execute this list of processes + Executes the list of processes. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. """ + import datetime self.start = datetime.datetime.now() @@ -481,24 +665,35 @@ class ProcessList(Process): try: child.execute() except: - print("%s : caught exception in child class %s" % ( + print('%s : caught exception in child class %s' % ( self.__class__, child.__class__)) traceback.print_exc() child.status = -1 if self.blocking and child.status != 0: - print("%s : child class %s finished with an error" % ( + print('%s : child class %s finished with an error' % ( self.__class__, child.__class__)) self.status = -1 break self.end = datetime.datetime.now() - # execute - -# ProcessList def main(): + """ + Object description. + + Parameters + ---------- + parameter : type + Parameter description. + + Returns + ------- + type + Return value description. + """ + import optparse p = optparse.OptionParser(description='A process logging script', @@ -511,38 +706,30 @@ def main(): options, arguments = p.parse_args() - # - # Get options - # cmd = options.cmd - logFilename = options.log + log_filename = options.log try: - argsStart = sys.argv.index('--') + 1 - args = sys.argv[argsStart:] + args_start = sys.argv.index('--') + 1 + args = sys.argv[args_start:] except: - argsStart = len(sys.argv) + 1 + args_start = len(sys.argv) + 1 args = [] - if cmd == None: - print("process: No command specified") + if cmd is None: + print('process: No command specified') - # - # Test regular logging - # - process = Process(description="a process", cmd=cmd, args=args) + # Testing regular logging. + process = Process(description='a process', cmd=cmd, args=args) - # - # Test report generation and writing a log - # - processList = ProcessList("a process list") - processList.processes.append(process) - processList.echo = True - processList.execute() + # Testing report generation and writing a log. + process_list = ProcessList('a process list') + process_list.processes.append(process) + process_list.echo = True + process_list.execute() - processList.writeLogToDisk(logFilename) + process_list.write_log_to_disk(log_filename) -# main if __name__ == '__main__': main()