backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 23 May 2012 16:17:46 +0200
changeset 8425 b86bdc343c18
parent 8412 09432a572a44 (current diff)
parent 8424 664d0bf525c8 (diff)
child 8426 1cb51cdb4ce7
backport stable
.hgtags
__pkginfo__.py
debian/changelog
server/utils.py
view.py
web/data/cubicweb.css
web/data/cubicweb.old.css
web/views/baseviews.py
web/views/formrenderers.py
web/views/tableview.py
--- a/.hgtags	Tue May 22 12:41:18 2012 +0200
+++ b/.hgtags	Wed May 23 16:17:46 2012 +0200
@@ -254,3 +254,5 @@
 925db25a3250c5090cf640fc2b02bde5818b9798 cubicweb-debian-version-3.15.0-1
 3ba3ee5b3a89a54d1dc12ed41d5c12232eda1952 cubicweb-version-3.14.7
 20ee573bd2379a00f29ff27bb88a8a3344d4cdfe cubicweb-debian-version-3.14.7-1
+15fe07ff687238f8cc09d8e563a72981484085b3 cubicweb-version-3.14.8
+81394043ad226942ac0019b8e1d4f7058d67a49f cubicweb-debian-version-3.14.8-1
--- a/debian/changelog	Tue May 22 12:41:18 2012 +0200
+++ b/debian/changelog	Wed May 23 16:17:46 2012 +0200
@@ -4,6 +4,12 @@
 
  -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Thu, 12 Apr 2012 13:52:05 +0200
 
+cubicweb (3.14.8-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Wed, 23 May 2012 11:42:54 +0200
+
 cubicweb (3.14.7-1) unstable; urgency=low
 
   * new upstream release
--- a/doc/book/en/devweb/views/views.rst	Tue May 22 12:41:18 2012 +0200
+++ b/doc/book/en/devweb/views/views.rst	Wed May 23 16:17:46 2012 +0200
@@ -35,30 +35,7 @@
 Class `View` (`cubicweb.view`)
 ```````````````````````````````
 
-This class is an abstraction of a view class, used as a base class for
-every renderable object such as views, templates and other user
-interface components.
-
-A `View` is instantiated to render a result set or part of a result
-set. `View` subclasses may be parametrized using the following class
-attributes:
-
-* `templatable` indicates if the view may be embedded in a main
-  template or if it has to be rendered standalone (i.e. pure XML views
-  must not be embedded in the main template of HTML pages)
-
-* if the view is not templatable, it should set the `content_type`
-  class attribute to the correct MIME type (text/xhtml being the
-  default)
-
-* the `category` attribute may be used in the interface to regroup
-  related view kinds together
-
-A view writes to its output stream thanks to its attribute `w` (the
-append method of an `UStreamIO`, except for binary views).
-
-At instantiation time, the standard `_cw` and `cw_rset` attributes are
-added and the `w` attribute will be set at rendering time.
+.. autoclass:: cubicweb.view.View
 
 The basic interface for views is as follows (remember that the result
 set has a tabular structure with rows and columns, hence cells):
@@ -88,12 +65,13 @@
 
 Other basic view classes
 ````````````````````````
-Here are some of the subclasses of `View` defined in `cubicweb.view`
+Here are some of the subclasses of :ref:`View` defined in :ref:`cubicweb.view`
 that are more concrete as they relate to data rendering within the application:
 
-* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
-* `StartupView`, start view that does not require a result set to apply to
-* `AnyRsetView`, view applicable to any result set
+.. autoclass:: cubicweb.view.EntityView
+.. autoclass:: cubicweb.view.StartupView
+.. autoclass:: cubicweb.view.EntityStartupView
+.. autoclass:: cubicweb.view.AnyRsetView
 
 Examples of views class
 ```````````````````````
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/test/unittest_utils.py	Wed May 23 16:17:46 2012 +0200
@@ -0,0 +1,43 @@
+# copyright 2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+from logilab.common.testlib import TestCase, unittest_main
+
+from cubicweb.server import utils
+
+class UtilsTC(TestCase):
+    def test_crypt(self):
+        for hash in (
+            utils.crypt_password('xxx'), # default sha512
+            'ab$5UsKFxRKKN.d8iBIFBnQ80', # custom md5
+            'ab4Vlm81ZUHlg', # DES
+            ):
+            self.assertEqual(utils.crypt_password('xxx', hash), hash)
+            self.assertEqual(utils.crypt_password(u'xxx', hash), hash)
+            self.assertEqual(utils.crypt_password(u'xxx', unicode(hash)), hash)
+            self.assertEqual(utils.crypt_password('yyy', hash), '')
+
+        # accept any password for empty hashes (is it a good idea?)
+        self.assertEqual(utils.crypt_password('xxx', ''), '')
+        self.assertEqual(utils.crypt_password('yyy', ''), '')
+
+
+if __name__ == '__main__':
+    unittest_main()
--- a/server/utils.py	Tue May 22 12:41:18 2012 +0200
+++ b/server/utils.py	Wed May 23 16:17:46 2012 +0200
@@ -39,19 +39,18 @@
 
     @classmethod
     def from_string(cls, hash):
-        if hash is None:
-            raise ValueError("no hash specified")
-        if hash.count('$') != 1:
-            raise ValueError("invalid cubicweb-md5 hash")
-        salt = hash.split('$', 1)[0]
-        chk = hash.split('$', 1)[1]
-        return cls(salt=salt, checksum=chk, strict=True)
+        salt, chk = uh.parse_mc2(hash, u'')
+        if chk is None:
+            raise ValueError('missing checksum')
+        return cls(salt=salt, checksum=chk)
 
     def to_string(self):
         return to_hash_str(u'%s$%s' % (self.salt, self.checksum or u''))
 
+    # passlib 1.5 wants calc_checksum, 1.6 wants _calc_checksum
     def calc_checksum(self, secret):
-        return md5crypt(secret, self.salt.encode('ascii'))
+        return md5crypt(secret, self.salt.encode('ascii')).decode('utf-8')
+    _calc_checksum = calc_checksum
 
 _CRYPTO_CTX = CryptContext(['sha512_crypt', CustomMD5Crypt, 'des_crypt', 'ldap_salted_sha1'])
 
--- a/view.py	Tue May 22 12:41:18 2012 +0200
+++ b/view.py	Wed May 23 16:17:46 2012 +0200
@@ -90,19 +90,30 @@
 # base view object ############################################################
 
 class View(AppObject):
-    """abstract view class, used as base for every renderable object such
-    as views, templates, some components...web
+    """This class is an abstraction of a view class, used as a base class for
+    every renderable object such as views, templates and other user interface
+    components.
 
-    A view is instantiated to render a [part of a] result set. View
-    subclasses may be parametred using the following class attributes:
+    A `View` is instantiated to render a result set or part of a result
+    set. `View` subclasses may be parametrized using the following class
+    attributes:
 
-    * `templatable` indicates if the view may be embeded in a main
-      template or if it has to be rendered standalone (i.e. XML for
-      instance)
-    * if the view is not templatable, it should set the `content_type` class
-      attribute to the correct MIME type (text/xhtml by default)
-    * the `category` attribute may be used in the interface to regroup related
-      objects together
+    :py:attr:`templatable` indicates if the view may be embedded in a main
+      template or if it has to be rendered standalone (i.e. pure XML views must
+      not be embedded in the main template of HTML pages)
+    :py:attr:`content_type` if the view is not templatable, it should set the
+      `content_type` class attribute to the correct MIME type (text/xhtml being
+      the default)
+    :py:attr:`category` this attribute may be used in the interface to regroup
+      related objects (view kinds) together
+
+    :py:attr:`paginable`
+
+    :py:attr:`binary`
+
+
+    A view writes to its output stream thanks to its attribute `w` (the
+    append method of an `UStreamIO`, except for binary views).
 
     At instantiation time, the standard `_cw`, and `cw_rset` attributes are
     added and the `w` attribute will be set at rendering time to a write
--- a/web/data/cubicweb.css	Tue May 22 12:41:18 2012 +0200
+++ b/web/data/cubicweb.css	Wed May 23 16:17:46 2012 +0200
@@ -220,9 +220,6 @@
     font-style: italic;
 }
 
-.align-center{
-    text-align: center;
-}
 
 /***************************************/
 /*   LAYOUT                            */
@@ -992,11 +989,20 @@
 /********************************/
 
 img.align-right {
-  margin-left: 1.5em;
+  margin-left: auto;
+  display:block;
 }
 
 img.align-left {
-  margin-right: 1.5em;
+  margin-right: auto;
+  display:block;
+}
+
+img.align-center{
+  text-align: center;
+  margin-left: auto;
+  margin-right: auto;
+  display:block;
 }
 
 /******************************/
--- a/web/data/cubicweb.old.css	Tue May 22 12:41:18 2012 +0200
+++ b/web/data/cubicweb.old.css	Wed May 23 16:17:46 2012 +0200
@@ -64,9 +64,12 @@
   text-decoration: underline;
 }
 
-a img, img {
+a img{
+  text-align: center;
+}
+
+img{
   border: none;
-  text-align: center;
 }
 
 img.prevnext {
@@ -216,25 +219,44 @@
   visibility: hidden;
 }
 
-li.invisible { list-style: none; background: none; padding: 0px 0px
-1px 1px; }
+li.invisible {
+  list-style: none;
+  background: none;
+  padding: 0px 0px 1px 1px;
+}
 
 li.invisible div {
   display: inline;
 }
 
 .caption {
-    font-weight: bold;
+  font-weight: bold;
 }
 
 .legend{
-    font-style: italic;
+  font-style: italic;
+}
+
+/* rest related image classes generated with align: directive */
+
+img.align-right {
+  margin-left: auto;
+  display:block;
 }
 
-.align-center{
-    text-align: center;
+img.align-left {
+  margin-right: auto;
+  display:block;
 }
 
+img.align-center{
+  text-align: center;
+  margin-left: auto;
+  margin-right: auto;
+  display:block;
+}
+
+
 /***************************************/
 /*   LAYOUT                            */
 /***************************************/
--- a/web/views/baseviews.py	Tue May 22 12:41:18 2012 +0200
+++ b/web/views/baseviews.py	Wed May 23 16:17:46 2012 +0200
@@ -173,9 +173,9 @@
 class OutOfContextView(EntityView):
     """:__regid__: *outofcontext*
 
-    This view is used whenthe entity should be considered as displayed out of
-    its context. By default it produces the result of ``entity.dc_long_title()`` wrapped
-    in a link leading to the primary view of the entity.
+    This view is used when the entity should be considered as displayed out of
+    its context. By default it produces the result of ``entity.dc_long_title()``
+    wrapped in a link leading to the primary view of the entity.
     """
     __regid__ = 'outofcontext'
 
@@ -612,18 +612,18 @@
     def group_key(self, entity, **kwargs):
         value = super(AuthorView, self).group_key(entity, **kwargs)
         if value:
-            return value.login
-        return value
+            return (value.name(), value.login)
+        return (None, None)
 
     def index_link(self, basepath, key, items):
-        label = u'%s [%s]' % (key, len(items))
+        label = u'%s [%s]' % (key[0], len(items))
         etypes = set(entity.__regid__ for entity in items)
         vtitle = self._cw._('%(etype)s by %(author)s') % {
             'etype': ', '.join(display_name(self._cw, etype, 'plural')
                                for etype in etypes),
             'author': label}
-        url = self.index_url(basepath, key, vtitle=vtitle)
-        title = self._cw._('archive for %(author)s') % {'author': key}
+        url = self.index_url(basepath, key[1], vtitle=vtitle)
+        title = self._cw._('archive for %(author)s') % {'author': key[0]}
         return tags.a(label, href=url, title=title)
 
 
--- a/web/views/formrenderers.py	Tue May 22 12:41:18 2012 +0200
+++ b/web/views/formrenderers.py	Wed May 23 16:17:46 2012 +0200
@@ -494,6 +494,16 @@
     __regid__ = 'inline'
     fieldset_css_class = 'subentity'
 
+    def render_title(self, w, form, values):
+        w(u'<div class="iformTitle">')
+        w(u'<span>%(title)s</span> '
+          '#<span class="icounter">%(counter)s</span> ' % values)
+        if values['removejs']:
+            values['removemsg'] = self._cw._('remove-inlined-entity-form')
+            w(u'[<a href="javascript: %(removejs)s;$.noop();">%(removemsg)s</a>]'
+              % values)
+        w(u'</div>')
+
     def render(self, w, form, values):
         form.add_media()
         self.open_form(w, form, values)
@@ -518,18 +528,6 @@
     def close_form(self, w, form, values):
         w(u'</div></div>')
 
-    def render_title(self, w, form, values):
-        if values['removejs']:
-            values['removemsg'] = self._cw._('remove-inlined-entity-form')
-            w(u'<div class="iformTitle"><span>%(title)s</span> '
-              '#<span class="icounter">%(counter)s</span> '
-              '[<a href="javascript: %(removejs)s;$.noop();">%(removemsg)s</a>]</div>'
-              % values)
-        else:
-            w(u'<div class="iformTitle"><span>%(title)s</span> '
-              '#<span class="icounter">%(counter)s</span></div>'
-              % values)
-
     def render_fields(self, w, form, values):
         w(u'<fieldset id="fs-%(divid)s">' % values)
         fields = self._render_hidden_fields(w, form)
--- a/web/views/tableview.py	Tue May 22 12:41:18 2012 +0200
+++ b/web/views/tableview.py	Wed May 23 16:17:46 2012 +0200
@@ -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.
@@ -135,7 +135,7 @@
 
     * `header_column_idx`, if not `None`, should be a colum index or a set of
       column index where <th> tags should be generated instead of <td>
-    """
+    """ #'# make emacs happier
     __regid__ = 'table_layout'
     cssclass = "listing"
     needs_css = ('cubicweb.tableview.css',)
@@ -332,14 +332,14 @@
     :attr: `header`, the column header. If None, default to `_(colid)`
     :attr: `addcount`, if True, add the table size in parenthezis beside the header
     :attr: `trheader`, should the header be translated
-    :attr: `escapeheader`, should the header be xml_escape'd
+    :attr: `escapeheader`, should the header be xml_escaped
     :attr: `sortable`, tell if the column is sortable
     :attr: `view`, the table view
     :attr: `_cw`, the request object
     :attr: `colid`, the column identifier
     :attr: `attributes`, dictionary of attributes to put on the HTML tag when
             the cell is rendered
-    """
+    """ #'# make emacs
     attributes = {}
     empty_cell_content = u'&#160;'
 
@@ -576,7 +576,7 @@
     renderer.
 
     .. autoclass:: RsetTableColRenderer
-    """
+    """    #'# make emacs happier
     __regid__ = 'table'
     # selector trick for bw compath with the former :class:TableView
     __select__ = AnyRsetView.__select__ & (~match_kwargs(
@@ -599,16 +599,19 @@
         # may be listed in possible views
         return self.__regid__ == 'table'
 
-    def call(self, headers=None, displaycols=None, cellvids=None, **kwargs):
+    def call(self, headers=None, displaycols=None, cellvids=None,
+             paginate=None, **kwargs):
         if self.headers:
             self.headers = [h and self._cw._(h) for h in self.headers]
-        if (headers or displaycols or cellvids):
+        if (headers or displaycols or cellvids or paginate):
             if headers is not None:
                 self.headers = headers
             if displaycols is not None:
                 self.displaycols = displaycols
             if cellvids is not None:
                 self.cellvids = cellvids
+            if paginate is not None:
+                self.paginable = paginate
         if kwargs:
             # old table view arguments that we can safely ignore thanks to
             # selectors
--- a/web/wdoc/bookmarks_fr.rst	Tue May 22 12:41:18 2012 +0200
+++ b/web/wdoc/bookmarks_fr.rst	Wed May 23 16:17:46 2012 +0200
@@ -27,8 +27,4 @@
 ayez le droit de les modifier.
 
 
-Pour plus de détails sur les relations possibles, veuillez vous réferer au
-schéma_ du composant signet.
-
-.. _`schéma`: eetype/Bookmark?vid=eschema
 .. _`préférences utilisateurs`: myprefs