Index: mojo/public/third_party/jinja2/utils.py |
diff --git a/mojo/public/third_party/jinja2/utils.py b/mojo/public/third_party/jinja2/utils.py |
deleted file mode 100644 |
index ddc47da0a0462d480d4513f75f667f1472deb822..0000000000000000000000000000000000000000 |
--- a/mojo/public/third_party/jinja2/utils.py |
+++ /dev/null |
@@ -1,520 +0,0 @@ |
-# -*- coding: utf-8 -*- |
-""" |
- jinja2.utils |
- ~~~~~~~~~~~~ |
- |
- Utility functions. |
- |
- :copyright: (c) 2010 by the Jinja Team. |
- :license: BSD, see LICENSE for more details. |
-""" |
-import re |
-import errno |
-from collections import deque |
-from jinja2._compat import text_type, string_types, implements_iterator, \ |
- allocate_lock, url_quote |
- |
- |
-_word_split_re = re.compile(r'(\s+)') |
-_punctuation_re = re.compile( |
- '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % ( |
- '|'.join(map(re.escape, ('(', '<', '<'))), |
- '|'.join(map(re.escape, ('.', ',', ')', '>', '\n', '>'))) |
- ) |
-) |
-_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$') |
-_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)') |
-_entity_re = re.compile(r'&([^;]+);') |
-_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
-_digits = '0123456789' |
- |
-# special singleton representing missing values for the runtime |
-missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})() |
- |
-# internal code |
-internal_code = set() |
- |
-concat = u''.join |
- |
- |
-def contextfunction(f): |
- """This decorator can be used to mark a function or method context callable. |
- A context callable is passed the active :class:`Context` as first argument when |
- called from the template. This is useful if a function wants to get access |
- to the context or functions provided on the context object. For example |
- a function that returns a sorted list of template variables the current |
- template exports could look like this:: |
- |
- @contextfunction |
- def get_exported_names(context): |
- return sorted(context.exported_vars) |
- """ |
- f.contextfunction = True |
- return f |
- |
- |
-def evalcontextfunction(f): |
- """This decorator can be used to mark a function or method as an eval |
- context callable. This is similar to the :func:`contextfunction` |
- but instead of passing the context, an evaluation context object is |
- passed. For more information about the eval context, see |
- :ref:`eval-context`. |
- |
- .. versionadded:: 2.4 |
- """ |
- f.evalcontextfunction = True |
- return f |
- |
- |
-def environmentfunction(f): |
- """This decorator can be used to mark a function or method as environment |
- callable. This decorator works exactly like the :func:`contextfunction` |
- decorator just that the first argument is the active :class:`Environment` |
- and not context. |
- """ |
- f.environmentfunction = True |
- return f |
- |
- |
-def internalcode(f): |
- """Marks the function as internally used""" |
- internal_code.add(f.__code__) |
- return f |
- |
- |
-def is_undefined(obj): |
- """Check if the object passed is undefined. This does nothing more than |
- performing an instance check against :class:`Undefined` but looks nicer. |
- This can be used for custom filters or tests that want to react to |
- undefined variables. For example a custom default filter can look like |
- this:: |
- |
- def default(var, default=''): |
- if is_undefined(var): |
- return default |
- return var |
- """ |
- from jinja2.runtime import Undefined |
- return isinstance(obj, Undefined) |
- |
- |
-def consume(iterable): |
- """Consumes an iterable without doing anything with it.""" |
- for event in iterable: |
- pass |
- |
- |
-def clear_caches(): |
- """Jinja2 keeps internal caches for environments and lexers. These are |
- used so that Jinja2 doesn't have to recreate environments and lexers all |
- the time. Normally you don't have to care about that but if you are |
- messuring memory consumption you may want to clean the caches. |
- """ |
- from jinja2.environment import _spontaneous_environments |
- from jinja2.lexer import _lexer_cache |
- _spontaneous_environments.clear() |
- _lexer_cache.clear() |
- |
- |
-def import_string(import_name, silent=False): |
- """Imports an object based on a string. This is useful if you want to |
- use import paths as endpoints or something similar. An import path can |
- be specified either in dotted notation (``xml.sax.saxutils.escape``) |
- or with a colon as object delimiter (``xml.sax.saxutils:escape``). |
- |
- If the `silent` is True the return value will be `None` if the import |
- fails. |
- |
- :return: imported object |
- """ |
- try: |
- if ':' in import_name: |
- module, obj = import_name.split(':', 1) |
- elif '.' in import_name: |
- items = import_name.split('.') |
- module = '.'.join(items[:-1]) |
- obj = items[-1] |
- else: |
- return __import__(import_name) |
- return getattr(__import__(module, None, None, [obj]), obj) |
- except (ImportError, AttributeError): |
- if not silent: |
- raise |
- |
- |
-def open_if_exists(filename, mode='rb'): |
- """Returns a file descriptor for the filename if that file exists, |
- otherwise `None`. |
- """ |
- try: |
- return open(filename, mode) |
- except IOError as e: |
- if e.errno not in (errno.ENOENT, errno.EISDIR): |
- raise |
- |
- |
-def object_type_repr(obj): |
- """Returns the name of the object's type. For some recognized |
- singletons the name of the object is returned instead. (For |
- example for `None` and `Ellipsis`). |
- """ |
- if obj is None: |
- return 'None' |
- elif obj is Ellipsis: |
- return 'Ellipsis' |
- # __builtin__ in 2.x, builtins in 3.x |
- if obj.__class__.__module__ in ('__builtin__', 'builtins'): |
- name = obj.__class__.__name__ |
- else: |
- name = obj.__class__.__module__ + '.' + obj.__class__.__name__ |
- return '%s object' % name |
- |
- |
-def pformat(obj, verbose=False): |
- """Prettyprint an object. Either use the `pretty` library or the |
- builtin `pprint`. |
- """ |
- try: |
- from pretty import pretty |
- return pretty(obj, verbose=verbose) |
- except ImportError: |
- from pprint import pformat |
- return pformat(obj) |
- |
- |
-def urlize(text, trim_url_limit=None, nofollow=False): |
- """Converts any URLs in text into clickable links. Works on http://, |
- https:// and www. links. Links can have trailing punctuation (periods, |
- commas, close-parens) and leading punctuation (opening parens) and |
- it'll still do the right thing. |
- |
- If trim_url_limit is not None, the URLs in link text will be limited |
- to trim_url_limit characters. |
- |
- If nofollow is True, the URLs in link text will get a rel="nofollow" |
- attribute. |
- """ |
- trim_url = lambda x, limit=trim_url_limit: limit is not None \ |
- and (x[:limit] + (len(x) >=limit and '...' |
- or '')) or x |
- words = _word_split_re.split(text_type(escape(text))) |
- nofollow_attr = nofollow and ' rel="nofollow"' or '' |
- for i, word in enumerate(words): |
- match = _punctuation_re.match(word) |
- if match: |
- lead, middle, trail = match.groups() |
- if middle.startswith('www.') or ( |
- '@' not in middle and |
- not middle.startswith('http://') and |
- not middle.startswith('https://') and |
- len(middle) > 0 and |
- middle[0] in _letters + _digits and ( |
- middle.endswith('.org') or |
- middle.endswith('.net') or |
- middle.endswith('.com') |
- )): |
- middle = '<a href="http://%s"%s>%s</a>' % (middle, |
- nofollow_attr, trim_url(middle)) |
- if middle.startswith('http://') or \ |
- middle.startswith('https://'): |
- middle = '<a href="%s"%s>%s</a>' % (middle, |
- nofollow_attr, trim_url(middle)) |
- if '@' in middle and not middle.startswith('www.') and \ |
- not ':' in middle and _simple_email_re.match(middle): |
- middle = '<a href="mailto:%s">%s</a>' % (middle, middle) |
- if lead + middle + trail != word: |
- words[i] = lead + middle + trail |
- return u''.join(words) |
- |
- |
-def generate_lorem_ipsum(n=5, html=True, min=20, max=100): |
- """Generate some lorem impsum for the template.""" |
- from jinja2.constants import LOREM_IPSUM_WORDS |
- from random import choice, randrange |
- words = LOREM_IPSUM_WORDS.split() |
- result = [] |
- |
- for _ in range(n): |
- next_capitalized = True |
- last_comma = last_fullstop = 0 |
- word = None |
- last = None |
- p = [] |
- |
- # each paragraph contains out of 20 to 100 words. |
- for idx, _ in enumerate(range(randrange(min, max))): |
- while True: |
- word = choice(words) |
- if word != last: |
- last = word |
- break |
- if next_capitalized: |
- word = word.capitalize() |
- next_capitalized = False |
- # add commas |
- if idx - randrange(3, 8) > last_comma: |
- last_comma = idx |
- last_fullstop += 2 |
- word += ',' |
- # add end of sentences |
- if idx - randrange(10, 20) > last_fullstop: |
- last_comma = last_fullstop = idx |
- word += '.' |
- next_capitalized = True |
- p.append(word) |
- |
- # ensure that the paragraph ends with a dot. |
- p = u' '.join(p) |
- if p.endswith(','): |
- p = p[:-1] + '.' |
- elif not p.endswith('.'): |
- p += '.' |
- result.append(p) |
- |
- if not html: |
- return u'\n\n'.join(result) |
- return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result)) |
- |
- |
-def unicode_urlencode(obj, charset='utf-8'): |
- """URL escapes a single bytestring or unicode string with the |
- given charset if applicable to URL safe quoting under all rules |
- that need to be considered under all supported Python versions. |
- |
- If non strings are provided they are converted to their unicode |
- representation first. |
- """ |
- if not isinstance(obj, string_types): |
- obj = text_type(obj) |
- if isinstance(obj, text_type): |
- obj = obj.encode(charset) |
- return text_type(url_quote(obj)) |
- |
- |
-class LRUCache(object): |
- """A simple LRU Cache implementation.""" |
- |
- # this is fast for small capacities (something below 1000) but doesn't |
- # scale. But as long as it's only used as storage for templates this |
- # won't do any harm. |
- |
- def __init__(self, capacity): |
- self.capacity = capacity |
- self._mapping = {} |
- self._queue = deque() |
- self._postinit() |
- |
- def _postinit(self): |
- # alias all queue methods for faster lookup |
- self._popleft = self._queue.popleft |
- self._pop = self._queue.pop |
- self._remove = self._queue.remove |
- self._wlock = allocate_lock() |
- self._append = self._queue.append |
- |
- def __getstate__(self): |
- return { |
- 'capacity': self.capacity, |
- '_mapping': self._mapping, |
- '_queue': self._queue |
- } |
- |
- def __setstate__(self, d): |
- self.__dict__.update(d) |
- self._postinit() |
- |
- def __getnewargs__(self): |
- return (self.capacity,) |
- |
- def copy(self): |
- """Return a shallow copy of the instance.""" |
- rv = self.__class__(self.capacity) |
- rv._mapping.update(self._mapping) |
- rv._queue = deque(self._queue) |
- return rv |
- |
- def get(self, key, default=None): |
- """Return an item from the cache dict or `default`""" |
- try: |
- return self[key] |
- except KeyError: |
- return default |
- |
- def setdefault(self, key, default=None): |
- """Set `default` if the key is not in the cache otherwise |
- leave unchanged. Return the value of this key. |
- """ |
- self._wlock.acquire() |
- try: |
- try: |
- return self[key] |
- except KeyError: |
- self[key] = default |
- return default |
- finally: |
- self._wlock.release() |
- |
- def clear(self): |
- """Clear the cache.""" |
- self._wlock.acquire() |
- try: |
- self._mapping.clear() |
- self._queue.clear() |
- finally: |
- self._wlock.release() |
- |
- def __contains__(self, key): |
- """Check if a key exists in this cache.""" |
- return key in self._mapping |
- |
- def __len__(self): |
- """Return the current size of the cache.""" |
- return len(self._mapping) |
- |
- def __repr__(self): |
- return '<%s %r>' % ( |
- self.__class__.__name__, |
- self._mapping |
- ) |
- |
- def __getitem__(self, key): |
- """Get an item from the cache. Moves the item up so that it has the |
- highest priority then. |
- |
- Raise a `KeyError` if it does not exist. |
- """ |
- self._wlock.acquire() |
- try: |
- rv = self._mapping[key] |
- if self._queue[-1] != key: |
- try: |
- self._remove(key) |
- except ValueError: |
- # if something removed the key from the container |
- # when we read, ignore the ValueError that we would |
- # get otherwise. |
- pass |
- self._append(key) |
- return rv |
- finally: |
- self._wlock.release() |
- |
- def __setitem__(self, key, value): |
- """Sets the value for an item. Moves the item up so that it |
- has the highest priority then. |
- """ |
- self._wlock.acquire() |
- try: |
- if key in self._mapping: |
- self._remove(key) |
- elif len(self._mapping) == self.capacity: |
- del self._mapping[self._popleft()] |
- self._append(key) |
- self._mapping[key] = value |
- finally: |
- self._wlock.release() |
- |
- def __delitem__(self, key): |
- """Remove an item from the cache dict. |
- Raise a `KeyError` if it does not exist. |
- """ |
- self._wlock.acquire() |
- try: |
- del self._mapping[key] |
- try: |
- self._remove(key) |
- except ValueError: |
- # __getitem__ is not locked, it might happen |
- pass |
- finally: |
- self._wlock.release() |
- |
- def items(self): |
- """Return a list of items.""" |
- result = [(key, self._mapping[key]) for key in list(self._queue)] |
- result.reverse() |
- return result |
- |
- def iteritems(self): |
- """Iterate over all items.""" |
- return iter(self.items()) |
- |
- def values(self): |
- """Return a list of all values.""" |
- return [x[1] for x in self.items()] |
- |
- def itervalue(self): |
- """Iterate over all values.""" |
- return iter(self.values()) |
- |
- def keys(self): |
- """Return a list of all keys ordered by most recent usage.""" |
- return list(self) |
- |
- def iterkeys(self): |
- """Iterate over all keys in the cache dict, ordered by |
- the most recent usage. |
- """ |
- return reversed(tuple(self._queue)) |
- |
- __iter__ = iterkeys |
- |
- def __reversed__(self): |
- """Iterate over the values in the cache dict, oldest items |
- coming first. |
- """ |
- return iter(tuple(self._queue)) |
- |
- __copy__ = copy |
- |
- |
-# register the LRU cache as mutable mapping if possible |
-try: |
- from collections import MutableMapping |
- MutableMapping.register(LRUCache) |
-except ImportError: |
- pass |
- |
- |
-@implements_iterator |
-class Cycler(object): |
- """A cycle helper for templates.""" |
- |
- def __init__(self, *items): |
- if not items: |
- raise RuntimeError('at least one item has to be provided') |
- self.items = items |
- self.reset() |
- |
- def reset(self): |
- """Resets the cycle.""" |
- self.pos = 0 |
- |
- @property |
- def current(self): |
- """Returns the current item.""" |
- return self.items[self.pos] |
- |
- def __next__(self): |
- """Goes one item ahead and returns it.""" |
- rv = self.current |
- self.pos = (self.pos + 1) % len(self.items) |
- return rv |
- |
- |
-class Joiner(object): |
- """A joining helper for templates.""" |
- |
- def __init__(self, sep=u', '): |
- self.sep = sep |
- self.used = False |
- |
- def __call__(self): |
- if not self.used: |
- self.used = True |
- return u'' |
- return self.sep |
- |
- |
-# Imported here because that's where it was in the past |
-from markupsafe import Markup, escape, soft_unicode |