backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 15 Sep 2011 18:39:55 +0200
changeset 7797 a71618a75b53
parent 7796 8d8bde949535 (current diff)
parent 7793 8a330017ca4d (diff)
child 7798 8930f7a284dd
backport stable
__pkginfo__.py
devtools/testlib.py
doc/book/en/devrepo/datamodel/baseschema.rst
doc/book/en/devrepo/datamodel/definition.rst
entities/authobjs.py
entities/schemaobjs.py
misc/migration/bootstrapmigration_repository.py
misc/migration/postcreate.py
schema.py
schemas/__init__.py
schemas/base.py
schemas/workflow.py
server/migractions.py
server/repository.py
server/session.py
server/test/data/bootstrap_cubes
test/data/bootstrap_cubes
web/data/jquery.js
web/request.py
web/views/actions.py
web/views/autoform.py
web/views/management.py
web/views/primary.py
web/views/schema.py
--- a/debian/cubicweb-ctl.cubicweb.init	Thu Sep 15 17:36:58 2011 +0200
+++ b/debian/cubicweb-ctl.cubicweb.init	Thu Sep 15 18:39:55 2011 +0200
@@ -4,8 +4,8 @@
 # Provides:          cubicweb
 # Required-Start:    $remote_fs $syslog $local_fs $network
 # Required-Stop:     $remote_fs $syslog $local_fs $network
-# Should-Start:      $postgresql $pyro-nsd
-# Should-Stop:       $postgresql $pyro-nsd
+# Should-Start:      postgresql pyro-nsd
+# Should-Stop:       postgresql pyro-nsd
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
 # Short-Description: Start cubicweb application at boot time
--- a/i18n/fr.po	Thu Sep 15 17:36:58 2011 +0200
+++ b/i18n/fr.po	Thu Sep 15 18:39:55 2011 +0200
@@ -3239,7 +3239,7 @@
 msgstr "nombre d'entités dans la vue primaire"
 
 msgid "navigation.short-line-size"
-msgstr "description courtes"
+msgstr "taille des descriptions courtes"
 
 msgid "navtop"
 msgstr "haut de page du contenu principal"
--- a/server/querier.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/server/querier.py	Thu Sep 15 18:39:55 2011 +0200
@@ -666,7 +666,7 @@
         if server.DEBUG & (server.DBG_RQL | server.DBG_SQL):
             if server.DEBUG & (server.DBG_MORE | server.DBG_SQL):
                 print '*'*80
-            print 'querier input', rql, args
+            print 'querier input', repr(rql), repr(args)
         # parse the query and binds variables
         cachekey = rql
         try:
--- a/server/sources/__init__.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/server/sources/__init__.py	Thu Sep 15 18:39:55 2011 +0200
@@ -37,11 +37,11 @@
 
 def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
     if server.DEBUG & server.DBG_RQL:
-        print '  %s %s source: %s' % (prefix, uri, union.as_string())
+        print '  %s %s source: %s' % (prefix, uri, repr(union.as_string()))
         if varmap:
             print '    using varmap', varmap
         if server.DEBUG & server.DBG_MORE:
-            print '    args', args
+            print '    args', repr(args)
             print '    cache key', cachekey
             print '    solutions', ','.join(str(s.solutions)
                                             for s in union.children)
--- a/server/sources/native.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/server/sources/native.py	Thu Sep 15 18:39:55 2011 +0200
@@ -412,7 +412,8 @@
     def init(self, activated, source_entity):
         self.init_creating(source_entity._cw.cnxset)
         try:
-            source_entity._cw.system_sql('SELECT COUNT(asource) FROM entities')
+            # test if 'asource' column exists
+            source_entity._cw.system_sql('SELECT asource FROM entities LIMIT 1')
         except Exception, ex:
             self.eid_type_source = self.eid_type_source_pre_131
 
@@ -1650,7 +1651,7 @@
         return self._source.get_connection()
 
     def backup(self, backupfile):
-        archive=zipfile.ZipFile(backupfile, 'w')
+        archive=zipfile.ZipFile(backupfile, 'w', allowZip64=True)
         self.cnx = self.get_connection()
         try:
             self.cursor = self.cnx.cursor()
@@ -1746,7 +1747,7 @@
         return dumps((name, columns, rows), pickle.HIGHEST_PROTOCOL)
 
     def restore(self, backupfile):
-        archive = zipfile.ZipFile(backupfile, 'r')
+        archive = zipfile.ZipFile(backupfile, 'r', allowZip64=True)
         self.cnx = self.get_connection()
         self.cursor = self.cnx.cursor()
         sequences, tables, table_chunks = self.read_metadata(archive, backupfile)
--- a/web/action.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/web/action.py	Thu Sep 15 18:39:55 2011 +0200
@@ -15,7 +15,54 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""abstract action classes for CubicWeb web client"""
+"""abstract action classes for CubicWeb web client
+
+Actions are typically displayed in an action box, but can also be used
+in other parts of the interface (the user menu, the footer, etc.). The
+'order', 'category' and 'title' class attributes control how the action will
+be displayed. The 'submenu' attribute is only used for actions in the
+action box.
+
+The most important method from a developper point of view in the
+:meth:'Action.url' method, which returns a URL on which the navigation
+should directed to perform the action.  There are two common ways of
+writing that method:
+
+* do nothing special and simply return a URL to the current rset with
+  a special view (with `self._cw.build_url(...)` for instance)
+
+* define an inner function `callback_func(req, *args)` which will do
+  the work and call it through `self._cw.user_callback(callback_func,
+  args, msg)`: this method will return a URL which calls the inner
+  function, and displays the message in the web interface when the
+  callback has completed (and report any exception occuring in the
+  callback too)
+
+Many examples of the first approach are available in :mod:`cubicweb.web.views.actions`.
+
+Here is an example of the second approach:
+
+.. sourcecode:: python
+
+ from cubicweb.web import action
+ class SomeAction(action.Action):
+     __regid__ = 'mycube_some_action'
+     title = _(some action)
+     __select__ = action.Action.__select__ & is_instance('TargetEntity')
+ 
+     def url(self):
+         if self.cw_row is None:
+             eids = [row[0] for row in self.cw_rset]
+         else:
+             eids = (self.cw_rset[self.cw_row][self.cw_col or 0],)
+         def do_action(req, eids):
+             for eid in eids:
+                 entity = req.entity_from_eid(eid, 'TargetEntity')
+                 entity.perform_action()
+         msg = self._cw._('some_action performed')
+         return self._cw.user_callback(do_action, (eids,), msg)
+
+"""
 
 __docformat__ = "restructuredtext en"
 _ = unicode
--- a/web/request.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/web/request.py	Thu Sep 15 18:39:55 2011 +0200
@@ -362,10 +362,13 @@
         return self.base_url()
 
     def user_rql_callback(self, rqlargs, *args, **kwargs):
-        """register a user callback to execute some rql query and return an url
-        to call it ready to be inserted in html.
+        """register a user callback to execute some rql query, and return a URL
+        to call that callback which can be inserted in an HTML view.
 
-        rqlargs should be a tuple containing argument to give to the execute function.
+        `rqlargs` should be a tuple containing argument to give to the execute function.
+
+        The first argument following rqlargs must be the message to be
+        displayed after the callback is called.
 
         For other allowed arguments, see :meth:`user_callback` method
         """
@@ -374,8 +377,11 @@
         return self.user_callback(rqlexec, rqlargs, *args, **kwargs)
 
     def user_callback(self, cb, cbargs, *args, **kwargs):
-        """register the given user callback and return an url to call it ready
-        to be inserted in html.
+        """register the given user callback and return a URL which can
+        be inserted in an HTML view. When the URL is accessed, the
+        callback function will be called (as 'cb(req, *cbargs)', and a
+        message will be displayed in the web interface. The third
+        positional argument must be 'msg', containing the message.
 
         You can specify the underlying js function to call using a 'jsfunc'
         named args, to one of :func:`userCallback`,
--- a/web/views/cwuser.py	Thu Sep 15 17:36:58 2011 +0200
+++ b/web/views/cwuser.py	Thu Sep 15 18:39:55 2011 +0200
@@ -178,6 +178,7 @@
            'U primary_email UA?, UA address UAA, '
            'U cw_source UDS, US name UDSN')
     title = _('users and groups management')
+    cache_max_age = 0 # disable caching
 
     def call(self, **kwargs):
         self.w('<h1>%s</h1>' % self._cw._(self.title))