# HG changeset patch # User Sylvain Thénault # Date 1274087137 -7200 # Node ID 01a7228ab5a07ff5bea8fafe8d76792946027b32 # Parent c035a0fe75d898476eecb7de70e2b65bbdfc9913# Parent 4fcb0c13209882a7992388d1aa9fcc0c2337e42f backport stable diff -r c035a0fe75d8 -r 01a7228ab5a0 entity.py --- a/entity.py Tue May 11 08:29:15 2010 +0200 +++ b/entity.py Mon May 17 11:05:37 2010 +0200 @@ -432,12 +432,12 @@ def has_perm(self, action): return self.e_schema.has_perm(self._cw, action, eid=self.eid) - def view(self, __vid, __registry='views', **kwargs): + def view(self, __vid, __registry='views', w=None, **kwargs): """shortcut to apply a view on this entity""" view = self._cw.vreg[__registry].select(__vid, self._cw, rset=self.cw_rset, row=self.cw_row, col=self.cw_col, **kwargs) - return view.render(row=self.cw_row, col=self.cw_col, **kwargs) + return view.render(row=self.cw_row, col=self.cw_col, w=w, **kwargs) def absolute_url(self, *args, **kwargs): """return an absolute url to view this entity""" diff -r c035a0fe75d8 -r 01a7228ab5a0 etwist/http.py --- a/etwist/http.py Tue May 11 08:29:15 2010 +0200 +++ b/etwist/http.py Mon May 17 11:05:37 2010 +0200 @@ -45,10 +45,11 @@ def _finalize(self): + # we must set code before writing anything, else it's too late + if self._code is not None: + self._twreq.setResponseCode(self._code) if self._stream is not None: self._twreq.write(str(self._stream)) - if self._code is not None: - self._twreq.setResponseCode(self._code) self._twreq.finish() def __repr__(self): diff -r c035a0fe75d8 -r 01a7228ab5a0 goa/goaconfig.py --- a/goa/goaconfig.py Tue May 11 08:29:15 2010 +0200 +++ b/goa/goaconfig.py Mon May 17 11:05:37 2010 +0200 @@ -51,25 +51,25 @@ {'type' : 'csv', 'default': [], 'help': 'list of db model based cubes used by the instance.', - 'group': 'main', 'inputlevel': 1, + 'group': 'main', 'level': 1, }), ('included-yams-cubes', {'type' : 'csv', 'default': [], 'help': 'list of yams based cubes used by the instance.', - 'group': 'main', 'inputlevel': 1, + 'group': 'main', 'level': 1, }), ('use-google-auth', {'type' : 'yn', 'default': True, 'help': 'does this instance rely on google authentication service or not.', - 'group': 'main', 'inputlevel': 1, + 'group': 'main', 'level': 1, }), ('schema-type', {'type' : 'choice', 'choices': ('yams', 'dbmodel'), 'default': 'yams', 'help': 'does this instance is defining its schema using yams or db model.', - 'group': 'main', 'inputlevel': 1, + 'group': 'main', 'level': 1, }), # overriden options ('query-log-file', @@ -78,7 +78,7 @@ 'help': 'web instance query log file: DON\'T SET A VALUE HERE WHEN ' 'UPLOADING YOUR INSTANCE. This should only be used to analyse ' 'queries issued by your instance in the development environment.', - 'group': 'main', 'inputlevel': 2, + 'group': 'main', 'level': 2, }), ('anonymous-user', {'type' : 'string', @@ -87,7 +87,7 @@ '(if you want to allow anonymous). This option will be ignored if ' 'use-google-auth option is set (in which case you should control ' 'anonymous access using the app.yaml file)', - 'group': 'main', 'inputlevel': 1, + 'group': 'main', 'level': 1, }), ) + WebConfiguration.options + ServerConfiguration.options) diff -r c035a0fe75d8 -r 01a7228ab5a0 hooks/metadata.py --- a/hooks/metadata.py Tue May 11 08:29:15 2010 +0200 +++ b/hooks/metadata.py Mon May 17 11:05:37 2010 +0200 @@ -160,18 +160,10 @@ rtype = self.rtype session = self._cw ftcontainer = session.vreg.schema.rschema(rtype).fulltext_container - if self.event == 'after_add_relation': - if ftcontainer == 'subject': - session.repo.system_source.index_entity( - session, session.entity_from_eid(self.eidfrom)) - elif ftcontainer == 'object': - session.repo.system_source.index_entity( - session, session.entity_from_eid(self.eidto)) - # after delete relation - elif ftcontainer == 'subject': + if ftcontainer == 'subject': session.repo.system_source.index_entity( - session, entity=session.entity_from_eid(self.eidfrom)) + session, session.entity_from_eid(self.eidfrom)) elif ftcontainer == 'object': session.repo.system_source.index_entity( - session, entity=session.entity_from_eid(self.eidto)) + session, session.entity_from_eid(self.eidto)) diff -r c035a0fe75d8 -r 01a7228ab5a0 i18n/en.po --- a/i18n/en.po Tue May 11 08:29:15 2010 +0200 +++ b/i18n/en.po Mon May 17 11:05:37 2010 +0200 @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: 2.0\n" "POT-Creation-Date: 2006-01-12 17:35+CET\n" -"PO-Revision-Date: 2009-09-17 11:53+0200\n" +"PO-Revision-Date: 2010-05-16 18:58+0200\n" "Last-Translator: Sylvain Thenault \n" "Language-Team: English \n" "MIME-Version: 1.0\n" @@ -3158,14 +3158,14 @@ msgid "schema's permissions definitions" msgstr "" +msgid "schema-diagram" +msgstr "diagram" + msgid "schema-entity-types" -msgstr "" - -msgid "schema-image" -msgstr "image" +msgstr "entities" msgid "schema-relation-types" -msgstr "" +msgstr "relations" msgid "schema-security" msgstr "permissions" @@ -3947,3 +3947,6 @@ msgid "you should probably delete that property" msgstr "" + +#~ msgid "schema-image" +#~ msgstr "image" diff -r c035a0fe75d8 -r 01a7228ab5a0 i18n/es.po --- a/i18n/es.po Tue May 11 08:29:15 2010 +0200 +++ b/i18n/es.po Mon May 17 11:05:37 2010 +0200 @@ -3235,12 +3235,12 @@ msgid "schema's permissions definitions" msgstr "definiciones de permisos del esquema" +msgid "schema-diagram" +msgstr "" + msgid "schema-entity-types" msgstr "" -msgid "schema-image" -msgstr "esquema imagen" - msgid "schema-relation-types" msgstr "" @@ -4034,3 +4034,6 @@ msgid "you should probably delete that property" msgstr "deberia probablamente suprimir esta propriedad" + +#~ msgid "schema-image" +#~ msgstr "esquema imagen" diff -r c035a0fe75d8 -r 01a7228ab5a0 i18n/fr.po --- a/i18n/fr.po Tue May 11 08:29:15 2010 +0200 +++ b/i18n/fr.po Mon May 17 11:05:37 2010 +0200 @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: cubicweb 2.46.0\n" -"PO-Revision-Date: 2010-01-15 09:35+0100\n" +"PO-Revision-Date: 2010-05-16 18:59+0200\n" "Last-Translator: Logilab Team \n" "Language-Team: fr \n" "MIME-Version: 1.0\n" @@ -3272,12 +3272,12 @@ msgid "schema's permissions definitions" msgstr "permissions définies dans le schéma" +msgid "schema-diagram" +msgstr "diagramme" + msgid "schema-entity-types" msgstr "types d'entités" -msgid "schema-image" -msgstr "image" - msgid "schema-relation-types" msgstr "types de relations" @@ -4081,3 +4081,6 @@ msgid "you should probably delete that property" msgstr "vous devriez probablement supprimer cette propriété" + +#~ msgid "schema-image" +#~ msgstr "image" diff -r c035a0fe75d8 -r 01a7228ab5a0 req.py --- a/req.py Tue May 11 08:29:15 2010 +0200 +++ b/req.py Mon May 17 11:05:37 2010 +0200 @@ -289,7 +289,7 @@ # formating methods ####################################################### def view(self, __vid, rset=None, __fallback_oid=None, __registry='views', - initargs=None, **kwargs): + initargs=None, w=None, **kwargs): """Select object with the given id (`__oid`) then render it. If the object isn't selectable, try to select fallback object if `__fallback_oid` is specified. @@ -309,7 +309,7 @@ except RegistryException: view = self.vreg[__registry].select(__fallback_oid, self, rset=rset, **initargs) - return view.render(**kwargs) + return view.render(w=w, **kwargs) def format_date(self, date, date_format=None, time=False): """return a string for a date time according to instance's diff -r c035a0fe75d8 -r 01a7228ab5a0 server/checkintegrity.py --- a/server/checkintegrity.py Tue May 11 08:29:15 2010 +0200 +++ b/server/checkintegrity.py Mon May 17 11:05:37 2010 +0200 @@ -130,7 +130,7 @@ """check serialized schema""" print 'Checking serialized schema' unique_constraints = ('SizeConstraint', 'FormatConstraint', - 'VocabularyConstraint', 'RQLConstraint', + 'VocabularyConstraint', 'RQLVocabularyConstraint') rql = ('Any COUNT(X),RN,SN,ON,CTN GROUPBY RN,SN,ON,CTN ORDERBY 1 ' 'WHERE X is CWConstraint, R constrained_by X, ' @@ -142,6 +142,8 @@ if cstrname in unique_constraints: print "ERROR: got %s %r constraints on relation %s.%s.%s" % ( count, cstrname, sn, rn, on) + if fix: + print 'dunno how to fix, do it yourself' diff -r c035a0fe75d8 -r 01a7228ab5a0 server/hook.py --- a/server/hook.py Tue May 11 08:29:15 2010 +0200 +++ b/server/hook.py Mon May 17 11:05:37 2010 +0200 @@ -304,9 +304,9 @@ assert self.rtype in self.object_relations meid, seid = self.eidto, self.eidfrom self._cw.execute( - 'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\ + 'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P' % (self.main_rtype, self.main_rtype, self.main_rtype), - {'x': meid, 'e': seid}, ('x', 'e')) + {'x': meid, 'e': seid}) class PropagateSubjectRelationAddHook(Hook): @@ -326,12 +326,12 @@ if rel in eschema.subjrels: execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' 'X %s R, NOT R %s P' % (self.rtype, rel, self.rtype), - {'x': self.eidfrom, 'p': self.eidto}, 'x') + {'x': self.eidfrom, 'p': self.eidto}) for rel in self.object_relations: if rel in eschema.objrels: execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' 'R %s X, NOT R %s P' % (self.rtype, rel, self.rtype), - {'x': self.eidfrom, 'p': self.eidto}, 'x') + {'x': self.eidfrom, 'p': self.eidto}) class PropagateSubjectRelationDelHook(Hook): @@ -351,12 +351,12 @@ if rel in eschema.subjrels: execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' 'X %s R' % (self.rtype, rel), - {'x': self.eidfrom, 'p': self.eidto}, 'x') + {'x': self.eidfrom, 'p': self.eidto}) for rel in self.object_relations: if rel in eschema.objrels: execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' 'R %s X' % (self.rtype, rel), - {'x': self.eidfrom, 'p': self.eidto}, 'x') + {'x': self.eidfrom, 'p': self.eidto}) # abstract classes for operation ############################################### diff -r c035a0fe75d8 -r 01a7228ab5a0 server/sources/native.py --- a/server/sources/native.py Tue May 11 08:29:15 2010 +0200 +++ b/server/sources/native.py Mon May 17 11:05:37 2010 +0200 @@ -235,7 +235,7 @@ 'default': '', 'help': 'set to "Trusted_Connection" if you are using SQLServer and ' 'want trusted authentication for the database connection', - 'group': 'native-source', 'inputlevel': 2, + 'group': 'native-source', 'level': 2, }), ) diff -r c035a0fe75d8 -r 01a7228ab5a0 setup.py --- a/setup.py Tue May 11 08:29:15 2010 +0200 +++ b/setup.py Mon May 17 11:05:37 2010 +0200 @@ -27,15 +27,15 @@ from os.path import isdir, exists, join, walk try: - if os.environ.get('NO_SETUPTOOLS'): - raise ImportError() # do as there is no setuptools - from setuptools import setup - from setuptools.command import install_lib - USE_SETUPTOOLS = True + if os.environ.get('NO_SETUPTOOLS'): + raise ImportError() # do as there is no setuptools + from setuptools import setup + from setuptools.command import install_lib + USE_SETUPTOOLS = True except ImportError: - from distutils.core import setup - from distutils.command import install_lib - USE_SETUPTOOLS = False + from distutils.core import setup + from distutils.command import install_lib + USE_SETUPTOOLS = False # import required features from __pkginfo__ import modname, version, license, description, web, \ @@ -46,13 +46,13 @@ # import optional features import __pkginfo__ if USE_SETUPTOOLS: - requires = {} - for entry in ("__depends__", "__recommends__"): - requires.update(getattr(__pkginfo__, entry, {})) - install_requires = [("%s %s" % (d, v and v or "")).strip() + requires = {} + for entry in ("__depends__", "__recommends__"): + requires.update(getattr(__pkginfo__, entry, {})) + install_requires = [("%s %s" % (d, v and v or "")).strip() for d, v in requires.iteritems()] else: - install_requires = [] + install_requires = [] distname = getattr(__pkginfo__, 'distname', modname) scripts = getattr(__pkginfo__, 'scripts', ()) @@ -181,7 +181,7 @@ kwargs['package_dir'] = {modname : '.'} packages = [modname] + get_packages(os.getcwd(), modname) if USE_SETUPTOOLS: - kwargs['install_requires'] = install_requires + kwargs['install_requires'] = install_requires kwargs['packages'] = packages return setup(name=distname, version=version, license=license, url=web, description=description, long_description=long_description, diff -r c035a0fe75d8 -r 01a7228ab5a0 sobjects/notification.py --- a/sobjects/notification.py Tue May 11 08:29:15 2010 +0200 +++ b/sobjects/notification.py Mon May 17 11:05:37 2010 +0200 @@ -15,9 +15,8 @@ # # You should have received a copy of the GNU Lesser General Public License along # with CubicWeb. If not, see . -"""some views to handle notification on data changes +"""some views to handle notification on data changes""" -""" __docformat__ = "restructuredtext en" _ = unicode diff -r c035a0fe75d8 -r 01a7228ab5a0 web/facet.py --- a/web/facet.py Tue May 11 08:29:15 2010 +0200 +++ b/web/facet.py Mon May 17 11:05:37 2010 +0200 @@ -467,6 +467,7 @@ attrtype = 'String' # type of comparison: default is an exact match on the attribute value comparator = '=' # could be '<', '<=', '>', '>=' + i18nable = True def vocabulary(self): """return vocabulary for this facet, eg a list of 2-uple (label, value) @@ -491,7 +492,10 @@ return rset and self.rset_vocabulary(rset) def rset_vocabulary(self, rset): - _ = self._cw._ + if self.i18nable: + _ = self._cw._ + else: + _ = unicode return [(_(value), value) for value, in rset] def support_and(self): diff -r c035a0fe75d8 -r 01a7228ab5a0 web/uicfg.py --- a/web/uicfg.py Tue May 11 08:29:15 2010 +0200 +++ b/web/uicfg.py Mon May 17 11:05:37 2010 +0200 @@ -80,18 +80,13 @@ primaryview_section = RelationTags('primaryview_section', init_primaryview_section, frozenset(('attributes', 'relations', - 'sideboxes', 'hidden'))) + 'sideboxes', 'hidden'))) class DisplayCtrlRelationTags(RelationTagsDict): def __init__(self, *args, **kwargs): super(DisplayCtrlRelationTags, self).__init__(*args, **kwargs) - self._counter = 0 - - def tag_relation(self, key, tag): - tag = super(DisplayCtrlRelationTags, self).tag_relation(key, tag) - self._counter += 1 - tag.setdefault('order', self._counter) + self.counter = 0 def tag_subject_of(self, key, tag): subj, rtype, obj = key @@ -117,7 +112,8 @@ sschema = '*' label = '%s_%s' % (rschema, role) rtag.setdefault((sschema, rschema, oschema, role), 'label', label) - rtag.setdefault((sschema, rschema, oschema, role), 'order', rtag._counter) + rtag.counter += 1 + rtag.setdefault((sschema, rschema, oschema, role), 'order', rtag.counter) primaryview_display_ctrl = DisplayCtrlRelationTags('primaryview_display_ctrl', init_primaryview_display_ctrl) diff -r c035a0fe75d8 -r 01a7228ab5a0 web/views/actions.py --- a/web/views/actions.py Tue May 11 08:29:15 2010 +0200 +++ b/web/views/actions.py Mon May 17 11:05:37 2010 +0200 @@ -264,12 +264,15 @@ def actual_actions(self): entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0) eschema = entity.e_schema - for rschema, teschema, x in self.add_related_schemas(entity): - if x == 'subject': - label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) + for rschema, teschema, role in self.add_related_schemas(entity): + if rschema.role_rdef(eschema, teschema, role).role_cardinality(role) in '1?': + if entity.related(rschema, role): + continue + if role == 'subject': + label = 'add %s %s %s %s' % (eschema, rschema, teschema, role) url = self.linkto_url(entity, rschema, teschema, 'object') else: - label = 'add %s %s %s %s' % (teschema, rschema, eschema, x) + label = 'add %s %s %s %s' % (teschema, rschema, eschema, role) url = self.linkto_url(entity, rschema, teschema, 'subject') yield self.build_action(self._cw._(label), url) diff -r c035a0fe75d8 -r 01a7228ab5a0 web/views/baseviews.py --- a/web/views/baseviews.py Tue May 11 08:29:15 2010 +0200 +++ b/web/views/baseviews.py Mon May 17 11:05:37 2010 +0200 @@ -21,13 +21,13 @@ * primary, sidebox * oneline, incontext, outofcontext, text * list - +""" -""" __docformat__ = "restructuredtext en" _ = unicode from datetime import timedelta +from warnings import warn from rql import nodes @@ -308,6 +308,18 @@ __regid__ = 'simplelist' redirect_vid = 'incontext' + def call(self, subvid=None, **kwargs): + """display a list of entities by calling their view + + :param listid: the DOM id to use for the root element + """ + if subvid is None and 'vid' in kwargs: + warn("should give a 'subvid' argument instead of 'vid'", + DeprecationWarning, stacklevel=2) + else: + kwargs['vid'] = subvid + return super(SimpleListView, self).call(**kwargs) + class SameETypeListView(EntityView): """list of entities of the same type, when asked explicitly for same etype list @@ -344,10 +356,15 @@ __regid__ = 'csv' redirect_vid = 'incontext' - def call(self, **kwargs): + def call(self, subvid=None, **kwargs): + if subvid is None and 'vid' in kwargs: + warn("should give a 'subvid' argument instead of 'vid'", + DeprecationWarning, stacklevel=2) + else: + kwargs['vid'] = subvid rset = self.cw_rset for i in xrange(len(rset)): - self.cell_call(i, 0, vid=kwargs.get('vid')) + self.cell_call(i, 0, **kwargs) if i < rset.rowcount-1: self.w(u", ") diff -r c035a0fe75d8 -r 01a7228ab5a0 web/views/boxes.py --- a/web/views/boxes.py Tue May 11 08:29:15 2010 +0200 +++ b/web/views/boxes.py Mon May 17 11:05:37 2010 +0200 @@ -201,20 +201,5 @@ if title: self.w(u'
%s
' % title) self.w(u'
' % boxclass) - # if not too much entities, show them all in a list - maxrelated = self._cw.property_value('navigation.related-limit') - if self.cw_rset.rowcount <= maxrelated: - if len(self.cw_rset) == 1: - self.wview('incontext', self.cw_rset, row=0) - elif 1 < len(self.cw_rset) < 5: - self.wview('csv', self.cw_rset) - else: - self.wview('simplelist', self.cw_rset) - # else show links to display related entities - else: - self.cw_rset.limit(maxrelated) - rql = self.cw_rset.printable_rql(encoded=False) - self.wview('simplelist', self.cw_rset) - self.w(u'[%s]' % (self._cw.build_url(rql=rql), - self._cw._('see them all'))) + self.wview('autolimited', self.cw_rset, **self.cw_extra_kwargs) self.w(u'
\n
\n') diff -r c035a0fe75d8 -r 01a7228ab5a0 web/views/primary.py --- a/web/views/primary.py Tue May 11 08:29:15 2010 +0200 +++ b/web/views/primary.py Mon May 17 11:05:37 2010 +0200 @@ -178,7 +178,7 @@ DeprecationWarning) label, rset, vid = box self.w(u'') else: try: @@ -265,30 +265,33 @@ __regid__ = 'autolimited' def call(self, **kwargs): - # nb: rset retreived using entity.related with limit + 1 if any - # because of that, we known that rset.printable_rql() will return - # rql with no limit set anyway (since it's handled manually) + # nb: rset is retreived using entity.related with limit + 1 if any. + # Because of that, we know that rset.printable_rql() will return rql + # with no limit set anyway (since it's handled manually) if 'dispctrl' in self.cw_extra_kwargs: limit = self.cw_extra_kwargs['dispctrl'].get('limit') + subvid = self.cw_extra_kwargs['dispctrl'].get('subvid', 'incontext') else: limit = None + subvid = 'incontext' if limit is None or self.cw_rset.rowcount <= limit: if self.cw_rset.rowcount == 1: - self.wview('incontext', self.cw_rset, row=0) + self.wview(subvid, self.cw_rset, row=0) elif 1 < self.cw_rset.rowcount <= 5: - self.wview('csv', self.cw_rset) + self.wview('csv', self.cw_rset, subvid=subvid) else: self.w(u'
') - self.wview('simplelist', self.cw_rset) + self.wview('simplelist', self.cw_rset, subvid=subvid) self.w(u'
') # else show links to display related entities else: rql = self.cw_rset.printable_rql() self.cw_rset.limit(limit) # remove extra entity self.w(u'
') - self.wview('simplelist', self.cw_rset) - self.w(u'[%s]' % (self._cw.build_url(rql=rql), - self._cw._('see them all'))) + self.wview('simplelist', self.cw_rset, subvid=subvid) + self.w(u'[%s]' % ( + xml_escape(self._cw.build_url(rql=rql, vid=subvid)), + self._cw._('see them all'))) self.w(u'
') diff -r c035a0fe75d8 -r 01a7228ab5a0 web/views/schema.py --- a/web/views/schema.py Tue May 11 08:29:15 2010 +0200 +++ b/web/views/schema.py Mon May 17 11:05:37 2010 +0200 @@ -138,9 +138,9 @@ """display schema information (graphically, listing tables...) in tabs""" __regid__ = 'schema' title = _('instance schema') - tabs = [_('schema-image'), _('schema-entity-types'), + tabs = [_('schema-diagram'), _('schema-entity-types'), _('schema-relation-types'), _('schema-security')] - default_tab = 'schema-image' + default_tab = 'schema-diagram' def call(self): self.w(u'

%s

' % _('Schema of the data model')) @@ -148,7 +148,7 @@ class SchemaImageTab(StartupView): - __regid__ = 'schema-image' + __regid__ = 'schema-diagram' def call(self): self.w(_(u'
This schema of the data model excludes the ' diff -r c035a0fe75d8 -r 01a7228ab5a0 web/webconfig.py --- a/web/webconfig.py Tue May 11 08:29:15 2010 +0200 +++ b/web/webconfig.py Mon May 17 11:05:37 2010 +0200 @@ -134,7 +134,7 @@ 'help': "duration of the cookie used to store session identifier. " "If 0, the cookie will expire when the user exist its browser. " "Should be 0 or greater than repository\'s session-time.", - 'group': 'web', 'inputlevel': 2, + 'group': 'web', 'level': 2, }), ('cleanup-session-time', {'type' : 'time',