XSLTools

XSLForms/Resources.py

211:a4006b6da1a0
2005-08-25 paulb [project @ 2005-08-25 14:43:34 by paulb] Changed the path encoding to UTF-8 - if this is not correct, ISO-8859-1 will be tried anyway.
     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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA    21 """    22     23 import WebStack.Generic    24 import XSLForms.Fields    25 import XSLForms.Prepare    26 import XSLForms.Output    27 from XSLTools import XSLOutput    28 import os    29     30 class XSLFormsResource:    31     32     """    33     A generic XSLForms resource for use with WebStack.    34     35     When overriding this class, define the following attributes appropriately:    36     37       * template_resources    - a dictionary mapping output identifiers to    38                                 (template_filename, output_filename) tuples,    39                                 indicating the template and stylesheet filenames    40                                 to be employed    41     42       * in_page_resources     - a dictionary mapping fragment identifiers to    43                                 (output_filename, node_identifier) tuples,    44                                 indicating the stylesheet filename to be    45                                 employed, along with the node identifier used in    46                                 the original template and output documents to    47                                 mark a region of those documents as the fragment    48                                 to be updated upon "in-page" requests    49     50       * transform_resources   - a dictionary mapping transform identifiers to    51                                 lists of stylesheet filenames for use with the    52                                 transformation methods    53     54       * document_resources    - a dictionary mapping document identifiers to    55                                 single filenames for use as source documents or    56                                 as references with the transformation methods    57     58       * resource_dir          - the absolute path of the directory in which    59                                 stylesheet resources are to reside    60     61     All filenames shall be simple leafnames for files residing in the resource's    62     special resource directory 'resource_dir'.    63     64     The following attributes may also be specified:    65     66       * path_encoding         - the assumed encoding of characters in request    67                                 paths    68     69       * encoding              - the assumed encoding of characters in request    70                                 bodies    71     """    72     73     path_encoding = "urf-8"    74     encoding = "utf-8"    75     template_resources = {}    76     in_page_resources = {}    77     transform_resources = {}    78     document_resources = {}    79     resource_dir = None    80     81     def clean_parameters(self, parameters):    82     83         """    84         Workaround stray zero value characters from Konqueror in XMLHttpRequest    85         communications.    86         """    87     88         for name, values in parameters.items():    89             new_values = []    90             for value in values:    91                 if value.endswith("\x00"):    92                     new_values.append(value[:-1])    93                 else:    94                     new_values.append(value)    95             parameters[name] = new_values    96     97     def prepare_output(self, output_identifier):    98     99         """   100         Prepare the output stylesheets using the given 'output_identifier' to   101         indicate which templates and stylesheets are to be employed in the   102         production of output from the resource.   103    104         The 'output_identifier' is used as a key to the 'template_resources'   105         dictionary attribute.   106    107         Return the full path to the output stylesheet for use with 'send_output'   108         or 'get_result'.   109         """   110    111         template_filename, output_filename = self.template_resources[output_identifier]   112         output_path = os.path.join(self.resource_dir, output_filename)   113         template_path = os.path.join(self.resource_dir, template_filename)   114         XSLForms.Prepare.ensure_stylesheet(template_path, output_path)   115         return output_path   116    117     def prepare_fragment(self, output_identifier, fragment_identifier):   118    119         """   120         Prepare the output stylesheets for the given 'output_identifier' and   121         'fragment_identifier', indicating which templates and stylesheets are to   122         be employed in the production of output from the resource.   123    124         The 'output_identifier' is used as a key to the 'template_resources'   125         dictionary attribute; the 'fragment_identifier' is used as a key to the   126         'in_page_resources' dictionary attribute.   127    128         Return the full path to the output stylesheet for use with 'send_output'   129         or 'get_result'.   130         """   131    132         output_path = self.prepare_output(output_identifier)   133         fragment_filename, node_identifier = self.in_page_resources[fragment_identifier]   134         fragment_path = os.path.join(self.resource_dir, fragment_filename)   135         XSLForms.Prepare.ensure_stylesheet_fragment(output_path, fragment_path, node_identifier)   136         return fragment_path   137    138     def send_output(self, trans, stylesheet_filenames, document, stylesheet_parameters=None, references=None):   139    140         """   141         Send the output from the resource to the user employing the transaction   142         'trans', stylesheets having the given 'stylesheet_filenames', the   143         'document' upon which the output will be based, the optional parameters   144         as defined in the 'stylesheet_parameters' dictionary, and the optional   145         'references' to external documents.   146         """   147    148         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters, references=references)   149         proc.send_output(trans.get_response_stream(), trans.get_response_stream_encoding(),   150             document)   151    152     def get_result(self, stylesheet_filenames, document, stylesheet_parameters=None, references=None):   153    154         """   155         Get the result of applying a transformation using stylesheets with the   156         given 'stylesheet_filenames', the 'document' upon which the result will   157         be based, the optional parameters as defined in the   158         'stylesheet_parameters' dictionary, and the optional 'references' to   159         external documents.   160         """   161    162         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters, references=references)   163         return proc.get_result(document)   164    165     def prepare_transform(self, transform_identifier):   166    167         """   168         Prepare a transformation using the given 'transform_identifier'.   169    170         Return a list of full paths to the output stylesheets for use with   171         'send_output' or 'get_result'.   172         """   173    174         filenames = self.transform_resources[transform_identifier]   175         paths = []   176         for filename in filenames:   177             paths.append(os.path.join(self.resource_dir, filename))   178         return paths   179    180     def prepare_document(self, document_identifier):   181    182         """   183         Prepare a document using the given 'document_identifier'.   184    185         Return the full path of the document for use either as the source   186         document or as a reference with 'send_output' or 'get_result'.   187         """   188    189         filename = self.document_resources[document_identifier]   190         return os.path.join(self.resource_dir, filename)   191    192     def get_in_page_resource(self, trans):   193    194         """   195         Return the in-page resource being referred to in the given transaction   196         'trans'.   197         """   198    199         return trans.get_path_info(self.path_encoding).split("/")[-1]   200    201     def respond(self, trans):   202    203         """   204         Respond to the request described by the given transaction 'trans'.   205         """   206    207         # Only obtain field information according to the stated method.   208    209         method = trans.get_request_method()   210         in_page_resource = self.get_in_page_resource(trans)   211    212         # Handle typical request methods, processing request information.   213    214         if method == "GET":   215    216             # Get the fields from the request path (URL).   217             # NOTE: The encoding is actually redundant since WebStack produces   218             # NOTE: Unicode values.   219    220             form = XSLForms.Fields.Form(encoding=self.path_encoding, values_are_lists=1)   221             parameters = trans.get_fields_from_path()   222             form.set_parameters(parameters)   223    224         elif method == "POST":   225    226             # Get the fields from the request body.   227             # NOTE: The encoding is actually redundant since WebStack produces   228             # NOTE: Unicode values.   229    230             form = XSLForms.Fields.Form(encoding=self.encoding, values_are_lists=1)   231             parameters = trans.get_fields_from_body(self.encoding)   232    233             # NOTE: Konqueror workaround.   234             self.clean_parameters(parameters)   235    236             form.set_parameters(parameters)   237    238         else:   239    240             # Initialise empty containers.   241    242             parameters = {}   243             documents = {}   244    245         # Call an overridden method with the processed request information.   246    247         self.respond_to_form(trans, form)   248    249     def respond_to_form(self, trans, form):   250    251         """   252         Respond to the request described by the given transaction 'trans', using   253         the given 'form' object to conveniently retrieve field (request   254         parameter) information and structured form information (as DOM-style XML   255         documents).   256         """   257    258         trans.set_response_code(500)   259         raise WebStack.Generic.EndOfResponse   260    261 # vim: tabstop=4 expandtab shiftwidth=4