# HG changeset patch # User paulb # Date 1168115432 0 # Node ID b5942e4096c8dfd49c504060e49687fdd115e0c9 # Parent 67356ca8b07b1d47c1a6e2d287c9320f44bfef49 [project @ 2007-01-06 20:30:32 by paulb] Added a Selectors module. Updated MapResource, making path_encoding an alias for urlencoding. diff -r 67356ca8b07b -r b5942e4096c8 WebStack/Resources/ResourceMap.py --- a/WebStack/Resources/ResourceMap.py Sat Jan 06 20:29:51 2007 +0000 +++ b/WebStack/Resources/ResourceMap.py Sat Jan 06 20:30:32 2007 +0000 @@ -3,7 +3,7 @@ """ Mapping from names to resources. -Copyright (C) 2004, 2005 Paul Boddie +Copyright (C) 2004, 2005, 2007 Paul Boddie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,9 @@ "A resource mapping names to other resources." - def __init__(self, mapping, pass_through=0, directory_redirects=1, urlencoding="utf-8"): + path_encoding = "utf-8" + + def __init__(self, mapping, pass_through=0, directory_redirects=1, path_encoding=None, urlencoding=None): """ Initialise the resource with a 'mapping' of names to resources. The @@ -38,7 +40,9 @@ mapping is {"mammals" : ..., "reptiles" : ..., None : ...} /mammals/cat -> matches "mammals" + /reptiles/python -> matches "reptiles" + /creatures/goblin -> no match, handled by None When this resource matches a name in the virtual path info to one of the @@ -67,21 +71,22 @@ resource is set as its own "catch all" resource. For example: map_resource = MapResource(...) + map_resource.mapping[None] = map_resource The optional 'directory_redirects' parameter, if set to a true value (as is the default setting), causes a redirect adding a trailing "/" character if the request path does not end with such a character. - The optional 'urlencoding' is used to decode "URL encoded" character - values in the request path, and overrides the default encoding wherever - possible. + The optional 'path_encoding' (for which 'urlencoding' is a synonym) is + used to decode "URL encoded" character values in the request path, and + overrides the default encoding wherever possible. """ self.mapping = mapping self.pass_through = pass_through self.directory_redirects = directory_redirects - self.urlencoding = urlencoding + self.path_encoding = path_encoding or urlencoding or self.path_encoding def respond(self, trans): @@ -92,7 +97,7 @@ # Get the path info. - parts = trans.get_virtual_path_info(self.urlencoding).split("/") + parts = trans.get_virtual_path_info(self.path_encoding).split("/") # Where the published resource has a path info value defined (ie. its # path info consists of a "/" character plus some other text), the first @@ -150,7 +155,7 @@ trans.set_response_code(404) trans.set_content_type(WebStack.Generic.ContentType("text/plain")) out = trans.get_response_stream() - out.write("Resource '%s' not found." % trans.get_path_info(self.urlencoding)) + out.write("Resource '%s' not found." % trans.get_path_info(self.path_encoding)) def send_redirect(self, trans): @@ -159,10 +164,10 @@ end of the request path. """ - path_without_query = trans.get_path_without_query(self.urlencoding) + path_without_query = trans.get_path_without_query(self.path_encoding) query_string = trans.get_query_string() if query_string: query_string = "?" + query_string - trans.redirect(trans.encode_path(path_without_query, self.urlencoding) + "/" + query_string) + trans.redirect(trans.encode_path(path_without_query, self.path_encoding) + "/" + query_string) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 67356ca8b07b -r b5942e4096c8 WebStack/Resources/Selectors.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebStack/Resources/Selectors.py Sat Jan 06 20:30:32 2007 +0000 @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +""" +Resources which "select" other resources, sometimes causing desirable +side-effects. + +Copyright (C) 2007 Paul Boddie + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +""" + +class PathSelector: + + "Set a request's current path and processed path info on an attribute." + + def __init__(self, resource, add_slash=1, attribute_name="root", path_encoding="utf-8"): + + """ + Initialise the selector with a 'resource' (to which all requests shall + be forwarded), specifying whether a "/" character shall be added to + stored paths using the optional 'add_slash' parameter (default is true), + along with an optional 'attribute_name' (indicating the name of the + attribute on which the path information shall be stored), and the + optional 'path_encoding' for interpreting URL-encoded path values. + """ + + self.resource = resource + self.add_slash = add_slash + self.attribute_name = attribute_name + self.path_encoding = path_encoding + + def _slash(self): + if self.add_slash: + return "/" + else: + return "" + + def respond(self, trans): + + """ + Respond to the transaction 'trans' by storing the current path and + processed virtual path info on the named transaction attribute. + """ + + pwi = trans.get_path_without_info(self.path_encoding) + + # Make a note of the path given the following general rule: + # path_without_info + path_info + # == path_without_info + processed_virtual_path_info + virtual_path_info + + attributes = trans.get_attributes() + attributes[self.attribute_name] = trans.encode_path( + pwi + trans.get_processed_virtual_path_info(self.path_encoding) + self._slash(), + self.path_encoding + ) + + self.resource.respond(trans) + +# vim: tabstop=4 expandtab shiftwidth=4