Changeset 54
- Timestamp:
- 12/17/05 15:33:18 (3 years ago)
- Files:
-
- branches/timcommithook/lib/path.py (modified) (1 diff)
- branches/timcommithook/pyramid/core.py (modified) (1 diff)
- branches/timcommithook/pyramid/flatteners.py (modified) (5 diffs)
- branches/timcommithook/pyramid/pyramid (modified) (6 diffs)
- branches/timcommithook/pyramid/yamlRegistry.py (modified) (7 diffs)
- branches/timcommithook/setup.py (modified) (1 diff)
- pyramid.wpr (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/timcommithook/lib/path.py
r46 r54 57 57 58 58 59 class path (_base):59 class path: 60 60 """ Represents a filesystem path. 61 61 branches/timcommithook/pyramid/core.py
r1 r54 1 1 from nevow import tags as T 2 from p ath import path2 from pyramid.path import path 3 3 4 4 DOCTYPE = T.xml('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n') 5 5 6 6 class Context: 7 def __init__(self ):7 def __init__(self,node={}): 8 8 # set root level data as an empty dictionary 9 self.data = {}10 self.path = path( '')11 self.verbose = False12 self.root = path( '')9 self.data = node.get('data',{}) 10 self.path = path(node.get('path','')) 11 self.verbose = node.get('verbose',False) 12 self.root = path(node.get('root','')) branches/timcommithook/pyramid/flatteners.py
r51 r54 3 3 import syck 4 4 import os 5 from p ath import path5 from pyramid.path import path 6 6 import copy 7 7 from pprint import pprint … … 90 90 data = inheritAndMergeLocals(self,ctx,dir,name,parentdata).get(key,{}) 91 91 return flatten(data, ctx, dir) 92 93 def acquireTemplate(ctx,template): 94 searchpath = ctx.path 95 while searchpath != ctx.root: 96 try: 97 open(searchpath / path(template)) 98 break 99 except IOError: 100 searchpath = searchpath.parent 101 return searchpath / template 102 103 class FragmentFileFlattener(components.Adapter): 104 ''' This is the core flattener that renders fragment types (which are template/data packets) 105 This works on a file like fragment (one which has a filename as it's 'file' key 106 ''' 107 def flatten(self, ctx, dir): 108 109 dir,name = os.path.split(os.path.join(dir,self.original.file)) 110 111 if ctx.verbose: 112 print '=== Current Fragment ( %s )' % name 92 113 114 parentdata = getFragmentData(self,ctx,dir,name) 115 116 mergedData = inheritAndMergeLocals(self,ctx,dir,name,parentdata) 117 118 flattenedMergedData = flatten( mergedData, ctx, dir ) 119 120 if ctx.verbose: 121 logPageData(mergedData) 122 123 # Search for the template in this directory and above 124 template = acquireTemplate(ctx,self.original.template) 125 return T.xml(page.Fragment(os.path.join(dir,template), flattenedMergedData).generate()) 93 126 94 127 class FragmentFlattener(components.Adapter): … … 96 129 ''' 97 130 def flatten(self, ctx, dir): 131 # Search for the template in this directory and above 132 #dir, name = os.path.split(os.path.join(dir,self.original.file)) 133 template = acquireTemplate(ctx,self.original.template) 134 flattenedData = flatten( self.original.globals, ctx, dir ) 135 return T.xml(page.Fragment(os.path.join(dir,template), flattenedData).generate()) 136 137 def getFragmentData(self,ctx,dir,name): 138 ''' this is a file fragment so try to parse 139 ''' 98 140 99 # if the template node has a file attribute then this is a real file fragment100 if self.original.file:101 dir, name, parentdata = getFragmentData(self,ctx,dir)102 103 data = flatten( inheritAndMergeLocals(self,ctx,dir,name,parentdata), ctx, dir )104 105 if ctx.verbose:106 logPageData(data)107 108 # Search for the template in this directory and above109 template = path(self.original.template)110 searchpath = ctx.path111 while searchpath != ctx.root:112 try:113 open(searchpath / template)114 break115 except IOError:116 searchpath = searchpath.parent117 118 return T.xml(page.Fragment(os.path.join(dir,searchpath / template), data).generate())119 120 121 def getFragmentData(self,ctx,dir):122 ''' this is a file fragment so try to parse123 '''124 # join and re-split the dir and item.file to get the canonical head and tail125 dir, name = os.path.split(os.path.join(dir,self.original.file))126 if ctx.verbose:127 print '=== Current Fragment ( %s )' % name128 141 # get the parents data for this .yml fie (or set it as an empty fragment if not available) 129 parentdata = copy.deepcopy(ctx.data.get(str(ctx.path.parent),{}).get(name,Y.fragment({}))) 142 # this currently only looks 'up' one directory 143 parentpath = str(ctx.path.parent) 144 parentdata = copy.deepcopy(ctx.data.get(parentpath,{}).get(name,Y.fragment({}))) 130 145 try: 131 146 # read then parse the file … … 133 148 self.original = syck.load(yaml,Loader=Y.Loader, implicit_typing=False) 134 149 except: 135 # if the file can't be read. fall back to the parent data 150 # if the file can't be read. fall back to the parent data. This is to allow a missing file to be inherited from further up 151 # also only looks up a single directory 136 152 self.original = copy.deepcopy(parentdata) 137 return dir, name,parentdata153 return parentdata 138 154 139 155 def inheritAndMergeLocals(self,ctx,dir,name,parentdata): … … 147 163 logFragmentData(path(self.original.template),parentdata, globals, locals) 148 164 149 # if this is a real file, then store it on the context 150 if name: 151 # take a copy of the data from this .yml file's globals and merge it with the parent data 152 node = Y.fragment( { 153 'template':self.original.template, 154 'global':dictutils.merge(parentdata.globals.copy(),globals,dir=path(dir).normpath()), 155 'local':{} 156 } ) 157 # set this fragment on the context with a key of the yaml file name 158 ctx.data.setdefault(str(ctx.path),{})[name] = node 159 # merge the parentdata and globals and render the item 160 globals = node.globals 165 # store it on the context 166 # take a copy of the data from this .yml file's globals and merge it with the parent data 167 node = Y.fragment( { 168 'template':self.original.template, 169 'global':dictutils.merge(parentdata.globals.copy(),globals,dir=path(dir).normpath()), 170 'local':{} 171 } ) 172 # set this fragment on the context with a key of the yaml file name 173 ctx.data.setdefault(str(ctx.path),{})[name] = node 174 # merge the parentdata and globals and render the item 175 globals = node.globals 161 176 162 data = dictutils.merge( globals.copy(),locals)177 data = dictutils.merge(node.globals.copy(),locals) 163 178 return data 164 179 165 180 166 181 # registration for adapters 167 components.registerAdapter(DictFlattener, dict, IFlattener) 168 components.registerAdapter(ListFlattener, list, IFlattener) 169 components.registerAdapter(ListFlattener, Y.sectionnav, IFlattener) 170 components.registerAdapter(RestFlattener, Y.rest, IFlattener) 171 components.registerAdapter(RestFileFlattener, Y.restfile, IFlattener) 172 components.registerAdapter(FragmentFlattener, Y.fragment, IFlattener) 173 components.registerAdapter(AHrefFlattener, Y.ahref, IFlattener) 174 components.registerAdapter(RHrefFlattener, Y.rhref, IFlattener) 175 components.registerAdapter(BreadcrumbFlattener, Y.breadcrumb, IFlattener) 176 components.registerAdapter(AcquireFlattener, Y.acquire, IFlattener) 182 components.registerAdapter(DictFlattener, dict, IFlattener) 183 components.registerAdapter(ListFlattener, list, IFlattener) 184 components.registerAdapter(ListFlattener, Y.sectionnav, IFlattener) 185 components.registerAdapter(RestFlattener, Y.rest, IFlattener) 186 components.registerAdapter(RestFileFlattener, Y.restfile, IFlattener) 187 components.registerAdapter(FragmentFlattener, Y.fragment, IFlattener) 188 components.registerAdapter(FragmentFileFlattener, Y.fragmentFile, IFlattener) 189 components.registerAdapter(AHrefFlattener, Y.ahref, IFlattener) 190 components.registerAdapter(RHrefFlattener, Y.rhref, IFlattener) 191 components.registerAdapter(BreadcrumbFlattener, Y.breadcrumb, IFlattener) 192 components.registerAdapter(AcquireFlattener, Y.acquire, IFlattener) 177 193 branches/timcommithook/pyramid/pyramid
r50 r54 1 #!/usr/bin/python 1 2 2 import sys, os 3 3 sys.path.insert(0, os.path.join(sys.prefix, 'lib/pyramid/dependencies')) … … 5 5 from pyramid.flatteners import flatten 6 6 from pyramid import yamlRegistry as Y, dictutils, utils 7 from pyramid.path import path 7 8 from nevow import flat 8 from path import path9 9 from optparse import OptionParser 10 10 import os 11 11 import shutil 12 import syck 12 13 13 def build(data,out,verbose=False,resourcedirs=[]): 14 14 import wingdbstub 15 16 17 class Dumper(syck.Dumper): 18 def represent_pyramid_path_path(self, object): 19 return syck.Scalar(object, tag="tag:python.yaml.org,2002:object:pyramid.path.path") 20 21 22 23 def build(data,out,verbose=False,resourcedirs=[],partialbuild=False): 24 15 25 DATADIR = os.path.abspath(data) 16 26 OUTPUTDIR = os.path.abspath(out) … … 32 42 33 43 # dangerous remove directory contents function 34 utils.recursiveRemoveDirectory(OUTPUTDIR) 44 if not partialbuild: 45 utils.recursiveRemoveDirectory(OUTPUTDIR) 35 46 36 47 # copy in any resources needed 37 48 for resourcedir in resourcedirs: 38 49 dir, name = os.path.split(resourcedir) 39 shutil.copytree(resourcedir,os.path.join(OUTPUTDIR,name)) 50 if not os.path.exists(os.path.join(OUTPUTDIR,name)): 51 shutil.copytree(resourcedir,os.path.join(OUTPUTDIR,name)) 40 52 41 53 # change the working directory … … 72 84 73 85 # create the html from the index.yml fragment 74 html = flat.flatten( [DOCTYPE,flatten(Y.fragment(os.path.join(root,'index.yml')),ctx)] ) 75 file(os.path.join(OUTPUTDIR,root,'index.html'),'w').write(html) 86 if root != '.': 87 outroot = path(OUTPUTDIR)/root 88 else: 89 outroot = path(OUTPUTDIR) 90 cachepath = outroot/'.cache.yml' 91 cachepathparent = outroot.parent /'.cache.yml' 92 if os.path.exists( cachepath ) and partialbuild: 93 ctx = syck.load(open(cachepath),Loader=Y.Loader,implicit_typing=False) 94 html = flat.flatten( [DOCTYPE,flatten(ctx.data[ctx.path]['index.yml'],ctx)] ) 95 else: 96 html = flat.flatten( [DOCTYPE,flatten(Y.fragmentConstructor(os.path.join(root,'index.yml')),ctx)] ) 97 98 # write the syck data for later use as a cache (for building subdirs only) 99 Dumper(open(cachepath,'w')).dump(ctx) 100 # write the output html 101 file(os.path.join(OUTPUTDIR,root,'index.html'),'w').write(html) 76 102 77 103 if ctx.verbose: … … 88 114 resourcedirs = [] 89 115 90 build(options.data,options.out,verbose=options.verbose,resourcedirs=resourcedirs )116 build(options.data,options.out,verbose=options.verbose,resourcedirs=resourcedirs,partialbuild=options.partialbuild) 91 117 92 118 if __name__ == "__main__": … … 96 122 parser.add_option("-r", "--resources", dest="resources", help="comma separated list of resource directories to copy", metavar="RESOURCES") 97 123 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="print status messages to stdout") 124 parser.add_option("-p", "--partialbuild", action="store_true", dest="partialbuild", default=False, help="allow a partial build from cache files, does not remove existing directory") 98 125 (options, args) = parser.parse_args() 99 126 branches/timcommithook/pyramid/yamlRegistry.py
r50 r54 1 1 import syck 2 from pyramid import utils 2 from pyramid import utils, core 3 from pyramid.path import path 3 4 from pprint import pprint 4 5 from cStringIO import StringIO … … 6 7 # set up classes for yaml parser 7 8 class fragment: 8 ''' fragment is either a yaml file for parsing or a tmpl data structure. 9 a template data structure can contain local and global data 9 ''' an inline fragment which contains data and a template 10 10 ''' 11 11 def __init__(self, node): 12 13 try: 14 self.template = node.get('template',None) 15 self.locals = node.get('local',{}) 16 self.globals = node.get('global',{}) 17 self.file = None 18 except AttributeError: 19 self.template = '' 20 self.locals = {} 21 self.globals = {} 22 self.file = node 12 self.template = node.get('template',None) 13 self.locals = node.get('local',{}) 14 self.globals = node.get('global',{}) 15 23 16 def __repr__(self): 24 17 s = StringIO() 25 print '<Y.fragment>', 26 pprint({'template':self.template,'globals':self.globals,'locals':self.locals,'file':self.file},s,4,10) 18 pprint({'template':self.template,'globals':self.globals,'locals':self.locals},s,4,10) 27 19 return s.getvalue() 20 21 class fragmentFile: 22 ''' A file fragment which points at another yaml file 23 ''' 24 def __init__(self, node): 25 self.file = node 26 27 def __repr__(self): 28 s = StringIO() 29 pprint({'file':self.file},s,4,10) 30 return s.getvalue() 31 32 def fragmentConstructor(node): 33 try: 34 if node.keys(): 35 return fragment(node) 36 except AttributeError: 37 return fragmentFile(node) 38 28 39 29 40 class rest(str): … … 94 105 return s.getvalue() 95 106 107 def pathconstruct(pathstring): 108 return path(pathstring) 109 110 111 def context(node): 112 return core.Context(node) 113 96 114 class Loader(syck.Loader): 97 115 … … 108 126 def construct(self, node): 109 127 if node.tag is not None: 110 parts = node.tag.split(':' )128 parts = node.tag.split(':',2) 111 129 if parts[0] == 'tag': 112 130 tld, year = parts[1].split(',') … … 117 135 year = None 118 136 name = parts[1] 137 119 138 if tld or year or name: 120 139 construct = self.__constructs.get((tld,year,name)) … … 125 144 # Set up type registry 126 145 _typeRegistry = { 127 ('yaml.org','2002','fragment'): fragment ,146 ('yaml.org','2002','fragment'): fragmentConstructor, 128 147 ('yaml.org','2002','rest'): rest, 129 148 ('yaml.org','2002','restfile'): restfile, … … 133 152 ('yaml.org','2002','breadcrumb'): breadcrumb, 134 153 ('yaml.org','2002','acquire'): acquire, 154 ('python.yaml.org','2002','object:pyramid.path.path'): pathconstruct, 155 ('python.yaml.org','2002','object:pyramid.core.Context'): context, 135 156 } 136 157 branches/timcommithook/setup.py
r47 r54 1 from distutils.coreimport setup1 from setuptools import setup 2 2 setup(name='pyramid', 3 3 version='0.1',
