XSLTools

XSLForms/Resources/WebResources.py

450:5efedee4f0fe
2005-12-06 paulb [project @ 2005-12-06 18:57:43 by paulb] Fixed the initialisation of form objects for non-GET/POST requests.
     1 #!/usr/bin/env python     2      3 """     4 Resources for use with WebStack.     5      6 Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk>     7      8 This library is free software; you can redistribute it and/or     9 modify it under the terms of the GNU Lesser General Public    10 License as published by the Free Software Foundation; either    11 version 2.1 of the License, or (at your option) any later version.    12     13 This library is distributed in the hope that it will be useful,    14 but WITHOUT ANY WARRANTY; without even the implied warranty of    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    16 Lesser General Public License for more details.    17     18 You should have received a copy of the GNU Lesser General Public    19 License along with this library; if not, write to the Free Software    20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA    21 """    22     23 import WebStack.Generic    24 import XSLForms.Fields    25 import XSLForms.Prepare    26 import XSLForms.Output    27 import XSLForms.Resources.Common    28 from XSLTools import XSLOutput    29 import os    30     31 class XSLFormsResource(XSLForms.Resources.Common.CommonResource):    32     33     """    34     A generic XSLForms resource for use with WebStack.    35     36     When overriding this class, define the following attributes appropriately:    37     38       * template_resources    - a dictionary mapping output identifiers to    39                                 (template_filename, output_filename) tuples,    40                                 indicating the template and stylesheet filenames    41                                 to be employed    42     43       * in_page_resources     - a dictionary mapping fragment identifiers to    44                                 (output_filename, node_identifier) tuples,    45                                 indicating the stylesheet filename to be    46                                 employed, along with the node identifier used in    47                                 the original template and output documents to    48                                 mark a region of those documents as the fragment    49                                 to be updated upon "in-page" requests    50     51       * init_resources        - a dictionary mapping initialiser/input    52                                 identifiers to (template_filename,    53                                 input_filename) tuples, indicating the template    54                                 and initialiser/input stylesheet filenames to be    55                                 employed    56                                     57       * transform_resources   - a dictionary mapping transform identifiers to    58                                 lists of stylesheet filenames for use with the    59                                 transformation methods    60     61       * document_resources    - a dictionary mapping document identifiers to    62                                 single filenames for use as source documents or    63                                 as references with the transformation methods    64     65       * resource_dir          - the absolute path of the directory in which    66                                 stylesheet resources are to reside    67     68     All filenames shall be simple leafnames for files residing in the resource's    69     special resource directory 'resource_dir'.    70     71     The following attributes may also be specified:    72     73       * path_encoding         - the assumed encoding of characters in request    74                                 paths    75     76       * encoding              - the assumed encoding of characters in request    77                                 bodies    78     """    79     80     path_encoding = "utf-8"    81     encoding = "utf-8"    82     template_resources = {}    83     in_page_resources = {}    84     init_resources = {}    85     transform_resources = {}    86     87     def clean_parameters(self, parameters):    88     89         """    90         Workaround stray zero value characters from Konqueror in XMLHttpRequest    91         communications.    92         """    93     94         for name, values in parameters.items():    95             new_values = []    96             for value in values:    97                 if value.endswith("\x00"):    98                     new_values.append(value[:-1])    99                 else:   100                     new_values.append(value)   101             parameters[name] = new_values   102    103     def prepare_output(self, output_identifier):   104    105         """   106         Prepare the output stylesheets using the given 'output_identifier' to   107         indicate which templates and stylesheets are to be employed in the   108         production of output from the resource.   109    110         The 'output_identifier' is used as a key to the 'template_resources'   111         dictionary attribute.   112    113         Return the full path to the output stylesheet for use with 'send_output'   114         or 'get_result'.   115         """   116    117         template_filename, output_filename = self.template_resources[output_identifier]   118         output_path = os.path.abspath(os.path.join(self.resource_dir, output_filename))   119         template_path = os.path.abspath(os.path.join(self.resource_dir, template_filename))   120         XSLForms.Prepare.ensure_stylesheet(template_path, output_path)   121         return output_path   122    123     def prepare_fragment(self, output_identifier, fragment_identifier):   124    125         """   126         Prepare the output stylesheets for the given 'output_identifier' and   127         'fragment_identifier', indicating which templates and stylesheets are to   128         be employed in the production of output from the resource.   129    130         The 'output_identifier' is used as a key to the 'template_resources'   131         dictionary attribute; the 'fragment_identifier' is used as a key to the   132         'in_page_resources' dictionary attribute.   133    134         Return the full path to the output stylesheet for use with 'send_output'   135         or 'get_result'.   136         """   137    138         output_path = self.prepare_output(output_identifier)   139         fragment_filename, node_identifier = self.in_page_resources[fragment_identifier]   140         fragment_path = os.path.abspath(os.path.join(self.resource_dir, fragment_filename))   141         XSLForms.Prepare.ensure_stylesheet_fragment(output_path, fragment_path, node_identifier)   142         return fragment_path   143    144     def prepare_parameters(self, parameters):   145    146         """   147         Prepare the stylesheet parameters from the given request 'parameters'.   148         This is most useful when preparing fragments for in-page update output.   149         """   150    151         element_path = parameters.get("element-path", [""])[0]   152         if element_path:   153             return {"element-path" : element_path}   154         else:   155             return {}   156    157     def send_output(self, trans, stylesheet_filenames, document, stylesheet_parameters=None,   158         stylesheet_expressions=None, references=None):   159    160         """   161         Send the output from the resource to the user employing the transaction   162         'trans', stylesheets having the given 'stylesheet_filenames', the   163         'document' upon which the output will be based, the optional parameters   164         as defined in the 'stylesheet_parameters' dictionary, the optional   165         expressions are defined in the 'stylesheet_expressions' dictionary, and   166         the optional 'references' to external documents.   167         """   168    169         # Sanity check for the filenames list.   170    171         if isinstance(stylesheet_filenames, str) or isinstance(stylesheet_filenames, unicode):   172             raise ValueError, stylesheet_filenames   173    174         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters,   175             expressions=stylesheet_expressions, references=references)   176         proc.send_output(trans.get_response_stream(), trans.get_response_stream_encoding(),   177             document)   178    179     def get_result(self, stylesheet_filenames, document, stylesheet_parameters=None,   180         stylesheet_expressions=None, references=None):   181    182         """   183         Get the result of applying a transformation using stylesheets with the   184         given 'stylesheet_filenames', the 'document' upon which the result will   185         be based, the optional parameters as defined in the   186         'stylesheet_parameters' dictionary, the optional parameters as defined   187         in the 'stylesheet_parameters' dictionaryand the optional 'references'   188         to external documents.   189         """   190    191         # Sanity check for the filenames list.   192    193         if isinstance(stylesheet_filenames, str) or isinstance(stylesheet_filenames, unicode):   194             raise ValueError, stylesheet_filenames   195    196         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters,   197             expressions=stylesheet_expressions, references=references)   198         return proc.get_result(document)   199    200     def prepare_initialiser(self, input_identifier, init_enumerations=1):   201    202         """   203         Prepare an initialiser/input transformation using the given   204         'input_identifier'. The optional 'init_enumerations' (defaulting to   205         true) may be used to indicate whether enumerations are to be initialised   206         from external documents.   207    208         Return the full path to the input stylesheet for use with 'send_output'   209         or 'get_result'.   210         """   211    212         template_filename, input_filename = self.init_resources[input_identifier]   213         input_path = os.path.abspath(os.path.join(self.resource_dir, input_filename))   214         template_path = os.path.abspath(os.path.join(self.resource_dir, template_filename))   215         XSLForms.Prepare.ensure_input_stylesheet(template_path, input_path, init_enumerations)   216         return input_path   217    218     def prepare_transform(self, transform_identifier):   219    220         """   221         Prepare a transformation using the given 'transform_identifier'.   222    223         Return a list of full paths to the output stylesheets for use with   224         'send_output' or 'get_result'.   225         """   226    227         filenames = self.transform_resources[transform_identifier]   228    229         # Sanity check for the filenames list.   230    231         if isinstance(filenames, str) or isinstance(filenames, unicode):   232             raise ValueError, filenames   233    234         paths = []   235         for filename in filenames:   236             paths.append(os.path.abspath(os.path.join(self.resource_dir, filename)))   237         return paths   238    239     def get_in_page_resource(self, trans):   240    241         """   242         Return the in-page resource being referred to in the given transaction   243         'trans'.   244         """   245    246         return trans.get_path_info(self.path_encoding).split("/")[-1]   247    248     def respond(self, trans):   249    250         """   251         Respond to the request described by the given transaction 'trans'.   252         """   253    254         # Only obtain field information according to the stated method.   255    256         method = trans.get_request_method()   257         in_page_resource = self.get_in_page_resource(trans)   258    259         # Handle typical request methods, processing request information.   260    261         if method == "GET":   262    263             # Get the fields from the request path (URL).   264             # NOTE: The encoding is actually redundant since WebStack produces   265             # NOTE: Unicode values.   266    267             form = XSLForms.Fields.Form(encoding=self.path_encoding, values_are_lists=1)   268             parameters = trans.get_fields_from_path()   269             form.set_parameters(parameters)   270    271         elif method == "POST":   272    273             # Get the fields from the request body.   274             # NOTE: The encoding is actually redundant since WebStack produces   275             # NOTE: Unicode values.   276    277             form = XSLForms.Fields.Form(encoding=self.encoding, values_are_lists=1)   278             parameters = trans.get_fields_from_body(self.encoding)   279    280             # NOTE: Konqueror workaround.   281             self.clean_parameters(parameters)   282    283             form.set_parameters(parameters)   284    285         else:   286    287             # Initialise empty container.   288    289             form = XSLForms.Fields.Form(encoding=self.encoding, values_are_lists=1)   290    291         # Call an overridden method with the processed request information.   292    293         self.respond_to_form(trans, form)   294    295     def respond_to_form(self, trans, form):   296    297         """   298         Respond to the request described by the given transaction 'trans', using   299         the given 'form' object to conveniently retrieve field (request   300         parameter) information and structured form information (as DOM-style XML   301         documents).   302         """   303    304         trans.set_response_code(500)   305         raise WebStack.Generic.EndOfResponse   306    307 # vim: tabstop=4 expandtab shiftwidth=4