[Zope-Checkins] SVN: Zope/branches/philikon-aq/lib/python/ Merge
c79698 from trunk - sane request.debug and .locale handling...
Hanno Schlichting
plone at hannosch.info
Mon Oct 15 05:38:45 EDT 2007
Log message for revision 80874:
Merge c79698 from trunk - sane request.debug and .locale handling...
Changed:
U Zope/branches/philikon-aq/lib/python/Products/Five/form/__init__.py
U Zope/branches/philikon-aq/lib/python/Products/Five/formlib/formbase.py
U Zope/branches/philikon-aq/lib/python/ZPublisher/HTTPRequest.py
U Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testHTTPRequest.py
-=-
Modified: Zope/branches/philikon-aq/lib/python/Products/Five/form/__init__.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/Products/Five/form/__init__.py 2007-10-15 04:42:12 UTC (rev 80873)
+++ Zope/branches/philikon-aq/lib/python/Products/Five/form/__init__.py 2007-10-15 09:38:44 UTC (rev 80874)
@@ -120,14 +120,11 @@
names=self.fieldNames)
if changed:
self.changed()
- # XXX: Needs locale support:
- #formatter = self.request.locale.dates.getFormatter(
- # 'dateTime', 'medium')
- #status = _("Updated on ${date_time}",
- # mapping={'date_time':
- # formatter.format(datetime.utcnow())})
+ formatter = self.request.locale.dates.getFormatter(
+ 'dateTime', 'medium')
status = _("Updated on ${date_time}",
- mapping={'date_time': str(datetime.utcnow())})
+ mapping={'date_time':
+ formatter.format(datetime.utcnow())})
self.update_status = status
return status
Modified: Zope/branches/philikon-aq/lib/python/Products/Five/formlib/formbase.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/Products/Five/formlib/formbase.py 2007-10-15 04:42:12 UTC (rev 80873)
+++ Zope/branches/philikon-aq/lib/python/Products/Five/formlib/formbase.py 2007-10-15 09:38:44 UTC (rev 80874)
@@ -59,27 +59,8 @@
class EditFormBase(FiveFormlibMixin, form.EditFormBase):
+ pass
- # Overrides formlib.form.EditFormBase.handle_edit_action, to remove
- # dependecy on request.locale
-
- @form.action(_("Apply"), condition=form.haveInputWidgets)
- def handle_edit_action(self, action, data):
- if form.applyChanges(
- self.context, self.form_fields, data, self.adapters):
-
- zope.event.notify(
- zope.lifecycleevent.ObjectModifiedEvent(self.context)
- )
- # TODO: Needs locale support. See also Five.form.EditView.
- self.status = _(
- "Updated on ${date_time}",
- mapping={'date_time': str(datetime.utcnow())}
- )
- else:
- self.status = _('No changes')
-
-
class DisplayFormBase(FiveFormlibMixin, form.DisplayFormBase):
pass
Modified: Zope/branches/philikon-aq/lib/python/ZPublisher/HTTPRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/HTTPRequest.py 2007-10-15 04:42:12 UTC (rev 80873)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/HTTPRequest.py 2007-10-15 09:38:44 UTC (rev 80874)
@@ -13,7 +13,7 @@
__version__='$Revision: 1.96 $'[11:-2]
-import re, sys, os, time, random, codecs, inspect, tempfile
+import re, sys, os, time, random, codecs, tempfile
from types import StringType, UnicodeType
from BaseRequest import BaseRequest, quote
from HTTPResponse import HTTPResponse
@@ -25,6 +25,8 @@
from maybe_lock import allocate_lock
xmlrpc=None # Placeholder for module that we'll import if we have to.
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.i18n.locales import locales, LoadLocaleError
from zope.publisher.base import DebugFlags
# This may get overwritten during configuration
@@ -240,6 +242,26 @@
"""
return self._client_addr
+ def setupLocale(self):
+ envadapter = IUserPreferredLanguages(self, None)
+ if envadapter is None:
+ self._locale = None
+ return
+
+ langs = envadapter.getPreferredLanguages()
+ for httplang in langs:
+ parts = (httplang.split('-') + [None, None])[:3]
+ try:
+ self._locale = locales.getLocale(*parts)
+ return
+ except LoadLocaleError:
+ # Just try the next combination
+ pass
+ else:
+ # No combination gave us an existing locale, so use the default,
+ # which is guaranteed to exist
+ self._locale = locales.getLocale(None, None, None)
+
def __init__(self, stdin, environ, response, clean=0):
self._orig_env=environ
# Avoid the overhead of scrubbing the environment in the
@@ -265,8 +287,9 @@
self._steps=[]
self._lazies={}
self._debug = DebugFlags()
+ # We don't set up the locale initially but just on first access
+ self._locale = _marker
-
if environ.has_key('REMOTE_ADDR'):
self._client_addr = environ['REMOTE_ADDR']
if environ.has_key('HTTP_X_FORWARDED_FOR') and self._client_addr in trusted_proxies:
@@ -1232,16 +1255,17 @@
# is discouraged and is likely to be deprecated in the future.
# request.get(key) or request[key] should be used instead
def __getattr__(self, key, default=_marker, returnTaints=0):
- # ugly hack to make request.debug work for Zope 3 code (the
- # ZPT engine, to be exact) while retaining request.debug
- # functionality for all other code
- if key == 'debug':
- lastframe = inspect.currentframe().f_back
- if lastframe.f_globals['__name__'].startswith('zope.'):
- return self._debug
-
v = self.get(key, default, returnTaints=returnTaints)
if v is _marker:
+ if key == 'locale':
+ # we only create the _locale on first access, as setting it
+ # up might be slow and we don't want to slow down every
+ # request
+ if self._locale is _marker:
+ self.setupLocale()
+ return self._locale
+ if key == 'debug':
+ return self._debug
raise AttributeError, key
return v
Modified: Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testHTTPRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testHTTPRequest.py 2007-10-15 04:42:12 UTC (rev 80873)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testHTTPRequest.py 2007-10-15 09:38:44 UTC (rev 80874)
@@ -717,44 +717,123 @@
self.assertEqual(f.next(),'test\n')
f.seek(0)
self.assertEqual(f.xreadlines(),f)
-
+
def testDebug(self):
TEST_ENVIRON = {
'REQUEST_METHOD': 'GET',
'SERVER_NAME': 'localhost',
'SERVER_PORT': '80',
}
+ from zope.publisher.base import DebugFlags
s = StringIO('')
- # accessing request.debug from non-Zope3 code will raise an
- # AttributeError
+ # when accessing request.debug we will see the DebugFlags instance
env = TEST_ENVIRON.copy()
request = HTTPRequest(s, env, None)
- request.processInputs()
- self.assertRaises(AttributeError, getattr, request, 'debug')
+ self.assert_(isinstance(request.debug, DebugFlags))
+ # It won't be available through dictonary lookup, though
+ self.assert_(request.get('debug') is None)
- # or it will actually yield a 'debug' form variable if it
- # exists
+ # request.debug will actually yield a 'debug' form variable
+ # if it exists
env = TEST_ENVIRON.copy()
env['QUERY_STRING'] = 'debug=1'
request = HTTPRequest(s, env, None)
request.processInputs()
self.assertEqual(request.debug, '1')
+ self.assertEqual(request.get('debug'), '1')
+ self.assertEqual(request['debug'], '1')
- # if we access request.debug from a Zope 3 package, however,
- # we will see the DebugFlags instance
- def getDebug(request):
- return request.debug
- # make a forged copy of getDebug that looks as if its module
- # was a Zope 3 package
- z3globals = globals().copy()
- z3globals['__name__'] = 'zope.apackage'
- import new
- getDebugFromZope3 = new.function(getDebug.func_code, z3globals)
- from zope.publisher.base import DebugFlags
- self.assertEqual(getDebug(request), '1')
- self.assert_(isinstance(getDebugFromZope3(request), DebugFlags))
-
+ # we can still override request.debug with a form variable or directly
+ env = TEST_ENVIRON.copy()
+ request = HTTPRequest(s, env, None)
+ request.processInputs()
+ self.assert_(isinstance(request.debug, DebugFlags))
+ request.form['debug'] = '1'
+ self.assertEqual(request.debug, '1')
+ request['debug'] = '2'
+ self.assertEqual(request.debug, '2')
+
+ def testLocale(self):
+ TEST_ENVIRON = {
+ 'HTTP_ACCEPT_LANGUAGE': 'en',
+ 'REQUEST_METHOD': 'GET',
+ 'SERVER_NAME': 'localhost',
+ 'SERVER_PORT': '80',
+ }
+ from StringIO import StringIO
+ from ZPublisher.HTTPRequest import HTTPRequest
+ from zope.component import provideAdapter
+ from zope.publisher.browser import BrowserLanguages
+ from zope.publisher.interfaces.http import IHTTPRequest
+ from zope.i18n.interfaces import IUserPreferredLanguages
+ from zope.i18n.interfaces.locales import ILocale
+
+ provideAdapter(BrowserLanguages, [IHTTPRequest],
+ IUserPreferredLanguages)
+ s = StringIO('')
+
+ # before accessing request.locale for the first time, request._locale
+ # is still a marker
+ from ZPublisher.HTTPRequest import _marker
+ env = TEST_ENVIRON.copy()
+ request = HTTPRequest(s, env, None)
+ self.assert_(request._locale is _marker)
+ # when accessing request.locale we will see an ILocale
+ self.assert_(ILocale.providedBy(request.locale))
+ # and request._locale has been set
+ self.assert_(request._locale is request.locale)
+ # It won't be available through dictonary lookup, though
+ self.assert_(request.get('locale') is None)
+
+ # request.locale will actually yield a 'locale' form variable
+ # if it exists
+ env = TEST_ENVIRON.copy()
+ env['QUERY_STRING'] = 'locale=1'
+ request = HTTPRequest(s, env, None)
+ request.processInputs()
+ self.assertEqual(request.locale, '1')
+ self.assertEqual(request.get('locale'), '1')
+ self.assertEqual(request['locale'], '1')
+
+ # we can still override request.locale with a form variable
+ env = TEST_ENVIRON.copy()
+ request = HTTPRequest(s, env, None)
+ request.processInputs()
+ self.assert_(ILocale.providedBy(request.locale))
+ request.form['locale'] = '1'
+ self.assertEqual(request.locale, '1')
+ request['locale'] = '2'
+ self.assertEqual(request.locale, '2')
+
+ # we should also test the correct semantics of the locale
+ for httplang in ('it', 'it-ch', 'it-CH', 'IT', 'IT-CH', 'IT-ch'):
+ env = TEST_ENVIRON.copy()
+ env['HTTP_ACCEPT_LANGUAGE'] = httplang
+ request = HTTPRequest(s, env, None)
+ locale = request.locale
+ self.assert_(ILocale.providedBy(locale))
+ parts = httplang.split('-')
+ lang = parts.pop(0).lower()
+ territory = variant = None
+ if parts:
+ territory = parts.pop(0).upper()
+ if parts:
+ variant = parts.pop(0).upper()
+ self.assertEqual(locale.id.language, lang)
+ self.assertEqual(locale.id.territory, territory)
+ self.assertEqual(locale.id.variant, variant)
+
+ # Now test for non-existant locale fallback
+ env = TEST_ENVIRON.copy()
+ env['HTTP_ACCEPT_LANGUAGE'] = 'xx'
+ request = HTTPRequest(s, env, None)
+ locale = request.locale
+ self.assert_(ILocale.providedBy(locale))
+ self.assert_(locale.id.language is None)
+ self.assert_(locale.id.territory is None)
+ self.assert_(locale.id.variant is None)
+
def testMethod(self):
TEST_ENVIRON = {
'REQUEST_METHOD': 'GET',
More information about the Zope-Checkins
mailing list