[Zope-Checkins] CVS: Zope/lib/python/ZPublisher - HTTPResponse.py:1.53.14.1
Toby Dickenson
tdickenson@geminidataloggers.com
Thu, 7 Mar 2002 04:32:01 -0500
Update of /cvs-repository/Zope/lib/python/ZPublisher
In directory cvs.zope.org:/tmp/cvs-serv25815/lib/python/ZPublisher
Modified Files:
Tag: toby-unicode-branch
HTTPResponse.py
Log Message:
first phase of dtml unicode support
=== Zope/lib/python/ZPublisher/HTTPResponse.py 1.53 => 1.53.14.1 ===
import types, sys, re
from string import translate, maketrans
-from types import StringType, InstanceType, LongType
+from types import StringType, InstanceType, LongType, UnicodeType
from BaseResponse import BaseResponse
from zExceptions import Unauthorized
@@ -230,7 +230,11 @@
if hasattr(body,'asHTML'):
body=body.asHTML()
- body=str(body)
+ body=ustr(body)
+
+ if type(body) is UnicodeType:
+ body = self._encode_unicode(body)
+
l=len(body)
if ((l < 200) and body[:1]=='<' and body.find('>')==l-1 and
bogus_str_search(body) is not None):
@@ -265,6 +269,16 @@
self.insertBase()
return self
+ def _encode_unicode(self,body,charset_re=re.compile(r'text/[0-9a-z]+\s*;\s*charset=([-_0-9a-z]+)(?:(?:\s*;)|\Z)',re.IGNORECASE)):
+ # Encode the Unicode data as requested
+ if self.headers.has_key('content-type'):
+ match = charset_re.match(self.headers['content-type'])
+ if match:
+ encoding = match.group(1)
+ return body.encode(encoding)
+ # Use the default character encoding
+ return body.encode('latin1','replace')
+
def setBase(self,base):
'Set the base URL for the returned document.'
if base[-1:] != '/':
@@ -531,7 +545,7 @@
# Try to capture exception info for bci calls
et = translate(str(t), nl2sp)
self.setHeader('bobo-exception-type', et)
- ev = translate(str(v), nl2sp)
+ ev = translate(ustr(v), nl2sp)
if ev.find( '<html>') >= 0:
ev = 'bobo exception'
self.setHeader('bobo-exception-value', ev[:255])
@@ -574,7 +588,7 @@
b = v
if isinstance(b, Exception):
try:
- b = str(b)
+ b = ustr(b)
except:
b = '<unprintable %s object>' % type(b).__name__
@@ -583,23 +597,28 @@
(str(t),
'Zope has exited normally.<p>' + self._traceback(t, v, tb)),
is_error=1)
- elif type(b) is not types.StringType or tag_search(b) is None:
- body = self.setBody(
- (str(t),
- 'Sorry, a site error occurred.<p>'
- + self._traceback(t, v, tb)),
- is_error=1)
- elif b.strip().lower()[:6]=='<html>' or \
- b.strip().lower()[:14]=='<!doctype html':
- # error is an HTML document, not just a snippet of html
- body = self.setBody(b + self._traceback(t, '(see above)', tb),
- is_error=1)
else:
- body = self.setBody((str(t),
- b + self._traceback(t,'(see above)', tb)),
- is_error=1)
- del tb
- return body
+ try:
+ match = tag_search(b)
+ except TypeError:
+ match = None
+ if match is None:
+ body = self.setBody(
+ (str(t),
+ 'Sorry, a site error occurred.<p>'
+ + self._traceback(t, v, tb)),
+ is_error=1)
+ elif b.strip().lower()[:6]=='<html>' or \
+ b.strip().lower()[:14]=='<!doctype html':
+ # error is an HTML document, not just a snippet of html
+ body = self.setBody(b + self._traceback(t, '(see above)', tb),
+ is_error=1)
+ else:
+ body = self.setBody((str(t),
+ b + self._traceback(t,'(see above)', tb)),
+ is_error=1)
+ del tb
+ return body
_wrote=None
@@ -694,3 +713,23 @@
self.stdout.write(data)
+
+# Duplicated from DocumentTemplate, to avoid the dependency.
+# Is there a better place for it?
+def ustr(v):
+ """convert an object to a string or unicode string
+ """
+ string_types = (StringType,UnicodeType)
+ if type(v) in string_types:
+ return v
+ else:
+ try:
+ fn = v.__str__
+ except AttributeError:
+ return str(v)
+ else:
+ v = fn()
+ if type(v) in string_types:
+ return v
+ else:
+ raise ValueError('__str__ returned wrong type')