1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# -*- coding: utf-8 -*-
2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)"""
3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    jinja2.utils
4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ~~~~~~~~~~~~
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    Utility functions.
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :copyright: (c) 2010 by the Jinja Team.
9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :license: BSD, see LICENSE for more details.
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)"""
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import re
12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)import errno
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from collections import deque
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from jinja2._compat import text_type, string_types, implements_iterator, \
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)     allocate_lock, url_quote
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_word_split_re = re.compile(r'(\s+)')
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_punctuation_re = re.compile(
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        '|'.join(map(re.escape, ('(', '<', '&lt;'))),
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        '|'.join(map(re.escape, ('.', ',', ')', '>', '\n', '&gt;')))
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    )
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles))
25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_entity_re = re.compile(r'&([^;]+);')
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)_digits = '0123456789'
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# special singleton representing missing values for the runtime
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# internal code
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)internal_code = set()
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)concat = u''.join
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def contextfunction(f):
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """This decorator can be used to mark a function or method context callable.
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    A context callable is passed the active :class:`Context` as first argument when
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    called from the template.  This is useful if a function wants to get access
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    to the context or functions provided on the context object.  For example
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    a function that returns a sorted list of template variables the current
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    template exports could look like this::
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        @contextfunction
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def get_exported_names(context):
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return sorted(context.exported_vars)
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.contextfunction = True
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def evalcontextfunction(f):
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    """This decorator can be used to mark a function or method as an eval
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    context callable.  This is similar to the :func:`contextfunction`
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    but instead of passing the context, an evaluation context object is
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    passed.  For more information about the eval context, see
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :ref:`eval-context`.
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    .. versionadded:: 2.4
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.evalcontextfunction = True
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def environmentfunction(f):
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """This decorator can be used to mark a function or method as environment
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    callable.  This decorator works exactly like the :func:`contextfunction`
72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    decorator just that the first argument is the active :class:`Environment`
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    and not context.
74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    f.environmentfunction = True
76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def internalcode(f):
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Marks the function as internally used"""
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    internal_code.add(f.__code__)
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return f
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def is_undefined(obj):
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Check if the object passed is undefined.  This does nothing more than
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    performing an instance check against :class:`Undefined` but looks nicer.
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    This can be used for custom filters or tests that want to react to
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    undefined variables.  For example a custom default filter can look like
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    this::
91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        def default(var, default=''):
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if is_undefined(var):
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                return default
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return var
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.runtime import Undefined
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return isinstance(obj, Undefined)
99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def consume(iterable):
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Consumes an iterable without doing anything with it."""
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for event in iterable:
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        pass
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def clear_caches():
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Jinja2 keeps internal caches for environments and lexers.  These are
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    used so that Jinja2 doesn't have to recreate environments and lexers all
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    the time.  Normally you don't have to care about that but if you are
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    messuring memory consumption you may want to clean the caches.
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.environment import _spontaneous_environments
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.lexer import _lexer_cache
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _spontaneous_environments.clear()
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    _lexer_cache.clear()
117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def import_string(import_name, silent=False):
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    """Imports an object based on a string.  This is useful if you want to
121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    use import paths as endpoints or something similar.  An import path can
122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    be specified either in dotted notation (``xml.sax.saxutils.escape``)
123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    or with a colon as object delimiter (``xml.sax.saxutils:escape``).
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If the `silent` is True the return value will be `None` if the import
126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    fails.
127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    :return: imported object
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if ':' in import_name:
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            module, obj = import_name.split(':', 1)
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        elif '.' in import_name:
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            items = import_name.split('.')
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            module = '.'.join(items[:-1])
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            obj = items[-1]
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        else:
138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return __import__(import_name)
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return getattr(__import__(module, None, None, [obj]), obj)
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    except (ImportError, AttributeError):
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not silent:
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def open_if_exists(filename, mode='rb'):
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Returns a file descriptor for the filename if that file exists,
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    otherwise `None`.
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return open(filename, mode)
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    except IOError as e:
152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if e.errno not in (errno.ENOENT, errno.EISDIR):
153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def object_type_repr(obj):
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Returns the name of the object's type.  For some recognized
158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    singletons the name of the object is returned instead. (For
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    example for `None` and `Ellipsis`).
160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if obj is None:
162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return 'None'
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    elif obj is Ellipsis:
164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return 'Ellipsis'
165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # __builtin__ in 2.x, builtins in 3.x
166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if obj.__class__.__module__ in ('__builtin__', 'builtins'):
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        name = obj.__class__.__name__
168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    else:
169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        name = obj.__class__.__module__ + '.' + obj.__class__.__name__
170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return '%s object' % name
171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def pformat(obj, verbose=False):
174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Prettyprint an object.  Either use the `pretty` library or the
175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    builtin `pprint`.
176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    try:
178b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        from pretty import pretty
179b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return pretty(obj, verbose=verbose)
180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    except ImportError:
181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        from pprint import pformat
182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return pformat(obj)
183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def urlize(text, trim_url_limit=None, nofollow=False):
186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Converts any URLs in text into clickable links. Works on http://,
187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    https:// and www. links. Links can have trailing punctuation (periods,
188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    commas, close-parens) and leading punctuation (opening parens) and
189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    it'll still do the right thing.
190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If trim_url_limit is not None, the URLs in link text will be limited
192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    to trim_url_limit characters.
193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    If nofollow is True, the URLs in link text will get a rel="nofollow"
195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    attribute.
196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """
197b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    trim_url = lambda x, limit=trim_url_limit: limit is not None \
198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         and (x[:limit] + (len(x) >=limit and '...'
199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         or '')) or x
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    words = _word_split_re.split(text_type(escape(text)))
201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    nofollow_attr = nofollow and ' rel="nofollow"' or ''
202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for i, word in enumerate(words):
203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        match = _punctuation_re.match(word)
204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if match:
205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            lead, middle, trail = match.groups()
206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if middle.startswith('www.') or (
207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                '@' not in middle and
208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                not middle.startswith('http://') and
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                not middle.startswith('https://') and
210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                len(middle) > 0 and
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle[0] in _letters + _digits and (
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.org') or
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.net') or
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    middle.endswith('.com')
215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                )):
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="http://%s"%s>%s</a>' % (middle,
217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    nofollow_attr, trim_url(middle))
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if middle.startswith('http://') or \
219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)               middle.startswith('https://'):
220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="%s"%s>%s</a>' % (middle,
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    nofollow_attr, trim_url(middle))
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if '@' in middle and not middle.startswith('www.') and \
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)               not ':' in middle and _simple_email_re.match(middle):
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if lead + middle + trail != word:
226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                words[i] = lead + middle + trail
227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return u''.join(words)
228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def generate_lorem_ipsum(n=5, html=True, min=20, max=100):
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """Generate some lorem impsum for the template."""
232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from jinja2.constants import LOREM_IPSUM_WORDS
233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from random import choice, randrange
234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    words = LOREM_IPSUM_WORDS.split()
235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    result = []
236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for _ in range(n):
238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        next_capitalized = True
239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        last_comma = last_fullstop = 0
240b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        word = None
241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        last = None
242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        p = []
243b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # each paragraph contains out of 20 to 100 words.
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        for idx, _ in enumerate(range(randrange(min, max))):
246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            while True:
247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word = choice(words)
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                if word != last:
249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    last = word
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    break
251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if next_capitalized:
252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word = word.capitalize()
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                next_capitalized = False
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            # add commas
255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if idx - randrange(3, 8) > last_comma:
256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_comma = idx
257b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_fullstop += 2
258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word += ','
259b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            # add end of sentences
260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if idx - randrange(10, 20) > last_fullstop:
261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                last_comma = last_fullstop = idx
262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                word += '.'
263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                next_capitalized = True
264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p.append(word)
265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
266b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # ensure that the paragraph ends with a dot.
267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        p = u' '.join(p)
268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if p.endswith(','):
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p = p[:-1] + '.'
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        elif not p.endswith('.'):
271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            p += '.'
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result.append(p)
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if not html:
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return u'\n\n'.join(result)
276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)def unicode_urlencode(obj, charset='utf-8'):
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    """URL escapes a single bytestring or unicode string with the
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    given charset if applicable to URL safe quoting under all rules
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    that need to be considered under all supported Python versions.
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    If non strings are provided they are converted to their unicode
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    representation first.
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    """
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if not isinstance(obj, string_types):
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        obj = text_type(obj)
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if isinstance(obj, text_type):
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        obj = obj.encode(charset)
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return text_type(url_quote(obj))
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class LRUCache(object):
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A simple LRU Cache implementation."""
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # this is fast for small capacities (something below 1000) but doesn't
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # scale.  But as long as it's only used as storage for templates this
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    # won't do any harm.
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, capacity):
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.capacity = capacity
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._mapping = {}
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._queue = deque()
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._postinit()
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def _postinit(self):
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        # alias all queue methods for faster lookup
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._popleft = self._queue.popleft
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._pop = self._queue.pop
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        self._remove = self._queue.remove
312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock = allocate_lock()
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._append = self._queue.append
314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getstate__(self):
316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return {
317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            'capacity':     self.capacity,
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            '_mapping':     self._mapping,
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            '_queue':       self._queue
320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        }
321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __setstate__(self, d):
323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.__dict__.update(d)
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._postinit()
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getnewargs__(self):
327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return (self.capacity,)
328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def copy(self):
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        """Return a shallow copy of the instance."""
331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv = self.__class__(self.capacity)
332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv._mapping.update(self._mapping)
333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv._queue = deque(self._queue)
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return rv
335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def get(self, key, default=None):
337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return an item from the cache dict or `default`"""
338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return self[key]
340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        except KeyError:
341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return default
342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def setdefault(self, key, default=None):
344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Set `default` if the key is not in the cache otherwise
345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        leave unchanged. Return the value of this key.
346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        self._wlock.acquire()
348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            try:
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                return self[key]
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            except KeyError:
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                self[key] = default
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                return default
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        finally:
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            self._wlock.release()
356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def clear(self):
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Clear the cache."""
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping.clear()
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._queue.clear()
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __contains__(self, key):
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Check if a key exists in this cache."""
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return key in self._mapping
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __len__(self):
371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return the current size of the cache."""
372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return len(self._mapping)
373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __repr__(self):
375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return '<%s %r>' % (
376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self.__class__.__name__,
377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping
378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        )
379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __getitem__(self, key):
381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Get an item from the cache. Moves the item up so that it has the
382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        highest priority then.
383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        Raise a `KeyError` if it does not exist.
385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        self._wlock.acquire()
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        try:
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            rv = self._mapping[key]
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            if self._queue[-1] != key:
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                try:
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    self._remove(key)
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                except ValueError:
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    # if something removed the key from the container
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    # when we read, ignore the ValueError that we would
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    # get otherwise.
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    pass
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                self._append(key)
39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            return rv
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        finally:
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            self._wlock.release()
401b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __setitem__(self, key, value):
403b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Sets the value for an item. Moves the item up so that it
404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        has the highest priority then.
405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            if key in self._mapping:
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                self._remove(key)
410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            elif len(self._mapping) == self.capacity:
411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                del self._mapping[self._popleft()]
412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._append(key)
413b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._mapping[key] = value
414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __delitem__(self, key):
418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Remove an item from the cache dict.
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        Raise a `KeyError` if it does not exist.
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self._wlock.acquire()
422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        try:
423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            del self._mapping[key]
424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            try:
425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                self._remove(key)
426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            except ValueError:
427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                # __getitem__ is not locked, it might happen
428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                pass
429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        finally:
430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self._wlock.release()
431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def items(self):
433b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of items."""
434b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result = [(key, self._mapping[key]) for key in list(self._queue)]
435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        result.reverse()
436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return result
437b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
438b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def iteritems(self):
439b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all items."""
440b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(self.items())
441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def values(self):
443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of all values."""
444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return [x[1] for x in self.items()]
445b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
446b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def itervalue(self):
447b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all values."""
448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(self.values())
449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def keys(self):
451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Return a list of all keys ordered by most recent usage."""
452b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return list(self)
453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def iterkeys(self):
455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over all keys in the cache dict, ordered by
456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        the most recent usage.
457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
458b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return reversed(tuple(self._queue))
459b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    __iter__ = iterkeys
461b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
462b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __reversed__(self):
463b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Iterate over the values in the cache dict, oldest items
464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        coming first.
465b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """
466b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return iter(tuple(self._queue))
467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
468b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    __copy__ = copy
469b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# register the LRU cache as mutable mapping if possible
472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try:
473b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    from collections import MutableMapping
474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    MutableMapping.register(LRUCache)
475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError:
476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    pass
477b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
478b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
47958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)@implements_iterator
480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Cycler(object):
481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A cycle helper for templates."""
482b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, *items):
484b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not items:
485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            raise RuntimeError('at least one item has to be provided')
486b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.items = items
487b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.reset()
488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
489b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def reset(self):
490b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Resets the cycle."""
491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.pos = 0
492b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
493b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    @property
494b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def current(self):
495b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Returns the current item."""
496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return self.items[self.pos]
497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    def __next__(self):
499b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        """Goes one item ahead and returns it."""
500b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        rv = self.current
501b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.pos = (self.pos + 1) % len(self.items)
502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return rv
503b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
504b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
505b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Joiner(object):
506b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    """A joining helper for templates."""
507b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __init__(self, sep=u', '):
509b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.sep = sep
510b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        self.used = False
511b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
512b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    def __call__(self):
513b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if not self.used:
514b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            self.used = True
515b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            return u''
516b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return self.sep
517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)# Imported here because that's where it was in the past
52058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from markupsafe import Markup, escape, soft_unicode
521