[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