def write(self, text): ''' Output specified text with the appropriate timestamp prefix. ''' self.ts_LineCount += 1 if self.ts_LineCount <= self.ts_LastHeaderLine or \ text == '\n': self.ts_File.write(text) else: self.ts_File.write('%s - %s' % ( tsru.getDateTimeString(time.time()), text))
def tsCreateScrollableRedirectionLog(self): ''' Return file instance used for scrollable redirected output. ''' # TBD - Begin prototype for Scrollable Redirection Window # Will need an application instance specific file name. theDirectory = os.getcwd() theWindowTitle = self.ts_Title theKeyWord = theWindowTitle.split(' ', 1) theNickName = theKeyWord[0].strip('_').title() theFileName = '%s-stdout' % theNickName if True: thePathName = os.path.join( tsLogger.TsLogger.defaultStandardOutputPath, '%s.log' % theFileName) else: thePathName = tsru.getNextPathName(theDirectory, theFileName) theLogFile = open(thePathName, 'w') theLogFileHeader = tsru.getSeparatorString( title='Begin %s on %s' % ( 'PRINT/STDOUT/STDERR log', tsru.getDateAndTimeString(time.time())), indent=0, position=tsru.layout['TitleIndent'], separatorCharacter='$', tab=4) theLogFile.write('%s\n\n' % theLogFileHeader) theLogFile.write('%s - Started logging to file "%s".\n\n' % ( tsru.getDateTimeString(time.time(), msec=True), thePathName)) # TBD - End prototype for Scrollable Redirection Window return (theLogFile)
def write(self, text): ''' Create the output window if needed and write the string to it. If not called in the context of the gui thread then uses CallAfter to do the work there. NOTE: In accordance with Python convention, this method supports the formating of a single line of output across multiple print statements. ''' if self.ts_Frame is None: msg1 = 'Print statements and other standard output ' msg2 = 'will now be directed to this window.' if wx.ThemeToUse['Stdio']['Timestamp']: theStartupText = '\n\n%s\n' % (msg1 + msg2) else: theStartupText = '%s\n' % (msg1 + msg2) if wx.ThemeToUse['Stdio']['Timestamp']: # Begin the new record with a timestamp. timestamp = tsru.getDateTimeString(time.time(), msec=True) self.ts_Cache += '%s - %s' % (timestamp, theStartupText) else: # Append the text to the existing record. self.ts_Cache += theStartupText self.CreateOutputWindow(theStartupText) if self.ts_logFile is None and \ wx.ThemeToUse['Stdio']['ScrollableLogFile']: self.ts_logFile = self.tsCreateScrollableRedirectionLog() theMarkup = None if self.ts_Frame.display.HasColors: # TBD - Fix so that we pass Attributes without colors. for theKey in wx.ThemeToUse['Stdio']['Markup'].keys(): thePriorityKey = '%s:' % theKey theKeyPosition = text.find(thePriorityKey) ## print('theKeyPosition[%s] = %d' % (theKey, theKeyPosition)) if (theKeyPosition > -1): theMarkup = wx.ThemeToUse['Stdio']['Markup'][theKey] ## print('theKeyPosition[%s] = %d' % ( ## theKey, theKeyPosition)) break # Original design based on wxPyOnDemandOutputWindow # without markup if theMarkup is None: # Apply default markup to increase brightness/conrtrast # in order to improve readability theKey = 'DEFAULT' theMarkup = wx.ThemeToUse['Stdio']['Markup'][theKey] if self.ts_Text is not None: terminalCharacter = len(text) terminalNewLine = text[ terminalCharacter - 1:terminalCharacter] == '\n' if text not in list(printMarkupToIgnore.keys()): if (self.ts_Cache == wx.EmptyString): # Begin the new record with a timestamp. timestamp = tsru.getDateTimeString(time.time(), msec=True) self.ts_Cache += '%s - %s' % (timestamp, text) else: # Append the text to the existing record. ## timestamp = wx.EmptyString ## theMarkup = None self.ts_Cache += text if terminalNewLine: # End and output those existing records that # contain a new line. self.ts_Text.AppendText(self.ts_Cache, markup=theMarkup) self.tsUpdateScrollableRedirectionLog(self.ts_Cache) self.ts_Cache = wx.EmptyString elif terminalNewLine: # End and output those existing records that # would now contain a new line. self.ts_Text.AppendText(self.ts_Cache, markup=theMarkup) self.tsUpdateScrollableRedirectionLog(self.ts_Cache) self.ts_Cache = wx.EmptyString else: # Append the text to the existing record. self.ts_Cache += text self.ts_Frame.Show(True)
msg = "tsWxApp: %s" % fileStdioDevicesError raise tse.ProgramException( tse.APPLICATION_TRAP, msg) theLogFileHeader = tsru.getSeparatorString( title='Begin %s on %s' % ( 'PRINT/STDOUT/STDERR log', tsru.getDateAndTimeString(time.time())), indent=0, position=tsru.layout['TitleIndent'], separatorCharacter='$', tab=4) self.stdioLog.write('%s\n\n' % theLogFileHeader) self.stdioLog.write('%s - Started logging to file "%s".\n\n' % ( tsru.getDateTimeString(time.time()), filename)) msg1 = 'Print statements and other standard output ' msg2 = 'will now be directed to this file.' self.stdioLog.write('%s\n' % (msg1 + msg2)) self.stdioLog.flush() #----------------------------------------------------------------------- def RestoreStdio(self): ''' Restore sys.stdout and sys.stderr. ''' try:
def RedirectStdio(self, filename=None): ''' Redirect sys.stdout and sys.stderr to a file or a popup window. ''' # Verify user accessibility of one library known to be in hierarchy. try: preRedirectStdioDevices = {'stdout': sys.stdout, 'stderr': sys.stderr, ' stdin': sys.stdin} for theKey in list(preRedirectStdioDevices.keys()): self.logger.debug( ' Saved %s %s' % ( theKey, preRedirectStdioDevices[theKey])) except Exception as preRedirectStdioDevicesError: msg = "tsWxApp: %s" % preRedirectStdioDevicesError raise tse.ProgramException( tse.APPLICATION_TRAP, msg) # Save configuration for future restoration by RestoreStdio. self.saveStdio = (sys.stdout, sys.stderr) if filename is None: # Redirect output to a window on the screen. # Capture redirected output to a default file for scrolling. # TBD - How can this support the ThemeToUse Timestamp feature? self.stdioWin = self.outputWindowClass(wx.ThemeToUse['Stdio']['Title']) sys.stdout = self.stdioWin sys.stderr = self.stdioWin try: windowStdioDevices = {'stdout': sys.stdout, 'stderr': sys.stderr, ' stdin': sys.stdin} for theKey in list(windowStdioDevices.keys()): self.logger.debug( ' Saved %s %s' % ( theKey, windowStdioDevices[theKey])) except Exception as windowStdioDevicesError: msg = "tsWxApp: %s" % windowStdioDevicesError raise tse.ProgramException( tse.APPLICATION_TRAP, msg) else: # Redirect output to the specified file. # Setting buffer size of 0 eliminates need for flushing. if wx.ThemeToUse['Stdio']['Timestamp']: self.stdioLog = tsCustomStdioFile(filename, 'w', 1) else: self.stdioLog = open(filename, 'w', 1) sys.stdout = self.stdioLog sys.stderr = self.stdioLog try: fileStdioDevices = {'stdout': sys.stdout, 'stderr': sys.stderr, ' stdin': sys.stdin} for theKey in list(fileStdioDevices.keys()): self.logger.debug( ' Saved %s %s' % ( theKey, fileStdioDevices[theKey])) except Exception as fileStdioDevicesError: msg = "tsWxApp: %s" % fileStdioDevicesError raise tse.ProgramException( tse.APPLICATION_TRAP, msg) theLogFileHeader = tsru.getSeparatorString( title='Begin %s on %s' % ( 'PRINT/STDOUT/STDERR log', tsru.getDateAndTimeString(time.time())), indent=0, position=tsru.layout['TitleIndent'], separatorCharacter='$', tab=4) self.stdioLog.write('%s\n\n' % theLogFileHeader) self.stdioLog.write('%s - Started logging to file "%s".\n\n' % ( tsru.getDateTimeString(time.time()), filename)) msg1 = 'Print statements and other standard output ' msg2 = 'will now be directed to this file.' self.stdioLog.write('%s\n' % (msg1 + msg2)) self.stdioLog.flush()