/[opental]/opental/OpenPT/OpenPTBase.py
ViewVC logotype

Diff of /opental/OpenPT/OpenPTBase.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by lalo, Mon Jan 27 19:59:12 2003 UTC revision 1.4 by lalo, Wed Jan 29 22:40:24 2003 UTC
# Line 17  Line 17 
17  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
18  __version__='$Revision$'[11:-2]  __version__='$Revision$'[11:-2]
19    
20    # ugh, this import list needs to be cleaned up
21  import OpenTAL, pax, PTmetal_handler, pax.paxtransform  import OpenTAL, pax, PTmetal_handler, pax.paxtransform
22  from pax.backwards_compatibility import *  from pax.backwards_compatibility import *
23  from ZPythonExpr import PythonExpr, SecureModuleImporter  from ZPythonExpr import PythonExpr, SecureModuleImporter
24  import cPickle as pickle  import cPickle as pickle
25  #import pickle  #import pickle
   
26  import AccessControl, Acquisition, sys  import AccessControl, Acquisition, sys
27  from Acquisition import aq_base  from Acquisition import aq_base
28  from Globals import DTMLFile, ImageFile, MessageDialog, package_home  from Globals import DTMLFile, ImageFile, MessageDialog, package_home
29  from zLOG import LOG, ERROR, INFO  from zLOG import LOG, PROBLEM, ERROR, INFO
30  from OFS.SimpleItem import SimpleItem  from OFS.SimpleItem import SimpleItem
31  from DateTime.DateTime import DateTime  from DateTime.DateTime import DateTime
32  from string import join, strip, rstrip, split, replace, lower  from string import join, strip, rstrip, split, replace, lower
# Line 47  from webdav.WriteLockInterface import Wr Line 47  from webdav.WriteLockInterface import Wr
47  from ZODB.PersistentMapping import PersistentMapping  from ZODB.PersistentMapping import PersistentMapping
48  from OFS.SimpleItem import SimpleItem  from OFS.SimpleItem import SimpleItem
49  import Globals  import Globals
50    from encodings.aliases import aliases as encoding_aliases
51  from DocumentTemplate.DT_Util import TemplateDict, InstanceDict  from DocumentTemplate.DT_Util import TemplateDict, InstanceDict
52  from AccessControl.DTML import RestrictedDTML  from AccessControl.DTML import RestrictedDTML
53  class Rtd(RestrictedDTML, TemplateDict):  class Rtd(RestrictedDTML, TemplateDict):
# Line 143  class RestrictedZopeContext(Unrestricted Line 144  class RestrictedZopeContext(Unrestricted
144          if not self._securityManager.validate(accessed, container, name, value, *a):          if not self._securityManager.validate(accessed, container, name, value, *a):
145              raise Unauthorized, name              raise Unauthorized, name
146    
147    class EncodingNegotiator(Acquisition.Explicit):
148        security = AccessControl.ClassSecurityInfo()
149        security.declareObjectPublic()
150        fallback = 'utf_8' # always acceptable
151        forced = None
152    
153        def log(self, message, severity=INFO):
154            LOG('EncodingNegotiator', severity, message)
155        
156        def __init__(self, preferred=None):
157            if preferred is None:
158                self.preferred = ('utf_8', 'utf_16')
159            else:
160                self.preferred = self.purify(preferred)
161            self.log('Initializing with %s' % self.preferred)
162            self.acceptable = sets.Set(self.preferred)
163            self.clients = []
164    
165        def purify_name(self, name):
166            "find if encoding is an alias and return the pythonic name"
167            name = name.replace('-', '_').replace(' ', '_').lower()
168            return encoding_aliases.get(name, name)
169    
170        def purify(self, encodings):
171            "find all encodings that are aliases and replace them by the pythonic name"
172            return [self.purify_name(name) for name in encodings]
173    
174        security.declarePublic('restrict')
175        def restrict(self, client, encodings):
176            "restrict the set of acceptable encodings by intersecting it with <encodings>"
177            client_id = id(client)
178            if client_id not in self.clients:
179                self.clients.append(client_id)
180                encodings = self.purify(encodings)
181                self.log('restricting with %s due to %s' % (encodings, client))
182                self.acceptable.intersection_update(sets.Set(encodings))
183                self.log('now: %s' % self.acceptable)
184            else:
185                self.log('client %s already cached' % client)
186    
187        security.declarePublic('force')
188        def force(self, encoding):
189            "force one encoding.  If it's called multiple times, bad luck, last one wins."
190            self.log('forcing %s' % encoding)
191            self.forced = encoding
192    
193        def encode(self, text):
194            if self.forced is not None:
195                try:
196                    return text.encode(self.forced), self.forced
197                except UnicodeError:
198                    self.log('Was told to force %s encoding but it failed' % self.forced, PROBLEM)
199            for enc in self.preferred:
200                if enc in self.acceptable:
201                    try:
202                        return text.encode(enc), enc
203                    except UnicodeError:
204                        pass
205            self.log('negotiation failed, falling back to %s' % self.fallback)
206            return text.encode(self.fallback), self.fallback # should never fail!
207    Globals.InitializeClass(EncodingNegotiator)
208    
209    
210  # paxtransform handlers  # paxtransform handlers
211  handler_registry = [OpenTAL.metal_handler, OpenTAL.tal_handler]  handler_registry = [OpenTAL.metal_handler, OpenTAL.tal_handler]
212  # paxtransform handlers  # paxtransform handlers
# Line 195  class OpenPageTemplate(Script, Historica Line 259  class OpenPageTemplate(Script, Historica
259      source_type = 'HTML'      source_type = 'HTML'
260      handlers = ('tal', 'metal')      handlers = ('tal', 'metal')
261      encoding = 'utf-8'      encoding = 'utf-8'
262        acceptable_encodings = ('utf_8', 'utf_16')
263      _errors = ()      _errors = ()
264      _warnings = ()      _warnings = ()
265      _text = '<opental />'      _text = '<opental />'
# Line 431  class OpenPageTemplate(Script, Historica Line 496  class OpenPageTemplate(Script, Historica
496              context = self._context_class(bound_names)              context = self._context_class(bound_names)
497              try:              try:
498                  context.encoding = self.default_zope_data_encoding                  context.encoding = self.default_zope_data_encoding
499              except:              except AttributeError:
500                  context.encoding = self.encoding                  context.encoding = self.encoding
501              context.root_xmlns_map = root_ns_map              context.root_xmlns_map = root_ns_map
502              tr_engine.initialize(context)              tr_engine.initialize(context)
503                encoding_neg = EncodingNegotiator(self.acceptable_encodings)
504                # we need the acquisition wrapper or AccessControl will squeal
505                self.REQUEST.pt_output_encoding = encoding_neg.__of__(self)
506                # now run the template
507              #result = pax.XML(tr_engine.transform(self.paxtree(), context),              #result = pax.XML(tr_engine.transform(self.paxtree(), context),
508              #                     root_ns_map, self.encoding)              #                     root_ns_map, self.encoding)
509              result = tr_engine.transform(self.paxtree(), context).text              result = tr_engine.transform(self.paxtree(), context).text
510                result, encoding = encoding_neg.encode(result)
511                # now this is hairy: how to get the official (IANA) http name
512                # of the encoding based on the python name?
513                # the hack below catches most usual cases, but far from all.
514                encoding = encoding.replace('_', '-')
515                if encoding.startswith('latin_'):
516                    encoding = 'latin' + encoding[6:]
517              if keyset is not None:              if keyset is not None:
518                  # Store the result in the cache.                  # Store the result in the cache.
519                  self.ZCacheable_set(result, keywords=keyset)                  self.ZCacheable_set(result, keywords=keyset)
520              try:              self.REQUEST.RESPONSE.setHeader('content-type', '%s; charset=%s' % (
                 self.REQUEST.RESPONSE.setHeader('content-type',  
                                                 '%s; charset=%s' % (  
521                                                   self.content_type,                                                   self.content_type,
522                                                   context.encoding))                                                   encoding))
523              except AttributeError:              print >>sys.stderr, self.REQUEST.RESPONSE.headers
                 pass  
524              return result              return result
525          finally:          finally:
526              security.removeContext(self)              security.removeContext(self)

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26