[migration] add migration file commands to follow option group changes
# 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/>."""The default primary view"""__docformat__="restructuredtext en"_=unicodefromwarningsimportwarnfromlogilab.mtconverterimportxml_escapefromcubicwebimportUnauthorizedfromcubicweb.selectorsimportmatch_kwargsfromcubicweb.viewimportEntityViewfromcubicweb.schemaimportVIRTUAL_RTYPES,display_namefromcubicweb.webimportuicfgclassPrimaryView(EntityView):"""the full view of an non final entity"""__regid__='primary'title=_('primary')show_attr_label=Trueshow_rel_label=Trueskip_none=Truersection=uicfg.primaryview_sectiondisplay_ctrl=uicfg.primaryview_display_ctrlmain_related_section=Truedefhtml_headers(self):"""return a list of html headers (eg something to be inserted between <head> and </head> of the returned page by default primary views are indexed """return[]defcell_call(self,row,col):self.cw_row=rowself.cw_col=colself.maxrelated=self._cw.property_value('navigation.related-limit')entity=self.cw_rset.complete_entity(row,col)self.render_entity(entity)defrender_entity(self,entity):self.render_entity_toolbox(entity)self.render_entity_title(entity)# entity's attributes and relations, excluding meta data# if the entity isn't meta itselfifself.is_primary():boxes=self._prepare_side_boxes(entity)else:boxes=Noneifboxesorhasattr(self,'render_side_related'):self.w(u'<table width="100%"><tr><td style="width: 75%">')self.render_entity_summary(entity)self.w(u'<div class="mainInfo">')self.content_navigation_components('navcontenttop')self.render_entity_attributes(entity)ifself.main_related_section:self.render_entity_relations(entity)self.content_navigation_components('navcontentbottom')self.w(u'</div>')# side boxesifboxesorhasattr(self,'render_side_related'):self.w(u'</td><td>')self.w(u'<div class="primaryRight">')ifhasattr(self,'render_side_related'):warn('render_side_related is deprecated')self.render_side_related(entity,[])self.render_side_boxes(boxes)self.w(u'</div>')self.w(u'</td></tr></table>')defcontent_navigation_components(self,context):self.w(u'<div class="%s">'%context)forcompinself._cw.vreg['contentnavigation'].poss_visible_objects(self._cw,rset=self.cw_rset,row=self.cw_row,view=self,context=context):try:comp.render(w=self.w,row=self.cw_row,view=self)exceptNotImplementedError:warn('component %s doesnt implement cell_call, please update'%comp.__class__,DeprecationWarning)comp.render(w=self.w,view=self)self.w(u'</div>')defrender_entity_title(self,entity):"""default implementation return dc_title"""title=xml_escape(entity.dc_title())iftitle:ifself.is_primary():self.w(u'<h1>%s</h1>'%title)else:atitle=self._cw._('follow this link for more information on this %s')%entity.dc_type()self.w(u'<h4><a href="%s" title="%s">%s</a></h4>'%(entity.absolute_url(),atitle,title))defrender_entity_toolbox(self,entity):self.content_navigation_components('ctxtoolbar')defrender_entity_metadata(self,entity):entity.view('metadata',w=self.w)defrender_entity_summary(self,entity):summary=self.summary(entity)# deprecate summary?ifsummary:self.w(u'<div class="summary">%s</div>'%summary)defsummary(self,entity):"""default implementation return an empty string"""returnu''defrender_entity_attributes(self,entity):display_attributes=[]forrschema,_,role,dispctrlinself._section_def(entity,'attributes'):vid=dispctrl.get('vid','reledit')ifrschema.finalorvid=='reledit':value=entity.view(vid,rtype=rschema.type,role=role)else:rset=self._relation_rset(entity,rschema,role,dispctrl)ifrset:value=self._cw.view(vid,rset)else:value=Noneifnotself.skip_noneor(valueisnotNoneandvalue!=''):display_attributes.append((rschema,role,dispctrl,value))ifdisplay_attributes:self.w(u'<table>')forrschema,role,dispctrl,valueindisplay_attributes:try:self._render_attribute(dispctrl,rschema,value,role=role,table=True)exceptTypeError:warn('[3.6] _render_attribute prototype has changed, please'' update %s'%self.__class___,DeprecationWarning)self._render_attribute(rschema,value,role=role,table=True)self.w(u'</table>')defrender_entity_relations(self,entity):forrschema,tschemas,role,dispctrlinself._section_def(entity,'relations'):rset=self._relation_rset(entity,rschema,role,dispctrl)ifrset:try:self._render_relation(dispctrl,rset,'autolimited')exceptTypeError:warn('[3.6] _render_relation prototype has changed, ''please update %s'%self.__class__,DeprecationWarning)self._render_relation(rset,dispctrl,'autolimited',self.show_rel_label)defrender_side_boxes(self,boxes):"""display side related relations: non-meta in a first step, meta in a second step """forboxinboxes:ifisinstance(box,tuple):try:label,rset,vid,dispctrl=boxexceptValueError:warn('[3.5] box views should now be defined as a 4-uple (label, rset, vid, dispctrl), ''please update %s'%self.__class__.__name__,DeprecationWarning)label,rset,vid=boxdispctrl={}self.w(u'<div class="sideBox">')self.wview(vid,rset,title=label,initargs={'dispctrl':dispctrl})self.w(u'</div>')else:try:box.render(w=self.w,row=self.cw_row)exceptNotImplementedError:# much probably a context insensitive box, which only implements# .call() and not cell_call()box.render(w=self.w)def_prepare_side_boxes(self,entity):sideboxes=[]forrschema,tschemas,role,dispctrlinself._section_def(entity,'sideboxes'):rset=self._relation_rset(entity,rschema,role,dispctrl)ifnotrset:continuelabel=display_name(self._cw,rschema.type,role)vid=dispctrl.get('vid','sidebox')sideboxes.append((label,rset,vid,dispctrl))sideboxes+=self._cw.vreg['boxes'].poss_visible_objects(self._cw,rset=self.cw_rset,row=self.cw_row,view=self,context='incontext')# XXX since we've two sorted list, it may be worth using bisectdefget_order(x):ifisinstance(x,tuple):# x is a view box (label, rset, vid, dispctrl)# default to 1000 so view boxes occurs after component boxesreturnx[-1].get('order',1000)# x is a component boxreturnx.cw_propval('order')returnsorted(sideboxes,key=get_order)def_section_def(self,entity,where):rdefs=[]eschema=entity.e_schemaforrschema,tschemas,roleineschema.relation_definitions(True):ifrschemainVIRTUAL_RTYPES:continuematchtschemas=[]fortschemaintschemas:section=self.rsection.etype_get(eschema,rschema,role,tschema)ifsection==where:matchtschemas.append(tschema)ifmatchtschemas:# XXX pick the latest dispctrldispctrl=self.display_ctrl.etype_get(eschema,rschema,role,matchtschemas[-1])rdefs.append((rschema,matchtschemas,role,dispctrl))returnsorted(rdefs,key=lambdax:x[-1]['order'])def_relation_rset(self,entity,rschema,role,dispctrl):try:dispctrl.setdefault('limit',self.maxrelated)rset=entity.related(rschema.type,role,limit=dispctrl['limit']+1)exceptUnauthorized:returnif'filter'indispctrl:rset=dispctrl['filter'](rset)returnrsetdef_render_relation(self,dispctrl,rset,defaultvid):self.w(u'<div class="section">')ifdispctrl.get('showlabel',self.show_rel_label):self.w(u'<h4>%s</h4>'%self._cw._(dispctrl['label']))self.wview(dispctrl.get('vid',defaultvid),rset,initargs={'dispctrl':dispctrl})self.w(u'</div>')def_render_attribute(self,dispctrl,rschema,value,role='subject',table=False):ifrschema.final:showlabel=dispctrl.get('showlabel',self.show_attr_label)else:showlabel=dispctrl.get('showlabel',self.show_rel_label)ifdispctrl.get('label'):label=self._cw._(dispctrl.get('label'))else:label=display_name(self._cw,rschema.type,role)self.field(label,value,show_label=showlabel,tr=False,table=table)classRelatedView(EntityView):__regid__='autolimited'defcall(self,**kwargs):# 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'inself.cw_extra_kwargs:limit=self.cw_extra_kwargs['dispctrl'].get('limit')subvid=self.cw_extra_kwargs['dispctrl'].get('subvid','incontext')else:limit=Nonesubvid='incontext'iflimitisNoneorself.cw_rset.rowcount<=limit:ifself.cw_rset.rowcount==1:self.wview(subvid,self.cw_rset,row=0)elif1<self.cw_rset.rowcount<=5:self.wview('csv',self.cw_rset,subvid=subvid)else:self.w(u'<div>')self.wview('simplelist',self.cw_rset,subvid=subvid)self.w(u'</div>')# else show links to display related entitieselse:rql=self.cw_rset.printable_rql()self.cw_rset.limit(limit)# remove extra entityself.w(u'<div>')self.wview('simplelist',self.cw_rset,subvid=subvid)self.w(u'[<a href="%s">%s</a>]'%(xml_escape(self._cw.build_url(rql=rql,vid=subvid)),self._cw._('see them all')))self.w(u'</div>')classURLAttributeView(EntityView):"""use this view for attributes whose value is an url and that you want to display as clickable link """__regid__='urlattr'__select__=EntityView.__select__&match_kwargs('rtype')defcell_call(self,row,col,rtype,**kwargs):entity=self.cw_rset.get_entity(row,col)url=entity.printable_value(rtype)ifurl:self.w(u'<a href="%s">%s</a>'%(url,url))## default primary ui configuration ###########################################_pvs=uicfg.primaryview_sectionforrtypein('eid','creation_date','modification_date','cwuri','is','is_instance_of','identity','owned_by','created_by','require_permission','see_also'):_pvs.tag_subject_of(('*',rtype,'*'),'hidden')_pvs.tag_object_of(('*',rtype,'*'),'hidden')