# HG changeset patch # User Sylvain Thénault # Date 1337782666 -7200 # Node ID b86bdc343c18f43b9e49503fcc4f8542fec55636 # Parent 09432a572a44c23fd188f13a2dbce87dd60c26b6# Parent 664d0bf525c8bf1842ccc8fa0c5107f9b3cb8841 backport stable diff -r 09432a572a44 -r b86bdc343c18 .hgtags --- 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 diff -r 09432a572a44 -r b86bdc343c18 __pkginfo__.py diff -r 09432a572a44 -r b86bdc343c18 debian/changelog --- 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 Thu, 12 Apr 2012 13:52:05 +0200 +cubicweb (3.14.8-1) unstable; urgency=low + + * new upstream release + + -- Sylvain Thénault Wed, 23 May 2012 11:42:54 +0200 + cubicweb (3.14.7-1) unstable; urgency=low * new upstream release diff -r 09432a572a44 -r b86bdc343c18 doc/book/en/devweb/views/views.rst --- 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 ``````````````````````` diff -r 09432a572a44 -r b86bdc343c18 server/test/unittest_utils.py --- /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 . +""" + +""" +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() diff -r 09432a572a44 -r b86bdc343c18 server/utils.py --- 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']) diff -r 09432a572a44 -r b86bdc343c18 view.py --- 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 diff -r 09432a572a44 -r b86bdc343c18 web/data/cubicweb.css --- 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; } /******************************/ diff -r 09432a572a44 -r b86bdc343c18 web/data/cubicweb.old.css --- 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 */ /***************************************/ diff -r 09432a572a44 -r b86bdc343c18 web/views/baseviews.py --- 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) diff -r 09432a572a44 -r b86bdc343c18 web/views/formrenderers.py --- 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'
') + w(u'%(title)s ' + '#%(counter)s ' % values) + if values['removejs']: + values['removemsg'] = self._cw._('remove-inlined-entity-form') + w(u'[%(removemsg)s]' + % values) + w(u'
') + 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'') - def render_title(self, w, form, values): - if values['removejs']: - values['removemsg'] = self._cw._('remove-inlined-entity-form') - w(u'
%(title)s ' - '#%(counter)s ' - '[%(removemsg)s]
' - % values) - else: - w(u'
%(title)s ' - '#%(counter)s
' - % values) - def render_fields(self, w, form, values): w(u'
' % values) fields = self._render_hidden_fields(w, form) diff -r 09432a572a44 -r b86bdc343c18 web/views/tableview.py --- 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 tags should be generated instead of - """ + """ #'# 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' ' @@ -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 diff -r 09432a572a44 -r b86bdc343c18 web/wdoc/bookmarks_fr.rst --- 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