utils.py (11639B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\utils.py 2 import re 3 import sys 4 import errno 5 try: 6 from urllib.parse import quote_from_bytes as url_quote 7 except ImportError: 8 from urllib import quote as url_quote 9 10 try: 11 from thread import allocate_lock 12 except ImportError: 13 from dummy_thread import allocate_lock 14 15 from collections import deque 16 from itertools import imap 17 _word_split_re = re.compile('(\\s+)') 18 _punctuation_re = re.compile('^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % ('|'.join(imap(re.escape, ('(', '<', '<'))), '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '>'))))) 19 _simple_email_re = re.compile('^\\S+@[a-zA-Z0-9._-]+\\.[a-zA-Z0-9._-]+$') 20 _striptags_re = re.compile('(<!--.*?-->|<[^>]*>)') 21 _entity_re = re.compile('&([^;]+);') 22 _letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 23 _digits = '0123456789' 24 missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})() 25 internal_code = set() 26 _concat = u''.join 27 try: 28 29 def _test_gen_bug(): 30 raise TypeError(_test_gen_bug) 31 yield 32 33 34 _concat(_test_gen_bug()) 35 except TypeError as _error: 36 if not _error.args or _error.args[0] is not _test_gen_bug: 37 38 def concat(gen): 39 try: 40 return _concat(list(gen)) 41 except Exception: 42 exc_type, exc_value, tb = sys.exc_info() 43 raise exc_type, exc_value, tb.tb_next 44 45 46 else: 47 concat = _concat 48 del _test_gen_bug 49 del _error 50 51 try: 52 next = next 53 except NameError: 54 55 def next(x): 56 return x.next() 57 58 59 if sys.version_info < (3, 0): 60 61 def _encode_filename(filename): 62 if isinstance(filename, unicode): 63 return filename.encode('utf-8') 64 return filename 65 66 67 else: 68 69 def _encode_filename(filename): 70 return filename 71 72 73 from keyword import iskeyword as is_python_keyword 74 75 class _C(object): 76 77 def method(self): 78 pass 79 80 81 def _func(): 82 yield 83 84 85 FunctionType = type(_func) 86 GeneratorType = type(_func()) 87 MethodType = type(_C.method) 88 CodeType = type(_C.method.func_code) 89 try: 90 raise TypeError() 91 except TypeError: 92 _tb = sys.exc_info()[2] 93 TracebackType = type(_tb) 94 FrameType = type(_tb.tb_frame) 95 96 del _C 97 del _tb 98 del _func 99 100 def contextfunction(f): 101 f.contextfunction = True 102 return f 103 104 105 def evalcontextfunction(f): 106 f.evalcontextfunction = True 107 return f 108 109 110 def environmentfunction(f): 111 f.environmentfunction = True 112 return f 113 114 115 def internalcode(f): 116 internal_code.add(f.func_code) 117 return f 118 119 120 def is_undefined(obj): 121 from jinja2.runtime import Undefined 122 return isinstance(obj, Undefined) 123 124 125 def consume(iterable): 126 for event in iterable: 127 pass 128 129 130 def clear_caches(): 131 from jinja2.environment import _spontaneous_environments 132 from jinja2.lexer import _lexer_cache 133 _spontaneous_environments.clear() 134 _lexer_cache.clear() 135 136 137 def import_string(import_name, silent = False): 138 try: 139 if ':' in import_name: 140 module, obj = import_name.split(':', 1) 141 elif '.' in import_name: 142 items = import_name.split('.') 143 module = '.'.join(items[:-1]) 144 obj = items[-1] 145 else: 146 return __import__(import_name) 147 return getattr(__import__(module, None, None, [obj]), obj) 148 except (ImportError, AttributeError): 149 if not silent: 150 raise 151 152 153 def open_if_exists(filename, mode = 'rb'): 154 try: 155 return open(filename, mode) 156 except IOError as e: 157 if e.errno not in (errno.ENOENT, errno.EISDIR): 158 raise 159 160 161 def object_type_repr(obj): 162 if obj is None: 163 return 'None' 164 if obj is Ellipsis: 165 return 'Ellipsis' 166 if obj.__class__.__module__ in ('__builtin__', 'builtins'): 167 name = obj.__class__.__name__ 168 else: 169 name = obj.__class__.__module__ + '.' + obj.__class__.__name__ 170 return '%s object' % name 171 172 173 def pformat(obj, verbose = False): 174 try: 175 from pretty import pretty 176 return pretty(obj, verbose=verbose) 177 except ImportError: 178 from pprint import pformat 179 return pformat(obj) 180 181 182 def urlize(text, trim_url_limit = None, nofollow = False): 183 trim_url = lambda x, limit = trim_url_limit: limit is not None and x[:limit] + (len(x) >= limit and '...' or '') or x 184 words = _word_split_re.split(unicode(escape(text))) 185 nofollow_attr = nofollow and ' rel="nofollow"' or '' 186 for i, word in enumerate(words): 187 match = _punctuation_re.match(word) 188 if match: 189 lead, middle, trail = match.groups() 190 if middle.startswith('www.') or '@' not in middle and not middle.startswith('http://') and len(middle) > 0 and middle[0] in _letters + _digits and (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com')): 191 middle = '<a href="http://%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle)) 192 if middle.startswith('http://') or middle.startswith('https://'): 193 middle = '<a href="%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle)) 194 if '@' in middle and not middle.startswith('www.') and ':' not in middle and _simple_email_re.match(middle): 195 middle = '<a href="mailto:%s">%s</a>' % (middle, middle) 196 if lead + middle + trail != word: 197 words[i] = lead + middle + trail 198 199 return u''.join(words) 200 201 202 def generate_lorem_ipsum(n = 5, html = True, min = 20, max = 100): 203 from jinja2.constants import LOREM_IPSUM_WORDS 204 from random import choice, randrange 205 words = LOREM_IPSUM_WORDS.split() 206 result = [] 207 for _ in xrange(n): 208 next_capitalized = True 209 last_comma = last_fullstop = 0 210 word = None 211 last = None 212 p = [] 213 for idx, _ in enumerate(xrange(randrange(min, max))): 214 while True: 215 word = choice(words) 216 if word != last: 217 last = word 218 break 219 220 if next_capitalized: 221 word = word.capitalize() 222 next_capitalized = False 223 if idx - randrange(3, 8) > last_comma: 224 last_comma = idx 225 last_fullstop += 2 226 word += ',' 227 if idx - randrange(10, 20) > last_fullstop: 228 last_comma = last_fullstop = idx 229 word += '.' 230 next_capitalized = True 231 p.append(word) 232 233 p = u' '.join(p) 234 if p.endswith(','): 235 p = p[:-1] + '.' 236 elif not p.endswith('.'): 237 p += '.' 238 result.append(p) 239 240 if not html: 241 return u'\n\n'.join(result) 242 return Markup(u'\n'.join((u'<p>%s</p>' % escape(x) for x in result))) 243 244 245 def unicode_urlencode(obj, charset = 'utf-8'): 246 if not isinstance(obj, basestring): 247 obj = unicode(obj) 248 if isinstance(obj, unicode): 249 obj = obj.encode(charset) 250 return unicode(url_quote(obj)) 251 252 253 class LRUCache(object): 254 255 def __init__(self, capacity): 256 self.capacity = capacity 257 self._mapping = {} 258 self._queue = deque() 259 self._postinit() 260 261 def _postinit(self): 262 self._popleft = self._queue.popleft 263 self._pop = self._queue.pop 264 if hasattr(self._queue, 'remove'): 265 self._remove = self._queue.remove 266 self._wlock = allocate_lock() 267 self._append = self._queue.append 268 269 def _remove(self, obj): 270 for idx, item in enumerate(self._queue): 271 if item == obj: 272 del self._queue[idx] 273 break 274 275 def __getstate__(self): 276 return {'capacity': self.capacity, 277 '_mapping': self._mapping, 278 '_queue': self._queue} 279 280 def __setstate__(self, d): 281 self.__dict__.update(d) 282 self._postinit() 283 284 def __getnewargs__(self): 285 return (self.capacity,) 286 287 def copy(self): 288 rv = self.__class__(self.capacity) 289 rv._mapping.update(self._mapping) 290 rv._queue = deque(self._queue) 291 return rv 292 293 def get(self, key, default = None): 294 try: 295 return self[key] 296 except KeyError: 297 return default 298 299 def setdefault(self, key, default = None): 300 try: 301 return self[key] 302 except KeyError: 303 self[key] = default 304 return default 305 306 def clear(self): 307 self._wlock.acquire() 308 try: 309 self._mapping.clear() 310 self._queue.clear() 311 finally: 312 self._wlock.release() 313 314 def __contains__(self, key): 315 return key in self._mapping 316 317 def __len__(self): 318 return len(self._mapping) 319 320 def __repr__(self): 321 return '<%s %r>' % (self.__class__.__name__, self._mapping) 322 323 def __getitem__(self, key): 324 rv = self._mapping[key] 325 if self._queue[-1] != key: 326 try: 327 self._remove(key) 328 except ValueError: 329 pass 330 331 self._append(key) 332 return rv 333 334 def __setitem__(self, key, value): 335 self._wlock.acquire() 336 try: 337 if key in self._mapping: 338 try: 339 self._remove(key) 340 except ValueError: 341 pass 342 343 elif len(self._mapping) == self.capacity: 344 del self._mapping[self._popleft()] 345 self._append(key) 346 self._mapping[key] = value 347 finally: 348 self._wlock.release() 349 350 def __delitem__(self, key): 351 self._wlock.acquire() 352 try: 353 del self._mapping[key] 354 try: 355 self._remove(key) 356 except ValueError: 357 pass 358 359 finally: 360 self._wlock.release() 361 362 def items(self): 363 result = [ (key, self._mapping[key]) for key in list(self._queue) ] 364 result.reverse() 365 return result 366 367 def iteritems(self): 368 return iter(self.items()) 369 370 def values(self): 371 return [ x[1] for x in self.items() ] 372 373 def itervalue(self): 374 return iter(self.values()) 375 376 def keys(self): 377 return list(self) 378 379 def iterkeys(self): 380 return reversed(tuple(self._queue)) 381 382 __iter__ = iterkeys 383 384 def __reversed__(self): 385 return iter(tuple(self._queue)) 386 387 __copy__ = copy 388 389 390 try: 391 from collections import MutableMapping 392 MutableMapping.register(LRUCache) 393 except ImportError: 394 pass 395 396 class Cycler(object): 397 398 def __init__(self, *items): 399 if not items: 400 raise RuntimeError('at least one item has to be provided') 401 self.items = items 402 self.reset() 403 404 def reset(self): 405 self.pos = 0 406 407 @property 408 def current(self): 409 return self.items[self.pos] 410 411 def next(self): 412 rv = self.current 413 self.pos = (self.pos + 1) % len(self.items) 414 return rv 415 416 417 class Joiner(object): 418 419 def __init__(self, sep = u', '): 420 self.sep = sep 421 self.used = False 422 423 def __call__(self): 424 if not self.used: 425 self.used = True 426 return u'' 427 return self.sep 428 429 430 try: 431 from markupsafe import Markup, escape, soft_unicode 432 except ImportError: 433 from jinja2._markupsafe import Markup, escape, soft_unicode 434 435 try: 436 from functools import partial 437 except ImportError: 438 439 class partial(object): 440 441 def __init__(self, _func, *args, **kwargs): 442 self._func = _func 443 self._args = args 444 self._kwargs = kwargs 445 446 def __call__(self, *args, **kwargs): 447 kwargs.update(self._kwargs) 448 return self._func(*(self._args + args), **kwargs)