--- a/.hgtags Wed Jul 27 20:17:45 2011 +0200
+++ b/.hgtags Fri Aug 05 14:23:55 2011 +0200
@@ -218,3 +218,5 @@
9ad5411199e00b2611366439b82f35d7d3285423 cubicweb-debian-version-3.13.2-1
0e82e7e5a34f57d7239c7a42e48ba4d5e53abab2 cubicweb-version-3.13.3
fb48c55cb80234bc0164c9bcc0e2cfc428836e5f cubicweb-debian-version-3.13.3-1
+223ecf0620b6c87d997f8011aca0d9f0ee4750af cubicweb-version-3.13.4
+52f26475d764129c5559b2d80fd57e6ea1bdd6ba cubicweb-debian-version-3.13.4-1
--- a/README Wed Jul 27 20:17:45 2011 +0200
+++ b/README Fri Aug 05 14:23:55 2011 +0200
@@ -5,20 +5,21 @@
developped at Logilab.
This package contains:
-* a repository server
-* a RQL command line client to the repository
-* an adaptative modpython interface to the server
-* a bunch of other management tools
+
+- a repository server
+- a RQL command line client to the repository
+- an adaptative modpython interface to the server
+- a bunch of other management tools
Install
-------
-More details at http://www.cubicweb.org/doc/en/admin/setup
+More details at http://docs.cubicweb.org/admin/setup
Getting started
---------------
-Execute:
+Execute::
apt-get install cubicweb cubicweb-dev cubicweb-blog
cubicweb-ctl create blog myblog
--- a/__pkginfo__.py Wed Jul 27 20:17:45 2011 +0200
+++ b/__pkginfo__.py Fri Aug 05 14:23:55 2011 +0200
@@ -22,7 +22,7 @@
modname = distname = "cubicweb"
-numversion = (3, 13, 3)
+numversion = (3, 13, 4)
version = '.'.join(str(num) for num in numversion)
description = "a repository of entities / relations for knowledge management"
@@ -43,7 +43,7 @@
'logilab-common': '>= 0.55.2',
'logilab-mtconverter': '>= 0.8.0',
'rql': '>= 0.28.0',
- 'yams': '>= 0.32.0',
+ 'yams': '>= 0.33.0',
'docutils': '>= 0.6',
#gettext # for xgettext, msgcat, etc...
# web dependancies
--- a/debian/changelog Wed Jul 27 20:17:45 2011 +0200
+++ b/debian/changelog Fri Aug 05 14:23:55 2011 +0200
@@ -1,3 +1,9 @@
+cubicweb (3.13.4-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr> Fri, 05 Aug 2011 12:22:11 +0200
+
cubicweb (3.13.3-1) unstable; urgency=low
* new upstream release
--- a/debian/control Wed Jul 27 20:17:45 2011 +0200
+++ b/debian/control Fri Aug 05 14:23:55 2011 +0200
@@ -99,7 +99,7 @@
Package: cubicweb-common
Architecture: all
XB-Python-Version: ${python:Versions}
-Depends: ${misc:Depends}, ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.55.2), python-yams (>= 0.32.0), python-rql (>= 0.28.0), python-lxml
+Depends: ${misc:Depends}, ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.55.2), python-yams (>= 0.33.0), python-rql (>= 0.28.0), python-lxml
Recommends: python-simpletal (>= 4.0), python-crypto
Conflicts: cubicweb-core
Replaces: cubicweb-core
--- a/devtools/__init__.py Wed Jul 27 20:17:45 2011 +0200
+++ b/devtools/__init__.py Fri Aug 05 14:23:55 2011 +0200
@@ -657,6 +657,24 @@
class SQLiteTestDataBaseHandler(TestDataBaseHandler):
DRIVER = 'sqlite'
+ __TMPDB = set()
+
+ @classmethod
+ def _cleanup_all_tmpdb(cls):
+ for dbpath in cls.__TMPDB:
+ cls._cleanup_database(dbpath)
+
+
+
+ def __init__(self, *args, **kwargs):
+ super(SQLiteTestDataBaseHandler, self).__init__(*args, **kwargs)
+ # use a dedicated base for each process.
+ if 'global-db-name' not in self.system_source:
+ self.system_source['global-db-name'] = self.system_source['db-name']
+ process_db = self.system_source['db-name'] + str(os.getpid())
+ self.__TMPDB.add(process_db)
+ self.system_source['db-name'] = process_db
+
@staticmethod
def _cleanup_database(dbfile):
try:
@@ -665,6 +683,10 @@
except OSError:
pass
+ @property
+ def dbname(self):
+ return self.system_source['global-db-name']
+
def absolute_dbfile(self):
"""absolute path of current database file"""
dbfile = join(self._ensure_test_backup_db_dir(),
@@ -707,6 +729,9 @@
self._cleanup_database(self.absolute_dbfile())
init_repository(self.config, interactive=False)
+import atexit
+atexit.register(SQLiteTestDataBaseHandler._cleanup_all_tmpdb)
+
def install_sqlite_patch(querier):
"""This patch hotfixes the following sqlite bug :
--- a/devtools/devctl.py Wed Jul 27 20:17:45 2011 +0200
+++ b/devtools/devctl.py Fri Aug 05 14:23:55 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -155,6 +155,9 @@
add_msg(w, cstrtype)
done = set()
for eschema in sorted(schema.entities()):
+ if eschema.type in libschema:
+ done.add(eschema.description)
+ for eschema in sorted(schema.entities()):
etype = eschema.type
if etype not in libschema:
add_msg(w, etype)
@@ -203,15 +206,19 @@
w('# (no object form for final or symmetric relation types)\n')
w('\n')
for rschema in sorted(schema.relations()):
+ if rschema.type in libschema:
+ done.add(rschema.type)
+ done.add(rschema.description)
+ for rschema in sorted(schema.relations()):
rtype = rschema.type
if rtype not in libschema:
# bw compat, necessary until all translation of relation are done
# properly...
add_msg(w, rtype)
+ done.add(rtype)
if rschema.description and rschema.description not in done:
- done.add(rschema.description)
add_msg(w, rschema.description)
- done.add(rtype)
+ done.add(rschema.description)
librschema = None
else:
librschema = libschema.rschema(rtype)
@@ -221,7 +228,7 @@
for subjschema in rschema.subjects():
if not subjschema in libsubjects:
add_msg(w, rtype, subjschema.type)
- if not (schema.rschema(rtype).final or rschema.symmetric):
+ if not (rschema.final or rschema.symmetric):
if rschema not in NO_I18NCONTEXT:
libobjects = librschema and librschema.objects() or ()
for objschema in rschema.objects():
@@ -231,6 +238,14 @@
# bw compat, necessary until all translation of relation are
# done properly...
add_msg(w, '%s_object' % rtype)
+ for rdef in rschema.rdefs.itervalues():
+ if not rdef.description or rdef.description in done:
+ continue
+ if (librschema is None or
+ (rdef.subject, rdef.object) not in librschema.rdefs or
+ librschema.rdefs[(rdef.subject, rdef.object)].description != rdef.description):
+ add_msg(w, rdef.description)
+ done.add(rdef.description)
for objid in _iter_vreg_objids(vreg, vregdone):
add_msg(w, '%s_description' % objid)
add_msg(w, objid)
--- a/doc/book/en/annexes/rql/language.rst Wed Jul 27 20:17:45 2011 +0200
+++ b/doc/book/en/annexes/rql/language.rst Fri Aug 05 14:23:55 2011 +0200
@@ -113,9 +113,38 @@
``````````````````````
::
- +, -, *, /
++==========+=====================+===========+========+
+| Operator | Description | Example | Result |
++==========+=====================+===========+========+
+| + | addition | 2 + 3 | 5 |
++----------+---------------------+-----------+--------+
+| - | subtraction | 2 - 3 | -1 |
++----------+---------------------+-----------+--------+
+| * | multiplication | 2 * 3 | 6 |
++----------+---------------------+-----------+--------+
+| / | division | 4 / 2 | 2 |
++----------+---------------------+-----------+--------+
+| % | modulo (remainder) | 5 % 4 | 1 |
++----------+---------------------+-----------+--------+
+| ^ | exponentiation | 2.0 ^ 3.0 | 8 |
++----------+---------------------+-----------+--------+
+| & | bitwise AND | 91 & 15 | 11 |
++----------+---------------------+-----------+--------+
+| | | bitwise OR | 32 | 3 | 35 |
++----------+---------------------+-----------+--------+
+| # | bitwise XOR | 17 # 5 | 20 |
++----------+---------------------+-----------+--------+
+| ~ | bitwise NOT | ~1 | -2 |
++----------+---------------------+-----------+--------+
+| << | bitwise shift left | 1 << 4 | 16 |
++----------+---------------------+-----------+--------+
+| >> | bitwise shift right | 8 >> 2 | 2 |
++----------+---------------------+-----------+--------+
-Those should behave as you expect.
+ +, -, *, /
+
+Notice integer division truncates results depending on the backend behaviour. For
+instance, postgresql does.
.. _RQLComparisonOperators:
@@ -191,13 +220,14 @@
Operators priority
``````````````````
-#. "(", ")"
-#. '*', '/'
-#. '+', '-'
-#. 'NOT'
-#. 'AND'
-#. 'OR'
-#. ','
+#. `(`, `)`
+#. `^`, `<<`, `>>`
+#. `*`, `/`, `%`, `&`
+#. `+`, `-`, `|`, `#`
+#. `NOT`
+#. `AND`
+#. `OR`
+#. `,`
.. _RQLSearchQuery:
@@ -328,7 +358,7 @@
You must use the `?` behind a variable to specify that the relation toward it
is optional. For instance:
-- Anomalies of a project attached or not to a version ::
+- Bugs of a project attached or not to a version ::
Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
@@ -340,6 +370,28 @@
Any C, P WHERE C is Card, P? documented_by C
+Notice you may also use outer join:
+
+- on the RHS of attribute relation, e.g. ::
+
+ Any X WHERE X ref XR, Y name XR?
+
+ so that Y is outer joined on X by ref/name attributes comparison
+
+
+- on any side of an `HAVING` expression, e.g. ::
+
+ Any X WHERE X creation_date XC, Y creation_date YC
+ HAVING YEAR(XC)=YEAR(YC)?
+
+ so that Y is outer joined on X by comparison of the year extracted from their
+ creation date. ::
+
+ Any X WHERE X creation_date XC, Y creation_date YC
+ HAVING YEAR(XC)?=YEAR(YC)
+
+ would outer join X on Y instead.
+
Having restrictions
```````````````````
--- a/entities/lib.py Wed Jul 27 20:17:45 2011 +0200
+++ b/entities/lib.py Fri Aug 05 14:23:55 2011 +0200
@@ -40,6 +40,7 @@
class EmailAddress(AnyEntity):
__regid__ = 'EmailAddress'
fetch_attrs, fetch_order = fetch_config(['address', 'alias'])
+ rest_attr = 'eid'
def dc_title(self):
if self.alias:
--- a/ext/rest.py Wed Jul 27 20:17:45 2011 +0200
+++ b/ext/rest.py Fri Aug 05 14:23:55 2011 +0200
@@ -105,11 +105,17 @@
else:
rql, vid = text, None
_cw.ensure_ro_rql(rql)
- rset = _cw.execute(rql, {'userid': _cw.user.eid})
- if vid is None:
- vid = vid_from_rset(_cw, rset, _cw.vreg.schema)
- view = _cw.vreg['views'].select(vid, _cw, rset=rset)
- content = view.render()
+ try:
+ rset = _cw.execute(rql, {'userid': _cw.user.eid})
+ if rset:
+ if vid is None:
+ vid = vid_from_rset(_cw, rset, _cw.vreg.schema)
+ else:
+ vid = 'noresult'
+ view = _cw.vreg['views'].select(vid, _cw, rset=rset)
+ content = view.render()
+ except Exception, exc:
+ content = 'an error occured while interpreting this rql directive: %r' % exc
set_classes(options)
return [nodes.raw('', content, format='html')], []
--- a/ext/test/unittest_rest.py Wed Jul 27 20:17:45 2011 +0200
+++ b/ext/test/unittest_rest.py Fri Aug 05 14:23:55 2011 +0200
@@ -63,6 +63,16 @@
self.assert_(out.endswith('<a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon</a>'
'</td></tr></tbody></table></div>\n</div>\n</p>\n'))
+ def test_rql_role_with_vid_empty_rset(self):
+ context = self.context()
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser, X login "nono":table`')
+ self.assert_(out.endswith('<p><div class="searchMessage"><strong>No result matching query</strong></div>\n</p>\n'))
+
+ def test_rql_role_with_unknown_vid(self):
+ context = self.context()
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:toto`')
+ self.assert_(out.startswith("<p>an error occured while interpreting this rql directive: ObjectNotFound(u'toto',)</p>"))
+
def test_rql_role_without_vid(self):
context = self.context()
out = rest_publish(context, ':rql:`Any X WHERE X is CWUser`')
--- a/hooks/syncsources.py Wed Jul 27 20:17:45 2011 +0200
+++ b/hooks/syncsources.py Fri Aug 05 14:23:55 2011 +0200
@@ -19,6 +19,7 @@
from socket import gethostname
+from logilab.common.decorators import clear_cache
from yams.schema import role_name
from cubicweb import ValidationError
@@ -66,7 +67,7 @@
SourceRemovedOp(self._cw, uri=self.entity.name)
-class SourceUpdatedOp(hook.DataOperationMixIn, hook.Operation):
+class SourceConfigUpdatedOp(hook.DataOperationMixIn, hook.Operation):
def precommit_event(self):
self.__processed = []
@@ -79,13 +80,45 @@
for source, conf in self.__processed:
source.repo_source.update_config(source, conf)
+
+class SourceRenamedOp(hook.LateOperation):
+
+ def precommit_event(self):
+ source = self.session.repo.sources_by_uri[self.oldname]
+ if source.copy_based_source:
+ sql = 'UPDATE entities SET asource=%(newname)s WHERE asource=%(oldname)s'
+ else:
+ sql = 'UPDATE entities SET source=%(newname)s, asource=%(newname)s WHERE source=%(oldname)s'
+ self.session.system_sql(sql, {'oldname': self.oldname,
+ 'newname': self.newname})
+
+ def postcommit_event(self):
+ repo = self.session.repo
+ # XXX race condition
+ source = repo.sources_by_uri.pop(self.oldname)
+ source.uri = self.newname
+ source.public_config['uri'] = self.newname
+ repo.sources_by_uri[self.newname] = source
+ repo._type_source_cache.clear()
+ clear_cache(repo, 'source_defs')
+ if not source.copy_based_source:
+ repo._extid_cache.clear()
+ repo._clear_planning_caches()
+ for cnxset in repo.cnxsets:
+ cnxset.source_cnxs[self.oldname] = cnxset.source_cnxs.pop(self.oldname)
+
+
class SourceUpdatedHook(SourceHook):
__regid__ = 'cw.sources.configupdate'
__select__ = SourceHook.__select__ & is_instance('CWSource')
- events = ('after_update_entity',)
+ events = ('before_update_entity',)
def __call__(self):
if 'config' in self.entity.cw_edited:
- SourceUpdatedOp.get_instance(self._cw).add_data(self.entity)
+ SourceConfigUpdatedOp.get_instance(self._cw).add_data(self.entity)
+ if 'name' in self.entity.cw_edited:
+ oldname, newname = self.entity.cw_edited.oldnewvalue('name')
+ SourceRenamedOp(self._cw, oldname=oldname, newname=newname)
+
class SourceHostConfigUpdatedHook(SourceHook):
__regid__ = 'cw.sources.hostconfigupdate'
@@ -97,7 +130,7 @@
not 'config' in self.entity.cw_edited:
return
try:
- SourceUpdatedOp.get_instance(self._cw).add_data(self.entity.cwsource)
+ SourceConfigUpdatedOp.get_instance(self._cw).add_data(self.entity.cwsource)
except IndexError:
# XXX no source linked to the host config yet
pass
--- a/i18n/de.po Wed Jul 27 20:17:45 2011 +0200
+++ b/i18n/de.po Fri Aug 05 14:23:55 2011 +0200
@@ -1250,6 +1250,9 @@
msgid "auto"
msgstr "automatisch"
+msgid "autocomputed attribute used to ensure transition coherency"
+msgstr ""
+
msgid "automatic"
msgstr "automatisch"
@@ -2288,9 +2291,6 @@
msgid "eid"
msgstr ""
-msgid "email address to use for notification"
-msgstr "E-Mail-Adresse für Mitteilungen."
-
msgid "emails successfully sent"
msgstr "E-Mails erfolgreich versandt."
@@ -2619,6 +2619,18 @@
msgid "groups"
msgstr "Gruppen"
+msgid "groups allowed to add entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to delete entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to read entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to update entities/relations of this type"
+msgstr ""
+
msgid "groups grant permissions to the user"
msgstr "die Gruppen geben dem Nutzer Rechte"
@@ -3604,6 +3616,18 @@
msgid "right"
msgstr "rechts"
+msgid "rql expression allowing to add entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to delete entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to read entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to update entities/relations of this type"
+msgstr ""
+
msgid "rql expressions"
msgstr "RQL-Ausdrücke"
@@ -4323,6 +4347,9 @@
msgid "user preferences"
msgstr "Nutzereinstellungen"
+msgid "user's email account"
+msgstr ""
+
msgid "users"
msgstr "Nutzer"
@@ -4521,3 +4548,6 @@
#, python-format
msgid "you should un-inline relation %s which is supported and may be crossed "
msgstr ""
+
+#~ msgid "email address to use for notification"
+#~ msgstr "E-Mail-Adresse für Mitteilungen."
--- a/i18n/en.po Wed Jul 27 20:17:45 2011 +0200
+++ b/i18n/en.po Fri Aug 05 14:23:55 2011 +0200
@@ -1205,6 +1205,9 @@
msgid "auto"
msgstr "automatic"
+msgid "autocomputed attribute used to ensure transition coherency"
+msgstr ""
+
msgid "automatic"
msgstr ""
@@ -2233,9 +2236,6 @@
msgid "eid"
msgstr ""
-msgid "email address to use for notification"
-msgstr ""
-
msgid "emails successfully sent"
msgstr ""
@@ -2554,6 +2554,18 @@
msgid "groups"
msgstr ""
+msgid "groups allowed to add entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to delete entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to read entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to update entities/relations of this type"
+msgstr ""
+
msgid "groups grant permissions to the user"
msgstr ""
@@ -3511,6 +3523,18 @@
msgid "right"
msgstr ""
+msgid "rql expression allowing to add entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to delete entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to read entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to update entities/relations of this type"
+msgstr ""
+
msgid "rql expressions"
msgstr ""
@@ -4209,6 +4233,9 @@
msgid "user preferences"
msgstr ""
+msgid "user's email account"
+msgstr ""
+
msgid "users"
msgstr ""
--- a/i18n/es.po Wed Jul 27 20:17:45 2011 +0200
+++ b/i18n/es.po Fri Aug 05 14:23:55 2011 +0200
@@ -1261,6 +1261,9 @@
msgid "auto"
msgstr "Automático"
+msgid "autocomputed attribute used to ensure transition coherency"
+msgstr ""
+
msgid "automatic"
msgstr "Automático"
@@ -2327,9 +2330,6 @@
msgid "eid"
msgstr "eid"
-msgid "email address to use for notification"
-msgstr "Dirección electrónica a utilizarse para notificar"
-
msgid "emails successfully sent"
msgstr "Mensajes enviados con éxito"
@@ -2661,6 +2661,18 @@
msgid "groups"
msgstr "Grupos"
+msgid "groups allowed to add entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to delete entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to read entities/relations of this type"
+msgstr ""
+
+msgid "groups allowed to update entities/relations of this type"
+msgstr ""
+
msgid "groups grant permissions to the user"
msgstr "Los grupos otorgan los permisos al usuario"
@@ -3654,6 +3666,18 @@
msgid "right"
msgstr "Derecha"
+msgid "rql expression allowing to add entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to delete entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to read entities/relations of this type"
+msgstr ""
+
+msgid "rql expression allowing to update entities/relations of this type"
+msgstr ""
+
msgid "rql expressions"
msgstr "Expresiones RQL"
@@ -4373,6 +4397,9 @@
msgid "user preferences"
msgstr "Preferencias"
+msgid "user's email account"
+msgstr ""
+
msgid "users"
msgstr "Usuarios"
@@ -4576,3 +4603,6 @@
#~ msgctxt "CWAttribute"
#~ msgid "cw_schema_object"
#~ msgstr "mapeado por"
+
+#~ msgid "email address to use for notification"
+#~ msgstr "Dirección electrónica a utilizarse para notificar"
--- a/i18n/fr.po Wed Jul 27 20:17:45 2011 +0200
+++ b/i18n/fr.po Fri Aug 05 14:23:55 2011 +0200
@@ -164,7 +164,7 @@
#, python-format
msgid ""
"'%s' action for in_state relation should at least have 'linkattr=name' option"
-msgstr ""
+msgstr "l'action '%s' pour la relation in_state doit au moins avoir l'option 'linkattr=name'"
#, python-format
msgid "'%s' action requires 'linkattr' option"
@@ -1174,7 +1174,7 @@
#, python-format
msgid "allowed values for \"action\" are %s"
-msgstr ""
+msgstr "les valeurs autorisées pour \"action\" sont %s"
msgid "allowed_transition"
msgstr "transitions autorisées"
@@ -1259,6 +1259,9 @@
msgid "auto"
msgstr "automatique"
+msgid "autocomputed attribute used to ensure transition coherency"
+msgstr "attribut calculé automatiquement pour assurer la cohérence de la transition"
+
msgid "automatic"
msgstr "automatique"
@@ -2326,9 +2329,6 @@
msgid "eid"
msgstr "eid"
-msgid "email address to use for notification"
-msgstr "adresse email à utiliser pour la notification"
-
msgid "emails successfully sent"
msgstr "courriels envoyés avec succès"
@@ -2660,6 +2660,18 @@
msgid "groups"
msgstr "groupes"
+msgid "groups allowed to add entities/relations of this type"
+msgstr "groupes autorisés à ajouter des entités/relations de ce type"
+
+msgid "groups allowed to delete entities/relations of this type"
+msgstr "groupes autorisés à supprimer des entités/relations de ce type"
+
+msgid "groups allowed to read entities/relations of this type"
+msgstr "groupes autorisés à lire des entités/relations de ce type"
+
+msgid "groups allowed to update entities/relations of this type"
+msgstr "groupes autorisés à mettre à jour des entités/relations de ce type"
+
msgid "groups grant permissions to the user"
msgstr "les groupes donnent des permissions à l'utilisateur"
@@ -3239,10 +3251,10 @@
msgstr "aucune permission associée"
msgid "no content next link"
-msgstr ""
+msgstr "pas de lien 'suivant'"
msgid "no content prev link"
-msgstr ""
+msgstr "pas de lien 'précédent'"
msgid "no edited fields specified"
msgstr "aucun champ à éditer spécifié"
@@ -3655,6 +3667,18 @@
msgid "right"
msgstr "droite"
+msgid "rql expression allowing to add entities/relations of this type"
+msgstr "expression rql autorisant à ajouter des entités/relations de ce type"
+
+msgid "rql expression allowing to delete entities/relations of this type"
+msgstr "expression rql autorisant à supprimer des entités/relations de ce type"
+
+msgid "rql expression allowing to read entities/relations of this type"
+msgstr "expression rql autorisant à lire des entités/relations de ce type"
+
+msgid "rql expression allowing to update entities/relations of this type"
+msgstr "expression rql autorisant à mettre à jour des entités/relations de ce type"
+
msgid "rql expressions"
msgstr "conditions rql"
@@ -4013,10 +4037,10 @@
msgstr "la valeur \"%s\" est déjà utilisée, veuillez utiliser une autre valeur"
msgid "there is no next page"
-msgstr ""
+msgstr "il n'y a pas de page suivante"
msgid "there is no previous page"
-msgstr ""
+msgstr "il n'y a pas de page précédente"
msgid "this action is not reversible!"
msgstr ""
@@ -4372,6 +4396,9 @@
msgid "user preferences"
msgstr "préférences utilisateur"
+msgid "user's email account"
+msgstr "email de l'utilisateur"
+
msgid "users"
msgstr "utilisateurs"
@@ -4572,7 +4599,3 @@
msgstr ""
"vous devriez enlevé la mise en ligne de la relation %s qui est supportée et "
"peut-être croisée"
-
-#~ msgctxt "CWAttribute"
-#~ msgid "cw_schema_object"
-#~ msgstr "mappé par"
--- a/misc/migration/bootstrapmigration_repository.py Wed Jul 27 20:17:45 2011 +0200
+++ b/misc/migration/bootstrapmigration_repository.py Fri Aug 05 14:23:55 2011 +0200
@@ -36,7 +36,7 @@
commit(ask_confirm=False)
if applcubicwebversion <= (3, 13, 0) and cubicwebversion >= (3, 13, 1):
- sql('ALTER TABLE entities ADD COLUMN asource VARCHAR(64)')
+ sql('ALTER TABLE entities ADD asource VARCHAR(64)')
sql('UPDATE entities SET asource=cw_name '
'FROM cw_CWSource, cw_source_relation '
'WHERE entities.eid=cw_source_relation.eid_from AND cw_source_relation.eid_to=cw_CWSource.cw_eid')
--- a/schemas/base.py Wed Jul 27 20:17:45 2011 +0200
+++ b/schemas/base.py Fri Aug 05 14:23:55 2011 +0200
@@ -42,12 +42,6 @@
firstname = String(maxsize=64)
surname = String(maxsize=64)
last_login_time = Datetime(description=_('last connection date'))
- # allowing an email to be the primary email of multiple entities is necessary for
- # test at least :-/
- primary_email = SubjectRelation('EmailAddress', cardinality='??',
- description=_('email address to use for notification'))
- use_email = SubjectRelation('EmailAddress', cardinality='*?', composite='subject')
-
in_group = SubjectRelation('CWGroup', cardinality='+*',
constraints=[RQLConstraint('NOT O name "owners"')],
description=_('groups grant permissions to the user'))
@@ -71,17 +65,35 @@
to indicate which is the preferred form.'))
class use_email(RelationType):
- """ """
+ fulltext_container = 'subject'
+
+
+class use_email_relation(RelationDefinition):
+ """user's email account"""
+ name = "use_email"
__permissions__ = {
'read': ('managers', 'users', 'guests',),
'add': ('managers', RRQLExpression('U has_update_permission S'),),
'delete': ('managers', RRQLExpression('U has_update_permission S'),),
}
- fulltext_container = 'subject'
+ subject = "CWUser"
+ object = "EmailAddress"
+ cardinality = '*?'
+ composite = 'subject'
+
-class primary_email(RelationType):
+class primary_email(RelationDefinition):
"""the prefered email"""
- __permissions__ = use_email.__permissions__
+ __permissions__ = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', RRQLExpression('U has_update_permission S'),),
+ 'delete': ('managers', RRQLExpression('U has_update_permission S'),),
+ }
+ subject = "CWUser"
+ object = "EmailAddress"
+ cardinality = '??'
+ constraints= [RQLConstraint('S use_email O')]
+
class prefered_form(RelationType):
__permissions__ = {
--- a/server/repository.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/repository.py Fri Aug 05 14:23:55 2011 +0200
@@ -505,12 +505,7 @@
This is a public method, not requiring a session id.
"""
- try:
- # necessary to support pickling used by pyro
- self.schema.__hashmode__ = 'pickle'
- return self.schema
- finally:
- self.schema.__hashmode__ = None
+ return self.schema
def get_cubes(self):
"""Return the list of cubes used by this instance.
--- a/server/rqlannotation.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/rqlannotation.py Fri Aug 05 14:23:55 2011 +0200
@@ -109,8 +109,9 @@
ostinfo = rhs.children[0].variable.stinfo
else:
ostinfo = lhs.variable.stinfo
- if not any(orel for orel in ostinfo['relations']
- if orel.optional and orel is not rel):
+ if not (ostinfo.get('optcomparisons') or
+ any(orel for orel in ostinfo['relations']
+ if orel.optional and orel is not rel)):
break
if rschema.final or (onlhs and rschema.inlined):
if rschema.type != 'has_text':
--- a/server/session.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/session.py Fri Aug 05 14:23:55 2011 +0200
@@ -1180,7 +1180,8 @@
def _build_descr(self, result, basedescription, todetermine):
description = []
etype_from_eid = self.describe
- for row in result:
+ todel = []
+ for i, row in enumerate(result):
row_descr = basedescription[:]
for index, isfinal in todetermine:
value = row[index]
@@ -1194,10 +1195,14 @@
try:
row_descr[index] = etype_from_eid(value)[0]
except UnknownEid:
- self.critical('wrong eid %s in repository, you should '
- 'db-check the database' % value)
- row_descr[index] = row[index] = None
- description.append(tuple(row_descr))
+ self.error('wrong eid %s in repository, you should '
+ 'db-check the database' % value)
+ todel.append(i)
+ break
+ else:
+ description.append(tuple(row_descr))
+ for i in reversed(todel):
+ del result[i]
return description
# deprecated ###############################################################
--- a/server/sources/datafeed.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/sources/datafeed.py Fri Aug 05 14:23:55 2011 +0200
@@ -218,7 +218,7 @@
"""
entity = super(DataFeedSource, self).before_entity_insertion(
session, lid, etype, eid, sourceparams)
- entity.cw_edited['cwuri'] = unicode(lid)
+ entity.cw_edited['cwuri'] = lid.decode('utf-8')
entity.cw_edited.set_defaults()
sourceparams['parser'].before_entity_copy(entity, sourceparams)
return entity
@@ -275,6 +275,8 @@
else:
source = self.source
sourceparams['parser'] = self
+ if isinstance(uri, unicode):
+ uri = uri.encode('utf-8')
try:
eid = session.repo.extid2eid(source, str(uri), etype, session,
complete=False, commit=False,
@@ -351,10 +353,10 @@
def parse(self, url):
if url.startswith('http'):
- from cubicweb.sobjects.parsers import HOST_MAPPING
- for mappedurl in HOST_MAPPING:
+ from cubicweb.sobjects.parsers import URL_MAPPING
+ for mappedurl in URL_MAPPING:
if url.startswith(mappedurl):
- url = url.replace(mappedurl, HOST_MAPPING[mappedurl], 1)
+ url = url.replace(mappedurl, URL_MAPPING[mappedurl], 1)
break
self.source.info('GET %s', url)
stream = _OPENER.open(url)
--- a/server/sources/rql2sql.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/sources/rql2sql.py Fri Aug 05 14:23:55 2011 +0200
@@ -1238,35 +1238,47 @@
def _visit_outer_join_inlined_relation(self, relation, rschema):
- leftvar, leftconst, rightvar, rightconst = relation_info(relation)
- assert not (leftconst and rightconst), "doesn't make sense"
- if relation.optional != 'right':
- leftvar, rightvar = rightvar, leftvar
- leftconst, rightconst = rightconst, leftconst
- outertype = 'FULL' if relation.optional == 'both' else 'LEFT'
- leftalias = self._var_table(leftvar)
+ lhsvar, lhsconst, rhsvar, rhsconst = relation_info(relation)
+ assert not (lhsconst and rhsconst), "doesn't make sense"
attr = 'eid' if relation.r_type == 'identity' else relation.r_type
- lhs, rhs = relation.get_variable_parts()
+ lhsalias = self._var_table(lhsvar)
+ rhsalias = rhsvar and self._var_table(rhsvar)
try:
- lhssql = self._varmap['%s.%s' % (lhs.name, attr)]
+ lhssql = self._varmap['%s.%s' % (lhsvar.name, attr)]
except KeyError:
- lhssql = '%s.%s%s' % (self._var_table(lhs.variable), SQL_PREFIX, attr)
- if rightvar is not None:
- rightalias = self._var_table(rightvar)
- if rightalias is None:
- if rightconst is not None:
- # inlined relation with invariant as rhs
- condition = '%s=%s' % (lhssql, rightconst.accept(self))
- if relation.r_type != 'identity':
- condition = '(%s OR %s IS NULL)' % (condition, lhssql)
- if not leftvar.stinfo.get('optrelations'):
- return condition
- self._state.add_outer_join_condition(leftalias, condition)
- return
- if leftalias is None:
- leftalias = leftvar._q_sql.split('.', 1)[0]
- self._state.replace_tables_by_outer_join(
- leftalias, rightalias, outertype, '%s=%s' % (lhssql, rhs.accept(self)))
+ if lhsalias is None:
+ lhssql = lhsconst.accept(self)
+ else:
+ lhssql = '%s.%s%s' % (lhsalias, SQL_PREFIX, attr)
+ condition = '%s=%s' % (lhssql, (rhsconst or rhsvar).accept(self))
+ # this is not a typo, rhs optional variable means lhs outer join and vice-versa
+ if relation.optional == 'left':
+ lhsvar, rhsvar = rhsvar, lhsvar
+ lhsconst, rhsconst = rhsconst, lhsconst
+ lhsalias, rhsalias = rhsalias, lhsalias
+ outertype = 'LEFT'
+ elif relation.optional == 'both':
+ outertype = 'FULL'
+ else:
+ outertype = 'LEFT'
+ if rhsalias is None:
+ if rhsconst is not None:
+ # inlined relation with invariant as rhs
+ if relation.r_type != 'identity':
+ condition = '(%s OR %s IS NULL)' % (condition, lhssql)
+ if not lhsvar.stinfo.get('optrelations'):
+ return condition
+ self._state.add_outer_join_condition(lhsalias, condition)
+ return
+ if lhsalias is None:
+ if lhsconst is not None and not rhsvar.stinfo.get('optrelations'):
+ return condition
+ lhsalias = lhsvar._q_sql.split('.', 1)[0]
+ if lhsalias == rhsalias:
+ self._state.add_outer_join_condition(lhsalias, condition)
+ else:
+ self._state.replace_tables_by_outer_join(
+ lhsalias, rhsalias, outertype, condition)
return ''
def _visit_var_attr_relation(self, relation, rhs_vars):
@@ -1442,6 +1454,10 @@
pass
return '(%s %s %s)'% (lhs.accept(self), operator, rhs.accept(self))
+ def visit_unaryexpression(self, uexpr):
+ """generate SQL for a unary expression"""
+ return '%s%s'% (uexpr.operator, uexpr.children[0].accept(self))
+
def visit_function(self, func):
"""generate SQL name for a function"""
if func.name == 'FTIRANK':
--- a/server/test/unittest_datafeed.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/test/unittest_datafeed.py Fri Aug 05 14:23:55 2011 +0200
@@ -94,9 +94,26 @@
self.assertTrue(dfsource.latest_retrieval)
self.assertTrue(dfsource.fresh())
+ # test_rename_source
+ req = self.request()
+ req.execute('SET S name "myrenamedfeed" WHERE S is CWSource, S name "myfeed"')
+ self.commit()
+ entity = self.execute('Card X').get_entity(0, 0)
+ self.assertEqual(entity.cwuri, 'http://www.cubicweb.org/')
+ self.assertEqual(entity.cw_source[0].name, 'myrenamedfeed')
+ self.assertEqual(entity.cw_metainformation(),
+ {'type': 'Card',
+ 'source': {'uri': 'myrenamedfeed', 'type': 'datafeed', 'use-cwuri-as-url': True},
+ 'extid': 'http://www.cubicweb.org/'}
+ )
+ self.assertEqual(self.repo._type_source_cache[entity.eid],
+ ('Card', 'system', 'http://www.cubicweb.org/', 'myrenamedfeed'))
+ self.assertEqual(self.repo._extid_cache[('http://www.cubicweb.org/', 'system')],
+ entity.eid)
+
# test_delete_source
req = self.request()
- req.execute('DELETE CWSource S WHERE S name "myfeed"')
+ req.execute('DELETE CWSource S WHERE S name "myrenamedfeed"')
self.commit()
self.failIf(self.execute('Card X WHERE X title "cubicweb.org"'))
self.failIf(self.execute('Any X WHERE X has_text "cubicweb.org"'))
--- a/server/test/unittest_repository.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/test/unittest_repository.py Fri Aug 05 14:23:55 2011 +0200
@@ -366,7 +366,6 @@
schema = cnx.get_schema()
self.failUnless(cnx.vreg)
self.failUnless('etypes'in cnx.vreg)
- self.assertEqual(schema.__hashmode__, None)
cu = cnx.cursor()
rset = cu.execute('Any U,G WHERE U in_group G')
user = iter(rset.entities()).next()
--- a/server/test/unittest_rql2sql.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/test/unittest_rql2sql.py Fri Aug 05 14:23:55 2011 +0200
@@ -88,7 +88,6 @@
]
BASIC = [
-
("Any AS WHERE AS is Affaire",
'''SELECT _AS.cw_eid
FROM cw_Affaire AS _AS'''),
@@ -201,7 +200,12 @@
('Any X WHERE X title V, NOT X wikiid V, NOT X title "parent", X is Card',
'''SELECT _X.cw_eid
FROM cw_Card AS _X
-WHERE NOT (_X.cw_wikiid=_X.cw_title) AND NOT (_X.cw_title=parent)''')
+WHERE NOT (_X.cw_wikiid=_X.cw_title) AND NOT (_X.cw_title=parent)'''),
+
+ ("Any -AS WHERE AS is Affaire",
+ '''SELECT -_AS.cw_eid
+FROM cw_Affaire AS _AS'''),
+
]
BASIC_WITH_LIMIT = [
@@ -972,7 +976,7 @@
('Any CASE, CALIBCFG, CFG '
'WHERE CASE eid 1, CFG ecrit_par CASE, CALIBCFG? ecrit_par CASE',
'''SELECT _CFG.cw_ecrit_par, _CALIBCFG.cw_eid, _CFG.cw_eid
-FROM cw_Note AS _CFG LEFT OUTER JOIN cw_Note AS _CALIBCFG ON (_CALIBCFG.cw_ecrit_par=_CFG.cw_ecrit_par)
+FROM cw_Note AS _CFG LEFT OUTER JOIN cw_Note AS _CALIBCFG ON (_CALIBCFG.cw_ecrit_par=1)
WHERE _CFG.cw_ecrit_par=1'''),
('Any U,G WHERE U login UL, G name GL, G is CWGroup HAVING UPPER(UL)=UPPER(GL)?',
@@ -986,6 +990,17 @@
('Any U,G WHERE U login UL, G name GL, G is CWGroup HAVING UPPER(UL)?=UPPER(GL)?',
'''SELECT _U.cw_eid, _G.cw_eid
FROM cw_CWUser AS _U FULL OUTER JOIN cw_CWGroup AS _G ON (UPPER(_U.cw_login)=UPPER(_G.cw_name))'''),
+
+ ('Any H, COUNT(X), SUM(XCE)/1000 '
+ 'WHERE X type "0", X date XSCT, X para XCE, X? ecrit_par F, F eid 999999, F is Personne, '
+ 'DH is Affaire, DH ref H '
+ 'HAVING XSCT?=H',
+ '''SELECT _DH.cw_ref, COUNT(_X.cw_eid), (SUM(_X.cw_para) / 1000)
+FROM cw_Affaire AS _DH LEFT OUTER JOIN cw_Note AS _X ON (_X.cw_date=_DH.cw_ref AND _X.cw_type=0 AND _X.cw_ecrit_par=999999)'''),
+
+ ('Any C WHERE X ecrit_par C?, X? inline1 F, F eid 1, X type XT, Z is Personne, Z nom ZN HAVING ZN=XT?',
+ '''SELECT _X.cw_ecrit_par
+FROM cw_Personne AS _Z LEFT OUTER JOIN cw_Note AS _X ON (_Z.cw_nom=_X.cw_type AND _X.cw_inline1=1)'''),
]
VIRTUAL_VARS = [
@@ -1721,7 +1736,7 @@
class SqlServer2005SQLGeneratorTC(PostgresSQLGeneratorTC):
backend = 'sqlserver2005'
def _norm_sql(self, sql):
- return sql.strip().replace(' SUBSTR', ' SUBSTRING').replace(' || ', ' + ').replace(' ILIKE ', ' LIKE ')
+ return sql.strip().replace(' SUBSTR', ' SUBSTRING').replace(' || ', ' + ').replace(' ILIKE ', ' LIKE ').replace('TRUE', '1').replace('FALSE', '0')
def test_has_text(self):
for t in self._parse(HAS_TEXT_LG_INDEXER):
--- a/server/test/unittest_session.py Wed Jul 27 20:17:45 2011 +0200
+++ b/server/test/unittest_session.py Fri Aug 05 14:23:55 2011 +0200
@@ -78,5 +78,15 @@
self.assertEqual(session._tx_data, {})
self.assertEqual(session.cnxset, None)
+ def test_build_descr(self):
+ rset = self.execute('(Any U,L WHERE U login L) UNION (Any G,N WHERE G name N, G is CWGroup)')
+ orig_length = len(rset)
+ rset.rows[0][0] = 9999999
+ description = self.session.build_description(rset.syntax_tree(), None, rset.rows)
+ self.assertEqual(len(description), orig_length - 1)
+ self.assertEqual(len(rset.rows), orig_length - 1)
+ self.failIf(rset.rows[0][0] == 9999999)
+
+
if __name__ == '__main__':
unittest_main()
--- a/sobjects/parsers.py Wed Jul 27 20:17:45 2011 +0200
+++ b/sobjects/parsers.py Fri Aug 05 14:23:55 2011 +0200
@@ -459,10 +459,10 @@
def registration_callback(vreg):
vreg.register_all(globals().values(), __name__)
- global HOST_MAPPING
- HOST_MAPPING = {}
+ global URL_MAPPING
+ URL_MAPPING = {}
if vreg.config.apphome:
- host_mapping_file = osp.join(vreg.config.apphome, 'hostmapping.py')
- if osp.exists(host_mapping_file):
- HOST_MAPPING = eval(file(host_mapping_file).read())
- vreg.info('using host mapping %s from %s', HOST_MAPPING, host_mapping_file)
+ url_mapping_file = osp.join(vreg.config.apphome, 'urlmapping.py')
+ if osp.exists(url_mapping_file):
+ URL_MAPPING = eval(file(url_mapping_file).read())
+ vreg.info('using url mapping %s from %s', URL_MAPPING, url_mapping_file)
--- a/web/data/cubicweb.reset.css Wed Jul 27 20:17:45 2011 +0200
+++ b/web/data/cubicweb.reset.css Fri Aug 05 14:23:55 2011 +0200
@@ -1,53 +1,48 @@
-/* http://meyerweb.com/eric/tools/css/reset/ */
-/* v1.0 | 20080212 */
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
+del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-size: 100%;
- vertical-align: baseline;
- background: transparent;
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
}
body {
- line-height: 1;
+ line-height: 1;
}
ol, ul {
- list-style: none;
+ list-style: none;
}
blockquote, q {
- quotes: none;
+ quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
- content: '';
- content: none;
-}
-
-/* remember to define focus styles! */
-:focus {
- outline: 0;
+ content: '';
+ content: none;
}
-
-/* remember to highlight inserts somehow! */
-ins {
- text-decoration: none;
-}
-del {
- text-decoration: line-through;
-}
-
-/* tables still need 'cellspacing="0"' in the markup */
table {
- border-collapse: collapse;
- border-spacing: 0;
+ border-collapse: collapse;
+ border-spacing: 0;
}
\ No newline at end of file
--- a/web/test/unittest_views_editforms.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/test/unittest_views_editforms.py Fri Aug 05 14:23:55 2011 +0200
@@ -77,9 +77,9 @@
# (appears here while expected in hidden
self.assertListEqual([x for x in rbc(e, 'main', 'relations')
if x != ('tags', 'object')],
- [('primary_email', 'subject'),
- ('connait', 'subject'),
+ [('connait', 'subject'),
('custom_workflow', 'subject'),
+ ('primary_email', 'subject'),
('checked_by', 'object'),
])
self.assertListEqual(rbc(e, 'main', 'inlined'),
--- a/web/views/actions.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/views/actions.py Fri Aug 05 14:23:55 2011 +0200
@@ -135,8 +135,13 @@
params = self._cw.form.copy()
for param in ('vid', '__message') + controller.NAV_FORM_PARAMETERS:
params.pop(param, None)
- return self._cw.build_url(self._cw.relative_path(includeparams=False),
- **params)
+ if self._cw.json_request:
+ path = 'view'
+ if self.cw_rset is not None:
+ params = {'rql': self.cw_rset.printable_rql()}
+ else:
+ path = self._cw.relative_path(includeparams=False)
+ return self._cw.build_url(path, **params)
class ModifyAction(action.Action):
@@ -163,7 +168,7 @@
order = 10
def url(self):
- return self._cw.build_url('view', rql=self.cw_rset.rql, vid='muledit')
+ return self._cw.build_url('view', rql=self.cw_rset.printable_rql(), vid='muledit')
# generic "more" actions #######################################################
--- a/web/views/cwuser.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/views/cwuser.py Fri Aug 05 14:23:55 2011 +0200
@@ -168,6 +168,10 @@
class CWUserManagementView(StartupView):
__regid__ = 'cw.user-management'
+ # XXX one could wish to display for instance only user's firstname/surname
+ # for non managers but filtering out NULL cause crash with an ldapuser
+ # source.
+ __select__ = StartupView.__select__ & match_user_groups('managers')
rql = ('Any U,USN,F,S,U,UAA,UDS, L,UAA,UDSN ORDERBY L WHERE U is CWUser, '
'U login L, U firstname F, U surname S, '
'U in_state US, US name USN, '
--- a/web/views/emailaddress.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/views/emailaddress.py Fri Aug 05 14:23:55 2011 +0200
@@ -15,9 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Specific views for email addresses entities
+"""Specific views for email addresses entities"""
-"""
__docformat__ = "restructuredtext en"
from logilab.mtconverter import xml_escape
@@ -85,8 +84,7 @@
class EmailAddressOneLineView(baseviews.OneLineView):
__select__ = is_instance('EmailAddress')
- def cell_call(self, row, col, **kwargs):
- entity = self.cw_rset.get_entity(row, col)
+ def entity_call(self, entity, **kwargs):
if entity.reverse_primary_email:
self.w(u'<b>')
if entity.alias:
@@ -106,8 +104,7 @@
__regid__ = 'mailto'
__select__ = is_instance('EmailAddress')
- def cell_call(self, row, col, **kwargs):
- entity = self.cw_rset.get_entity(row, col)
+ def entity_call(self, entity, **kwargs):
if entity.reverse_primary_email:
self.w(u'<b>')
if entity.alias:
@@ -130,7 +127,10 @@
__select__ = is_instance('EmailAddress')
def cell_call(self, row, col, **kwargs):
- self.wview('mailto', self.cw_rset, row=row, col=col, **kwargs)
+ if self._cw.vreg.config['mangle-emails']:
+ self.wview('oneline', self.cw_rset, row=row, col=col, **kwargs)
+ else:
+ self.wview('mailto', self.cw_rset, row=row, col=col, **kwargs)
class EmailAddressTextView(baseviews.TextView):
--- a/web/views/forms.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/views/forms.py Fri Aug 05 14:23:55 2011 +0200
@@ -384,7 +384,8 @@
else:
msg = self._cw._('entity linked')
if msg:
- self.add_hidden('__message', msg)
+ msgid = self._cw.set_redirect_message(msg)
+ self.add_hidden('_cwmsgid', msgid)
def session_key(self):
"""return the key that may be used to store / retreive data about a
--- a/web/views/tabs.py Wed Jul 27 20:17:45 2011 +0200
+++ b/web/views/tabs.py Fri Aug 05 14:23:55 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.