[bfss] fix file update to ensure file's content is available on the fs asap...
and not only at commit time. So it's consistent with entity creation behaviour.
The new file is created at assignement time and removed if the commit is
rollbacked.
# copyright 2003-2010 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/>."""Set of tree-building widgets, based on jQuery treeview plugin"""__docformat__="restructuredtext en"fromlogilab.mtconverterimportxml_escapefromcubicweb.utilsimportmake_uidfromcubicweb.interfacesimportITreefromcubicweb.selectorsimportimplementsfromcubicweb.viewimportEntityViewfromcubicweb.webimportjsondeftreecookiename(treeid):returnstr('%s-treestate'%treeid)classTreeView(EntityView):__regid__='treeview'itemvid='treeitemview'subvid='oneline'css_classes='treeview widget'title=_('tree view')def_init_params(self,subvid,treeid,initial_load,initial_thru_ajax,morekwargs):form=self._cw.formifsubvidisNone:subvid=form.pop('treesubvid',self.subvid)# consume itiftreeidisNone:treeid=form.pop('treeid',None)iftreeidisNone:treeid='throw_away'+make_uid('uid')if'morekwargs'inself._cw.form:ajaxargs=json.loads(form.pop('morekwargs'))# got unicode & python keywords must be stringsmorekwargs.update(dict((str(k),v)fork,vinajaxargs.iteritems()))toplevel_thru_ajax=form.pop('treeview_top',False)orinitial_thru_ajaxtoplevel=toplevel_thru_ajaxor(initial_loadandnotform.get('fname'))returnsubvid,treeid,toplevel_thru_ajax,topleveldef_init_headers(self,treeid,toplevel_thru_ajax):self._cw.add_css('jquery.treeview.css')self._cw.add_js(('cubicweb.ajax.js','cubicweb.widgets.js','jquery.treeview.js'))self._cw.html_headers.add_onload(u"""jQuery("#tree-%s").treeview({toggle: toggleTree, prerendered: true});"""%treeid)defcall(self,subvid=None,treeid=None,initial_load=True,initial_thru_ajax=False,**morekwargs):subvid,treeid,toplevel_thru_ajax,toplevel=self._init_params(subvid,treeid,initial_load,initial_thru_ajax,morekwargs)ulid=' 'iftoplevel:self._init_headers(treeid,toplevel_thru_ajax)ulid=' id="tree-%s"'%treeidself.w(u'<ul%s class="%s">'%(ulid,self.css_classes))# XXX force sorting on x.sortvalue() (which return dc_title by default)# we need proper ITree & co specification to avoid this.# (pb when type ambiguity at the other side of the tree relation,# unability to provide generic implementation on eg Folder...)fori,entityinenumerate(sorted(self.cw_rset.entities(),key=lambdax:x.sortvalue())):ifi+1<len(self.cw_rset):morekwargs['is_last']=Falseelse:morekwargs['is_last']=Trueentity.view(self.itemvid,vid=subvid,parentvid=self.__regid__,treeid=treeid,w=self.w,**morekwargs)self.w(u'</ul>')defcell_call(self,*args,**allargs):""" does not makes much sense until you have to invoke somentity.view('treeview') """allargs.pop('row')allargs.pop('col')self.call(*args,**allargs)classFileTreeView(TreeView):"""specific version of the treeview to display file trees """__regid__='filetree'css_classes='treeview widget filetree'title=_('file tree view')defcall(self,subvid=None,treeid=None,initial_load=True,**kwargs):super(FileTreeView,self).call(treeid=treeid,subvid='filetree-oneline',initial_load=initial_load,**kwargs)classFileItemInnerView(EntityView):"""inner view used by the TreeItemView instead of oneline view This view adds an enclosing <span> with some specific CSS classes around the oneline view. This is needed by the jquery treeview plugin. """__regid__='filetree-oneline'defcell_call(self,row,col):entity=self.cw_rset.get_entity(row,col)ifITree.is_implemented_by(entity.__class__)andnotentity.is_leaf():self.w(u'<div class="folder">%s</div>\n'%entity.view('oneline'))else:# XXX define specific CSS classes according to mime typesself.w(u'<div class="file">%s</div>\n'%entity.view('oneline'))classDefaultTreeViewItemView(EntityView):"""default treeitem view for entities which don't implement ITree"""__regid__='treeitemview'defcell_call(self,row,col,vid='oneline',treeid=None,**morekwargs):asserttreeidisnotNoneitemview=self._cw.view(vid,self.cw_rset,row=row,col=col)last_class=morekwargs['is_last']and' class="last"'or''self.w(u'<li%s>%s</li>'%(last_class,itemview))classTreeViewItemView(EntityView):"""specific treeitem view for entities which implement ITree (each item should be expandable if it's not a tree leaf) """__regid__='treeitemview'__select__=implements(ITree)default_branch_state_is_open=Falsedefopen_state(self,eeid,treeid):cookies=self._cw.get_cookie()treestate=cookies.get(treecookiename(treeid))iftreestate:returnstr(eeid)intreestate.value.split(':')returnself.default_branch_state_is_opendefcell_call(self,row,col,treeid,vid='oneline',parentvid='treeview',is_last=False,**morekwargs):w=self.wentity=self.cw_rset.get_entity(row,col)liclasses=[]is_open=self.open_state(entity.eid,treeid)is_leaf=nothasattr(entity,'is_leaf')orentity.is_leaf()ifis_leaf:ifis_last:liclasses.append('last')w(u'<li class="%s">'%u' '.join(liclasses))else:rql=entity.children_rql()%{'x':entity.eid}url=xml_escape(self._cw.build_url('json',rql=rql,vid=parentvid,pageid=self._cw.pageid,treeid=treeid,fname='view',treesubvid=vid,morekwargs=json.dumps(morekwargs)))divclasses=['hitarea']ifis_open:liclasses.append('collapsable')divclasses.append('collapsable-hitarea')else:liclasses.append('expandable')divclasses.append('expandable-hitarea')ifis_last:ifis_open:liclasses.append('lastCollapsable')divclasses.append('lastCollapsable-hitarea')else:liclasses.append('lastExpandable')divclasses.append('lastExpandable-hitarea')ifis_open:w(u'<li class="%s">'%u' '.join(liclasses))else:w(u'<li cubicweb:loadurl="%s" class="%s">'%(url,u' '.join(liclasses)))iftreeid.startswith('throw_away'):divtail=''else:divtail=""" onclick="asyncRemoteExec('node_clicked', '%s', '%s')" """%(treeid,entity.eid)w(u'<div class="%s"%s></div>'%(u' '.join(divclasses),divtail))# add empty <ul> because jquery's treeview plugin checks for# sublists presenceifnotis_open:w(u'<ul class="placeholder"><li>place holder</li></ul>')# the local node infoself.wview(vid,self.cw_rset,row=row,col=col,**morekwargs)ifis_openandnotis_leaf:# => rql is definedself.wview(parentvid,entity.children(entities=False),subvid=vid,treeid=treeid,initial_load=False,**morekwargs)w(u'</li>')