SourceCode.py


directory : D:\2018_py_proj\TkGridGUI\tkgridgui
Line Count : 246
Line Clip Size : No Clipping

tab_of_notebook_changed  Word MatchCase (0) 
1 #!/usr/bin/env python 2 # -*- coding: ascii -*- 3 from __future__ import print_function 4 from __future__ import unicode_literals 5 from builtins import range 6 from builtins import object 7 import sys 8 import os, stat 9 10 startTag = '# %s generated code. DO NOT EDIT THE FOLLOWING. section "%s"\n' 11 userTag = '# >>>>>>insert any user code below this comment for section "%s"\n' 12 13 def lineIsStartTag( line ): 14 lineL = line.split() 15 if len(lineL) < 11: 16 return 0,'' 17 if lineL[0] != '#': 18 return 0,'' 19 if line.find('generated code. DO NOT EDIT THE FOLLOWING. section') > -1: 20 #print( 'lenth =',len(lineL) ) 21 return 1,lineL[-1][1:-1] 22 else: 23 return 0,'' 24 25 def lineIsUserTag( line ): 26 lineL = line.split() 27 if len(lineL) < 11: 28 return 0,'' 29 if lineL[0] != '#': 30 return 0,'' 31 if line.find('# >>>>>>insert any user code below this comment for section') > -1: 32 #print( 'lenth =',len(lineL) ) 33 return 1,lineL[-1][1:-1] 34 else: 35 return 0,'' 36 37 38 class SourceSection(object): 39 40 def __init__(self, name='top_of_init', appName='TkGridGUI', allowUserCode=1): 41 42 self.name = name 43 self.genCodeL = [] # list of lines of generated code 44 self.userCodeL = [] # lines of code entered by user 45 self.allowUserCode = allowUserCode 46 47 self.startTag = startTag%(appName, name) 48 self.userTag = userTag%(name, ) 49 50 def Indents(self, lineL): 51 '''find initial and final indents in the list of lines''' 52 firstIndent = 0 53 for line in lineL: 54 if len( line.strip() ) > 0: 55 firstIndent = len(line) - len( line.lstrip() ) 56 break 57 lastIndent = 0 58 for i in range( len(lineL)-1, -1, -1): 59 line = lineL[i] 60 if len( line.strip() ) > 0: 61 lastIndent = len(line) - len( line.lstrip() ) 62 break 63 return firstIndent, lastIndent 64 65 def saveToFile(self, fileObj): 66 67 firstIndent, lastIndent = self.Indents(self.genCodeL) 68 fileObj.write( ' '*firstIndent + self.startTag ) 69 for line in self.genCodeL: 70 fileObj.write( line ) 71 72 if self.allowUserCode: 73 fileObj.write( ' '*lastIndent + self.userTag ) 74 if self.numLinesOfUserCode()==0: 75 fileObj.write('\n\n') 76 else: 77 for line in self.userCodeL: 78 fileObj.write( line ) 79 80 def getGenCode(self): 81 return ''.join( self.genCodeL ) 82 83 def getUserCode(self): 84 return ''.join( self.userCodeL ) 85 86 def addGenCode(self, line): 87 self.genCodeL.append( line ) 88 89 def addUserCode(self, line): 90 self.userCodeL.append( line ) 91 92 def numLinesOfUserCode(self): 93 N=0 94 for line in self.userCodeL: 95 if len(line.strip()) > 0: 96 N = N + 1 97 return N 98 99 def numLinesOfGenCode(self): 100 return len( self.genCodeL ) 101 102 def printSummary(self): 103 print( 'Lines of code for section',self.name,'user:%i'%self.numLinesOfUserCode(), end='') 104 print( 'generated:%i'%self.numLinesOfGenCode() ) 105 106 class SourceFile(object): 107 108 def saveToFile(self, fOut=None): 109 110 if fOut is None: 111 fOut = open( self.pathopen, 'w') 112 113 # put shebang line for Linux and future line for python 2 114 fOut.write('#!/usr/bin/env python\n# -*- coding: ascii -*-\nfrom __future__ import print_function\n\n') 115 fOut.write('''# NOTICE... this file is generated by TkGridGUI. 116 # Any code or comments added by the user must be in designated areas ONLY. 117 # User additions will be lost if they are placed in code-generated areas. 118 # (i.e. Saving from TkGridGUI will over-write code-generated areas.) 119 120 ''') 121 if fOut != sys.stdout: 122 print( 'Saving python source to:',os.path.split(self.pathopen)[-1] ) 123 #print( 'SAVING to DEBUG file test_out.py' ) 124 #fOut = open( 'test_out.py', 'w') 125 for sectName in self.sectionNameList: 126 self.sectionSrcD[sectName].saveToFile(fOut) 127 128 if fOut != sys.stdout: 129 fOut.close() 130 131 # set execute permissions on python file 132 os.chmod( self.pathopen, stat.S_IRWXU + stat.S_IRWXG + stat.S_IROTH ) 133 134 135 def __init__(self, fName, appName='TkGridGUI', noUserCodeList=None): 136 137 self.pathopen = os.path.abspath(fName) 138 self.fName = fName 139 140 # sections in the file that are not added with addSection WILL BE LOST 141 self.sectionNameList = [] # will be populated ONLY from addSection method 142 self.sectionSrcD = {}# will be populated from BOTH file read and addSection method 143 self.appName = appName 144 if noUserCodeList==None: 145 self.noUserCodeList=[] 146 else: 147 self.noUserCodeList = noUserCodeList 148 149 150 # if source file already exists, read it an fill source sections 151 if os.path.isfile( self.pathopen ): # if file exists, read it 152 fIn = open( self.pathopen,'r') 153 self.oldLines = fIn.readlines() # will still have \n line endings 154 fIn.close() 155 else: 156 self.oldLines = [] 157 158 self.numOldLines = len(self.oldLines) 159 #print( 'old file',self.pathopenm ) 160 #print( 'numOldLines =',self.numOldLines ) 161 162 # loop through lines of code looking for section tags and user code tags 163 activeSection = None 164 inUserSection = 0 165 startSect = '' 166 for line in self.oldLines: 167 isStartTag, section = lineIsStartTag( line ) 168 if isStartTag: 169 startSect = section 170 activeSection = SourceSection( startSect ) 171 self.sectionSrcD[startSect] = activeSection 172 inUserSection = 0 173 elif activeSection: 174 isUserTag,userSect = lineIsUserTag( line ) 175 if isUserTag: 176 inUserSection = 1 177 if userSect != startSect: 178 print( 'WARNING... Section mismatch in file' ) 179 else: 180 if inUserSection: 181 activeSection.addUserCode( line ) 182 else: 183 activeSection.addGenCode( line ) 184 185 def clearGenCode(self): 186 for section, scode in list(self.sectionSrcD.items()): 187 scode.genCodeL = [] 188 189 def getCleanList(self, myList): 190 # clean up any multiline entries 191 returnL = [] 192 for line in myList: 193 if line.count('\n')>1: 194 sL = line.split('\n') 195 for s in sL: 196 returnL.append( s+'\n' ) 197 else: 198 returnL.append(line) 199 return returnL 200 201 def addSection(self, sectionName, genCodeL, allowUserCode=1, defaultUserCodeL=None): 202 '''Sections will be printed to file in the order added here. 203 ONLY sections added here will be printed to file''' 204 205 #print('defaultUserCodeL = ',defaultUserCodeL) 206 207 if sectionName not in self.sectionSrcD: 208 self.sectionSrcD[sectionName] = SourceSection( sectionName ) 209 210 if not allowUserCode: 211 self.sectionSrcD[sectionName].allowUserCode = 0 212 213 # clear genCodeL and add new generated lines 214 self.sectionSrcD[sectionName].genCodeL = [] 215 sL = self.getCleanList( genCodeL ) 216 for line in sL: 217 self.sectionSrcD[sectionName].genCodeL.append( line ) 218 219 # add default user code ONLY if available and not already in file 220 if defaultUserCodeL and self.sectionSrcD[sectionName].numLinesOfUserCode()==0: 221 #print('Saving Default User code for ',sectionName) 222 #print(' sL =',sL) 223 sL = self.getCleanList( defaultUserCodeL ) 224 for line in sL: 225 self.sectionSrcD[sectionName].userCodeL.append( line ) 226 else: 227 #print('# Overwrite of User code disallowed for ',sectionName) 228 pass 229 230 231 self.sectionNameList.append( sectionName ) 232 233 if __name__ == '__main__': 234 235 sf = SourceFile( os.path.normpath('./NewForm.py') ) 236 237 for key,sect in list(sf.sectionSrcD.items()): 238 sect.printSummary() 239 print( sect.getUserCode() ) 240 241 import copy 242 genCodeL = copy.deepcopy( sf.sectionSrcD['top_of_init'].genCodeL ) 243 sf.addSection('top_of_init', genCodeL) 244 genCodeL = copy.deepcopy( sf.sectionSrcD['end'].genCodeL ) 245 sf.addSection('end', genCodeL, allowUserCode=0) 246 sf.saveToFile()