# HG changeset patch # User paulb # Date 1104372215 0 # Node ID 8ba9ea11cbe5bec2c2570857a1a3d75ab0f3dc0d # Parent 8b720272b3123809cd49538dfd1a053ef1e76901 [project @ 2004-12-30 02:03:30 by paulb] Added another example application. diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/BaseHTTPRequestHandler/ConfiguratorApp.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/BaseHTTPRequestHandler/ConfiguratorApp.py Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +from WebStack.Adapters import BaseHTTPRequestHandler +from Configurator import ConfiguratorResource +import BaseHTTPServer + +# Special magic incantation. + +handler = BaseHTTPRequestHandler.HandlerFactory(ConfiguratorResource()) +address = ("", 8080) +server = BaseHTTPServer.HTTPServer(address, handler) +print "Serving..." +server.serve_forever() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/Resources/config_database.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/config_database.xml Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/Resources/config_database.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/config_database.xsl Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,104 @@ + + + + + + + + + +
+ + + base-system + + + + cpu + +
+ + + + + memory-unit + + + + + + + + hard-disk + + + + + + + + storage-unit + + + + + + + keyboard + + + + mouse + + + + screen + + +
+
+ + + + + -enum + + + + + + + + + + + + + + + true + + + + + true + + + + + + + + + + + + + + + + + +
diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/Resources/config_input.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/config_input.xml Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,11 @@ + + +
+ + +
+ + + + +
diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/Resources/config_template.xhtml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/config_template.xhtml Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,131 @@ + + + + + System Configurator + + + + + +

System Configurator

+ +
+
+
+

Base System

+ +

Model + +

+ +

Processor

+ +

CPU + +

+
+ +
+

Memory

+ +

Memory unit + + +

+ +

+

+
+
+ +
+
+

Input Devices

+ +

Keyboard + +

+ +

Mouse + +

+ +

Display

+ +

Screen + +

+
+ +
+

Price

+ +

Total for this configuration: +

+ +

+ +

+
+
+
+ + diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/Resources/styles.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/styles.css Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,40 @@ +#left { + float: left; + width: 50%; +} + +#right { + float: right; + width: 50%; +} + +#bottom { + position: relative; + width: 100%; +} + +div.details { + width: 100%; +} + +div.memory { + width: 100%; +} + +div.hard-disks { + width: 100%; +} + +div.storage { + width: 100%; +} + +div.peripherals { + float: right; + width: 50%; +} + +div.price { + float: left; + width: 50%; +} diff -r 8b720272b312 -r 8ba9ea11cbe5 examples/Common/Configurator/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/__init__.py Thu Dec 30 02:03:35 2004 +0000 @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +"A WebStack application for a system configurator." + +import WebStack.Generic +import XSLForms.Fields +import XSLForms.Output +import XSLOutput +import libxml2dom +import os + +# NOTE: Move these functions into a common utility library. + +def add_elements(positions, element_name, element_parent_name=None): + if not positions: + return + for position in positions: + if element_parent_name: + parent_elements = position.xpath(element_parent_name) + if not parent_elements: + parent_element = position.ownerDocument.createElementNS(None, element_parent_name) + position.appendChild(parent_element) + else: + parent_element = parent_elements[0] + else: + parent_element = position + parent_element.appendChild(position.ownerDocument.createElementNS(None, element_name)) + +def remove_elements(positions): + if not positions: + return + for position in positions: + position.parentNode.removeChild(position) + +class ConfiguratorResource: + + "A resource providing a system configurator." + + resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") + encoding = "utf-8" + + def respond(self, trans): + + # Produce stylesheet. + + if trans.get_path_info().split("/")[-1] == "styles.css": + trans.set_content_type(WebStack.Generic.ContentType("text/css", self.encoding)) + out = trans.get_response_stream() + f = open(os.path.join(self.resource_dir, "styles.css"), "rb") + out.write(f.read()) + f.close() + raise WebStack.Generic.EndOfResponse + + global XSLForms # NOTE: Strangely required to avoid UnboundLocalError! + method = trans.get_request_method() + + # Only obtain field information according to the stated method. + + if method == "GET": + fields = XSLForms.Fields.Fields(encoding="iso-8859-1", values_are_lists=1) + parameters = trans.get_fields_from_path() + documents = fields.make_documents(parameters.items()) + elif method == "POST": + fields = XSLForms.Fields.Fields(encoding=self.encoding, values_are_lists=1) + parameters = trans.get_fields_from_body(self.encoding) + documents = fields.make_documents(parameters.items()) + else: + trans.set_response_code(405) + raise WebStack.Generic.EndOfResponse + + # Ensure the presence of a document. + + if documents.has_key("configuration"): + configuration = documents["configuration"] + else: + configuration = fields.new_instance("configuration") + + # Add and remove elements according to the selectors found. + + selectors = fields.get_selectors(parameters.items(), documents) + add_elements(selectors.get("add-memory-unit"), "memory-unit") + remove_elements(selectors.get("remove-memory-unit")) + add_elements(selectors.get("add-storage-unit"), "storage-unit") + remove_elements(selectors.get("remove-storage-unit")) + add_elements(selectors.get("add-hard-disk"), "hard-disk") + remove_elements(selectors.get("remove-hard-disk")) + + # Send a response according to certain parameters. + # When exported, an XML version of the data is returned. + + if parameters.has_key("export"): + trans.set_content_type(WebStack.Generic.ContentType("text/xml", self.encoding)) + libxml2dom.toStream(configuration, trans.get_response_stream(), trans.get_response_stream_encoding()) + + # When not exported, the data is transformed to produce a normal Web + # page. + + else: + + # Transform, adding enumerations/ranges. + + database_xsl = os.path.join(self.resource_dir, "config_database.xsl") + database_xml = os.path.join(self.resource_dir, "config_database.xml") + proc = XSLOutput.Processor([database_xsl], {"database" : database_xml}) + configuration = proc.get_result(configuration) + + # Start the response. + + trans.set_content_type(WebStack.Generic.ContentType("text/html", self.encoding)) + + # Ensure that an output stylesheet exists. + + trans_xsl = os.path.join(self.resource_dir, "config_output.xsl") + template_xml = os.path.join(self.resource_dir, "config_template.xhtml") + + if not os.path.exists(trans_xsl) or \ + os.path.getmtime(trans_xsl) < os.path.getmtime(template_xml): + + import XSLForms.Prepare + template_xml = os.path.join(self.resource_dir, "config_template.xhtml") + XSLForms.Prepare.make_stylesheet(template_xml, trans_xsl) + + # Complete the response. + + proc = XSLOutput.Processor([trans_xsl]) + proc.send_output(trans.get_response_stream(), trans.get_response_stream_encoding(), + configuration) + +# vim: tabstop=4 expandtab shiftwidth=4