sites/irclogs.qmsk.net/urltree.py
branchsites
changeset 41 9585441a4bfb
parent 40 71ab68f31a1c
child 42 5a72c00c4ae4
--- a/sites/irclogs.qmsk.net/urltree.py	Sat Feb 07 21:21:10 2009 +0200
+++ b/sites/irclogs.qmsk.net/urltree.py	Sun Feb 08 00:29:36 2009 +0200
@@ -40,7 +40,7 @@
     """
 
     @staticmethod
-    def parse (mask, defaults) :
+    def parse (mask, defaults, types) :
         """
             Parse the given label-segment, and return a *Label instance
         """
@@ -59,12 +59,8 @@
             # type
             type = match.group("type")
             
-            if type :
-                # XXX: resolve using eval() for now, should be a module or something
-                type = eval(type)
-
-            else :
-                type = str
+            # lookup type, None for default
+            type = types[type]
 
             # defaults?
             default = defaults.get(key)
@@ -220,7 +216,7 @@
                 value = self.type(value)
 
             except Exception, e :
-                raise URLError("Bad value %r for type %s: %s" % (value, self.type.__name__, e))
+                raise URLError("Bad value %r for type %s: %s: %s" % (value, self.type.__name__, type(e).__name__, e))
 
             return LabelValue(self, value)
 
@@ -230,24 +226,55 @@
             ':%s' % (self.type.__name__ ) if self.type != str else '',
             '=%s' % (self.default, ) if self.default else '',
         )
-            
+
+class URLConfig (object) :
+    """
+        Global configuration relevant to all URLs
+    """
+
+    # built-in type codes
+    BUILTIN_TYPES = {
+        # default
+        None    : str,
+
+        # integer
+        'int'   : int,
+    }
+
+    def __init__ (self, type_dict=None) :
+        """
+            Create an URLConfig for use with URL
+
+            If type_dict is given, it should be a mapping of type names -> callables, and they will be available for
+            type specifications in addition to the defaults.
+        """
+
+        # build our type_dict
+        self.type_dict = self.BUILTIN_TYPES.copy()
+        
+        # apply the given type_dict
+        if type_dict :
+            self.type_dict.update(type_dict)
+
 class URL (object) :
     """
         Represents a specific URL
     """
 
-    def __init__ (self, url_mask, handler, **defaults) :
+
+    def __init__ (self, config, url_mask, handler, type_dict=None, **defaults) :
         """
-            Create an URL with the given url mask, handler, and default values
+            Create an URL using the given URLConfig, with the given url mask, handler, and default values.
         """
 
         # store
+        self.config = config
         self.url_mask = url_mask
         self.handler = handler
         self.defaults = defaults
 
         # build our labels
-        self.label_path = [Label.parse(mask, defaults) for mask in url_mask.split('/')]
+        self.label_path = [Label.parse(mask, defaults, config.type_dict) for mask in url_mask.split('/')]
         
     def get_label_path (self) :
         """