--- a/sites/irclogs.qmsk.net/urltree.py Sun Feb 08 00:29:36 2009 +0200
+++ b/sites/irclogs.qmsk.net/urltree.py Sun Feb 08 02:29:23 2009 +0200
@@ -93,6 +93,13 @@
"""
abstract
+
+ def build (self, value_dict) :
+ """
+ Return a string representing this label, using the values in the given value_dict if needed
+ """
+
+ abstract
class EmptyLabel (Label) :
"""
@@ -118,6 +125,9 @@
# only empty segments
if value == '' :
return True
+
+ def build (self, values) :
+ return str(self)
def __str__ (self) :
return ''
@@ -156,6 +166,9 @@
if value == self.name :
return True
+ def build (self, values) :
+ return str(self)
+
def __str__ (self) :
return self.name
@@ -180,6 +193,21 @@
"""
return isinstance(other, ValueLabel) and self.key == other.key
+
+ def build (self, values) :
+ """
+ Return either the assigned value from values, our default value, or raise an error
+ """
+
+ value = values.get(self.key)
+
+ if not value and self.default :
+ value = self.default
+
+ elif not value :
+ raise URLError("No value given for label %r" % (self.key, ))
+
+ return value
class SimpleValueLabel (ValueLabel) :
"""
@@ -273,9 +301,43 @@
self.handler = handler
self.defaults = defaults
- # build our labels
+ # query string
+ self.query_args = dict()
+
+ # parse any query string
+ # XXX: conflicts with regexp syntax
+ if '/?' in url_mask :
+ url_mask, query_mask = url_mask.split('/?')
+
+ else :
+ query_mask = None
+
+ # build our label path
self.label_path = [Label.parse(mask, defaults, config.type_dict) for mask in url_mask.split('/')]
-
+
+ # build our query args list
+ if query_mask :
+ # split into items
+ for query_item in query_mask.split('&') :
+ # parse default
+ if '=' in query_item :
+ query_item, default = query_item.split('=')
+
+ else :
+ default = None
+
+ # parse type
+ if ':' in query_item :
+ query_item, type = query_item.split(':')
+ else :
+ type = None
+
+ # parse key
+ key = query_item
+
+ # add to query_args as (type, default) tuple
+ self.query_args[key] = (self.config.type_dict[type], default)
+
def get_label_path (self) :
"""
Returns a list containing the labels in this url
@@ -295,9 +357,46 @@
# then add all the values
for label_value in label_values :
kwargs[label_value.label.key] = label_value.value
+
+ # then parse all query args
+ # XXX: catch missing arguments
+ for key, value in request.get_args() :
+ # lookup spec
+ type, default = self.query_args[key]
+
+ # normalize empty value to None
+ if not value :
+ value = None
+
+ else :
+ # process value
+ value = type(value)
+
+ # set default?
+ if not value :
+ if default :
+ value = default
+
+ if default == '' :
+ # do not pass key at all
+ continue
+
+ # otherwise, fail
+ raise URLError("No value given for required argument: %r" % (key, ))
+ # set key
+ kwargs[key] = value
+
# execute the handler
return self.handler(request, **kwargs)
+
+ def build (self, request, **values) :
+ """
+ Build an absolute URL pointing to this target, with the given values
+ """
+
+ # build URL from request page prefix and our labels
+ return request.page_prefix + '/'.join(label.build(values) for label in self.label_path)
def __str__ (self) :
return '/'.join(str(label) for label in self.label_path)