1.1 --- a/WebStack/Resources/ResourceMap.py Fri Jun 20 22:30:13 2008 +0200
1.2 +++ b/WebStack/Resources/ResourceMap.py Mon May 02 18:52:52 2005 +0000
1.3 @@ -14,7 +14,8 @@
1.4 Initialise the resource with a 'mapping' of names to resources. The
1.5 'mapping' should be a dictionary-like object employing simple names
1.6 without "/" characters; the special value None is used where no name
1.7 - is found in the request path.
1.8 + corresponds to that used in the request path and may be used to map to
1.9 + a "catch all" resource.
1.10 """
1.11
1.12 self.mapping = mapping
1.13 @@ -30,24 +31,28 @@
1.14
1.15 parts = trans.get_virtual_path_info().split("/")
1.16
1.17 - # The first part should always be empty.
1.18 + # The first part should always be empty, and there should always be a
1.19 + # second part.
1.20
1.21 - if len(parts) > 1:
1.22 - name = parts[1]
1.23 - else:
1.24 - name = None
1.25 + name = parts[1]
1.26
1.27 # Get the mapped resource.
1.28
1.29 resource = self.mapping.get(name)
1.30 + if resource is None:
1.31 + resource = self.mapping.get(None)
1.32
1.33 - # If a resource was found, change the transaction's path info, then
1.34 - # invoke the transaction, transferring control completely.
1.35 + # If a resource was found, change the transaction's path info.
1.36 + # eg. "/this/next" -> "/next"
1.37 + # eg. "/this/" -> "/"
1.38 + # eg. "/this" -> "/"
1.39
1.40 new_path = parts[0:1] + (parts[2:] or [""])
1.41 new_path_info = "/".join(new_path)
1.42 trans.set_virtual_path_info(new_path_info)
1.43
1.44 + # Invoke the transaction, transferring control completely.
1.45 +
1.46 if resource is not None:
1.47 resource.respond(trans)
1.48 return
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/WebStack/Resources/Static.py Mon May 02 18:52:52 2005 +0000
2.3 @@ -0,0 +1,78 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Resources for serving static content.
2.8 +"""
2.9 +
2.10 +from WebStack.Generic import ContentType, EndOfResponse
2.11 +import os
2.12 +
2.13 +class DirectoryResource:
2.14 +
2.15 + "A resource serving the contents of a filesystem directory."
2.16 +
2.17 + def __init__(self, directory, media_types=None, unrecognised_media_type="application/data"):
2.18 +
2.19 + """
2.20 + Initialise the resource to serve files from the given 'directory'.
2.21 +
2.22 + The optional 'media_types' dictionary can be used to map filename
2.23 + extensions to media types, where extensions consist of the part of a
2.24 + name after a "." character (such as "txt", "html"), and where media
2.25 + types are the usual content descriptions (such as "text/plain" and
2.26 + "text/html").
2.27 +
2.28 + If 'media_types' contains a mapping from None to a media type, then
2.29 + this mapping is used when no extension is present on a requested
2.30 + resource name.
2.31 +
2.32 + Where no media type can be found for a resource, a predefined media
2.33 + type is set which can be overridden by specifying a value for the
2.34 + optional 'unrecognised_media_type' parameter.
2.35 + """
2.36 +
2.37 + self.directory = directory
2.38 + self.media_types = media_types or {}
2.39 + self.unrecognised_media_type = unrecognised_media_type
2.40 +
2.41 + def respond(self, trans):
2.42 +
2.43 + "Respond to the given transaction, 'trans', by serving a file."
2.44 +
2.45 + parts = trans.get_virtual_path_info().split("/")
2.46 + filename = parts[1]
2.47 + out = trans.get_response_stream()
2.48 +
2.49 + # Test for the file's existence.
2.50 +
2.51 + pathname = os.path.join(self.directory, filename)
2.52 + if not (os.path.exists(pathname) and os.path.isfile(pathname)):
2.53 + trans.set_response_code(404)
2.54 + trans.set_content_type(ContentType("text/plain"))
2.55 + out.write("Resource '%s' not found." % filename)
2.56 + raise EndOfResponse
2.57 +
2.58 + # Get the extension.
2.59 +
2.60 + extension_parts = filename.split(".")
2.61 +
2.62 + if len(extension_parts) > 1:
2.63 + extension = extension_parts[-1]
2.64 + media_type = self.media_types.get(extension)
2.65 + else:
2.66 + media_type = self.media_types.get(None)
2.67 +
2.68 + # Set the content type.
2.69 +
2.70 + if media_type is not None:
2.71 + trans.set_content_type(ContentType(media_type))
2.72 + else:
2.73 + trans.set_content_type(ContentType(self.unrecognised_media_type))
2.74 +
2.75 + # Write the file to the client.
2.76 +
2.77 + f = open(os.path.join(self.directory, filename), "rb")
2.78 + out.write(f.read())
2.79 + f.close()
2.80 +
2.81 +# vim: tabstop=4 expandtab shiftwidth=4