# HG changeset patch # User Sylvain Thénault # Date 1258735894 -3600 # Node ID 8902b8745918465e2602d43e5d83dbf2ae258f2e # Parent 7ca53fc72a0a6d5b7f66bd1e3fb21192a821c430# Parent 6f145783409d751f419a1fec7cd9b18054b3a7fa backport stable branch diff -r 7ca53fc72a0a -r 8902b8745918 entities/test/unittest_wfobjs.py --- a/entities/test/unittest_wfobjs.py Thu Nov 19 12:55:47 2009 +0100 +++ b/entities/test/unittest_wfobjs.py Fri Nov 20 17:51:34 2009 +0100 @@ -495,12 +495,21 @@ # self.commit() # test that the workflow is correctly enforced + + def _cleanup_msg(self, msg): + """remove the variable part of one specific error message""" + lmsg = msg.split() + lmsg.pop(1) + lmsg.pop() + return ' '.join(lmsg) + def test_transition_checking1(self): cnx = self.login('stduser') user = cnx.user(self.current_session()) ex = self.assertRaises(ValidationError, user.fire_transition, 'activate') - self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"}) + self.assertEquals(self._cleanup_msg(ex.errors['by_transition']), + u"transition isn't allowed from") cnx.close() def test_transition_checking2(self): @@ -509,7 +518,8 @@ assert user.state == 'activated' ex = self.assertRaises(ValidationError, user.fire_transition, 'dummy') - self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"}) + self.assertEquals(self._cleanup_msg(ex.errors['by_transition']), + u"transition isn't allowed from") cnx.close() def test_transition_checking3(self): @@ -521,7 +531,8 @@ session.set_pool() ex = self.assertRaises(ValidationError, user.fire_transition, 'deactivate') - self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"}) + self.assertEquals(self._cleanup_msg(ex.errors['by_transition']), + u"transition isn't allowed from") # get back now user.fire_transition('activate') cnx.commit() diff -r 7ca53fc72a0a -r 8902b8745918 server/migractions.py --- a/server/migractions.py Thu Nov 19 12:55:47 2009 +0100 +++ b/server/migractions.py Fri Nov 20 17:51:34 2009 +0100 @@ -104,9 +104,14 @@ if migrscript.endswith('.sql'): if self.execscript_confirm(migrscript): sqlexec(open(migrscript).read(), self.session.system_sql) - else: + elif migrscript.endswith('.py'): return super(ServerMigrationHelper, self).cmd_process_script( migrscript, funcname, *args, **kwargs) + else: + print + print ('-> ignoring %s, only .py and .sql scripts are considered' % + migrscript) + print self.commit() except: self.rollback() diff -r 7ca53fc72a0a -r 8902b8745918 server/schemahooks.py --- a/server/schemahooks.py Thu Nov 19 12:55:47 2009 +0100 +++ b/server/schemahooks.py Fri Nov 20 17:51:34 2009 +0100 @@ -906,7 +906,7 @@ # don't use getattr(entity, attr), we would get the modified value if any for attr in ro_attrs: if attr in entity.edited_attributes: - orival, newval = entity_oldnewvalue(entity, attr) + origval, newval = entity_oldnewvalue(entity, attr) if newval != origval: errors[attr] = session._("can't change the %s attribute") % \ display_name(session, attr) diff -r 7ca53fc72a0a -r 8902b8745918 utils.py --- a/utils.py Thu Nov 19 12:55:47 2009 +0100 +++ b/utils.py Fri Nov 20 17:51:34 2009 +0100 @@ -148,6 +148,20 @@ return dict1 +# use networkX instead ? +# http://networkx.lanl.gov/reference/algorithms.traversal.html#module-networkx.algorithms.traversal.astar +def transitive_closure_of(entity, relname, _seen=None): + if _seen is None: + _seen = set() + _seen.add(entity.eid) + yield entity + for child in getattr(entity, relname): + if child.eid in _seen: + continue + for subchild in transitive_closure_of(child, relname, _seen): + yield subchild + + class SizeConstrainedList(list): """simple list that makes sure the list does not get bigger than a given size. diff -r 7ca53fc72a0a -r 8902b8745918 web/formfields.py --- a/web/formfields.py Thu Nov 19 12:55:47 2009 +0100 +++ b/web/formfields.py Fri Nov 20 17:51:34 2009 +0100 @@ -81,6 +81,8 @@ role of the entity in the relation (eg 'subject' or 'object') :fieldset: optional fieldset to which this field belongs to + :order: + key used by automatic forms to sort fields """ # default widget associated to this class of fields. May be overriden per @@ -94,7 +96,7 @@ def __init__(self, name=None, id=None, label=None, help=None, widget=None, required=False, initial=None, choices=None, sort=True, internationalizable=False, - eidparam=False, role='subject', fieldset=None): + eidparam=False, role='subject', fieldset=None, order=None): self.name = name self.id = id or name self.label = label or name @@ -108,6 +110,7 @@ self.role = role self.fieldset = fieldset self.init_widget(widget) + self.order = order # ordering number for this field instance self.creation_rank = Field.__creation_rank Field.__creation_rank += 1 @@ -178,12 +181,7 @@ renderer """ widget = self.get_widget(form) - try: - return widget.render(form, self, renderer) - except TypeError: - warn('[3.3] %s: widget.render now take the renderer as third argument, ' - 'please update implementation' % widget, DeprecationWarning) - return widget.render(form, self) + return widget.render(form, self, renderer) def vocabulary(self, form): """return vocabulary for this field. This method will be called by diff -r 7ca53fc72a0a -r 8902b8745918 web/views/autoform.py --- a/web/views/autoform.py Thu Nov 19 12:55:47 2009 +0100 +++ b/web/views/autoform.py Fri Nov 20 17:51:34 2009 +0100 @@ -182,6 +182,8 @@ except form.FieldNotFound: # meta attribute such as _format continue + fnum = len(self.fields) + self.fields.sort(key=lambda f: f.order is None and fnum or f.order) self.maxrelitems = self.req.property_value('navigation.related-limit') self.force_display = bool(self.req.form.get('__force_display')) diff -r 7ca53fc72a0a -r 8902b8745918 web/views/editforms.py --- a/web/views/editforms.py Thu Nov 19 12:55:47 2009 +0100 +++ b/web/views/editforms.py Fri Nov 20 17:51:34 2009 +0100 @@ -436,6 +436,7 @@ form = self.vreg['forms'].select('edition', self.req, rset=self.rset, row=row, attrcategories=('primary',), + copy_nav_params=False, mainform=False) # XXX rely on the EntityCompositeFormRenderer to put the eid input form.remove_field(form.field_by_name('eid')) @@ -452,7 +453,8 @@ should be the eid """ #self.form_title(entity) - form = self.vreg['forms'].select(self.id, self.req, rset=self.rset) + form = self.vreg['forms'].select(self.id, self.req, rset=self.rset, + copy_nav_params=True) self.w(form.form_render()) diff -r 7ca53fc72a0a -r 8902b8745918 web/views/forms.py --- a/web/views/forms.py Thu Nov 19 12:55:47 2009 +0100 +++ b/web/views/forms.py Fri Nov 20 17:51:34 2009 +0100 @@ -89,6 +89,7 @@ if mainform: self.form_add_hidden('__errorurl', self.session_key()) self.form_add_hidden('__domid', self.domid) + # XXX why do we need two different variables (mainform and copy_nav_params ?) if self.copy_nav_params: for param in NAV_FORM_PARAMETERS: if not param in kwargs: diff -r 7ca53fc72a0a -r 8902b8745918 web/views/treeview.py --- a/web/views/treeview.py Thu Nov 19 12:55:47 2009 +0100 +++ b/web/views/treeview.py Fri Nov 20 17:51:34 2009 +0100 @@ -180,7 +180,7 @@ # the local node info self.wview(vid, self.rset, row=row, col=col, **morekwargs) if is_open and not is_leaf: # => rql is defined - self.wview(parentvid, self.req.execute(rql), subvid=vid, treeid=treeid, - initial_load=False, **morekwargs) + self.wview(parentvid, entity.children(entities=False), subvid=vid, + treeid=treeid, initial_load=False, **morekwargs) w(u'')