Changeset 163
- Timestamp:
- 03/22/06 11:42:42 (3 years ago)
- Files:
-
- trunk/pyramid/build.py (modified) (16 diffs)
- trunk/pyramid/core.py (modified) (1 diff)
- trunk/pyramid/dictutils.py (modified) (6 diffs)
- trunk/pyramid/flatteners.py (modified) (17 diffs)
- trunk/pyramid/mergetrees.py (modified) (4 diffs)
- trunk/pyramid/mkpydir.py (modified) (4 diffs)
- trunk/pyramid/page.py (modified) (6 diffs)
- trunk/pyramid/path.py (modified) (2 diffs)
- trunk/pyramid/restParser.py (modified) (1 diff)
- trunk/pyramid/utils.py (modified) (9 diffs)
- trunk/pyramid/yamlRegistry.py (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/pyramid/build.py
r155 r163 31 31 DATADIR = os.path.abspath(data) 32 32 OUTPUTDIR = os.path.abspath(out) 33 33 34 34 # check to see if the output directory exists 35 35 if not os.path.exists(OUTPUTDIR): … … 42 42 if not os.path.isdir(OUTPUTDIR): 43 43 raise Error, 'OUTPUTDIR is not a directory' 44 44 45 45 # Check that the output dir is not in a subversion folder 46 46 if os.path.exists(os.path.join(OUTPUTDIR,'.svn')): 47 47 raise Error, 'the OUTPUTDIR contains .svn folders, halting operation for safety' 48 48 49 49 # dangerous remove directory contents function 50 50 if partialbuild is False and rebuilddirs is None: 51 51 utils.recursiveRemoveDirectoryContents(OUTPUTDIR) 52 52 53 53 # copy in any resources needed 54 54 for resourcedir in resourcedirs: … … 59 59 os.chdir(DATADIR) 60 60 basedir = path(DATADIR) 61 61 62 62 # initialise a context 63 63 ctx = Context() … … 70 70 # set constants 71 71 ctx.constants = constants 72 72 73 73 for root, dirs, files in os.walk('.'): 74 74 75 75 # get the path directory 76 76 ctx.path = path(root).abspath() 77 77 ctx.relpath = path(basedir).relpathto(root) 78 78 ctx.relpathparent = path(basedir).relpathto(ctx.path.parent) 79 79 80 80 # ignore svn folders 81 81 try: … … 83 83 except: 84 84 pass 85 85 86 86 # if the target directory is not available, create it 87 87 if not os.path.isdir(os.path.join(OUTPUTDIR,root)): … … 93 93 srcfile = os.path.join(ctx.path,f) 94 94 targetfile = os.path.join(OUTPUTDIR,root,f) 95 shutil.copy(srcfile,targetfile) 96 95 shutil.copy(srcfile,targetfile) 96 97 97 # create the html from the index.yml fragment 98 98 if root != '.': … … 102 102 cachepath = outroot/'.cache.dump' 103 103 cachepathparent = outroot.parent /'.cache.dump' 104 105 104 105 106 106 # check to see if the current directory is in the rebuild dirs list 107 107 matchesRebuildDir = False … … 111 111 matchesRebuildDir = True 112 112 break 113 113 114 114 # check for nobuild 115 115 nobuild = path(root) / 'NOBUILD' … … 117 117 utils.copytree(root,os.path.join(OUTPUTDIR,root),nocopylist=['.svn']) 118 118 continue 119 120 119 120 121 121 if os.path.exists( cachepath ) and partialbuild: 122 122 ctx = pickle.load(open(cachepath)) … … 127 127 if matchesRebuildDir: 128 128 ctx.data = pickle.load(open(cachepathparent)).data 129 129 130 130 if matchesRebuildDir or rebuilddirs is None: 131 131 if ctx.verbose > 0: … … 133 133 134 134 ctx.partialbuild = False 135 135 136 136 try: 137 137 html = flat.flatten( [DOCTYPE,flatten(Y.fragmentConstructor(os.path.join(root,'index.yml')),ctx)] ) … … 143 143 144 144 sys.exit() 145 145 146 146 file(os.path.join(OUTPUTDIR,root,'index.html'),'w').write(html) 147 147 if createcache: … … 150 150 if ctx.verbose > 1: 151 151 print '.. %s Rebuilt from Cached Data' % str(ctx.relpath) 152 153 152 153 154 154 def main(options,args): 155 155 if options.resources: … … 157 157 else: 158 158 resourcedirs = [] 159 159 160 160 if options.rebuilddirs: 161 161 rebuilddirs = options.rebuilddirs.strip().split(',') 162 162 else: 163 rebuilddirs = None 163 rebuilddirs = None 164 164 165 165 if options.constants: … … 173 173 constants[key]=value 174 174 else: 175 constants = None 176 175 constants = None 176 177 177 178 178 build(options.data,options.out,verbose=options.verbose,resourcedirs=resourcedirs,rebuilddirs=rebuilddirs,constants=constants,update=options.update,createcache=options.createcache) … … 184 184 parser.add_option("-o", "--out", dest="out", help="directory in which to save output (will be emptied)", metavar="OUT") 185 185 parser.add_option("-r", "--resources", dest="resources", help="comma separated list of resource directories to copy", metavar="RESOURCES") 186 parser.add_option("-v", "--verbose", action="store_const", dest="verbose", default=0, const=1, help="print status messages to stdout") 187 parser.add_option("-V", "--veryverbose", action="store_const", dest="verbose", default=0, const=2, help="print all data to stdout") 188 parser.add_option("-W", "--veryveryverbose", action="store_const", dest="verbose", default=0, const=3, help="print all data to stdout") 186 parser.add_option("-v", "--verbose", action="store_const", dest="verbose", default=0, const=1, help="print status messages to stdout") 187 parser.add_option("-V", "--veryverbose", action="store_const", dest="verbose", default=0, const=2, help="print all data to stdout") 188 parser.add_option("-W", "--veryveryverbose", action="store_const", dest="verbose", default=0, const=3, help="print all data to stdout") 189 189 parser.add_option("-R", "--rebuilddirs",dest="rebuilddirs",help="only rebuild below these comma separated directories",metavar="REBUILDDIRS") 190 190 parser.add_option("-C", "--createcache",action="store_true",dest="createcache",default=False,help="recreate the cache files",metavar="CREATECACHE") 191 191 parser.add_option("-c", "--constants", dest="constants", help="pass in the names constants (e.g. PDO=/root/pdo,PSF=/psf", metavar="CONSTANTS") 192 parser.add_option("-U", "--update", action="store_true", dest="update", default=False, help="NOT WORKING DO NOT USE try to build only those pages that have changed") 192 parser.add_option("-U", "--update", action="store_true", dest="update", default=False, help="NOT WORKING DO NOT USE try to build only those pages that have changed") 193 193 (options, args) = parser.parse_args() 194 194 main(options,args) trunk/pyramid/core.py
r149 r163 13 13 self.verbose = node.get('verbose',False) 14 14 self.root = path(node.get('root','')) 15 15 16 16 def __eq__(self,other): 17 17 return self.data == other.data 18 18 19 19 def __ne__(self,other): 20 20 return self.data != self.data trunk/pyramid/dictutils.py
r96 r163 4 4 5 5 def merge(a,b,dir=None,partialbuild=False): 6 6 7 7 if isinstance(a,Y.sectionnav) and isinstance(b,Y.sectionnav) and dir is not None: 8 8 # special case. If b is the same as a, it has been inhereited - sectionnav's … … 15 15 else: 16 16 mergetrees.merge(a,b,dir) 17 17 18 18 elif isinstance(b,dict) and isinstance(a,dict): 19 19 for bkey in b.keys(): … … 27 27 28 28 class stackdict(dict): 29 29 30 30 parent = None 31 31 32 32 def __init__(self, parent=None): 33 33 if parent is not None: 34 34 self.parent = parent 35 35 merge(self,parent) 36 36 37 37 def popStack(self): 38 38 return self.parent … … 40 40 # Test code: 41 41 if __name__ == "__main__": 42 42 43 43 def keyval(text): 44 44 ''' Factory to convert a string into key:val pair (split on last space) … … 46 46 t = text.split(' ') 47 47 return { ''.join(t[:-1]) : t[-1] } 48 48 49 49 x = ''' 50 50 a: 1 … … 59 59 b: 60 60 x: 15 61 z: 61 z: 62 62 p: 98 63 63 q: 99 64 64 c: 3P0 65 65 ''' 66 66 67 67 68 68 xd = syck.load(x,Loader=Y.Loader, implicit_typing=false) 69 69 yd = syck.load(y,Loader=Y.Loader, implicit_typing=false) 70 70 71 71 z = merge(xd,yd) 72 72 73 73 print z 74 74 75 75 print '-------------------' 76 76 77 77 d = stackdict() 78 78 d['a'] = 1 79 79 d['b'] = {'x':1,'y':2 } 80 80 print d 81 81 82 82 d = stackdict(d) 83 83 d['a'] = 2 84 84 print d 85 85 86 86 d = stackdict(d) 87 87 d['b'] = {'x':2,'y': {'p':4 } } 88 88 d['c'] = 100 89 89 print d 90 90 91 91 while 1: 92 92 d = d.popStack() 93 93 if d is None: 94 94 break 95 print d 95 print d trunk/pyramid/flatteners.py
r148 r163 21 21 print '--- = Page ---------------' 22 22 pprint(data) 23 23 24 24 # 25 25 # Flatteners adaption for different item types … … 49 49 def flatten(self, ctx, dir): 50 50 for value in self.original: 51 value = flatten(value, ctx, dir) 51 value = flatten(value, ctx, dir) 52 52 return self.original 53 53 … … 55 55 def flatten(self, ctx, dir): 56 56 return T.xml(restParser.html_fragment(self.original)) 57 57 58 58 class RestFileFlattener(components.Adapter): 59 def flatten(self, ctx, dir): 59 def flatten(self, ctx, dir): 60 60 try: 61 61 restfile = os.path.join(dir,self.original) 62 62 fp = open(restfile) 63 63 except IOError: 64 print 'IOError whilst trying to open "restfile" %s'%(restfile) 64 print 'IOError whilst trying to open "restfile" %s'%(restfile) 65 raise 65 66 66 67 try: … … 77 78 fp = open(htmlfile) 78 79 except IOError: 79 print 'IOError whilst trying to open "htmlfile" %s'%(htmlfile) 80 80 print 'IOError whilst trying to open "htmlfile" %s'%(htmlfile) 81 raise 82 81 83 return T.xml(fp.read()) 82 84 … … 87 89 if filename[0] != '/' and filename[0:4] != 'http': 88 90 filename = os.path.join(dir,filename) 89 return filename 91 return filename 90 92 91 93 def getFilePointer(ctx,dir,filename): … … 96 98 except IOError: 97 99 print 'IOError whilst trying to open "htfile" %s'%(filename) 100 raise 98 101 return fp 99 102 … … 101 104 def flatten(self, ctx, dir): 102 105 return T.xml(self.original) 103 106 104 107 class HtFileFlattener(components.Adapter): 105 108 def flatten(self, ctx, dir): … … 137 140 contents = '<strong>MoinMoin parse failed for %s - a wiki instance needs to be installed and the wikiconfig.py directory needs to be on the $PYTHONPATH</strong>'%url 138 141 return T.xml(contents) 139 142 140 143 class AHrefFlattener(components.Adapter): 141 144 def flatten(self, ctx, dir): … … 145 148 def flatten(self, ctx, dir): 146 149 return '/%s' % str(self.original) 147 150 148 151 class BreadcrumbFlattener(components.Adapter): 149 152 def flatten(self, ctx, dir): … … 162 165 hook = item['children'] 163 166 break 164 167 165 168 return flatten(breadcrumb,ctx) 166 169 … … 182 185 def acquireTemplate(ctx,template): 183 186 """ recursively ascends the data directory looking for an appropriate template 184 """ 187 """ 185 188 searchpath = ctx.path 186 189 #overkill checking for search path infinite recursion … … 190 193 break 191 194 except IOError: 192 searchpath = searchpath.parent 193 return searchpath / template 194 195 searchpath = searchpath.parent 196 return searchpath / template 197 195 198 class FragmentFileFlattener(components.Adapter): 196 199 ''' This is the core flattener that renders fragment types (which are template/data packets) … … 204 207 if ctx.verbose > 1: 205 208 print '=== Current Fragment ( %s )' % name 206 209 207 210 208 211 # get the parent data for the current file … … 236 239 template = acquireTemplate(ctx,self.original.template) 237 240 flattenedData = flatten( self.original.globals, ctx, dir ) 238 return T.xml(fragmentGenerate(dir,template,flattenedData)) 241 return T.xml(fragmentGenerate(dir,template,flattenedData)) 239 242 else: 240 243 # Get the canonical directory and filename for this file 241 244 dir,name = os.path.split(os.path.join(dir,self.original.file)) 242 245 243 246 if ctx.verbose > 1: 244 247 print '=== Current Fragment ( %s )' % name 245 248 246 249 # get the parent data for the current file 247 250 parentdata = getParentData(self,ctx,dir,name) … … 249 252 # inherit data from parent and merge the result with any 'local' data 250 253 mergedData = inheritAndMergeLocals(self,ctx,dir,name,self.original,parentdata) 251 254 252 255 # Flatten the resultant data ready for use in the template 253 256 flattenedMergedData = flatten( mergedData, ctx, dir ) 254 257 255 258 if ctx.verbose > 2: 256 259 logPageData(mergedData) 257 260 258 261 # Search for the template in this directory and above 259 262 template = acquireTemplate(ctx,self.original.template) … … 262 265 def getFragmentData(self,ctx,dir,name,parentdata): 263 266 ''' Get the fragment data and assign it to self.original, preserving the filename 264 ''' 267 ''' 265 268 # Try to get the data out of the current ctx first (if it is there, it 266 269 # must have come from the cache so return it … … 280 283 ''' get the parents data for this .yml fie (or set it as an empty fragment if not available) 281 284 this currently only looks 'up' one directory 282 ''' 285 ''' 283 286 parentpath = str(ctx.relpathparent) 284 287 parentdata = copy.deepcopy(ctx.data.get(parentpath,{}).get(name,Y.fragment({}))) trunk/pyramid/mergetrees.py
r50 r163 6 6 # create a pointer to the parent tree and initialise found 7 7 hook = ptree 8 8 9 9 if path: 10 10 pathsegments = path.split('/') 11 11 else: 12 12 return 13 13 14 14 # iterate on segments in the current path 15 15 for depth,segment in enumerate( pathsegments ): … … 26 26 # set the pointer to the found item's child list 27 27 hook = found.get('children',[]) 28 28 29 29 # (**a**) now we've got a pointer to the appropriate node, make each href 30 30 # attribue in the child tree into an absolute path by adding the path to it 31 makePathsAbsolute(ctree,path) 31 makePathsAbsolute(ctree,path) 32 32 addBreadcrumbData(ctree,found['data']) 33 33 34 34 # add the child tree to the found node and make the found node selected 35 35 found['children'] = ctree 36 36 found['selected'] = 'selected' 37 38 37 38 39 39 def findChildenForKey(treelist,key): 40 40 for item in treelist: … … 42 42 if str(href) == key or ( isinstance(href,Y.rhref) and '/%s'%str(href) == key ) : 43 43 return item 44 44 45 45 return None 46 46 … … 50 50 if isinstance(item['data']['href'],Y.rhref): 51 51 item['data']['href'] = '/%s/%s' % (path,item['data']['href']) 52 52 53 53 def addBreadcrumbData(children,parentdata): 54 54 for item in children: 55 55 item['data']['breadcrumb'] = copy.deepcopy(parentdata.get('breadcrumb',[]) ) 56 56 item['data']['breadcrumb'].append( Y.url( '%s %s' % (item['data']['label'],item['data']['href']) ) ) 57 trunk/pyramid/mkpydir.py
r133 r163 1 1 import os 2 2 from optparse import OptionParser 3 import shutil 3 import shutil 4 4 5 5 index_yml = """--- !fragment … … 43 43 cyml.close() 44 44 45 45 46 46 def mkpydir(directive,prefix,path,outputdir,copy,title): 47 47 OUTPUTDIR = os.path.abspath(outputdir) 48 48 if os.path.isdir(outputdir) is not True: 49 49 os.mkdir(OUTPUTDIR) 50 50 51 51 if directive == 'htfile': 52 52 53 53 if copy is True: 54 54 htfile = 'content.ht' … … 84 84 chtml.write(content_html) 85 85 chtml.close() 86 86 87 87 def main(options,args): 88 88 if os.path.isdir(options.outputdir) and options.replace is True: 89 89 shutil.rmtree(options.outputdir) 90 90 91 91 mkpydir(options.type,options.dir,options.path,options.outputdir,options.copy,options.title) 92 92 … … 115 115 parser.add_option("-c", "--copy", action="store_true", help="copy the htfile into the directory",dest="copy", metavar="COPY",default=True) 116 116 (options, args) = parser.parse_args() 117 # further checking of options 117 # further checking of options 118 118 if options.copy is not False: 119 119 options.copy=True trunk/pyramid/page.py
r147 r163 43 43 def render_tree(self,ctx,data): 44 44 ''' custom renderer for a tree like data structure (ie with data and children keys) 45 ''' 45 ''' 46 46 pgen = getPatterns(ctx.tag) 47 47 48 48 html = [] 49 49 if data: … … 52 52 for key in item['data'].keys(): 53 53 ptag.fillSlots(key,item['data'][key]) 54 54 55 55 selected = item.get('selected','') 56 56 ptag.fillSlots('selected',selected) … … 76 76 except ValueError: 77 77 raise 'invalid slice values' 78 78 79 79 tag = context.tag 80 80 headers = tag.allPatterns('header') … … 82 82 divider = tag.patternGenerator('divider', default=tags.invisible) 83 83 content = [(pattern(data=element), divider(data=element)) for element in data[int(start):int(end)]] 84 84 85 85 if not content: 86 86 content = tag.allPatterns('empty') … … 89 89 content[-1] = content[-1][0] 90 90 footers = tag.allPatterns('footer') 91 91 92 92 return tag.clear()[ headers, content, footers ] 93 93 return render … … 102 102 except IndexError: 103 103 raise FragmentError, 'An error has occured whilst building the breadcrumb trail. This usually occurs when a content template has a breadcrumb trail renderer but the parent nav.yml does not include a reference to the current templates directory. Use -V to find out more information about which page cause this error.' 104 104 105 105 return tag 106 106 107 107 def generate(self): 108 108 ''' render the fragment trunk/pyramid/path.py
r96 r163 323 323 d.files('*.pyc'). 324 324 """ 325 325 326 326 return [p for p in self.listdir(pattern) if p.isfile()] 327 327 … … 805 805 def startfile(self): 806 806 os.startfile(self) 807 trunk/pyramid/restParser.py
r114 r163 68 68 except: 69 69 input_string = input_string.decode('iso-8859-1') 70 70 71 71 parts = html_parts( 72 72 input_string=input_string, source_path=source_path, trunk/pyramid/utils.py
r143 r163 3 3 4 4 class Stack: 5 5 6 6 def __init__(self, indent, pointer): 7 7 self.indent = indent … … 9 9 self.indentStack = [] 10 10 self.pointerStack = [] 11 11 12 12 def push(self,indent): 13 13 self.indentStack.append(self.indent) … … 19 19 self.indent = self.indentStack.pop() 20 20 self.pointer = self.pointerStack.pop() 21 21 22 22 def prevIndent(self): 23 23 return self.indentStack[-1] 24 24 25 25 def parseIndentedList(text, factory): 26 26 27 27 lines = text.split('\n') 28 28 data = {'children':[]} … … 31 31 while lines[0].strip() == '': 32 32 lines = lines[1:] 33 33 34 34 # this should be the first non-empty line 35 35 trimline, newindent = stripAndCountIndent(lines[0]) … … 42 42 if newindent > stack.indent: 43 43 stack.push(newindent) 44 44 45 45 if newindent < stack.indent: 46 46 while newindent < stack.indent: … … 50 50 51 51 stack.pointer.append( {'data':factory(trimline), 'children':[] } ) 52 52 53 53 return data['children'] 54 54 55 55 def stripAndCountIndent(line): 56 56 lstripline = line.lstrip() 57 57 return lstripline, len(line)-len(lstripline) 58 58 59 59 def recursiveRemoveDirectoryContents(dir): 60 60 for root, dirs, files in os.walk(dir, topdown=False): … … 67 67 segments = [] 68 68 head = path 69 while 1: 69 while 1: 70 70 head, tail = os.path.split(head) 71 71 segments.append(tail) … … 87 87 more... /downloads 88 88 ''' 89 90 89 90 91 91 def f(text): 92 92 t = text.split(' ') 93 93 return {'href': t[-1], 'label': t[:-1]} 94 94 95 95 print 'text' 96 96 print text 97 97 tree = parseIndentedList(text, f) 98 98 99 99 print "indented list" 100 100 from pprint import pprint 101 101 pprint(tree) 102 102 103 103 # recreate indented list from data 104 104 def printnode(item, indent=0): … … 107 107 for child in item['children']: 108 108 printnode(child, indent+4) 109 109 110 110 printnode(tree, indent=-4) 111 111 112 112 113 113 trunk/pyramid/yamlRegistry.py
r124 r163 42 42 43 43 class fragmentFile: 44 ''' A file fragment which points at another yaml file 44 ''' A file fragment which points at another yaml file 45 45 ''' 46 46 def __init__(self, node): 47 47 self.file = node 48 48 49 49 def __repr__(self): 50 50 s = StringIO() … … 54 54 pprint({'file':self.file},s) 55 55 return s.getvalue() 56 56 57 57 def __eq__(self,other): 58 58 return self.file == other.file 59 59 60 60 def __ne__(self,other): 61 61 return self.file != other.file 62 62 63 63 def fragmentConstructor(node): 64 64 try: … … 67 67 except AttributeError: 68 68 return fragmentFile(node) 69 69 70 70 71 71 class rest(str): … … 73 73 ''' 74 74 pass 75 75 76 76 class restfile(str): 77 77 ''' a rest file for converting to html … … 105 105 self.file = node['file'] 106 106 self.key = node.get('key',None) 107 107 108 108 def __repr__(self): 109 109 return '<htfiledata: file=%s, key=%s>'%(self.file,self.key) 110 110 111 111 def __eq__(self,other): 112 112 return self.file == other.file and self.key == other.key … … 142 142 ''' 143 143 return utils.parseIndentedList(node,url) 144 144 145 145 class sectionnav(list): 146 146 ''' section navigation (inherited) … … 178 178 def pathconstruct(pathstring): 179 179 return path(pathstring) 180 180 181 181 182 182 def context(node): … … 193 193 year = int(year) 194 194 cls.__constructs[(tld,year,name)] = func 195 195 196 196 register_construct = classmethod(register_construct) 197 197 … … 212 212 if construct is not None: 213 213 return construct(node.value) 214 return syck.Loader.construct(self, node) 215 214 return syck.Loader.construct(self, node) 215 216 216 # Set up type registry 217 217 _typeRegistry = { … … 235 235 for vartype, factory in _typeRegistry.items(): 236 236 Loader.register_construct(factory, vartype[2],tld=vartype[0],year=vartype[1]) 237 238 239
