۶eTc@s"dZddlZddlZddlZddlZddlZddlZddlm Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZyddlmZWn$ek rdfdYZnXeZeejerejZdZnddlZejZdZdd lmZmZdd lm Z dd l!m"Z"dd l#m$Z$m%Z%dd l&m'Z'm(Z(ddl)m*Z*ddl)m+Z+ddl,m-Z-ddl.m/Z/ddl0m1Z1ddl2m3Z3m4Z4ddl5m6Z6m7Z7ddl8m9Z9ddl:m;Z;m<Z<m=Z=ddl>m?Z?e@ZAdZBdeCfdYZDdeDfdYZEdZFdZGdZHeaId ZJd!eKfd"YZLd#eKfd$YZMd%e"fd&YZNeNZOePeQeNeN_Rd'ZSdS((sw Provides the core API for Cheetah. See the docstring in the Template class and the Users' Guide for more information iN(t randrange(tLockRcBseZdZdZRS(cCsdS(N((tself((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pytacquirescCsdS(N((R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pytreleases(t__name__t __module__RR(((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRs cCstj|d|S(N(ttypest MethodTypetNone(tfunctcls((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyt createMethod&scCstj||S(N(RR(R R ((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyR +s(tconvertVersionStringToTupletMinCompatibleVersionTuple(tMinCompatibleVersion(tServlet(t ParseErrort SourceReader(tCompilertDEFAULT_COMPILER_SETTINGS(t ErrorCatchers(tFilters(tconvertTmplPathToModuleName(t checkKeywords(tIndenter(tNotFoundtvalueFromSearchList(tMemoryCacheStoretMemcachedCacheStore(t CacheRegion(t _Convertert_lookuptNonNumericInputError(t UnspecifiedcCs|tde*ed3Z?ed4Z@e@ZAeeeeeeed5ZBd6ZCd7ZDeed&e2eeeed8ZEeee*eed9ZFed:ed;ZGd<ZHfd=d>d?d@d?d@edAZIRS(BsW This class provides a) methods used by templates at runtime and b) methods for compiling Cheetah source code into template classes. This documentation assumes you already know Python and the basics of object oriented programming. If you don't know Python, see the sections of the Cheetah Users' Guide for non-programmers. It also assumes you have read about Cheetah's syntax in the Users' Guide. The following explains how to use Cheetah from within Python programs or via the interpreter. If you statically compile your templates on the command line using the 'cheetah' script, this is not relevant to you. Statically compiled Cheetah template modules/classes (e.g. myTemplate.py: MyTemplateClasss) are just like any other Python module or class. Also note, most Python web frameworks (Webware, Aquarium, mod_python, Turbogears, CherryPy, Quixote, etc.) provide plugins that handle Cheetah compilation for you. There are several possible usage patterns: 1) tclass = Template.compile(src) t1 = tclass() # or tclass(namespaces=[namespace,...]) t2 = tclass() # or tclass(namespaces=[namespace2,...]) outputStr = str(t1) # or outputStr = t1.aMethodYouDefined() Template.compile provides a rich and very flexible API via its optional arguments so there are many possible variations of this pattern. One example is: tclass = Template.compile('hello $name from $caller', baseclass=dict) print tclass(name='world', caller='me') See the Template.compile() docstring for more details. 2) tmplInstance = Template(src) # or Template(src, namespaces=[namespace,...]) outputStr = str(tmplInstance) # or outputStr = tmplInstance.aMethodYouDefined(...args...) Notes on the usage patterns: usage pattern 1) This is the most flexible, but it is slightly more verbose unless you write a wrapper function to hide the plumbing. Under the hood, all other usage patterns are based on this approach. Templates compiled this way can #extend (subclass) any Python baseclass: old-style or new-style (based on object or a builtin type). usage pattern 2) This was Cheetah's original usage pattern. It returns an instance, but you can still access the generated class via tmplInstance.__class__. If you want to use several different namespace 'searchLists' with a single template source definition, you're better off with Template.compile (1). Limitations (use pattern 1 instead): - Templates compiled this way can only #extend subclasses of the new-style 'object' baseclass. Cheetah.Template is a subclass of 'object'. You also can not #extend dict, list, or other builtin types. - If your template baseclass' __init__ constructor expects args there is currently no way to pass them in. If you need to subclass a dynamically compiled Cheetah class, do something like this: from Cheetah.Template import Template T1 = Template.compile('$meth1 #def meth1: this is meth1 in T1') T2 = Template.compile('#implements meth1 this is meth1 redefined in T2', baseclass=T1) print T1, T1() print T2, T2() Note about class and instance attribute names: Attributes used by Cheetah have a special prefix to avoid confusion with the attributes of the templates themselves or those of template baseclasses. Class attributes which are used in class methods look like this: klass._CHEETAH_useCompilationCache (_CHEETAH_xxx) Instance attributes look like this: klass._CHEETAH__globalSetVars (_CHEETAH__xxx with 2 underscores) t_initCheetahInstancet searchListt errorCatchertgetVart varExiststgetFileContentsti18ntrunAsMainProgramtrespondtshutdowntwebInputtserverSidePathtgeneratedClassCodetgeneratedModuleCodet_getCacheStoret_getCacheStoreIdPrefixt_createCacheRegiontgetCacheRegiontgetCacheRegionst refreshCachet_handleCheetahIncludet2_getTemplateAPIClassForIncludeDirectiveCompilationtsubclasstcacheRegionClasst cacheStoretcacheStoreIdPrefixtcacheStoreClasst"DynamicallyCompiledCheetahTemplatecCs|jS(N(t_CHEETAH_compilerClass(RSRTRU((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyt_getCompilerClass@scCs|jS(N(t_CHEETAH_compilerSettings(RSRTRU((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyt_getCompilerSettingsDsc(BsJ d}e|ejef r8e|ddfne|ejeef rme|ddfn| ekr|j} ne| er| j } ne| ejee f re|ddfn| ekr|j } ne| e e f re|dd fn| ekr4|j} ne| e e f rce|d d fn|ekr|j||pi}ne|e re|d d fn|ekr|j||}n| ekr|j} n|ekr|j}ne|e e f r3e|d d fne|ejef ree|ddfne}| r|oe|ere|}|}n |j}n|ekr|j}ne|ejef re|ddfnejdd|p|}|ekr%|j}ne|ejef rWe|ddfn| ekro|j} n|ekr|j}ne|e e f re|dd fn|ekr|j}ne|ejef re|ddfn| r*|}|j||| \}}ne}e}| r|e| erT| }n%e| e ryd| j}| }nne}e}|pe|ere}|re |}ne}| re | }ne}|r e!e"|}e#dr|e!e$j%j&|7}nnybdj'ge"|||||e"|e"| ||e"|g D]}e!|^qf}WnnXnd}e}| o|o||j(kr|j(|}|j)}nn|||d|d|d|d|d|pi}|r|j*|j+n|j,|j-}|j.}| r|dk r|j/d}|j0dd|dj'|}n|j1|Sn|re2j2|_3|j4Snz|j5j6e7|} | d}!|r5e$j%j8| re9d|ne$j%j'||!}!e:|!d j;|nej<e!| }"| rx*| j=D]\}#}e>|"|#|q]Wn|!|"_?|oe$j%j8|r||"_@n| o|re>|"||ny'e,||!d!}$|$|"jAfd"UWneBk rP}%yeC|||d#|%}&Wn#eD|!|||%_E|%nX|&n,e9k r{}%eD|!|||%_EnX|"eFjG| ||d       tRawOrEncodedUnicodec Csd} | d} t|tjtfs;t| d!nt|tjttfsit| d"nt|ttjf rt|tot|t j  rt| d#nt|ttj fst| d$n|d k r[t } t|ttjfrt} nt|tr?t|tjr?t} n| r[t| d%q[n|tk rt|tjst| d&qn|d k r|d k rtddntt|jt|dsMyQtj|jj}|j}t|}|tkr,td|tfnWqMtk rCqMqMXn|rx|D]}t|t rZ|j!t"|j#@}t}|rt }nt|t r|j$drt}n|rt%j&dt%j&ddj't(|t%j&dt%j&dqqZqZWn|j)d|d|d|d |d |d| d|d| |d k sp|d k r|j*||d|nd S('s,a) compiles a new template OR b) instantiates an existing template. Read this docstring carefully as there are two distinct usage patterns. You should also read this class' main docstring. a) to compile a new template: t = Template(source=aSourceString) # or t = Template(file='some/path') # or t = Template(file=someFileObject) # or namespaces = [{'foo':'bar'}] t = Template(source=aSourceString, namespaces=namespaces) # or t = Template(file='some/path', namespaces=namespaces) print t b) to create an instance of an existing, precompiled template class: ## i) first you need a reference to a compiled template class: tclass = Template.compile(source=src) # or just Template.compile(src) # or tclass = Template.compile(file='some/path') # or tclass = Template.compile(file=someFileObject) # or # if you used the command line compiler or have Cheetah's ImportHooks # installed your template class is also available via Python's # standard import mechanism: from ACompileTemplate import AcompiledTemplate as tclass ## ii) then you create an instance t = tclass(namespaces=namespaces) # or t = tclass(namespaces=namespaces, filter='RawOrEncodedUnicode') print t Arguments: for usage pattern a) If you are compiling a new template, you must provide either a 'source' or 'file' arg, but not both: - source (string or None) - file (string path, file-like object, or None) Optional args (see below for more) : - compilerSettings Default: Template._CHEETAH_compilerSettings=None a dictionary of settings to override those defined in DEFAULT_COMPILER_SETTINGS. See Cheetah.Template.DEFAULT_COMPILER_SETTINGS and the Users' Guide for details. You can pass the source arg in as a positional arg with this usage pattern. Use keywords for all other args. for usage pattern b) Do not use positional args with this usage pattern, unless your template subclasses something other than Cheetah.Template and you want to pass positional args to that baseclass. E.g.: dictTemplate = Template.compile('hello $name from $caller', baseclass=dict) tmplvars = dict(name='world', caller='me') print dictTemplate(tmplvars) This usage requires all Cheetah args to be passed in as keyword args. optional args for both usage patterns: - namespaces (aka 'searchList') Default: None an optional list of namespaces (dictionaries, objects, modules, etc.) which Cheetah will search through to find the variables referenced in $placeholders. If you provide a single namespace instead of a list, Cheetah will automatically convert it into a list. NOTE: Cheetah does NOT force you to use the namespaces search list and related features. It's on by default, but you can turn if off using the compiler settings useSearchList=False or useNameMapper=False. - filter Default: 'EncodeUnicode' Which filter should be used for output filtering. This should either be a string which is the name of a filter in the 'filtersLib' or a subclass of Cheetah.Filters.Filter. . See the Users' Guide for more details. - filtersLib Default: Cheetah.Filters A module containing subclasses of Cheetah.Filters.Filter. See the Users' Guide for more details. - errorCatcher Default: None This is a debugging tool. See the Users' Guide for more details. Do not use this or the #errorCatcher diretive with live production systems. Do NOT mess with the args _globalSetVars or _preBuiltSearchList! sarg '%s' must be %ss %sRTsstring or NoneRUs&string, file open for reading, or Nonetfiltersstring or classs6(if class, must be subclass of Cheetah.Filters.Filter)t filtersLibsstring or modules>(if module, must contain subclasses of Cheetah.Filters.Filter)Rpsstring, class or NonesB(if class, must be subclass of Cheetah.ErrorCatchers.ErrorCatcher)RRs-you must supply either a source string or thes& 'file' keyword argument, but not botht_CHEETAH_versionTupleslThis template was compiled with Cheetah version %s. Templates compiled before version %s must be recompiled.tprioritizeSearchListOverSelfs` The following keys are members of the Template class and will result in NameMapper collisions! s > %s s, s Please change the key's name or use the compiler setting "prioritizeSearchListOverSelf=True" to prevent the NameMapper from using s: the Template member in place of your searchList variable RoRt_globalSetVarst_preBuiltSearchListN(ssourcesstring or None(sfiles&string, file open for reading, or None(sfiltersstring or classs6(if class, must be subclass of Cheetah.Filters.Filter)(s filtersLibsstring or modules>(if module, must contain subclasses of Cheetah.Filters.Filter)(s errorCatchersstring, class or NonesB(if class, must be subclass of Cheetah.ErrorCatchers.ErrorCatcher)(scompilerSettingss dictionary(+R)RRRRRtTypeTypeRt issubclassRtFilterRR RRRt ErrorCatcherR"tDictTypeR RmRQRYR:R;RRt__CHEETAH_version__R RtAssertionErrorRR*tReserved_SearchListtsettkeystgettloggingtinfoRR,Rnt_compile(RRTRRoRURRRpRR!R"Rt errmsgextraterrRtcompiledVersiontcompiledVersionTuplet namespacet intersectiontwarn((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRQsz  "                    cCs|jS(seReturn the module code the compiler generated, or None if no compilation took place. (R(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyR{scCs&|j|jjd|jjd!S(sdReturn the class code the compiler generated, or None if no compilation took place. s class s ## END CLASS DEFINITION(Rtfind(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRzscCs|jS(s-Return a reference to the searchlist (t_CHEETAH__searchList(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRoscCs|jS(s7Return a reference to the current errorCatcher (t_CHEETAH__errorCatcher(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRpscCs@|js9|jdk r'|j|_q9|j|_n|jS(N(t_CHEETAH__cacheStoret_CHEETAH_cacheStoreR t_CHEETAH_cacheStoreClass(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyR|s  cCs*|jdk r|jStt|SdS(N(t_CHEETAH_cacheStoreIdPrefixR R<tid(R((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyR}scCs(|jd|d|jd|jS(NtregionIDttemplateCacheIdPrefixR(t_CHEETAH_cacheRegionClassR}R|(RR@((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyR~s  cCsB|jj|}| r>|r>|j|}||j|RR"(RtvarNametdefaulttautoCall((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRqOs &  cCsCy*t|j|jdd|tSWntk r>tSXdS(s:Test if a variable name exists in the searchList. RNRN(RRoR>RRR(RRORQ((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRr]s " c Cs|S(sThis is just a stub at this time. plural = the plural form of the message n = a sized argument to distinguish between single and plural forms id = msgid in the translation catalog domain = translation domain source = source lang target = a specific target lang comment = a comment to the translation team See the following for some ideas http://www.zope.org/DevHome/Wikis/DevSite/Projects/ComponentArchitecture/ZPTInternationalizationSupport Other notes: - There is no need to replicate the i18n:name attribute from plone / PTL, as cheetah placeholders serve the same purpose (( RtmessagetpluraltnR?tdomainRTttargettcomment((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRtjscCs)t|d}|j}|j|S(s'A hook for getting the contents of a file. The default implementation just uses the Python open() function to load local files. This method could be reimplemented to allow reading of remote files via various protocols, as PHP allows with its 'URL fopen wrapper' tr(RWRRRX(RRtfptoutput((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRss  cCs'ddlm}|d|jdS(sAllows the Template to function as a standalone command-line program for static page generation. Type 'python yourtemplate.py --help to see what it's capabable of. i(t CmdLineIfacet templateObjN(tTemplateCmdLineIfaceR[trun(RR[((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRusc Cst|dtrdS|dk r+|}n|dk rYt|ttf rY|g}ni|_|dk rz||_n|dk rt||_|jj|nh|j|g|_|dk rt|t r|j dr||j|_q|jj t|ni|_ i|_ t|_||_i|_t|trj|} t|j| } n|} | j} | |j|_|j| <|j|_i|_|rt|trtt|} nt|tr|} n| ||_} | |j|jjd |jj } } n\|dkrcd|jj } } n7|dkrd |jj j } } n t d | d} itd d||d 6tdt||d6tdt||d6}i}x3|D]+}t|| t|\}}||| tags. ** KLUDGE: 'debug' is supposed to insert into the template output, but it wasn't working so I changed it to a'print' statement. So the debugging output will appear wherever standard output is pointed, whether at the terminal, in a Webware log file, or whatever. *** Since we didn't specify any coversions, the value is a string. It's a 'single' value because we specified it in 'names' rather than 'namesMulti'. Single values work like this: * If one value is found, take it. * If several values are found, choose one arbitrarily and ignore the rest. * If no values are found, use or raise the appropriate 'default*' value. Multi values work like this: * If one value is found, put it in a list. * If several values are found, leave them in a list. * If no values are found, use the empty list ([]). The 'default*' arguments are *not* consulted in this case. Example: assume 'days' came from a set of checkboxes or a multiple combo box on a form, and the user chose'Monday', 'Tuesday' and 'Thursday'. #silent $webInput([], ['days']) The days you chose are: #slurp #for $day in $days $day #slurp #end for dic = self.webInput([], ['days']) write('The days you chose are: ') for day in dic['days']: write(day + ' ') Both these examples print: 'The days you chose are: Monday Tuesday Thursday'. By default, missing strings are replaced by '' and missing/bad numbers by zero. (A'bad number' means the converter raised an exception for it, usually because of non-numeric characters in the value.) This mimics Perl/PHP behavior, and simplifies coding for many applications where missing/bad values *should* be blank/zero. In those relatively few cases where you must distinguish between empty-string/zero on the one hand and missing/bad on the other, change the appropriate 'default*' and 'bad*' arguments to something like: * None * another constant value * $NonNumericInputError/self.NonNumericInputError * $ValueError/ValueError (NonNumericInputError is defined in this class and is useful for distinguishing between bad input vs a TypeError/ValueError thrown for some other rason.) Here's an example using multiple values to schedule newspaper deliveries. 'checkboxes' comes from a form with checkboxes for all the days of the week. The days the user previously chose are preselected. The user checks/unchecks boxes as desired and presses Submit. The value of 'checkboxes' is a list of checkboxes that were checked when Submit was pressed. Our task now is to turn on the days the user checked, turn off the days he unchecked, and leave on or off the days he didn't change. dic = self.webInput([], ['dayCheckboxes']) wantedDays = dic['dayCheckboxes'] # The days the user checked. for day, on in self.getAllValues(): if not on and wantedDays.has_key(day): self.TurnOn(day) # ... Set a flag or insert a database record ... elif on and not wantedDays.has_key(day): self.TurnOff(day) # ... Unset a flag or delete a database record ... 'source' allows you to look up the variables from a number of different sources: 'f' fields (CGI GET/POST parameters) 'c' cookies 's' session variables 'v' 'values', meaning fields or cookies In many forms, you're dealing only with strings, which is why the 'default' argument is third and the numeric arguments are banished to the end. But sometimes you want automatic number conversion, so that you can do numeric comparisions in your templates without having to write a bunch of conversion/exception handling code. Example: #silent $webInput(['name', 'height:int']) $name is $height cm tall. #if $height >= 300 Wow, you're tall! #else Pshaw, you're short. #end if dic = self.webInput(['name', 'height:int']) name = dic[name] height = dic[height] write('%s is %s cm tall.' % (name, height)) if height > 300: write('Wow, you're tall!') else: write('Pshaw, you're short.') To convert a value to a number, suffix ':int' or ':float' to the name. The method will search first for a 'height:int' variable and then for a 'height' variable. (It will be called 'height' in the final dictionary.) If a numeric conversion fails, use or raise 'badInt' or 'badFloat'. Missing values work the same way as for strings, except the default is 'defaultInt' or 'defaultFloat' instead of 'default'. If a name represents an uploaded file, the entire file will be read into memory. For more sophistocated file-upload handling, leave that name out of the list and do your own handling, or wait for Cheetah.Utils.UploadFileMixin. This only in a subclass that also inherits from Webware's Servlet or HTTPServlet. Otherwise you'll get an AttributeError on 'self.request'. EXCEPTIONS: ValueError if 'source' is not one of the stated characters. TypeError if a conversion suffix is not ':int' or ':float'. FUTURE EXPANSION: a future version of this method may allow source cascading; e.g., 'vs' would look first in 'values' and then in session variables. Meta-Data ================================================================================ Author: Mike Orr License: This software is released for unlimited distribution under the terms of the MIT license. See the LICENSE file. Version: $Revision: 1.186 $ Start Date: 2002/03/17 Last Revision Date: $Date: 2008/03/10 04:48:11 $ RcR3tfieldtcs#can't get cookies from a CGI scripttss-can't get session variables from a CGI scriptR%tsessiontcookiesarg 'src' invalidtstringRRtfloats
s	
i(RcR3N(tlowerRlt_formUsedByWebInputR tcgit FieldStoragetgetvaluet RuntimeErrortrequestR%RRRRRRRR RRtpprinttpformatRoR(Rtnamest namesMultiRPRGt defaultIntt defaultFloattbadInttbadFloattdebugtisCgiRTR tsourcest converterstdictnameR7R3((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRx`sN           (JRRRlRRRRRR RR*RRRRqRRRRRRRRRRRRRRRNRRR!RRBRR=R<R>RRRR"R]RRRRRRRRQR{RzRoRpR|R}R~RRRRwRqRrthasVarRtRsRuRnR0RRRx(((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRmsN     8K           N ,, c Cs@t|ttfr|pd}tj}tjd||j}t|drd|j }n!t t j d|j d}|j}g} xNtddD]=} || dkrPn| j|d| ||| fqWg} xPtddD]?} || t|ksPn| j|| ||| fqW| jd} | d7} x:| r| j} | di| dd 6| dd 67} q^Wt|d r| d d |jpdd7} nx:| r| j} | di| dd 6| dd 67} qWddddt|d| ddg}t j d|}|rt |j d}t |j d}|jdnd}d}t j ddj|t|dd}|rt |j d}t |j d}|jd|jdndj|}t|d|}t||d|d|S(Nitlinenos[ ]*File.*line (\d+)iisLine|Python Code sC----|------------------------------------------------------------- s%(row)-4d|%(line)s trowtlinetoffsett is^ sCError in the Python code which Cheetah generated for this template:t=iPRsline (\d+), col (\d+)is) Here is the corresponding Cheetah code: s s( Here is the corresponding Cheetah code.sM** I had to guess the line & column numbers, so they are probably incorrect: RFtcol(R)R<RVR tStringIOt tracebackt print_excRRYRRRtsearchtgroupRDtrangeR.RCtreversetpopRRtmaxRR(RTRUtgeneratedPyCodeRRFtsiot formatedExctpyLinenoRJt prevLinestit nextLinestreporttlineInfoRRtcheetahPosMatchRRtreader((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pyRHsj!   ! '#    ("  (   # (TRlR:RR.Rtos.pathRR=trandomRtimpR[RRRRRt threadingRt ImportErrorR RR)t version_infoR0tFileTypeR tiotIOBasetCheetah.VersionR RRtCheetah.ServletRtCheetah.ParserRRtCheetah.CompilerRRtCheetahRRt#Cheetah.convertTmplPathToModuleNameRtCheetah.Utils.MiscRtCheetah.Utils.IndenterRtCheetah.NameMapperRRtCheetah.CacheStoreRRtCheetah.CacheRegionRtCheetah.Utils.WebInputMixinRR R!tCheetah.UnspecifiedR"RR#R&RR'R(R-R+RARRLRRMRNRmtTR+tdirR*R(((s?/opt/freeware/lib64/python2.7/site-packages/Cheetah/Template.pytsz                       +