diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piecrust/uriutil.py	Sun Aug 10 23:43:16 2014 -0700
@@ -0,0 +1,74 @@
+import re
+import string
+import logging
+import functools
+
+
+logger = logging.getLogger(__name__)
+
+
+class UriError(Exception):
+    def __init__(self, uri):
+        super(UriError, self).__init__("Invalid URI: %s" % uri)
+
+
+@functools.total_ordering
+class UriInfo(object):
+    def __init__(self, uri, source, args, taxonomy=None, page_num=1):
+        self.uri = uri
+        self.source = source
+        self.args = args
+        self.taxonomy = taxonomy
+        self.page_num = page_num
+
+    def __eq__(self, other):
+        return ((self.uri, self.source, self.args, self.taxonomy,
+                self.page_num) ==
+            (other.uri, other.source, other.args, other.taxonomy,
+                other.page_num))
+
+    def __lt__(self, other):
+        return ((self.uri, self.source, self.args, self.taxonomy,
+                self.page_num) <
+            (other.uri, other.source, other.args, other.taxonomy,
+                other.page_num))
+
+
+pagenum_pattern = re.compile(r'/(\d+)/?$')
+
+
+def parse_uri(routes, uri):
+    if string.find(uri, '..') >= 0:
+        raise UriError(uri)
+
+    page_num = 1
+    match = pagenum_pattern.search(uri)
+    if match is not None:
+        uri = uri[:match.start()]
+        page_num = int(match.group(1))
+
+    uri = '/' + uri.strip('/')
+
+    for rn, rc in routes.iteritems():
+        pattern = route_to_pattern(rn)
+        m = re.match(pattern, uri)
+        if m is not None:
+            args = m.groupdict()
+            return UriInfo(uri, rc['source'], args, rc.get('taxonomy'),
+                    page_num)
+
+    return None
+
+
+r2p_pattern = re.compile(r'%(\w+)%')
+
+
+def route_to_pattern(route):
+    return r2p_pattern.sub(r'(?P<\1>[\w\-]+)', route)
+
+
+def multi_replace(text, replacements):
+    reps = dict((re.escape(k), v) for k, v in replacements.iteritems())
+    pattern = re.compile("|".join(reps.keys()))
+    return pattern.sub(lambda m: reps[re.escape(m.group(0))], text)
+