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

utils.py (11554B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\utils.py
      2 import re
      3 import os
      4 from time import time
      5 from datetime import datetime, timedelta
      6 from werkzeug._internal import _decode_unicode, _iter_modules, _ExtendedCookie, _ExtendedMorsel, _DictAccessorProperty, _dump_date, _parse_signature, _missing
      7 _format_re = re.compile('\\$(?:(%s)|\\{(%s)\\})' % ('[a-zA-Z_][a-zA-Z0-9_]*', '[a-zA-Z_][a-zA-Z0-9_]*'))
      8 _entity_re = re.compile('&([^;]+);')
      9 _filename_ascii_strip_re = re.compile('[^A-Za-z0-9_.-]')
     10 _windows_device_files = ('CON', 'AUX', 'COM1', 'COM2', 'COM3', 'COM4', 'LPT1', 'LPT2', 'LPT3', 'PRN', 'NUL')
     11 
     12 class cached_property(object):
     13 
     14     def __init__(self, func, name = None, doc = None, writeable = False):
     15         if writeable:
     16             from warnings import warn
     17             warn(DeprecationWarning('the writeable argument to the cached property is a noop since 0.6 because the property is writeable by default for performance reasons'))
     18         self.__name__ = name or func.__name__
     19         self.__module__ = func.__module__
     20         self.__doc__ = doc or func.__doc__
     21         self.func = func
     22 
     23     def __get__(self, obj, type = None):
     24         if obj is None:
     25             return self
     26         value = obj.__dict__.get(self.__name__, _missing)
     27         if value is _missing:
     28             value = self.func(obj)
     29             obj.__dict__[self.__name__] = value
     30         return value
     31 
     32 
     33 class environ_property(_DictAccessorProperty):
     34     read_only = True
     35 
     36     def lookup(self, obj):
     37         return obj.environ
     38 
     39 
     40 class header_property(_DictAccessorProperty):
     41 
     42     def lookup(self, obj):
     43         return obj.headers
     44 
     45 
     46 class HTMLBuilder(object):
     47     from htmlentitydefs import name2codepoint
     48     _entity_re = re.compile('&([^;]+);')
     49     _entities = name2codepoint.copy()
     50     _entities['apos'] = 39
     51     _empty_elements = set(['area',
     52      'base',
     53      'basefont',
     54      'br',
     55      'col',
     56      'frame',
     57      'hr',
     58      'img',
     59      'input',
     60      'isindex',
     61      'link',
     62      'meta',
     63      'param'])
     64     _boolean_attributes = set(['selected',
     65      'checked',
     66      'compact',
     67      'declare',
     68      'defer',
     69      'disabled',
     70      'ismap',
     71      'multiple',
     72      'nohref',
     73      'noresize',
     74      'noshade',
     75      'nowrap'])
     76     _plaintext_elements = set(['textarea'])
     77     _c_like_cdata = set(['script', 'style'])
     78     del name2codepoint
     79 
     80     def __init__(self, dialect):
     81         self._dialect = dialect
     82 
     83     def __call__(self, s):
     84         return escape(s)
     85 
     86     def __getattr__(self, tag):
     87         if tag[:2] == '__':
     88             raise AttributeError(tag)
     89 
     90         def proxy(*children, **arguments):
     91             buffer = ['<' + tag]
     92             write = buffer.append
     93             for key, value in arguments.iteritems():
     94                 if value is None:
     95                     continue
     96                 if key.endswith('_'):
     97                     key = key[:-1]
     98                 if key in self._boolean_attributes:
     99                     if not value:
    100                         continue
    101                     value = self._dialect == 'xhtml' and '="%s"' % key or ''
    102                 else:
    103                     value = '="%s"' % escape(value, True)
    104                 write(' ' + key + value)
    105 
    106             if not children and tag in self._empty_elements:
    107                 write(self._dialect == 'xhtml' and ' />' or '>')
    108                 return ''.join(buffer)
    109             write('>')
    110             children_as_string = ''.join((unicode(x) for x in children if x is not None))
    111             if children_as_string:
    112                 if tag in self._plaintext_elements:
    113                     children_as_string = escape(children_as_string)
    114                 elif tag in self._c_like_cdata and self._dialect == 'xhtml':
    115                     children_as_string = '/*<![CDATA[*/%s/*]]>*/' % children_as_string
    116             buffer.extend((children_as_string, '</%s>' % tag))
    117             return ''.join(buffer)
    118 
    119         return proxy
    120 
    121     def __repr__(self):
    122         return '<%s for %r>' % (self.__class__.__name__, self._dialect)
    123 
    124 
    125 html = HTMLBuilder('html')
    126 xhtml = HTMLBuilder('xhtml')
    127 
    128 def get_content_type(mimetype, charset):
    129     if mimetype.startswith('text/') or mimetype == 'application/xml' or mimetype.startswith('application/') and mimetype.endswith('+xml'):
    130         mimetype += '; charset=' + charset
    131     return mimetype
    132 
    133 
    134 def format_string(string, context):
    135 
    136     def lookup_arg(match):
    137         x = context[match.group(1) or match.group(2)]
    138         if not isinstance(x, basestring):
    139             x = type(string)(x)
    140         return x
    141 
    142     return _format_re.sub(lookup_arg, string)
    143 
    144 
    145 def secure_filename(filename):
    146     if isinstance(filename, unicode):
    147         from unicodedata import normalize
    148         filename = normalize('NFKD', filename).encode('ascii', 'ignore')
    149     for sep in (os.path.sep, os.path.altsep):
    150         if sep:
    151             filename = filename.replace(sep, ' ')
    152 
    153     filename = str(_filename_ascii_strip_re.sub('', '_'.join(filename.split()))).strip('._')
    154     if os.name == 'nt' and filename and filename.split('.')[0].upper() in _windows_device_files:
    155         filename = '_' + filename
    156     return filename
    157 
    158 
    159 def escape(s, quote = False):
    160     if s is None:
    161         return ''
    162     if hasattr(s, '__html__'):
    163         return s.__html__()
    164     if not isinstance(s, basestring):
    165         s = unicode(s)
    166     s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
    167     if quote:
    168         s = s.replace('"', '&quot;')
    169     return s
    170 
    171 
    172 def unescape(s):
    173 
    174     def handle_match(m):
    175         name = m.group(1)
    176         if name in HTMLBuilder._entities:
    177             return unichr(HTMLBuilder._entities[name])
    178         try:
    179             if name[:2] in ('#x', '#X'):
    180                 return unichr(int(name[2:], 16))
    181             if name.startswith('#'):
    182                 return unichr(int(name[1:]))
    183         except ValueError:
    184             pass
    185 
    186         return u''
    187 
    188     return _entity_re.sub(handle_match, s)
    189 
    190 
    191 def cookie_date(expires = None):
    192     return _dump_date(expires, '-')
    193 
    194 
    195 def parse_cookie(header, charset = 'utf-8', errors = 'ignore', cls = None):
    196     if isinstance(header, dict):
    197         header = header.get('HTTP_COOKIE', '')
    198     if cls is None:
    199         cls = TypeConversionDict
    200     cookie = _ExtendedCookie()
    201     cookie.load(header)
    202     result = {}
    203     for key, value in cookie.iteritems():
    204         if value.value is not None:
    205             result[key] = _decode_unicode(unquote_header_value(value.value), charset, errors)
    206 
    207     return cls(result)
    208 
    209 
    210 def dump_cookie(key, value = '', max_age = None, expires = None, path = '/', domain = None, secure = None, httponly = False, charset = 'utf-8', sync_expires = True):
    211     try:
    212         key = str(key)
    213     except UnicodeError:
    214         raise TypeError('invalid key %r' % key)
    215 
    216     if isinstance(value, unicode):
    217         value = value.encode(charset)
    218     value = quote_header_value(value)
    219     morsel = _ExtendedMorsel(key, value)
    220     if isinstance(max_age, timedelta):
    221         max_age = max_age.days * 60 * 60 * 24 + max_age.seconds
    222     if expires is not None:
    223         if not isinstance(expires, basestring):
    224             expires = cookie_date(expires)
    225         morsel['expires'] = expires
    226     elif max_age is not None and sync_expires:
    227         morsel['expires'] = cookie_date(time() + max_age)
    228     for k, v in (('path', path),
    229      ('domain', domain),
    230      ('secure', secure),
    231      ('max-age', max_age),
    232      ('httponly', httponly)):
    233         if v is not None and v is not False:
    234             morsel[k] = str(v)
    235 
    236     return morsel.output(header='').lstrip()
    237 
    238 
    239 def http_date(timestamp = None):
    240     return _dump_date(timestamp, ' ')
    241 
    242 
    243 def redirect(location, code = 302):
    244     from werkzeug.wrappers import BaseResponse
    245     display_location = location
    246     if isinstance(location, unicode):
    247         from werkzeug.urls import iri_to_uri
    248         location = iri_to_uri(location)
    249     response = BaseResponse('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="%s">%s</a>.  If not click the link.' % (location, display_location), code, mimetype='text/html')
    250     response.headers['Location'] = location
    251     return response
    252 
    253 
    254 def append_slash_redirect(environ, code = 301):
    255     new_path = environ['PATH_INFO'].strip('/') + '/'
    256     query_string = environ.get('QUERY_STRING')
    257     if query_string:
    258         new_path += '?' + query_string
    259     return redirect(new_path, code)
    260 
    261 
    262 def import_string(import_name, silent = False):
    263     if isinstance(import_name, unicode):
    264         import_name = str(import_name)
    265     try:
    266         if ':' in import_name:
    267             module, obj = import_name.split(':', 1)
    268         elif '.' in import_name:
    269             module, obj = import_name.rsplit('.', 1)
    270         else:
    271             return __import__(import_name)
    272         if isinstance(obj, unicode):
    273             obj = obj.encode('utf-8')
    274         return getattr(__import__(module, None, None, [obj]), obj)
    275     except (ImportError, AttributeError):
    276         if not silent:
    277             raise
    278 
    279 
    280 def find_modules(import_path, include_packages = False, recursive = False):
    281     module = import_string(import_path)
    282     path = getattr(module, '__path__', None)
    283     if path is None:
    284         raise ValueError('%r is not a package' % import_path)
    285     basename = module.__name__ + '.'
    286     for modname, ispkg in _iter_modules(path):
    287         modname = basename + modname
    288         if ispkg:
    289             if include_packages:
    290                 yield modname
    291             if recursive:
    292                 for item in find_modules(modname, include_packages, True):
    293                     yield item
    294 
    295         else:
    296             yield modname
    297 
    298 
    299 def validate_arguments(func, args, kwargs, drop_extra = True):
    300     parser = _parse_signature(func)
    301     args, kwargs, missing, extra, extra_positional = parser(args, kwargs)[:5]
    302     if missing:
    303         raise ArgumentValidationError(tuple(missing))
    304     elif (extra or extra_positional) and not drop_extra:
    305         raise ArgumentValidationError(None, extra, extra_positional)
    306     return (tuple(args), kwargs)
    307 
    308 
    309 def bind_arguments(func, args, kwargs):
    310     args, kwargs, missing, extra, extra_positional, arg_spec, vararg_var, kwarg_var = _parse_signature(func)(args, kwargs)
    311     values = {}
    312     for (name, has_default, default), value in zip(arg_spec, args):
    313         values[name] = value
    314 
    315     if vararg_var is not None:
    316         values[vararg_var] = tuple(extra_positional)
    317     elif extra_positional:
    318         raise TypeError('too many positional arguments')
    319     if kwarg_var is not None:
    320         multikw = set(extra) & set([ x[0] for x in arg_spec ])
    321         if multikw:
    322             raise TypeError('got multiple values for keyword argument ' + repr(iter(multikw).next()))
    323         values[kwarg_var] = extra
    324     elif extra:
    325         raise TypeError('got unexpected keyword argument ' + repr(iter(extra).next()))
    326     return values
    327 
    328 
    329 class ArgumentValidationError(ValueError):
    330 
    331     def __init__(self, missing = None, extra = None, extra_positional = None):
    332         self.missing = set(missing or ())
    333         self.extra = extra or {}
    334         self.extra_positional = extra_positional or []
    335         ValueError.__init__(self, 'function arguments invalid.  (%d missing, %d additional)' % (len(self.missing), len(self.extra) + len(self.extra_positional)))
    336 
    337 
    338 from werkzeug.http import quote_header_value, unquote_header_value
    339 from werkzeug.exceptions import BadRequest
    340 from werkzeug.datastructures import TypeConversionDict
    341 from werkzeug.datastructures import MultiDict, CombinedMultiDict, Headers, EnvironHeaders