<s> from objc import YES , NO , IBAction , IBOutlet <EOL> from Foundation import * <EOL> from AppKit import * <EOL> import munki <EOL> import os <EOL> class MSCLogViewDataSource ( NSObject ) : <EOL> """<STR_LIT>""" <EOL> logFileData = NSMutableArray . alloc ( ) . init ( ) <EOL> filteredData = logFileData <EOL> lastLineIsPartial = False <EOL> filterText = '<STR_LIT>' <EOL> def tableView_writeRowsWithIndexes_toPasteboard_ ( <EOL> self , aTableView , rowIndexes , pasteboard ) : <EOL> '''<STR_LIT>''' <EOL> text_to_copy = '<STR_LIT>' <EOL> index_set = aTableView . selectedRowIndexes ( ) <EOL> index = index_set . firstIndex ( ) <EOL> while index != NSNotFound : <EOL> line = self . filteredData . objectAtIndex_ ( index ) <EOL> text_to_copy += line + '<STR_LIT:\n>' <EOL> index = index_set . indexGreaterThanIndex_ ( index ) <EOL> result = pasteboard . writeObjects_ ( [ text_to_copy ] ) <EOL> return YES <EOL> def applyFilterToData ( self ) : <EOL> '''<STR_LIT>''' <EOL> if len ( self . filterText ) : <EOL> filterPredicate = NSPredicate . predicateWithFormat_ ( <EOL> '<STR_LIT>' , self . filterText ) <EOL> self . filteredData = ( <EOL> self . logFileData . filteredArrayUsingPredicate_ ( filterPredicate ) ) <EOL> else : <EOL> self . filteredData = self . logFileData <EOL> def addLine_partial_ ( self , line , isPartial ) : <EOL> '''<STR_LIT>''' <EOL> if self . lastLineIsPartial : <EOL> joinedLine = self . logFileData . lastObject ( ) + line <EOL> self . logFileData . removeLastObject ( ) <EOL> self . logFileData . addObject_ ( joinedLine ) <EOL> else : <EOL> self . logFileData . addObject_ ( line ) <EOL> self . lastLineIsPartial = isPartial <EOL> self . applyFilterToData ( ) <EOL> def removeAllLines ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . logFileData . removeAllObjects ( ) <EOL> def lineCount ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . filteredData . count ( ) <EOL> def numberOfRowsInTableView_ ( self , tableView ) : <EOL> '''<STR_LIT>''' <EOL> return self . lineCount ( ) <EOL> def tableView_objectValueForTableColumn_row_ ( self , tableView , column , row ) : <EOL> '''<STR_LIT>''' <EOL> if column . identifier ( ) == '<STR_LIT:data>' : <EOL> return self . filteredData . objectAtIndex_ ( row ) <EOL> else : <EOL> return '<STR_LIT>' <EOL> class MSCLogWindowController ( NSObject ) : <EOL> '''<STR_LIT>''' <EOL> window = IBOutlet ( ) <EOL> logView = IBOutlet ( ) <EOL> searchField = IBOutlet ( ) <EOL> pathControl = IBOutlet ( ) <EOL> logFileData = MSCLogViewDataSource . alloc ( ) . init ( ) <EOL> fileHandle = None <EOL> updateTimer = None <EOL> def copy_ ( self , sender ) : <EOL> '''<STR_LIT>''' <EOL> text_to_copy = '<STR_LIT>' <EOL> index_set = self . logView . selectedRowIndexes ( ) <EOL> index = index_set . firstIndex ( ) <EOL> while index != NSNotFound : <EOL> line = self . logFileData . filteredData . objectAtIndex_ ( index ) <EOL> text_to_copy += line + '<STR_LIT:\n>' <EOL> index = index_set . indexGreaterThanIndex_ ( index ) <EOL> pasteboard = NSPasteboard . generalPasteboard ( ) <EOL> changeCount = pasteboard . clearContents ( ) <EOL> result = pasteboard . writeObjects_ ( [ text_to_copy ] ) <EOL> @ IBAction <EOL> def searchFilterChanged_ ( self , sender ) : <EOL> '''<STR_LIT>''' <EOL> filterString = self . searchField . stringValue ( ) . lower ( ) <EOL> self . logFileData . filterText = filterString <EOL> self . logFileData . applyFilterToData ( ) <EOL> self . logView . reloadData ( ) <EOL> @ IBAction <EOL> def showLogWindow_ ( self , notification ) : <EOL> '''<STR_LIT>''' <EOL> if self . window . isVisible ( ) : <EOL> self . window . makeKeyAndOrderFront_ ( self ) <EOL> return <EOL> screenRect = NSScreen . mainScreen ( ) . frame ( ) <EOL> windowRect = screenRect . copy ( ) <EOL> windowRect . origin . x = <NUM_LIT> <EOL> windowRect . origin . y = <NUM_LIT> <EOL> windowRect . size . width -= <NUM_LIT> <EOL> windowRect . size . height -= <NUM_LIT> <EOL> logfile = munki . pref ( '<STR_LIT>' ) <EOL> self . pathControl . setURL_ ( NSURL . fileURLWithPath_ ( logfile ) ) <EOL> self . window . setTitle_ ( os . path . basename ( logfile ) ) <EOL> self . window . setFrame_display_ ( windowRect , NO ) <EOL> self . window . makeKeyAndOrderFront_ ( self ) <EOL> self . watchLogFile_ ( logfile ) <EOL> self . logView . setDraggingSourceOperationMask_forLocal_ ( <EOL> NSDragOperationAll , NO ) <EOL> def watchLogFile_ ( self , logFile ) : <EOL> '''<STR_LIT>''' <EOL> self . stopWatching ( ) <EOL> self . logFileData . removeAllLines ( ) <EOL> self . logView . setDataSource_ ( self . logFileData ) <EOL> self . logView . reloadData ( ) <EOL> self . fileHandle = NSFileHandle . fileHandleForReadingAtPath_ ( logFile ) <EOL> self . refreshLog ( ) <EOL> self . updateTimer = ( <EOL> NSTimer . <EOL> scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_ ( <EOL> <NUM_LIT> , self , self . refreshLog , None , YES ) ) <EOL> def stopWatching ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . fileHandle is not None : <EOL> self . fileHandle . closeFile ( ) <EOL> self . fileHandle = None <EOL> if self . updateTimer is not None : <EOL> self . updateTimer . invalidate ( ) <EOL> self . updateTimer = None <EOL> def refreshLog ( self ) : <EOL> '''<STR_LIT>''' <EOL> data = self . fileHandle . availableData ( ) <EOL> if data . length ( ) : <EOL> utf8string = NSString . alloc ( ) . initWithData_encoding_ ( <EOL> data , NSUTF8StringEncoding ) <EOL> for line in utf8string . splitlines ( True ) : <EOL> if line . endswith ( u"<STR_LIT:\n>" ) : <EOL> self . logFileData . addLine_partial_ ( line . rstrip ( u"<STR_LIT:\n>" ) , False ) <EOL> else : <EOL> self . logFileData . addLine_partial_ ( line , True ) <EOL> self . logView . reloadData ( ) <EOL> self . logView . scrollRowToVisible_ ( self . logFileData . lineCount ( ) - <NUM_LIT:1> ) <EOL> def windowWillClose_ ( self , notification ) : <EOL> '''<STR_LIT>''' <EOL> self . stopWatching ( ) </s>
