NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

bccache.py (4586B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\bccache.py
      2 from os import path, listdir
      3 import sys
      4 import marshal
      5 import tempfile
      6 import cPickle as pickle
      7 import fnmatch
      8 try:
      9     from hashlib import sha1
     10 except ImportError:
     11     from sha import new as sha1
     12 
     13 from jinja2.utils import open_if_exists
     14 if sys.version_info > (3, 0):
     15     from io import BytesIO
     16     marshal_dump = marshal.dump
     17     marshal_load = marshal.load
     18 else:
     19     from cStringIO import StringIO as BytesIO
     20 
     21     def marshal_dump(code, f):
     22         if isinstance(f, file):
     23             marshal.dump(code, f)
     24         else:
     25             f.write(marshal.dumps(code))
     26 
     27 
     28     def marshal_load(f):
     29         if isinstance(f, file):
     30             return marshal.load(f)
     31         return marshal.loads(f.read())
     32 
     33 
     34 bc_version = 2
     35 bc_magic = 'j2'.encode('ascii') + pickle.dumps(bc_version, 2) + pickle.dumps(sys.version_info[0] << 24 | sys.version_info[1])
     36 
     37 class Bucket(object):
     38 
     39     def __init__(self, environment, key, checksum):
     40         self.environment = environment
     41         self.key = key
     42         self.checksum = checksum
     43         self.reset()
     44 
     45     def reset(self):
     46         self.code = None
     47 
     48     def load_bytecode(self, f):
     49         magic = f.read(len(bc_magic))
     50         if magic != bc_magic:
     51             self.reset()
     52             return
     53         checksum = pickle.load(f)
     54         if self.checksum != checksum:
     55             self.reset()
     56             return
     57         self.code = marshal_load(f)
     58 
     59     def write_bytecode(self, f):
     60         if self.code is None:
     61             raise TypeError("can't write empty bucket")
     62         f.write(bc_magic)
     63         pickle.dump(self.checksum, f, 2)
     64         marshal_dump(self.code, f)
     65 
     66     def bytecode_from_string(self, string):
     67         self.load_bytecode(BytesIO(string))
     68 
     69     def bytecode_to_string(self):
     70         out = BytesIO()
     71         self.write_bytecode(out)
     72         return out.getvalue()
     73 
     74 
     75 class BytecodeCache(object):
     76 
     77     def load_bytecode(self, bucket):
     78         raise NotImplementedError()
     79 
     80     def dump_bytecode(self, bucket):
     81         raise NotImplementedError()
     82 
     83     def clear(self):
     84         pass
     85 
     86     def get_cache_key(self, name, filename = None):
     87         hash = sha1(name.encode('utf-8'))
     88         if filename is not None:
     89             filename = '|' + filename
     90             if isinstance(filename, unicode):
     91                 filename = filename.encode('utf-8')
     92             hash.update(filename)
     93         return hash.hexdigest()
     94 
     95     def get_source_checksum(self, source):
     96         return sha1(source.encode('utf-8')).hexdigest()
     97 
     98     def get_bucket(self, environment, name, filename, source):
     99         key = self.get_cache_key(name, filename)
    100         checksum = self.get_source_checksum(source)
    101         bucket = Bucket(environment, key, checksum)
    102         self.load_bytecode(bucket)
    103         return bucket
    104 
    105     def set_bucket(self, bucket):
    106         self.dump_bytecode(bucket)
    107 
    108 
    109 class FileSystemBytecodeCache(BytecodeCache):
    110 
    111     def __init__(self, directory = None, pattern = '__jinja2_%s.cache'):
    112         if directory is None:
    113             directory = tempfile.gettempdir()
    114         self.directory = directory
    115         self.pattern = pattern
    116 
    117     def _get_cache_filename(self, bucket):
    118         return path.join(self.directory, self.pattern % bucket.key)
    119 
    120     def load_bytecode(self, bucket):
    121         f = open_if_exists(self._get_cache_filename(bucket), 'rb')
    122         if f is not None:
    123             try:
    124                 bucket.load_bytecode(f)
    125             finally:
    126                 f.close()
    127 
    128     def dump_bytecode(self, bucket):
    129         f = open(self._get_cache_filename(bucket), 'wb')
    130         try:
    131             bucket.write_bytecode(f)
    132         finally:
    133             f.close()
    134 
    135     def clear(self):
    136         from os import remove
    137         files = fnmatch.filter(listdir(self.directory), self.pattern % '*')
    138         for filename in files:
    139             try:
    140                 remove(path.join(self.directory, filename))
    141             except OSError:
    142                 pass
    143 
    144 
    145 class MemcachedBytecodeCache(BytecodeCache):
    146 
    147     def __init__(self, client, prefix = 'jinja2/bytecode/', timeout = None):
    148         self.client = client
    149         self.prefix = prefix
    150         self.timeout = timeout
    151 
    152     def load_bytecode(self, bucket):
    153         code = self.client.get(self.prefix + bucket.key)
    154         if code is not None:
    155             bucket.bytecode_from_string(code)
    156 
    157     def dump_bytecode(self, bucket):
    158         args = (self.prefix + bucket.key, bucket.bytecode_to_string())
    159         if self.timeout is not None:
    160             args += (self.timeout,)
    161         self.client.set(*args)