backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 20 Feb 2012 11:46:28 +0100
changeset 8249 c59c05c51321
parent 8246 84f0a2e0059e (current diff)
parent 8248 9550555e4c26 (diff)
child 8250 171a9d6bff8f
backport stable
__pkginfo__.py
devtools/devctl.py
--- a/.hgtags	Mon Feb 20 11:32:55 2012 +0100
+++ b/.hgtags	Mon Feb 20 11:46:28 2012 +0100
@@ -243,3 +243,5 @@
 17ebd836cee30a9f690e83af7ce98287a7216d57 cubicweb-debian-version-3.14.2-1
 60efdbb455204899103c30bfa8d805c1b15161f6 cubicweb-version-3.14.3
 4d0f5d18e8a07ab218efe90d758af723ea4a1b2b cubicweb-debian-version-3.14.3-1
+508645a542870cb0def9c43056e5084ff8def5ca cubicweb-version-3.14.4
+bc40991b7f13642d457f5ca80ac1486c29e25a6e cubicweb-debian-version-3.14.4-1
--- a/debian/changelog	Mon Feb 20 11:32:55 2012 +0100
+++ b/debian/changelog	Mon Feb 20 11:46:28 2012 +0100
@@ -1,3 +1,9 @@
+cubicweb (3.14.4-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- David Douard <david.douard@logilab.fr>  Fri, 17 Feb 2012 13:06:48 +0100
+
 cubicweb (3.14.3-1) unstable; urgency=low
 
   * new upstream release
--- a/devtools/devctl.py	Mon Feb 20 11:32:55 2012 +0100
+++ b/devtools/devctl.py	Mon Feb 20 11:46:28 2012 +0100
@@ -32,7 +32,7 @@
 from logilab.common import STD_BLACKLIST
 
 from cubicweb.__pkginfo__ import version as cubicwebversion
-from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage
+from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage, ExecutionError
 from cubicweb.cwctl import CWCTL
 from cubicweb.cwconfig import CubicWebNoAppConfiguration
 from cubicweb.toolsutils import (SKEL_EXCLUDE, Command, copy_skeleton,
@@ -377,7 +377,8 @@
                      for cube in DevConfiguration.available_cubes()]
             cubes = [cubepath for cubepath in cubes
                      if osp.exists(osp.join(cubepath, 'i18n'))]
-        update_cubes_catalogs(cubes)
+        if not update_cubes_catalogs(cubes):
+            raise ExecutionError("update cubes i18n catalog failed")
 
 
 def update_cubes_catalogs(cubes):
@@ -391,6 +392,7 @@
             import traceback
             traceback.print_exc()
             print '-> error while updating catalogs for cube', cubedir
+            return False
         else:
             # instructions pour la suite
             if toedit:
@@ -399,6 +401,7 @@
                 print '* ' + '\n* '.join(toedit)
                 print ('When you are done, run "cubicweb-ctl i18ninstance '
                        '<yourinstance>" to see changes in your instances.')
+            return True
 
 def update_cube_catalogs(cubedir):
     import shutil
--- a/i18n/de.po	Mon Feb 20 11:32:55 2012 +0100
+++ b/i18n/de.po	Mon Feb 20 11:46:28 2012 +0100
@@ -962,6 +962,9 @@
 msgid "a float is expected"
 msgstr "Eine Dezimalzahl (float) wird erwartet."
 
+msgid "a number (in seconds) or 20s, 10min, 24h or 4d are expected"
+msgstr ""
+
 msgid ""
 "a simple cache entity characterized by a name and a validity date. The "
 "target application is responsible for updating timestamp when necessary to "
--- a/i18n/en.po	Mon Feb 20 11:32:55 2012 +0100
+++ b/i18n/en.po	Mon Feb 20 11:46:28 2012 +0100
@@ -922,6 +922,9 @@
 msgid "a float is expected"
 msgstr ""
 
+msgid "a number (in seconds) or 20s, 10min, 24h or 4d are expected"
+msgstr ""
+
 msgid ""
 "a simple cache entity characterized by a name and a validity date. The "
 "target application is responsible for updating timestamp when necessary to "
--- a/i18n/es.po	Mon Feb 20 11:32:55 2012 +0100
+++ b/i18n/es.po	Mon Feb 20 11:46:28 2012 +0100
@@ -967,6 +967,9 @@
 msgid "a float is expected"
 msgstr "un nĂºmero flotante es requerido"
 
+msgid "a number (in seconds) or 20s, 10min, 24h or 4d are expected"
+msgstr ""
+
 msgid ""
 "a simple cache entity characterized by a name and a validity date. The "
 "target application is responsible for updating timestamp when necessary to "
--- a/i18n/fr.po	Mon Feb 20 11:32:55 2012 +0100
+++ b/i18n/fr.po	Mon Feb 20 11:46:28 2012 +0100
@@ -967,6 +967,9 @@
 msgid "a float is expected"
 msgstr "un nombre flottant est attendu"
 
+msgid "a number (in seconds) or 20s, 10min, 24h or 4d are expected"
+msgstr "un nombre (en seconde) ou 20s, 10min, 24h ou 4d sont attendus"
+
 msgid ""
 "a simple cache entity characterized by a name and a validity date. The "
 "target application is responsible for updating timestamp when necessary to "
--- a/server/sources/rql2sql.py	Mon Feb 20 11:32:55 2012 +0100
+++ b/server/sources/rql2sql.py	Mon Feb 20 11:46:28 2012 +0100
@@ -1454,6 +1454,8 @@
         lhs, rhs = mexpr.get_parts()
         # check for string concatenation
         operator = mexpr.operator
+        if operator == '%':
+            operator = '%%'
         try:
             if mexpr.operator == '+' and mexpr.get_type(self._state.solution, self._args) == 'String':
                 return '(%s)' % self.dbhelper.sql_concat_string(lhs.accept(self),
--- a/server/test/unittest_rql2sql.py	Mon Feb 20 11:32:55 2012 +0100
+++ b/server/test/unittest_rql2sql.py	Mon Feb 20 11:46:28 2012 +0100
@@ -1744,6 +1744,9 @@
 GROUP BY CAST(EXTRACT(YEAR from _X.cw_modification_date) AS INTEGER),CAST(EXTRACT(MONTH from _X.cw_modification_date) AS INTEGER)
 ORDER BY 1'''),
 
+    def test_modulo(self):
+        self._check('Any 5 % 2', '''SELECT (5 % 2)''')
+
 
 class SqlServer2005SQLGeneratorTC(PostgresSQLGeneratorTC):
     backend = 'sqlserver2005'
--- a/web/formfields.py	Mon Feb 20 11:32:55 2012 +0100
+++ b/web/formfields.py	Mon Feb 20 11:46:28 2012 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -43,6 +43,7 @@
 .. autoclass:: cubicweb.web.formfields.DateField()
 .. autoclass:: cubicweb.web.formfields.DateTimeField()
 .. autoclass:: cubicweb.web.formfields.TimeField()
+.. autoclass:: cubicweb.web.formfields.TimeIntervalField()
 
 Compound fields
 ''''''''''''''''
@@ -63,11 +64,13 @@
 __docformat__ = "restructuredtext en"
 
 from warnings import warn
-from datetime import datetime
+from datetime import datetime, timedelta
 
 from logilab.mtconverter import xml_escape
 from logilab.common import nullobject
 from logilab.common.date import ustrftime
+from logilab.common.configuration import format_time
+from logilab.common.textutils import apply_units, TIME_UNITS
 
 from yams.schema import KNOWN_METAATTRIBUTES, role_name
 from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
@@ -929,6 +932,38 @@
         return None
 
 
+class TimeIntervalField(StringField):
+    """Use this field to edit time interval (`Interval` yams type).
+
+    Unless explicitly specified, the widget for this field will be a
+    :class:`~cubicweb.web.formwidgets.TextInput`.
+    """
+    widget = fw.TextInput
+
+    def format_single_value(self, req, value):
+        if value:
+            value = format_time(value.days * 24 * 3600 + value.seconds)
+            return unicode(value)
+        return u''
+
+    def example_format(self, req):
+        """return a sample string describing what can be given as input for this
+        field
+        """
+        return u'20s, 10min, 24h, 4d'
+
+    def _ensure_correctly_typed(self, form, value):
+        if isinstance(value, basestring):
+            value = value.strip()
+            if not value:
+                return None
+            try:
+                value = apply_units(value, TIME_UNITS)
+            except ValueError:
+                raise ProcessFormError(form._cw._('a number (in seconds) or 20s, 10min, 24h or 4d are expected'))
+        return timedelta(0, value)
+
+
 class DateField(StringField):
     """Use this field to edit date (`Date` yams type).
 
@@ -1201,5 +1236,5 @@
     'TZDatetime': DateTimeField,
     'Time':       TimeField,
     'TZTime':     TimeField,
-    # XXX implement 'Interval': TimeIntervalField,
+    'Interval':   TimeIntervalField,
     }