""" ``curly`` module.
"""
import re
from wheezy.routing.regex import RegexRoute
from wheezy.routing.utils import outer_split
RE_SPLIT = re.compile(r"(?P<n>{[\w:]+.*?})")
[docs]def try_build_curly_route(pattern, finishing=True, kwargs=None, name=None):
"""Convert pattern expression into regex with
named groups and create regex route.
"""
if isinstance(pattern, RegexRoute):
return pattern
if RE_SPLIT.search(pattern):
return RegexRoute(convert(pattern), finishing, kwargs, name)
return None
patterns = {
# one or more digits
"i": r"\d+",
"int": r"\d+",
"number": r"\d+",
"digits": r"\d+",
# one or more word characters
"w": r"\w+",
"word": r"\w+",
# everything until ``/``
"s": r"[^/]+",
"segment": r"[^/]+",
"part": r"[^/]+",
# any
"*": r".+",
"a": r".+",
"any": r".+",
"rest": r".+",
}
default_pattern = "s"
[docs]def convert(s):
"""Convert curly expression into regex with
named groups.
"""
parts = outer_split(s, sep="[]")
parts[1::2] = ["(%s)?" % p for p in map(convert, parts[1::2])]
parts[::2] = map(convert_single, parts[::2])
return "".join(parts)
[docs]def convert_single(s):
"""Convert curly expression into regex with
named groups.
"""
parts = RE_SPLIT.split(s)
return "".join(map(replace, parts))
[docs]def replace(val):
"""Replace ``{group_name:pattern_name}`` by regex with
named groups.
"""
if val.startswith("{") and val.endswith("}"):
group_name, pattern_name = parse(val[1:-1])
pattern = patterns.get(pattern_name, pattern_name)
return "(?P<%s>%s)" % (group_name, pattern)
return val
[docs]def parse(s):
"""Parse ``s`` according to ``group_name:pattern_name``.
There is just ``group_name``, return default
``pattern_name``.
"""
if ":" in s:
return tuple(s.split(":", 1))
return s, default_pattern