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', _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins