Mercurial > piecrust2
comparison piecrust/uriutil.py @ 3:f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
- Serving works, with debug window.
- Baking works, multi-threading, with dependency handling.
- Various things not implemented yet.
| author | Ludovic Chabant <ludovic@chabant.com> |
|---|---|
| date | Sun, 10 Aug 2014 23:43:16 -0700 |
| parents | |
| children | 474c9882decf |
comparison
equal
deleted
inserted
replaced
| 2:40fa08b261b9 | 3:f485ba500df3 |
|---|---|
| 1 import re | |
| 2 import string | |
| 3 import logging | |
| 4 import functools | |
| 5 | |
| 6 | |
| 7 logger = logging.getLogger(__name__) | |
| 8 | |
| 9 | |
| 10 class UriError(Exception): | |
| 11 def __init__(self, uri): | |
| 12 super(UriError, self).__init__("Invalid URI: %s" % uri) | |
| 13 | |
| 14 | |
| 15 @functools.total_ordering | |
| 16 class UriInfo(object): | |
| 17 def __init__(self, uri, source, args, taxonomy=None, page_num=1): | |
| 18 self.uri = uri | |
| 19 self.source = source | |
| 20 self.args = args | |
| 21 self.taxonomy = taxonomy | |
| 22 self.page_num = page_num | |
| 23 | |
| 24 def __eq__(self, other): | |
| 25 return ((self.uri, self.source, self.args, self.taxonomy, | |
| 26 self.page_num) == | |
| 27 (other.uri, other.source, other.args, other.taxonomy, | |
| 28 other.page_num)) | |
| 29 | |
| 30 def __lt__(self, other): | |
| 31 return ((self.uri, self.source, self.args, self.taxonomy, | |
| 32 self.page_num) < | |
| 33 (other.uri, other.source, other.args, other.taxonomy, | |
| 34 other.page_num)) | |
| 35 | |
| 36 | |
| 37 pagenum_pattern = re.compile(r'/(\d+)/?$') | |
| 38 | |
| 39 | |
| 40 def parse_uri(routes, uri): | |
| 41 if string.find(uri, '..') >= 0: | |
| 42 raise UriError(uri) | |
| 43 | |
| 44 page_num = 1 | |
| 45 match = pagenum_pattern.search(uri) | |
| 46 if match is not None: | |
| 47 uri = uri[:match.start()] | |
| 48 page_num = int(match.group(1)) | |
| 49 | |
| 50 uri = '/' + uri.strip('/') | |
| 51 | |
| 52 for rn, rc in routes.iteritems(): | |
| 53 pattern = route_to_pattern(rn) | |
| 54 m = re.match(pattern, uri) | |
| 55 if m is not None: | |
| 56 args = m.groupdict() | |
| 57 return UriInfo(uri, rc['source'], args, rc.get('taxonomy'), | |
| 58 page_num) | |
| 59 | |
| 60 return None | |
| 61 | |
| 62 | |
| 63 r2p_pattern = re.compile(r'%(\w+)%') | |
| 64 | |
| 65 | |
| 66 def route_to_pattern(route): | |
| 67 return r2p_pattern.sub(r'(?P<\1>[\w\-]+)', route) | |
| 68 | |
| 69 | |
| 70 def multi_replace(text, replacements): | |
| 71 reps = dict((re.escape(k), v) for k, v in replacements.iteritems()) | |
| 72 pattern = re.compile("|".join(reps.keys())) | |
| 73 return pattern.sub(lambda m: reps[re.escape(m.group(0))], text) | |
| 74 |
