1 #!/usr/bin/env python 2 3 "A WebStack application for a system configurator." 4 5 import WebStack.Generic 6 import XSLForms.Fields 7 import XSLForms.Output 8 import XSLForms.Prepare 9 import XSLForms.Utils 10 import XSLOutput 11 import libxml2dom 12 import os 13 14 class ConfiguratorResource: 15 16 "A resource providing a system configurator." 17 18 resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") 19 encoding = "utf-8" 20 in_page_resources = { 21 "/cpu" : ("config_output_cpu.xsl", "cpu-node"), 22 "/memory" : ("config_output_memory.xsl", "memory-node"), 23 "/hard-disks" : ("config_output_harddisks.xsl", "hard-disks-node") 24 } 25 26 def get_fields_from_body(self, trans, encoding): 27 text = trans.get_request_stream().read() 28 parameters = {} 29 for text_line in text.split("\r\n"): 30 text_parts = text_line.split("=") 31 text_name, text_value = text_parts[0], "=".join(text_parts[1:]) 32 if not parameters.has_key(text_name): 33 parameters[text_name] = [] 34 # NOTE: Workaround from posted text. 35 if text_value[-1] == "\x00": 36 text_value = text_value[:-1] 37 parameters[text_name].append(text_value) 38 return parameters 39 40 def respond(self, trans): 41 42 global XSLForms # NOTE: Strangely required to avoid UnboundLocalError! 43 44 # Only obtain field information according to the stated method. 45 46 method = trans.get_request_method() 47 path_info = trans.get_path_info() 48 49 if method == "GET": 50 fields = XSLForms.Fields.Fields(encoding="iso-8859-1", values_are_lists=1) 51 parameters = trans.get_fields_from_path() 52 documents = fields.make_documents(parameters.items()) 53 elif method == "POST": 54 fields = XSLForms.Fields.Fields(encoding=self.encoding, values_are_lists=1) 55 56 # Handle requests for fragments. 57 58 if path_info in self.in_page_resources.keys(): 59 parameters = self.get_fields_from_body(trans, self.encoding) 60 else: 61 parameters = trans.get_fields_from_body(self.encoding) 62 63 # Get the XML representation of the request. 64 65 documents = fields.make_documents(parameters.items()) 66 else: 67 trans.set_response_code(405) 68 raise WebStack.Generic.EndOfResponse 69 70 # Ensure the presence of a document. 71 72 if documents.has_key("configuration"): 73 configuration = documents["configuration"] 74 else: 75 configuration = fields.new_instance("configuration") 76 #print "*", configuration.toString() 77 78 # Add and remove elements according to the selectors found. 79 80 selectors = fields.get_selectors(parameters.items(), documents) 81 XSLForms.Utils.add_elements(selectors.get("add-memory-unit"), "memory-unit") 82 XSLForms.Utils.remove_elements(selectors.get("remove-memory-unit")) 83 XSLForms.Utils.add_elements(selectors.get("add-storage-unit"), "storage-unit") 84 XSLForms.Utils.remove_elements(selectors.get("remove-storage-unit")) 85 XSLForms.Utils.add_elements(selectors.get("add-hard-disk"), "hard-disk") 86 XSLForms.Utils.remove_elements(selectors.get("remove-hard-disk")) 87 88 # Send a response according to certain parameters. 89 # When exported, an XML version of the data is returned. 90 91 if parameters.has_key("export"): 92 trans.set_content_type(WebStack.Generic.ContentType("text/xml", self.encoding)) 93 configuration.toStream(trans.get_response_stream(), trans.get_response_stream_encoding()) 94 95 # When not exported, the data is transformed to produce a normal Web 96 # page. 97 98 else: 99 100 # Transform, adding enumerations/ranges. 101 102 database_xsl = os.path.join(self.resource_dir, "config_database.xsl") 103 database_xml = os.path.join(self.resource_dir, "config_database.xml") 104 proc = XSLOutput.Processor([database_xsl], references={"database" : database_xml}) 105 configuration = proc.get_result(configuration) 106 107 # Start the response. 108 109 trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding)) 110 111 # Define the stylesheet parameters. 112 113 stylesheet_parameters = {} 114 115 # Ensure that an output stylesheet exists. 116 117 if path_info in self.in_page_resources.keys(): 118 trans_xsl_filename, trans_xsl_region = self.in_page_resources[path_info] 119 template_xml = os.path.join(self.resource_dir, "config_output.xsl") 120 trans_xsl = os.path.join(self.resource_dir, trans_xsl_filename) 121 XSLForms.Prepare.ensure_stylesheet_fragment(template_xml, trans_xsl, trans_xsl_region) 122 element_path = parameters.get("element-path", [""])[0] 123 stylesheet_parameters["element-path"] = element_path 124 #print "*", repr(stylesheet_parameters["element-path"]) 125 else: 126 trans_xsl = os.path.join(self.resource_dir, "config_output.xsl") 127 template_xml = os.path.join(self.resource_dir, "config_template.xhtml") 128 XSLForms.Prepare.ensure_stylesheet(template_xml, trans_xsl) 129 130 stylesheet_parameters["application-url"] = \ 131 "http://%s:%s%s" % (trans.get_server_name(), trans.get_server_port(), trans.get_path_without_query()) 132 133 # Complete the response. 134 135 proc = XSLOutput.Processor([trans_xsl], parameters=stylesheet_parameters) 136 proc.send_output(trans.get_response_stream(), trans.get_response_stream_encoding(), 137 configuration) 138 139 #import sys 140 #proc = XSLOutput.Processor([trans_xsl], parameters=stylesheet_parameters) 141 #proc.send_output(sys.stderr, "iso-8859-1", configuration) 142 143 # vim: tabstop=4 expandtab shiftwidth=4