[service] allow repo_stats for users
It's used by the siteinfo view, which is available to managers and
users. This change prevents a crash in that view.
# copyright 2003-2011 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/>."""breadcrumbs components definition for CubicWeb web client"""__docformat__="restructuredtext en"_=unicodefromwarningsimportwarnfromlogilab.mtconverterimportxml_escapefromcubicwebimporttags,uilibfromcubicweb.entityimportEntityfromcubicweb.predicatesimport(is_instance,one_line_rset,adaptable,one_etype_rset,multi_lines_rset,any_rset,match_form_params)fromcubicweb.viewimportEntityView,EntityAdapterfromcubicweb.web.viewsimportbasecomponents# don't use AnyEntity since this may cause bug with isinstance() due to reloadingclassIBreadCrumbsAdapter(EntityAdapter):"""adapters for entities which can be"located" on some path to display in the web ui """__regid__='IBreadCrumbs'__select__=is_instance('Any',accept_none=False)defparent_entity(self):itree=self.entity.cw_adapt_to('ITree')ifitreeisnotNone:returnitree.parent()returnNonedefbreadcrumbs(self,view=None,recurs=None):"""return a list containing some: * tuple (url, label) * entity * simple label string defining path from a root to the current view the main view is given as argument so breadcrumbs may vary according to displayed view (may be None). When recursing on a parent entity, the `recurs` argument should be a set of already traversed nodes (infinite loop safety belt). """parent=self.parent_entity()ifparentisnotNone:ifrecursisTrue:_recurs=set()warn('[3.10] recurs argument should be a set() or None',DeprecationWarning,stacklevel=2)elifrecurs:_recurs=recurselse:ifrecursisFalse:warn('[3.10] recurs argument should be a set() or None',DeprecationWarning,stacklevel=2)_recurs=set()if_recursandparent.eidin_recurs:self.error('cycle in breadcrumbs for entity %s'%self.entity)return[]_recurs.add(parent.eid)adapter=parent.cw_adapt_to('IBreadCrumbs')path=adapter.breadcrumbs(view,_recurs)+[self.entity]else:path=[self.entity]ifnotrecurs:ifviewisNone:if'vtitle'inself._cw.form:# embeding for instancepath.append(self._cw.form['vtitle'])elifview.__regid__!='primary'andhasattr(view,'title'):path.append(self._cw._(view.title))returnpathclassBreadCrumbEntityVComponent(basecomponents.HeaderComponent):__regid__='breadcrumbs'__select__=(basecomponents.HeaderComponent.__select__&one_line_rset()&adaptable('IBreadCrumbs'))order=basecomponents.ApplicationName.order+1context=basecomponents.ApplicationName.contextseparator=u' > 'link_template=u'<a href="%s">%s</a>'first_separator=True# XXX support kwargs for compat with other components which gets the view as# argumentdefrender(self,w,**kwargs):try:entity=self.cw_extra_kwargs['entity']exceptKeyError:entity=self.cw_rset.get_entity(0,0)adapter=entity.cw_adapt_to('IBreadCrumbs')view=self.cw_extra_kwargs.get('view')path=adapter.breadcrumbs(view)ifpath:self.open_breadcrumbs(w)self.render_breadcrumbs(w,entity,path)self.close_breadcrumbs(w)defopen_breadcrumbs(self,w):w(u'<span id="breadcrumbs" class="pathbar">')ifself.first_separator:w(self.separator)defclose_breadcrumbs(self,w):w(u'</span>')defrender_breadcrumbs(self,w,contextentity,path):root=path.pop(0)ifisinstance(root,Entity):w(self.link_template%(self._cw.build_url(root.__regid__),root.dc_type('plural')))w(self.separator)self.wpath_part(w,root,contextentity,notpath)fori,parentinenumerate(path):w(self.separator)w(u"\n")self.wpath_part(w,parent,contextentity,i==len(path)-1)defwpath_part(self,w,part,contextentity,last=False):# XXX deprecates last argument?ifisinstance(part,Entity):w(part.view('breadcrumbs'))elifisinstance(part,tuple):url,title=parttextsize=self._cw.property_value('navigation.short-line-size')w(self.link_template%(xml_escape(url),xml_escape(uilib.cut(title,textsize))))else:textsize=self._cw.property_value('navigation.short-line-size')w(xml_escape(uilib.cut(unicode(part),textsize)))classBreadCrumbETypeVComponent(BreadCrumbEntityVComponent):__select__=(basecomponents.HeaderComponent.__select__&multi_lines_rset()&one_etype_rset()&adaptable('IBreadCrumbs'))defrender_breadcrumbs(self,w,contextentity,path):# XXX hack: only display etype name or first non entity path partroot=path.pop(0)ifisinstance(root,Entity):w(u'<a href="%s">%s</a>'%(self._cw.build_url(root.__regid__),root.dc_type('plural')))else:self.wpath_part(w,root,contextentity,notpath)classBreadCrumbAnyRSetVComponent(BreadCrumbEntityVComponent):__select__=basecomponents.HeaderComponent.__select__&any_rset()# XXX support kwargs for compat with other components which gets the view as# argumentdefrender(self,w,**kwargs):self.open_breadcrumbs(w)w(self._cw._('search'))self.close_breadcrumbs(w)classBreadCrumbLinkToVComponent(BreadCrumbEntityVComponent):__select__=basecomponents.HeaderComponent.__select__&match_form_params('__linkto')defrender(self,w,**kwargs):eid=self._cw.list_form_param('__linkto')[0].split(':')[1]entity=self._cw.entity_from_eid(eid)ecmp=self._cw.vreg[self.__registry__].select(self.__regid__,self._cw,entity=entity,**kwargs)ecmp.render(w,**kwargs)classBreadCrumbView(EntityView):__regid__='breadcrumbs'defcell_call(self,row,col,**kwargs):entity=self.cw_rset.get_entity(row,col)desc=uilib.cut(entity.dc_description(),50)# NOTE remember camember: tags.a autoescapesself.w(tags.a(entity.view('breadcrumbtext'),href=entity.absolute_url(),title=desc))classBreadCrumbTextView(EntityView):__regid__='breadcrumbtext'defcell_call(self,row,col,**kwargs):entity=self.cw_rset.get_entity(row,col)textsize=self._cw.property_value('navigation.short-line-size')self.w(uilib.cut(entity.dc_title(),textsize))