XSLTools

XSLForms/Resources.py

260:03cee0e46a02
2005-10-03 paulb [project @ 2005-10-03 00:53:24 by paulb] Introduced input/initialiser stylesheets in place of the types stylesheets previously used.
     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       * init_resources        - a dictionary mapping initialiser/input    51                                 identifiers to (template_filename,    52                                 input_filename) tuples, indicating the template    53                                 and initialiser/input stylesheet filenames to be    54                                 employed    55                                     56       * transform_resources   - a dictionary mapping transform identifiers to    57                                 lists of stylesheet filenames for use with the    58                                 transformation methods    59     60       * document_resources    - a dictionary mapping document identifiers to    61                                 single filenames for use as source documents or    62                                 as references with the transformation methods    63     64       * resource_dir          - the absolute path of the directory in which    65                                 stylesheet resources are to reside    66     67     All filenames shall be simple leafnames for files residing in the resource's    68     special resource directory 'resource_dir'.    69     70     The following attributes may also be specified:    71     72       * path_encoding         - the assumed encoding of characters in request    73                                 paths    74     75       * encoding              - the assumed encoding of characters in request    76                                 bodies    77     """    78     79     path_encoding = "utf-8"    80     encoding = "utf-8"    81     template_resources = {}    82     in_page_resources = {}    83     transform_resources = {}    84     document_resources = {}    85     resource_dir = None    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 send_output(self, trans, stylesheet_filenames, document, stylesheet_parameters=None, references=None):   145    146         """   147         Send the output from the resource to the user employing the transaction   148         'trans', stylesheets having the given 'stylesheet_filenames', the   149         'document' upon which the output will be based, the optional parameters   150         as defined in the 'stylesheet_parameters' dictionary, and the optional   151         'references' to external documents.   152         """   153    154         # Sanity check for the filenames list.   155    156         if isinstance(stylesheet_filenames, str) or isinstance(stylesheet_filenames, unicode):   157             raise ValueError, stylesheet_filenames   158    159         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters, references=references)   160         proc.send_output(trans.get_response_stream(), trans.get_response_stream_encoding(),   161             document)   162    163     def get_result(self, stylesheet_filenames, document, stylesheet_parameters=None, references=None):   164    165         """   166         Get the result of applying a transformation using stylesheets with the   167         given 'stylesheet_filenames', the 'document' upon which the result will   168         be based, the optional parameters as defined in the   169         'stylesheet_parameters' dictionary, and the optional 'references' to   170         external documents.   171         """   172    173         # Sanity check for the filenames list.   174    175         if isinstance(stylesheet_filenames, str) or isinstance(stylesheet_filenames, unicode):   176             raise ValueError, stylesheet_filenames   177    178         proc = XSLOutput.Processor(stylesheet_filenames, parameters=stylesheet_parameters, references=references)   179         return proc.get_result(document)   180    181     def prepare_initialiser(self, input_identifier):   182    183         """   184         Prepare an initialiser/input transformation using the given   185         'input_identifier'.   186    187         Return the full path to the input stylesheet for use with 'send_output'   188         or 'get_result'.   189         """   190    191         template_filename, input_filename = self.init_resources[input_identifier]   192         input_path = os.path.abspath(os.path.join(self.resource_dir, input_filename))   193         template_path = os.path.abspath(os.path.join(self.resource_dir, template_filename))   194         XSLForms.Prepare.ensure_input_stylesheet(template_path, input_path)   195         return input_path   196    197     def prepare_transform(self, transform_identifier):   198    199         """   200         Prepare a transformation using the given 'transform_identifier'.   201    202         Return a list of full paths to the output stylesheets for use with   203         'send_output' or 'get_result'.   204         """   205    206         filenames = self.transform_resources[transform_identifier]   207         paths = []   208         for filename in filenames:   209             paths.append(os.path.abspath(os.path.join(self.resource_dir, filename)))   210         return paths   211    212     def prepare_document(self, document_identifier):   213    214         """   215         Prepare a document using the given 'document_identifier'.   216    217         Return the full path of the document for use either as the source   218         document or as a reference with 'send_output' or 'get_result'.   219         """   220    221         filename = self.document_resources[document_identifier]   222         return os.path.abspath(os.path.join(self.resource_dir, filename))   223    224     def get_in_page_resource(self, trans):   225    226         """   227         Return the in-page resource being referred to in the given transaction   228         'trans'.   229         """   230    231         return trans.get_path_info(self.path_encoding).split("/")[-1]   232    233     def respond(self, trans):   234    235         """   236         Respond to the request described by the given transaction 'trans'.   237         """   238    239         # Only obtain field information according to the stated method.   240    241         method = trans.get_request_method()   242         in_page_resource = self.get_in_page_resource(trans)   243    244         # Handle typical request methods, processing request information.   245    246         if method == "GET":   247    248             # Get the fields from the request path (URL).   249             # NOTE: The encoding is actually redundant since WebStack produces   250             # NOTE: Unicode values.   251    252             form = XSLForms.Fields.Form(encoding=self.path_encoding, values_are_lists=1)   253             parameters = trans.get_fields_from_path()   254             form.set_parameters(parameters)   255    256         elif method == "POST":   257    258             # Get the fields from the request body.   259             # NOTE: The encoding is actually redundant since WebStack produces   260             # NOTE: Unicode values.   261    262             form = XSLForms.Fields.Form(encoding=self.encoding, values_are_lists=1)   263             parameters = trans.get_fields_from_body(self.encoding)   264    265             # NOTE: Konqueror workaround.   266             self.clean_parameters(parameters)   267    268             form.set_parameters(parameters)   269    270         else:   271    272             # Initialise empty containers.   273    274             parameters = {}   275             documents = {}   276    277         # Call an overridden method with the processed request information.   278    279         self.respond_to_form(trans, form)   280    281     def respond_to_form(self, trans, form):   282    283         """   284         Respond to the request described by the given transaction 'trans', using   285         the given 'form' object to conveniently retrieve field (request   286         parameter) information and structured form information (as DOM-style XML   287         documents).   288         """   289    290         trans.set_response_code(500)   291         raise WebStack.Generic.EndOfResponse   292    293 # vim: tabstop=4 expandtab shiftwidth=4