[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/>."""This module (``cubicweb.web.uicfg``) regroups a set of structures that may beused to configure various options of the generated web interface.To configure the interface generation, we use ``RelationTag`` objects.Index view configuration````````````````````````:indexview_etype_section: entity type category in the index/manage page. May be one of: * ``application`` * ``system`` * ``schema`` * ``subobject`` (not displayed by default)Actions box configuration`````````````````````````:actionbox_appearsin_addmenu: simple boolean relation tags used to control the "add entity" submenu. Relations whose rtag is True will appears, other won't... sourcecode:: python # Adds all subjects of the entry_of relation in the add menu of the ``Blog`` # primary view uicfg.actionbox_appearsin_addmenu.tag_object_of(('*', 'entry_of', 'Blog'), True)"""__docformat__="restructuredtext en"fromwarningsimportwarnfromlogilab.common.compatimportanyfromcubicwebimportneg_rolefromcubicweb.rtagsimport(RelationTags,RelationTagsBool,RelationTagsSet,RelationTagsDict,register_rtag,_ensure_str_key)fromcubicweb.schemaimportMETA_RTYPES# primary view configuration ##################################################definit_primaryview_section(rtag,sschema,rschema,oschema,role):ifrtag.get(sschema,rschema,oschema,role)isNone:rdef=rschema.rdef(sschema,oschema)ifrschema.final:ifrschema.metaorsschema.is_metadata(rschema) \oroschema.typein('Password','Bytes'):section='hidden'else:section='attributes'else:ifrdef.role_cardinality(role)in'1+':section='attributes'elifrdef.composite==neg_role(role):section='relations'else:section='sideboxes'rtag.tag_relation((sschema,rschema,oschema,role),section)primaryview_section=RelationTags('primaryview_section',init_primaryview_section,frozenset(('attributes','relations','sideboxes','hidden')))classDisplayCtrlRelationTags(RelationTagsDict):def__init__(self,*args,**kwargs):super(DisplayCtrlRelationTags,self).__init__(*args,**kwargs)self.counter=0deftag_subject_of(self,key,tag):subj,rtype,obj=keyifobj!='*':self.warning('using explict target type in display_ctrl.tag_subject_of() ''has no effect, use (%s, %s, "*") instead of (%s, %s, %s)',subj,rtype,subj,rtype,obj)super(DisplayCtrlRelationTags,self).tag_subject_of((subj,rtype,'*'),tag)deftag_object_of(self,key,tag):subj,rtype,obj=keyifsubj!='*':self.warning('using explict subject type in display_ctrl.tag_object_of() ''has no effect, use ("*", %s, %s) instead of (%s, %s, %s)',rtype,obj,subj,rtype,obj)super(DisplayCtrlRelationTags,self).tag_object_of(('*',rtype,obj),tag)definit_primaryview_display_ctrl(rtag,sschema,rschema,oschema,role):ifrole=='subject':oschema='*'label=rschema.typeelse:sschema='*'label='%s_%s'%(rschema,role)rtag.setdefault((sschema,rschema,oschema,role),'label',label)rtag.counter+=1rtag.setdefault((sschema,rschema,oschema,role),'order',rtag.counter)primaryview_display_ctrl=DisplayCtrlRelationTags('primaryview_display_ctrl',init_primaryview_display_ctrl)# index view configuration ##################################################### entity type section in the index/manage page. May be one of# * 'application'# * 'system'# * 'schema'# * 'hidden'# * 'subobject' (not displayed by default)classInitializableDict(dict):def__init__(self,*args,**kwargs):super(InitializableDict,self).__init__(*args,**kwargs)register_rtag(self)self.__defaults=dict(self)definit(self,schema,check=True):self.update(self.__defaults)foreschemainschema.entities():ifeschema.final:continueifeschema.schema_entity():self.setdefault(eschema,'schema')elifeschema.is_subobject(strict=True):self.setdefault(eschema,'subobject')else:self.setdefault(eschema,'application')indexview_etype_section=InitializableDict(EmailAddress='subobject',# entity types in the 'system' table by default (managers only)CWUser='system',CWGroup='system',CWPermission='system',CWCache='system',Workflow='system',ExternalUri='system',Bookmark='system',)# autoform.AutomaticEntityForm configuration ##################################def_formsections_as_dict(formsections):result={}forformsectioninformsections:formtype,section=formsection.split('_',1)result[formtype]=sectionreturnresultdef_card_and_comp(sschema,rschema,oschema,role):rdef=rschema.rdef(sschema,oschema)ifrole=='subject':card=rdef.cardinality[0]composed=notrschema.finalandrdef.composite=='object'else:card=rdef.cardinality[1]composed=notrschema.finalandrdef.composite=='subject'returncard,composedclassAutoformSectionRelationTags(RelationTagsSet):"""autoform relations'section"""bw_tag_map={'primary':{'main':'attributes','muledit':'attributes'},'secondary':{'main':'attributes','muledit':'hidden'},'metadata':{'main':'metadata'},'generic':{'main':'relations'},'generated':{'main':'hidden'},}_allowed_form_types=('main','inlined','muledit')_allowed_values={'main':('attributes','inlined','relations','metadata','hidden'),'inlined':('attributes','inlined','hidden'),'muledit':('attributes','hidden'),}definit(self,schema,check=True):super(AutoformSectionRelationTags,self).init(schema,check)self.apply(schema,self._initfunc_step2)@staticmethoddef_initfunc(self,sschema,rschema,oschema,role):formsections=self.init_get(sschema,rschema,oschema,role)ifformsectionsisNone:formsections=self.tag_container_cls()ifnotany(tag.startswith('inlined')fortaginformsections):ifnotrschema.final:negsects=self.init_get(sschema,rschema,oschema,neg_role(role))if'main_inlined'innegsects:formsections.add('inlined_hidden')key=_ensure_str_key((sschema,rschema,oschema,role))self._tagdefs[key]=formsections@staticmethoddef_initfunc_step2(self,sschema,rschema,oschema,role):formsections=self.get(sschema,rschema,oschema,role)sectdict=_formsections_as_dict(formsections)ifrschemainMETA_RTYPES:sectdict.setdefault('main','hidden')sectdict.setdefault('muledit','hidden')sectdict.setdefault('inlined','hidden')# ensure we have a tag for each form typeifnot'main'insectdict:ifnotrschema.finaland(sectdict.get('inlined')=='attributes'or'inlined_attributes'inself.init_get(sschema,rschema,oschema,neg_role(role))):sectdict['main']='hidden'elifsschema.is_metadata(rschema):sectdict['main']='metadata'else:card,composed=_card_and_comp(sschema,rschema,oschema,role)ifcardin'1+':sectdict['main']='attributes'ifnot'muledit'insectdict:sectdict['muledit']='attributes'elifrschema.final:sectdict['main']='attributes'else:sectdict['main']='relations'ifnot'muledit'insectdict:sectdict['muledit']='hidden'ifsectdict['main']=='attributes':card,composed=_card_and_comp(sschema,rschema,oschema,role)ifcardin'1+'andnotcomposed:sectdict['muledit']='attributes'ifnot'inlined'insectdict:sectdict['inlined']=sectdict['main']# recompute formsections and set it to avoid recomputingforformtype,sectioninsectdict.iteritems():formsections.add('%s_%s'%(formtype,section))deftag_relation(self,key,formtype,section=None):ifisinstance(formtype,tuple):forftypeinformtype:self.tag_relation(key,ftype,section)returnifsectionisNone:tag=formtypeforformtype,sectioninself.bw_tag_map[tag].iteritems():warn('[3.6] add tag to autoform section by specifying form ''type and tag. Replace %s by formtype="%s", section="%s"'%(tag,formtype,section),DeprecationWarning,stacklevel=3)self.tag_relation(key,formtype,section)assertformtypeinself._allowed_form_types, \'formtype should be in (%s), not %s'%(','.join(self._allowed_form_types),formtype)assertsectioninself._allowed_values[formtype], \'section for %s should be in (%s), not %s'%(formtype,','.join(self._allowed_values[formtype]),section)rtags=self._tagdefs.setdefault(_ensure_str_key(key),self.tag_container_cls())# remove previous section for this form type if anyifrtags:fortaginrtags.copy():iftag.startswith(formtype):rtags.remove(tag)rtags.add('%s_%s'%(formtype,section))returnrtagsdefinit_get(self,stype,rtype,otype,tagged):key=(stype,rtype,otype,tagged)rtags={}forkeyinself._get_keys(stype,rtype,otype,tagged):tags=self._tagdefs.get(key,())fortagintags:assert'_'intag,(tag,tags)section,value=tag.split('_',1)rtags[section]=valuecls=self.tag_container_clsrtags=cls('_'.join([section,value])forsection,valueinrtags.iteritems())returnrtagsdefget(self,*key):# overriden to avoid recomputing done in parent classesreturnself._tagdefs.get(key,())defrelations_by_section(self,entity,formtype,section,permission,strict=False):"""return a list of (relation schema, target schemas, role) for the given entity matching categories and permission. `strict`: bool telling if having local role is enough (strict = False) or not """tag='%s_%s'%(formtype,section)eschema=entity.e_schemapermsoverrides=autoform_permissions_overridesifentity.has_eid():eid=entity.eidelse:eid=Nonestrict=Falseifpermission=='update':assertsectionin('attributes','metadata','hidden')relpermission='add'else:assertsectionnotin('attributes','metadata','hidden')relpermission=permissioncw=entity._cwforrschema,targetschemas,roleineschema.relation_definitions(True):_targetschemas=[]fortschemaintargetschemas:# check section's tag first, potentially lower cost than# checking permission which may imply rql queriesifnottaginself.etype_get(eschema,rschema,role,tschema):continuerdef=rschema.role_rdef(eschema,tschema,role)ifrschema.final:ifnotrdef.has_perm(cw,permission,eid=eid,creating=eidisNone):continueelifstrictornotrdef.has_local_role(relpermission):ifrole=='subject':ifnotrdef.has_perm(cw,relpermission,fromeid=eid):continueelifrole=='object':ifnotrdef.has_perm(cw,relpermission,toeid=eid):continue_targetschemas.append(tschema)ifnot_targetschemas:continuetargetschemas=_targetschemasrdef=eschema.rdef(rschema,role=role,targettype=targetschemas[0])# XXX tag allowing to hijack the permission machinery when# permission is not verifiable until the entity is actually# created...ifeidisNoneand'%s_on_new'%permissioninpermsoverrides.etype_get(eschema,rschema,role):yield(rschema,targetschemas,role)continueifnotrschema.finalandrole=='subject':# on relation with cardinality 1 or ?, we need delete perm as well# if the relation is already setif(relpermission=='add'andrdef.role_cardinality(role)in'1?'andeidandentity.related(rschema.type,role)andnotrdef.has_perm(cw,'delete',fromeid=eid,toeid=entity.related(rschema.type,role)[0][0])):continueelifrole=='object':# on relation with cardinality 1 or ?, we need delete perm as well# if the relation is already setif(relpermission=='add'andrdef.role_cardinality(role)in'1?'andeidandentity.related(rschema.type,role)andnotrdef.has_perm(cw,'delete',toeid=eid,fromeid=entity.related(rschema.type,role)[0][0])):continueyield(rschema,targetschemas,role)autoform_section=AutoformSectionRelationTags('autoform_section')# relations'field classautoform_field=RelationTags('autoform_field')# relations'field explicit kwargs (given to field's __init__)autoform_field_kwargs=RelationTagsDict()# set of tags of the form <action>_on_new on relations. <action> is a# schema action (add/update/delete/read), and when such a tag is found# permissions checking is by-passed and supposed to be okautoform_permissions_overrides=RelationTagsSet('autoform_permissions_overrides')# boxes.EditBox configuration ################################################## 'link' / 'create' relation tags, used to control the "add entity" submenudefinit_actionbox_appearsin_addmenu(rtag,sschema,rschema,oschema,role):ifrtag.get(sschema,rschema,oschema,role)isNone:ifrschemainMETA_RTYPES:rtag.tag_relation((sschema,rschema,oschema,role),False)returnrdef=rschema.rdef(sschema,oschema)ifnotrdef.role_cardinality(role)in'?1'andrdef.composite==role:rtag.tag_relation((sschema,rschema,oschema,role),True)actionbox_appearsin_addmenu=RelationTagsBool('actionbox_appearsin_addmenu',init_actionbox_appearsin_addmenu)# deprecated ###################################################################classAutoformIsInlined(RelationTags):"""XXX for < 3.6 bw compat"""deftag_relation(self,key,tag):warn('autoform_is_inlined is deprecated, use autoform_section ''with formtype="main", section="inlined"',DeprecationWarning,stacklevel=3)section=tagand'inlined'or'hidden'autoform_section.tag_relation(key,'main',section)# inlined view flag for non final relations: when True for an entry, the# entity(ies) at the other end of the relation will be editable from the# form of the edited entityautoform_is_inlined=AutoformIsInlined('autoform_is_inlined')