diff options
Diffstat (limited to 'module/lib/jinja2/bccache.py')
| -rw-r--r-- | module/lib/jinja2/bccache.py | 280 | 
1 files changed, 0 insertions, 280 deletions
diff --git a/module/lib/jinja2/bccache.py b/module/lib/jinja2/bccache.py deleted file mode 100644 index 1e2236c3a..000000000 --- a/module/lib/jinja2/bccache.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -""" -    jinja2.bccache -    ~~~~~~~~~~~~~~ - -    This module implements the bytecode cache system Jinja is optionally -    using.  This is useful if you have very complex template situations and -    the compiliation of all those templates slow down your application too -    much. - -    Situations where this is useful are often forking web applications that -    are initialized on the first request. - -    :copyright: (c) 2010 by the Jinja Team. -    :license: BSD. -""" -from os import path, listdir -import marshal -import tempfile -import cPickle as pickle -import fnmatch -from cStringIO import StringIO -try: -    from hashlib import sha1 -except ImportError: -    from sha import new as sha1 -from jinja2.utils import open_if_exists - - -bc_version = 1 -bc_magic = 'j2'.encode('ascii') + pickle.dumps(bc_version, 2) - - -class Bucket(object): -    """Buckets are used to store the bytecode for one template.  It's created -    and initialized by the bytecode cache and passed to the loading functions. - -    The buckets get an internal checksum from the cache assigned and use this -    to automatically reject outdated cache material.  Individual bytecode -    cache subclasses don't have to care about cache invalidation. -    """ - -    def __init__(self, environment, key, checksum): -        self.environment = environment -        self.key = key -        self.checksum = checksum -        self.reset() - -    def reset(self): -        """Resets the bucket (unloads the bytecode).""" -        self.code = None - -    def load_bytecode(self, f): -        """Loads bytecode from a file or file like object.""" -        # make sure the magic header is correct -        magic = f.read(len(bc_magic)) -        if magic != bc_magic: -            self.reset() -            return -        # the source code of the file changed, we need to reload -        checksum = pickle.load(f) -        if self.checksum != checksum: -            self.reset() -            return -        # now load the code.  Because marshal is not able to load -        # from arbitrary streams we have to work around that -        if isinstance(f, file): -            self.code = marshal.load(f) -        else: -            self.code = marshal.loads(f.read()) - -    def write_bytecode(self, f): -        """Dump the bytecode into the file or file like object passed.""" -        if self.code is None: -            raise TypeError('can\'t write empty bucket') -        f.write(bc_magic) -        pickle.dump(self.checksum, f, 2) -        if isinstance(f, file): -            marshal.dump(self.code, f) -        else: -            f.write(marshal.dumps(self.code)) - -    def bytecode_from_string(self, string): -        """Load bytecode from a string.""" -        self.load_bytecode(StringIO(string)) - -    def bytecode_to_string(self): -        """Return the bytecode as string.""" -        out = StringIO() -        self.write_bytecode(out) -        return out.getvalue() - - -class BytecodeCache(object): -    """To implement your own bytecode cache you have to subclass this class -    and override :meth:`load_bytecode` and :meth:`dump_bytecode`.  Both of -    these methods are passed a :class:`~jinja2.bccache.Bucket`. - -    A very basic bytecode cache that saves the bytecode on the file system:: - -        from os import path - -        class MyCache(BytecodeCache): - -            def __init__(self, directory): -                self.directory = directory - -            def load_bytecode(self, bucket): -                filename = path.join(self.directory, bucket.key) -                if path.exists(filename): -                    with open(filename, 'rb') as f: -                        bucket.load_bytecode(f) - -            def dump_bytecode(self, bucket): -                filename = path.join(self.directory, bucket.key) -                with open(filename, 'wb') as f: -                    bucket.write_bytecode(f) - -    A more advanced version of a filesystem based bytecode cache is part of -    Jinja2. -    """ - -    def load_bytecode(self, bucket): -        """Subclasses have to override this method to load bytecode into a -        bucket.  If they are not able to find code in the cache for the -        bucket, it must not do anything. -        """ -        raise NotImplementedError() - -    def dump_bytecode(self, bucket): -        """Subclasses have to override this method to write the bytecode -        from a bucket back to the cache.  If it unable to do so it must not -        fail silently but raise an exception. -        """ -        raise NotImplementedError() - -    def clear(self): -        """Clears the cache.  This method is not used by Jinja2 but should be -        implemented to allow applications to clear the bytecode cache used -        by a particular environment. -        """ - -    def get_cache_key(self, name, filename=None): -        """Returns the unique hash key for this template name.""" -        hash = sha1(name.encode('utf-8')) -        if filename is not None: -            if isinstance(filename, unicode): -                filename = filename.encode('utf-8') -            hash.update('|' + filename) -        return hash.hexdigest() - -    def get_source_checksum(self, source): -        """Returns a checksum for the source.""" -        return sha1(source.encode('utf-8')).hexdigest() - -    def get_bucket(self, environment, name, filename, source): -        """Return a cache bucket for the given template.  All arguments are -        mandatory but filename may be `None`. -        """ -        key = self.get_cache_key(name, filename) -        checksum = self.get_source_checksum(source) -        bucket = Bucket(environment, key, checksum) -        self.load_bytecode(bucket) -        return bucket - -    def set_bucket(self, bucket): -        """Put the bucket into the cache.""" -        self.dump_bytecode(bucket) - - -class FileSystemBytecodeCache(BytecodeCache): -    """A bytecode cache that stores bytecode on the filesystem.  It accepts -    two arguments: The directory where the cache items are stored and a -    pattern string that is used to build the filename. - -    If no directory is specified the system temporary items folder is used. - -    The pattern can be used to have multiple separate caches operate on the -    same directory.  The default pattern is ``'__jinja2_%s.cache'``.  ``%s`` -    is replaced with the cache key. - -    >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') - -    This bytecode cache supports clearing of the cache using the clear method. -    """ - -    def __init__(self, directory=None, pattern='__jinja2_%s.cache'): -        if directory is None: -            directory = tempfile.gettempdir() -        self.directory = directory -        self.pattern = pattern - -    def _get_cache_filename(self, bucket): -        return path.join(self.directory, self.pattern % bucket.key) - -    def load_bytecode(self, bucket): -        f = open_if_exists(self._get_cache_filename(bucket), 'rb') -        if f is not None: -            try: -                bucket.load_bytecode(f) -            finally: -                f.close() - -    def dump_bytecode(self, bucket): -        f = open(self._get_cache_filename(bucket), 'wb') -        try: -            bucket.write_bytecode(f) -        finally: -            f.close() - -    def clear(self): -        # imported lazily here because google app-engine doesn't support -        # write access on the file system and the function does not exist -        # normally. -        from os import remove -        files = fnmatch.filter(listdir(self.directory), self.pattern % '*') -        for filename in files: -            try: -                remove(path.join(self.directory, filename)) -            except OSError: -                pass - - -class MemcachedBytecodeCache(BytecodeCache): -    """This class implements a bytecode cache that uses a memcache cache for -    storing the information.  It does not enforce a specific memcache library -    (tummy's memcache or cmemcache) but will accept any class that provides -    the minimal interface required. - -    Libraries compatible with this class: - -    -   `werkzeug <http://werkzeug.pocoo.org/>`_.contrib.cache -    -   `python-memcached <http://www.tummy.com/Community/software/python-memcached/>`_ -    -   `cmemcache <http://gijsbert.org/cmemcache/>`_ - -    (Unfortunately the django cache interface is not compatible because it -    does not support storing binary data, only unicode.  You can however pass -    the underlying cache client to the bytecode cache which is available -    as `django.core.cache.cache._client`.) - -    The minimal interface for the client passed to the constructor is this: - -    .. class:: MinimalClientInterface - -        .. method:: set(key, value[, timeout]) - -            Stores the bytecode in the cache.  `value` is a string and -            `timeout` the timeout of the key.  If timeout is not provided -            a default timeout or no timeout should be assumed, if it's -            provided it's an integer with the number of seconds the cache -            item should exist. - -        .. method:: get(key) - -            Returns the value for the cache key.  If the item does not -            exist in the cache the return value must be `None`. - -    The other arguments to the constructor are the prefix for all keys that -    is added before the actual cache key and the timeout for the bytecode in -    the cache system.  We recommend a high (or no) timeout. - -    This bytecode cache does not support clearing of used items in the cache. -    The clear method is a no-operation function. -    """ - -    def __init__(self, client, prefix='jinja2/bytecode/', timeout=None): -        self.client = client -        self.prefix = prefix -        self.timeout = timeout - -    def load_bytecode(self, bucket): -        code = self.client.get(self.prefix + bucket.key) -        if code is not None: -            bucket.bytecode_from_string(code) - -    def dump_bytecode(self, bucket): -        args = (self.prefix + bucket.key, bucket.bytecode_to_string()) -        if self.timeout is not None: -            args += (self.timeout,) -        self.client.set(*args)  | 
