[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/>."""management and error screens"""__docformat__="restructuredtext en"_=unicodefromtimeimportstrftime,localtimefromlogilab.mtconverterimportxml_escapefromcubicwebimportBadConnectionIdfromcubicweb.predicatesimportnone_rset,match_user_groupsfromcubicweb.viewimportStartupViewfromcubicweb.web.viewsimportactions,tabsdefdict_to_html(w,dict):# XHTML doesn't allow emtpy <ul> nodesifdict:w(u'<ul>')forkeyinsorted(dict):w(u'<li><span class="label">%s</span>: <span>%s</span></li>'%(xml_escape(str(key)),xml_escape(repr(dict[key]))))w(u'</ul>')classSiteInfoAction(actions.ManagersAction):__regid__='siteinfo'__select__=match_user_groups('users','managers')title=_('Site information')category='manage'order=1000classSiteInfoView(tabs.TabsMixin,StartupView):__regid__='siteinfo'title=_('Site information')tabs=[_('info'),_('registry'),_('gc')]default_tab='info'defcall(self,**kwargs):"""The default view representing the instance's management"""self.w(u'<h1>%s</h1>'%self._cw._(self.title))self.render_tabs(self.tabs,self.default_tab)classProcessInformationView(StartupView):"""display various web server /repository information"""__regid__='info'__select__=none_rset()&match_user_groups('managers','users')title=_('server information')cache_max_age=0defcall(self,**kwargs):req=self._cwdtformat=req.property_value('ui.datetime-format')_=req._w=self.w# generic instance informationw(u'<h2>%s</h2>'%_('Instance'))w(u'<table>')w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(_('config type'),self._cw.vreg.config.name))w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(_('config mode'),self._cw.vreg.config.mode))w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(_('instance home'),self._cw.vreg.config.apphome))w(u'</table>')vcconf=req.vreg.config.vc_config()w(u'<h3>%s</h3>'%_('versions configuration'))w(u'<table>')w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%('CubicWeb',vcconf.get('cubicweb',_('no version information'))))forcubeinsorted(self._cw.vreg.config.cubes()):cubeversion=vcconf.get(cube,_('no version information'))w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(cube,cubeversion))w(u'</table>')# repository informationrepo=req.vreg.config.repository(None)w(u'<h2>%s</h2>'%_('Repository'))w(u'<h3>%s</h3>'%_('resources usage'))w(u'<table>')stats=self._cw.call_service('repo_stats')forelementinsorted(stats):w(u'<tr><th align="left">%s</th><td>%s%s</td></tr>'%(element,xml_escape(unicode(stats[element])),element.endswith('percent')and'%'or''))w(u'</table>')ifreq.cnx.is_repo_in_memoryandreq.user.is_in_group('managers'):w(u'<h3>%s</h3>'%_('opened sessions'))sessions=repo._sessions.values()ifsessions:w(u'<ul>')forsessioninsessions:w(u'<li>%s (%s: %s)<br/>'%(xml_escape(unicode(session)),_('last usage'),strftime(dtformat,localtime(session.timestamp))))dict_to_html(w,session.data)w(u'</li>')w(u'</ul>')else:w(u'<p>%s</p>'%_('no repository sessions found'))# web server informationw(u'<h2>%s</h2>'%_('Web server'))w(u'<table>')w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(_('base url'),req.base_url()))w(u'<tr><th align="left">%s</th><td>%s</td></tr>'%(_('data directory url'),req.datadir_url))w(u'</table>')ifreq.user.is_in_group('managers'):fromcubicweb.web.applicationimportSESSION_MANAGERsessions=SESSION_MANAGER.current_sessions()w(u'<h3>%s</h3>'%_('opened web sessions'))ifsessions:w(u'<ul>')forsessioninsessions:last_usage_time=session.mtimew(u'<li>%s (%s: %s)<br/>'%(session.sessionid,_('last usage'),strftime(dtformat,localtime(last_usage_time))))dict_to_html(w,session.data)w(u'</li>')w(u'</ul>')else:w(u'<p>%s</p>'%_('no web sessions found'))classRegistryView(StartupView):"""display vregistry content"""__regid__='registry'__select__=StartupView.__select__&match_user_groups('managers')title=_('registry')cache_max_age=0defcall(self,**kwargs):self.w(u'<h2>%s</h2>'%self._cw._("Registry's content"))keys=sorted(self._cw.vreg)url=xml_escape(self._cw.url())self.w(u'<p>%s</p>\n'%' - '.join('<a href="%s#%s">%s</a>'%(url,key,key)forkeyinkeys))forkeyinkeys:ifkeyin('boxes','contentnavigation'):# those are bw compat registriescontinueself.w(u'<h3 id="%s">%s</h3>'%(key,key))ifself._cw.vreg[key]:values=sorted(self._cw.vreg[key].iteritems())self.wview('pyvaltable',pyvalue=[(key,xml_escape(repr(val)))forkey,valinvalues])else:self.w(u'<p>Empty</p>\n')classGCView(StartupView):"""display garbage collector information"""__regid__='gc'__select__=StartupView.__select__&match_user_groups('managers')title=_('memory leak debugging')cache_max_age=0defcall(self,**kwargs):fromcubicweb._gcdebugimportgc_infofromrql.stmtsimportUnionfromcubicweb.appobjectimportAppObjectfromcubicweb.rsetimportResultSetfromcubicweb.dbapiimportConnection,Cursorfromcubicweb.web.requestimportCubicWebRequestBaselookupclasses=(AppObject,Union,ResultSet,Connection,Cursor,CubicWebRequestBase)try:fromcubicweb.server.sessionimportSession,InternalSessionlookupclasses+=(InternalSession,Session)exceptImportError:pass# no server part installedself.w(u'<h2>%s</h2>'%_('Garbage collection information'))counters,ocounters,garbage=gc_info(lookupclasses,viewreferrersclasses=())self.w(u'<h3>%s</h3>'%self._cw._('Looked up classes'))values=sorted(counters.iteritems(),key=lambdax:x[1],reverse=True)self.wview('pyvaltable',pyvalue=values)self.w(u'<h3>%s</h3>'%self._cw._('Most referenced classes'))values=sorted(ocounters.iteritems(),key=lambdax:x[1],reverse=True)self.wview('pyvaltable',pyvalue=values[:self._cw.form.get('nb',20)])ifgarbage:self.w(u'<h3>%s</h3>'%self._cw._('Unreachable objects'))values=sorted(xml_escape(repr(o))foroingarbage)self.wview('pyvallist',pyvalue=values)