home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.6)
-
- __release__ = '0.8.1'
- __license__ = 'MIT License'
- __all__ = [
- 'Template',
- 'Engine',
- 'helpers',
- 'html']
- import re
- import sys
- import os
- import time
- import marshal
- python3 = sys.version_info[0] == 3
- python2 = sys.version_info[0] == 2
- logger = None
-
- def _write_binary_file(filename, content):
- f = None
-
- try:
- import random
- tmpfile = filename + str(random.random())[1:]
- f = open(tmpfile, 'wb')
- f.write(content)
- finally:
- if f:
- f.close()
- os.rename(tmpfile, filename)
-
-
-
-
- def _read_binary_file(filename):
- f = None
-
- try:
- f = open(filename, 'rb')
- return f.read()
- finally:
- if f:
- f.close()
-
-
-
- if python2:
-
- def _read_template_file(filename, encoding = None):
- s = _read_binary_file(filename)
- if encoding:
- s = s.decode(encoding)
-
- return s
-
- elif python3:
-
- def _read_template_file(filename, encoding = None):
- s = _read_binary_file(filename)
- if not encoding:
- pass
- return s.decode('utf-8')
-
-
-
- def _create_module(module_name):
- import types
- mod = types.ModuleType(module_name)
- mod.__file__ = __file__
- sys.modules[module_name] = mod
- return mod
-
-
- def _create_helpers_module():
- if python2:
-
- def generate_tostrfunc(encode = None, decode = None):
- if encode:
- if decode:
- raise ValueError("can't specify both encode and decode encoding.")
- decode
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val
- if isinstance(val, unicode):
- return val.encode(encode)
- return str(val)
-
- elif decode:
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val.decode(decode)
- if isinstance(val, unicode):
- return val
- return unicode(val)
-
- else:
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val
- if isinstance(val, unicode):
- return val
- return str(val)
-
- return to_str
-
- elif python3:
-
- def generate_tostrfunc(decode = None, encode = None):
- if encode:
- if decode:
- raise ValueError("can't specify both encode and decode encoding.")
- decode
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val.encode(encode)
- if isinstance(val, bytes):
- return val
- return str(val).encode(encode)
-
- elif decode:
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val
- if isinstance(val, bytes):
- return val.decode(decode)
- return str(val)
-
- else:
-
- def to_str(val):
- if val is None:
- return ''
- if isinstance(val, str):
- return val
- if isinstance(val, bytes):
- return val
- return str(val)
-
- return to_str
-
-
- if python2:
- to_str = generate_tostrfunc(encode = 'utf-8')
- elif python3:
- to_str = generate_tostrfunc(decode = 'utf-8')
-
-
- def echo(string):
- frame = sys._getframe(1)
- context = frame.f_locals
- context['_buf'].append(string)
-
-
- def start_capture(varname = None):
- frame = sys._getframe(1)
- context = frame.f_locals
- context['_buf_tmp'] = context['_buf']
- context['_capture_varname'] = varname
- context['_buf'] = []
-
-
- def stop_capture(store_to_context = True):
- frame = sys._getframe(1)
- context = frame.f_locals
- result = ''.join(context['_buf'])
- context['_buf'] = context.pop('_buf_tmp')
- varname = context.pop('_capture_varname')
- if varname:
- context[varname] = result
- if store_to_context:
- context['_context'][varname] = result
-
-
- return result
-
-
- def captured_as(name):
- frame = sys._getframe(1)
- context = frame.f_locals
- if name in context:
- _buf = context['_buf']
- _buf.append(context[name])
- return True
- return False
-
-
- def _p(arg):
- return '<`#%s#`>' % arg
-
-
- def _P(arg):
- return '<`$%s$`>' % arg
-
-
- def _decode_params(s):
- import urllib
- if python2:
- unquote = unquote
- import urllib
- elif python3:
- unquote = unquote
- import urllib.parse
-
- dct = {
- 'lt': '<',
- 'gt': '>',
- 'amp': '&',
- 'quot': '"',
- '#039': "'" }
-
- def unescape(s):
- return re.sub(('&(lt|gt|quot|amp|#039);',), (lambda m: dct[m.group(1)]), s)
-
- s = to_str(s)
- s = re.sub(('%3C%60%23(.*?)%23%60%3E',), (lambda m: '#{%s}' % unquote(m.group(1))), s)
- s = re.sub(('%3C%60%24(.*?)%24%60%3E',), (lambda m: '${%s}' % unquote(m.group(1))), s)
- s = re.sub(('<`#(.*?)#`>',), (lambda m: '#{%s}' % unescape(m.group(1))), s)
- s = re.sub(('<`\\$(.*?)\\$`>',), (lambda m: '${%s}' % unescape(m.group(1))), s)
- s = re.sub('<`#(.*?)#`>', '#{\\1}', s)
- s = re.sub('<`\\$(.*?)\\$`>', '${\\1}', s)
- return s
-
- mod = _create_module('tenjin.helpers')
- mod.to_str = to_str
- mod.generate_tostrfunc = generate_tostrfunc
- mod.echo = echo
- mod.start_capture = start_capture
- mod.stop_capture = stop_capture
- mod.captured_as = captured_as
- mod._p = _p
- mod._P = _P
- mod._decode_params = _decode_params
- mod.__all__ = [
- 'escape',
- 'to_str',
- 'echo',
- 'generate_tostrfunc',
- 'start_capture',
- 'stop_capture',
- 'captured_as',
- '_p',
- '_P',
- '_decode_params']
- return mod
-
- helpers = _create_helpers_module()
- del _create_helpers_module
- generate_tostrfunc = helpers.generate_tostrfunc
-
- def _create_html_module():
- to_str = helpers.to_str
- _escape_table = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"' }
- _escape_pattern = re.compile('[&<>"]')
-
- _escape_callable = lambda m: _escape_table[m.group(0)]
-
- def escape_xml(s):
- return _escape_pattern.sub(_escape_callable, s)
-
-
- def tagattr(name, expr, value = (None, (None,)), escape = (None, True)):
- if not expr:
- return ''
- if value is None:
- value = expr
-
- if escape:
- value = escape_xml(to_str(value))
-
- return ' %s="%s"' % (name, value)
-
-
- def tagattrs(**kwargs):
- if 'klass' in kwargs:
- kwargs['class'] = kwargs.pop('klass')
-
- if 'checked' in kwargs:
- if not kwargs.pop('checked') or 'checked':
- pass
- kwargs['checked'] = None
-
- if 'selected' in kwargs:
- if not kwargs.pop('selected') or 'selected':
- pass
- kwargs['selected'] = None
-
- if 'disabled' in kwargs:
- if not kwargs.pop('disabled') or 'disabled':
- pass
- kwargs['disabled'] = None
-
- return [](_[1])
-
-
- def checked(expr):
- if not expr or ' checked="checked"':
- pass
- return ''
-
-
- def selected(expr):
- if not expr or ' selected="selected"':
- pass
- return ''
-
-
- def disabled(expr):
- if not expr or ' disabled="disabled"':
- pass
- return ''
-
-
- def nl2br(text):
- if not text:
- return ''
- return text.replace('\n', '<br />\n')
-
-
- def text2html(text):
- if not text:
- return ''
- return nl2br(escape_xml(text).replace(' ', ' '))
-
-
- def nv(name, value, sep = ((None, (None, None)), None), **kwargs):
- if not sep or 'name="%s" value="%s" id="%s"' % (name, value, name + sep + value):
- pass
- s = 'name="%s" value="%s"' % (name, escape_xml(value))
- if not kwargs or s + tagattrs(**kwargs):
- pass
- return s
-
-
- def new_cycle(*values):
-
- def gen(values):
- n = len(values)
- i = 0
- while True:
- yield values[i]
- i = (i + 1) % n
-
- if python2:
- return gen(values).next
- if python3:
- return gen(values).__next__
-
- mod = _create_module('tenjin.helpers.html')
- mod._escape_table = _escape_table
- mod.escape_xml = escape_xml
- mod.escape = escape_xml
- mod.tagattr = tagattr
- mod.tagattrs = tagattrs
- mod.checked = checked
- mod.selected = selected
- mod.disabled = disabled
- mod.nl2br = nl2br
- mod.text2html = text2html
- mod.nv = nv
- mod.new_cycle = new_cycle
- return mod
-
- helpers.html = _create_html_module()
- del _create_html_module
- helpers.escape = helpers.html.escape_xml
-
- class Template(object):
- filename = None
- encoding = None
- escapefunc = 'escape'
- tostrfunc = 'to_str'
- indent = 4
- preamble = None
- postamble = None
- smarttrim = None
- args = None
- timestamp = None
-
- def __init__(self, filename = None, encoding = None, escapefunc = None, tostrfunc = None, indent = None, preamble = None, postamble = None, smarttrim = None):
- if encoding is not None:
- self.encoding = encoding
-
- if escapefunc is not None:
- self.escapefunc = escapefunc
-
- if tostrfunc is not None:
- self.tostrfunc = tostrfunc
-
- if indent is not None:
- self.indent = indent
-
- if preamble is not None:
- self.preamble = preamble
-
- if postamble is not None:
- self.postamble = postamble
-
- if smarttrim is not None:
- self.smarttrim = smarttrim
-
- if preamble is True:
- self.preamble = '_buf = []'
-
- if postamble is True:
- self.postamble = "print ''.join(_buf)"
-
- if filename:
- self.convert_file(filename)
- else:
- self._reset()
-
-
- def _reset(self, input = None, filename = None):
- self._spaces = ''
- self.script = None
- self.bytecode = None
- self.input = input
- self.filename = filename
- if input != None:
- i = input.find('\n')
- if i < 0:
- self.newline = '\n'
- elif len(input) >= 2 and input[i - 1] == '\r':
- self.newline = '\r\n'
- else:
- self.newline = '\n'
-
- self._stmt_not_added_yet = True
-
-
- def before_convert(self, buf):
- if self.preamble:
- buf.append(self.preamble)
- if not self.input.startswith('<?py') or '\n':
- pass
- buf.append('; ')
-
-
-
- def after_convert(self, buf):
- if self.postamble:
- if not buf[-1].endswith('\n'):
- buf.append('\n')
-
- buf.append(self.postamble + '\n')
-
-
-
- def convert_file(self, filename):
- input = _read_template_file(filename)
- return self.convert(input, filename)
-
-
- def convert(self, input, filename = None):
- if python2:
- if self.encoding and isinstance(input, str):
- input = input.decode(self.encoding)
-
-
- self._reset(input, filename)
- buf = []
- self.before_convert(buf)
- self.parse_stmts(buf, input)
- self.after_convert(buf)
- script = ''.join(buf)
- self.script = script
- return script
-
-
- def compile_stmt_pattern(pi):
- return re.compile('<\\?%s( |\\t|\\r?\\n)(.*?) ?\\?>([ \\t]*\\r?\\n)?' % pi, re.S)
-
- STMT_PATTERN = None
- compile_stmt_pattern = staticmethod(compile_stmt_pattern)
-
- def stmt_pattern(self):
- pat = Template.STMT_PATTERN
- if not pat:
- pat = Template.STMT_PATTERN = Template.compile_stmt_pattern('py')
-
- return pat
-
-
- def parse_stmts(self, buf, input):
- if not input:
- return None
- rexp = self.stmt_pattern()
- is_bol = True
- index = 0
- for m in rexp.finditer(input):
- (mspace, code, rspace) = m.groups()
- text = input[index:m.start()]
- index = m.end()
- lspace = None
- if text == '':
- if is_bol:
- lspace = ''
-
- elif text[-1] == '\n':
- lspace = ''
- else:
- rindex = text.rfind('\n')
- if rindex < 0:
- if is_bol and text.isspace():
- lspace = text
- text = ''
-
- else:
- s = text[rindex + 1:]
- if s.isspace():
- lspace = s
- text = text[:rindex + 1]
-
- self.parse_exprs(buf, text, is_bol)
- is_bol = rspace is not None
- if lspace:
- buf.append(lspace)
-
- if mspace != ' ':
- if not mspace == '\t' or '\t':
- pass
- buf.append('\n')
-
- if code:
- code = self.statement_hook(code)
- self.add_stmt(buf, code)
-
- self._set_spaces(code, lspace, mspace)
- if rspace:
- buf.append('\n')
- continue
-
- rest = input[index:]
- if rest:
- self.parse_exprs(buf, rest)
-
-
-
- def statement_hook(self, stmt):
- if self.args is None:
- args_pattern = '^ *#@ARGS(?:[ \\t]+(.*?))?$'
- m = re.match(args_pattern, stmt)
- if m:
- if not m.group(1):
- pass
- arr = ''.split(',')
- args = []
- declares = []
- for s in arr:
- arg = s.strip()
- if not s:
- continue
-
- if not re.match('^[a-zA-Z_]\\w*$', arg):
- raise ValueError('%s: invalid template argument.' % arg)
- re.match('^[a-zA-Z_]\\w*$', arg)
- args.append(arg)
- declares.append("%s = _context.get('%s'); " % (arg, arg))
-
- self.args = args
- return ''.join(declares)
-
- return stmt
-
- EXPR_PATTERN = None
-
- def expr_pattern(self):
- pat = Template.EXPR_PATTERN
- if not pat:
- pat = Template.EXPR_PATTERN = re.compile('([#$])\\{(.*?)\\}', re.S)
-
- return pat
-
-
- def get_expr_and_escapeflag(self, match):
- return (match.group(2), match.group(1) == '$')
-
-
- def parse_exprs(self, buf, input, is_bol = False):
- if not input:
- return None
- if self._spaces:
- buf.append(self._spaces)
-
- self.start_text_part(buf)
- rexp = self.expr_pattern()
- smarttrim = self.smarttrim
- nl = self.newline
- nl_len = len(nl)
- pos = 0
- for m in rexp.finditer(input):
- start = m.start()
- text = input[pos:start]
- pos = m.end()
- (expr, flag_escape) = self.get_expr_and_escapeflag(m)
- if text:
- self.add_text(buf, text)
-
- self.add_expr(buf, expr, flag_escape)
- if smarttrim:
- if not text.endswith(nl) and not text and start > 0:
- pass
- flag_bol = is_bol
- if flag_bol and not flag_escape and input[pos:pos + nl_len] == nl:
- pos += nl_len
- buf.append('\n')
-
- input[pos:pos + nl_len] == nl
-
- if smarttrim:
- if buf and buf[-1] == '\n':
- buf.pop()
-
-
- rest = input[pos:]
- if rest:
- self.add_text(buf, rest, True)
-
- self.stop_text_part(buf)
- if input[-1] == '\n':
- buf.append('\n')
-
-
-
- def start_text_part(self, buf):
- buf.append('_buf.extend((')
-
-
- def stop_text_part(self, buf):
- buf.append('));')
-
- _quote_rexp = None
-
- def add_text(self, buf, text, encode_newline = False):
- if not text:
- return None
- if self.encoding and python2:
- buf.append("u'''")
- else:
- buf.append("'''")
- rexp = Template._quote_rexp
- if not rexp:
- rexp = Template._quote_rexp = re.compile("(['\\\\\\\\])")
-
- text = rexp.sub('\\\\\\1', text)
- if not encode_newline or text[-1] != '\n':
- buf.append(text)
- buf.append("''', ")
- elif len(text) >= 2 and text[-2] == '\r':
- buf.append(text[0:-2])
- buf.append("\\r\\n''', ")
- else:
- buf.append(text[0:-1])
- buf.append("\\n''', ")
-
- _add_text = add_text
-
- def add_expr(self, buf, code, flag_escape = None):
- if not code or code.isspace():
- return None
- if flag_escape is None:
- buf.append(code)
- buf.append(', ')
- elif flag_escape is False:
- buf.extend((self.tostrfunc, '(', code, '), '))
- else:
- buf.extend((self.escapefunc, '(', self.tostrfunc, '(', code, ')), '))
-
-
- def add_stmt(self, buf, code):
- if self._stmt_not_added_yet:
- if buf and buf[-1] != '\n' and buf[-1].isspace():
- buf[-1:-1] = ('if True: ## dummy\n',)
-
- self._stmt_not_added_yet = False
-
- if self.newline == '\r\n':
- code = code.replace('\r\n', '\n')
-
- buf.append(code)
-
-
- def _set_spaces(self, code, lspace, mspace):
- if lspace:
- if mspace == ' ':
- code = lspace + code
- elif mspace == '\t':
- code = lspace + '\t' + code
-
-
- i = code.rstrip().rfind('\n') + 1
- indent = 0
- n = len(code)
- ch = None
- while i < n:
- ch = code[i]
- if ch == ' ':
- indent += 1
- elif ch == '\t':
- indent += 8
- else:
- break
- i += 1
- if ch:
- if code.rstrip()[-1] == ':':
- indent += self.indent
-
- self._spaces = ' ' * indent
-
-
-
- def render(self, context = None, globals = None, _buf = None):
- if context is None:
- locals = context = { }
- elif self.args is None:
- locals = context.copy()
- else:
- locals = { }
- if '_engine' in context:
- context.get('_engine').hook_context(locals)
-
- locals['_context'] = context
- if globals is None:
- globals = sys._getframe(1).f_globals
-
- bufarg = _buf
- if _buf is None:
- _buf = []
-
- locals['_buf'] = _buf
- if not self.bytecode:
- self.compile()
-
- exec (self.bytecode, globals, locals)
- if bufarg is not None:
- return bufarg
- if not logger:
- return ''.join(_buf)
-
- try:
- return ''.join(_buf)
- except UnicodeDecodeError:
- logger
- logger
- bufarg is not None
- ex = sys.exc_info()[1]
- logger.error('[tenjin.Template] ' + str(ex))
- logger.error('[tenjin.Template] (_buf=%s)' % repr(_buf))
- raise
- except:
- logger
-
-
-
- def compile(self):
- filename = self.filename
- if not filename:
- filename = '(tenjin)'
-
- if isinstance(filename, unicode):
- filename = filename.encode('utf8')
-
- self.bytecode = compile(self.script, filename, 'exec')
-
-
-
- class Preprocessor(Template):
- STMT_PATTERN = None
-
- def stmt_pattern(self):
- pat = Preprocessor.STMT_PATTERN
- if not pat:
- pat = Preprocessor.STMT_PATTERN = Template.compile_stmt_pattern('PY')
-
- return Preprocessor.STMT_PATTERN
-
- EXPR_PATTERN = None
-
- def expr_pattern(self):
- pat = Preprocessor.EXPR_PATTERN
- if not pat:
- pat = Preprocessor.EXPR_PATTERN = re.compile('([#$])\\{\\{(.*?)\\}\\}', re.S)
-
- return Preprocessor.EXPR_PATTERN
-
-
- def add_expr(self, buf, code, flag_escape = None):
- if not code or code.isspace():
- return None
- code = '_decode_params(%s)' % code
- Template.add_expr(self, buf, code, flag_escape)
-
-
-
- class CacheStorage(object):
-
- def __init__(self, postfix = '.cache'):
- self.postfix = postfix
- self.items = { }
-
-
- def get(self, fullpath, create_template):
- template = self.items.get(fullpath)
- if not template:
- dict = self._load(fullpath)
- if dict:
- template = create_template()
- for k, v in dict.items():
- setattr(template, k, v)
-
- self.items[fullpath] = template
-
-
- return template
-
-
- def set(self, fullpath, template):
- self.items[fullpath] = template
- dict = self._save_data_of(template)
- return self._store(fullpath, dict)
-
-
- def _save_data_of(self, template):
- return {
- 'args': template.args,
- 'bytecode': template.bytecode,
- 'script': template.script,
- 'timestamp': template.timestamp }
-
-
- def unset(self, fullpath):
- self.items.pop(fullpath, None)
- return self._delete(fullpath)
-
-
- def clear(self):
- for k, v in self.items.items():
- self._delete(k)
-
- self.items.clear()
-
-
- def _load(self, fullpath):
- raise NotImplementedError.new('%s#_load(): not implemented yet.' % self.__class__.__name__)
-
-
- def _store(self, fullpath, template):
- raise NotImplementedError.new('%s#_store(): not implemented yet.' % self.__class__.__name__)
-
-
- def _delete(self, fullpath):
- raise NotImplementedError.new('%s#_delete(): not implemented yet.' % self.__class__.__name__)
-
-
- def _cachename(self, fullpath):
- return fullpath + self.postfix
-
-
-
- class MemoryCacheStorage(CacheStorage):
-
- def _load(self, fullpath):
- pass
-
-
- def _store(self, fullpath, template):
- pass
-
-
- def _delete(self, fullpath):
- pass
-
-
-
- class FileCacheStorage(CacheStorage):
-
- def _delete(self, fullpath):
- cachepath = self._cachename(fullpath)
- if os.path.isfile(cachepath):
- os.unlink(cachepath)
-
-
-
-
- class MarshalCacheStorage(FileCacheStorage):
-
- def _load(self, fullpath):
- cachepath = self._cachename(fullpath)
- if not os.path.isfile(cachepath):
- return None
- if logger:
- logger.info('[tenjin.MarshalCacheStorage] load cache (file=%s)' % repr(cachepath))
-
- dump = _read_binary_file(cachepath)
- return marshal.loads(dump)
-
-
- def _store(self, fullpath, dict):
- cachepath = self._cachename(fullpath)
- if logger:
- logger.info('[tenjin.MarshalCacheStorage] store cache (file=%s)' % repr(cachepath))
-
- _write_binary_file(cachepath, marshal.dumps(dict))
-
-
-
- class PickleCacheStorage(FileCacheStorage):
-
- def _load(self, fullpath):
-
- try:
- import cPickle as pickle
- except:
- import pickle
-
- cachepath = self._cachename(fullpath)
- if not os.path.isfile(cachepath):
- return None
- if logger:
- logger.info('[tenjin.PickleCacheStorage] load cache (file=%s)' % repr(cachepath))
-
- dump = _read_binary_file(cachepath)
- return pickle.loads(dump)
-
-
- def _store(self, fullpath, dict):
-
- try:
- import cPickle as pickle
- except:
- import pickle
-
- if 'bytecode' in dict:
- dict.pop('bytecode')
-
- cachepath = self._cachename(fullpath)
- if logger:
- logger.info('[tenjin.PickleCacheStorage] store cache (file=%s)' % repr(cachepath))
-
- _write_binary_file(cachepath, pickle.dumps(dict))
-
-
-
- class TextCacheStorage(FileCacheStorage):
-
- def _load(self, fullpath):
- cachepath = self._cachename(fullpath)
- if not os.path.isfile(cachepath):
- return None
- if logger:
- logger.info('[tenjin.TextCacheStorage] load cache (file=%s)' % repr(cachepath))
-
- s = _read_binary_file(cachepath)
- if python2:
- (header, script) = s.split('\n\n', 1)
- elif python3:
- (header, script) = s.split('\n\n'.encode('ascii'), 1)
- header = header.decode('ascii')
-
- timestamp = None
- encoding = None
- args = None
- for line in header.split('\n'):
- (key, val) = line.split(': ', 1)
- if key == 'timestamp':
- timestamp = float(val)
- continue
- if key == 'encoding':
- encoding = val
- continue
- if key == 'args':
- args = val.split(', ')
- continue
-
- if python2:
- if encoding:
- script = script.decode(encoding)
-
- elif python3:
- if not encoding:
- pass
- script = script.decode('utf-8')
-
- return {
- 'args': args,
- 'script': script,
- 'timestamp': timestamp }
-
-
- def _store(self, fullpath, dict):
- s = dict['script']
- if python2:
- if dict.get('encoding') and isinstance(s, unicode):
- s = s.encode(dict['encoding'])
-
-
- sb = []
- sb.append('timestamp: %s\n' % dict['timestamp'])
- if dict.get('encoding'):
- sb.append('encoding: %s\n' % dict['encoding'])
-
- if dict.get('args') is not None:
- sb.append('args: %s\n' % ', '.join(dict['args']))
-
- sb.append('\n')
- sb.append(s)
- s = ''.join(sb)
- if python3:
- if isinstance(s, str):
- if not dict.get('encoding'):
- pass
- s = s.encode('utf-8')
-
-
- cachepath = self._cachename(fullpath)
- if logger:
- logger.info('[tenjin.TextCacheStorage] store cache (file=%s)' % repr(cachepath))
-
- _write_binary_file(cachepath, s)
-
-
- def _save_data_of(self, template):
- dict = FileCacheStorage._save_data_of(self, template)
- dict['encoding'] = template.encoding
- return dict
-
-
-
- class GaeMemcacheCacheStorage(CacheStorage):
- lifetime = 0
-
- def __init__(self, lifetime = None, postfix = '.cache'):
- CacheStorage.__init__(self, postfix)
- if lifetime is not None:
- self.lifetime = lifetime
-
-
-
- def _load(self, fullpath):
- memcache = memcache
- import google.appengine.api
- key = self._cachename(fullpath)
- if logger:
- logger.info('[tenjin.GaeMemcacheCacheStorage] load cache (key=%s)' % repr(key))
-
- return memcache.get(key)
-
-
- def _store(self, fullpath, dict):
- if 'bytecode' in dict:
- dict.pop('bytecode')
-
- memcache = memcache
- import google.appengine.api
- key = self._cachename(fullpath)
- if logger:
- logger.info('[tenjin.GaeMemcacheCacheStorage] store cache (key=%s)' % repr(key))
-
- ret = memcache.set(key, dict, self.lifetime)
- if not ret:
- if logger:
- logger.info('[tenjin.GaeMemcacheCacheStorage: failed to store cache (key=%s)' % repr(key))
-
-
-
-
- def _delete(self, fullpath):
- memcache = memcache
- import google.appengine.api
- memcache.delete(self._cachename(fullpath))
-
-
-
- class Engine(object):
- prefix = ''
- postfix = ''
- layout = None
- templateclass = Template
- path = None
- cache = None
- preprocess = False
- _cache_storage_classes = {
- 'marshal': MarshalCacheStorage,
- 'pickle': PickleCacheStorage,
- 'text': TextCacheStorage }
-
- def __init__(self, prefix = None, postfix = None, layout = None, path = None, cache = True, preprocess = None, templateclass = None, **kwargs):
- if prefix:
- self.prefix = prefix
-
- if postfix:
- self.postfix = postfix
-
- if layout:
- self.layout = layout
-
- if templateclass:
- self.templateclass = templateclass
-
- if path is not None:
- self.path = path
-
- if preprocess is not None:
- self.preprocess = preprocess
-
- self.kwargs = kwargs
- self.encoding = kwargs.get('encoding')
- self._filepaths = { }
- self._set_cache_storage(cache)
-
-
- def _set_cache_storage(self, cache):
- if cache is True:
- self.cache = MarshalCacheStorage()
- elif cache is None:
- self.cache = MemoryCacheStorage()
- elif cache is False:
- self.cache = None
- elif isinstance(cache, CacheStorage):
- self.cache = cache
- elif self._cache_storage_classes.get(cache):
- self.cache = self._cache_storage_classes[cache]()
- else:
- raise ValueError('%s: invalid cache object.' % repr(cache))
- return cache is True
-
-
- def to_filename(self, template_name):
- if template_name[0] == ':':
- return self.prefix + template_name[1:] + self.postfix
- return template_name
-
-
- def _relative_and_absolute_path(self, template_name):
- pair = self._filepaths.get(template_name)
- if pair:
- return pair
- filename = self.to_filename(template_name)
- filepath = self._find_file(filename)
- if not filepath:
- raise IOError('%s: filename not found (path=%s).' % (filename, repr(self.path)))
- filepath
- fullpath = os.path.abspath(filepath)
- return pair
-
-
- def _find_file(self, filename):
- if self.path:
- for dirname in self.path:
- filepath = os.path.join(dirname, filename)
- if os.path.isfile(filepath):
- return filepath
-
- elif os.path.isfile(filename):
- return filename
-
-
- def _create_template(self, filepath, _context, _globals):
- if filepath and self.preprocess:
- s = self._preprocess(filepath, _context, _globals)
- template = self.templateclass(None, **self.kwargs)
- template.convert(s, filepath)
- else:
- template = self.templateclass(filepath, **self.kwargs)
- return template
-
-
- def _preprocess(self, filepath, _context, _globals):
- if '_engine' not in _context:
- self.hook_context(_context)
-
- preprocessor = Preprocessor(filepath)
- return preprocessor.render(_context, globals = _globals)
-
-
- def get_template(self, template_name, _context = None, _globals = None):
- (filename, fullpath) = self._relative_and_absolute_path(template_name)
- cache = self.cache
- if not cache or cache.get(fullpath, self.templateclass):
- pass
- template = None
- mtime = None
- if template:
- mtime = os.path.getmtime(filename)
- if template.timestamp != mtime:
- template = None
- if logger:
- logger.info('[tenjin.Engine] cache is old (filename=%s, template=%s)' % (repr(filename), repr(template)))
-
-
-
- if not template:
- if not mtime:
- mtime = os.path.getmtime(filename)
-
- if self.preprocess:
- if _context is None:
- _context = { }
-
- if _globals is None:
- _globals = sys._getframe(1).f_globals
-
-
- template = self._create_template(filename, _context, _globals)
- template.timestamp = mtime
- if cache:
- if not template.bytecode:
- template.compile()
-
- cache.set(fullpath, template)
-
-
- return template
-
-
- def include(self, template_name, append_to_buf = True):
- frame = sys._getframe(1)
- locals = frame.f_locals
- globals = frame.f_globals
- context = locals['_context']
- template = self.get_template(template_name, context, globals)
- if append_to_buf:
- _buf = locals['_buf']
- else:
- _buf = None
- return template.render(context, globals, _buf = _buf)
-
-
- def render(self, template_name, context = None, globals = None, layout = True):
- if context is None:
- context = { }
-
- if globals is None:
- globals = sys._getframe(1).f_globals
-
- self.hook_context(context)
- while True:
- template = self.get_template(template_name, context, globals)
- content = template.render(context, globals)
- layout = context.pop('_layout', layout)
- if layout is True or layout is None:
- layout = self.layout
-
- if not layout:
- break
-
- template_name = layout
- layout = False
- context['_content'] = content
- context.pop('_content', None)
- return content
-
-
- def hook_context(self, context):
- context['_engine'] = self
- context['include'] = self.include
-
-
-