"""Set of HTML base actions:organization: Logilab:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"_=unicodefromwarningsimportwarnfromcubicweb.schemaimportdisplay_namefromcubicweb.appobjectimportobjectify_selectorfromcubicweb.selectorsimport(EntitySelector,yes,one_line_rset,multi_lines_rset,one_etype_rset,relation_possible,nonempty_rset,non_final_entity,authenticated_user,match_user_groups,match_search_state,has_permission,has_add_permission,implements,)fromcubicweb.webimportuicfg,controller,actionfromcubicweb.web.viewsimportlinksearch_select_url,vid_from_rsetclasshas_editable_relation(EntitySelector):"""accept if some relations for an entity found in the result set is editable by the logged user. See `EntitySelector` documentation for behaviour when row is not specified. """defscore_entity(self,entity):# if user has no update right but it can modify some relation,# display action anywayform=entity._cw.vreg['forms'].select('edition',entity._cw,entity=entity)fordummyinform.editable_relations():return1try:editableattrs=form.editable_attributes(strict=True)exceptTypeError:warn('[3.6] %s: editable_attributes now take strict=False as ''optional argument',DeprecationWarning)editableattrs=form.editable_attributes()forrschema,roleineditableattrs:ifnotrschema.final:return1return0@objectify_selectordefmatch_searched_etype(cls,req,rset=None,**kwargs):returnreq.match_search_state(rset)@objectify_selectordefview_is_not_default_view(cls,req,rset=None,**kwargs):# interesting if it propose another view than the current onevid=req.form.get('vid')ifvidandvid!=vid_from_rset(req,rset,req.vreg.schema):return1return0@objectify_selectordefaddable_etype_empty_rset(cls,req,rset=None,**kwargs):ifrsetisnotNoneandnotrset.rowcount:rqlst=rset.syntax_tree()iflen(rqlst.children)>1:return0select=rqlst.children[0]iflen(select.defined_vars)==1andlen(select.solutions)==1:rset._searched_etype=select.solutions[0].itervalues().next()eschema=req.vreg.schema.eschema(rset._searched_etype)ifnot(eschema.finaloreschema.is_subobject(strict=True)) \andeschema.has_perm(req,'add'):return1return0# generic 'main' actions #######################################################classSelectAction(action.Action):"""base class for link search actions. By default apply on any size entity result search it the current state is 'linksearch' if accept match. """__regid__='select'__select__=(match_search_state('linksearch')&nonempty_rset()&match_searched_etype())title=_('select')category='mainactions'order=0defurl(self):returnlinksearch_select_url(self._cw,self.cw_rset)classCancelSelectAction(action.Action):__regid__='cancel'__select__=match_search_state('linksearch')title=_('cancel select')category='mainactions'order=10defurl(self):target,eid,r_type,searched_type=self._cw.search_state[1]returnself._cw.build_url(str(eid),vid='edition',__mode='normal')classViewAction(action.Action):__regid__='view'__select__=(action.Action.__select__&match_user_groups('users','managers')&view_is_not_default_view()&non_final_entity())title=_('view')category='mainactions'order=0defurl(self):params=self._cw.form.copy()forparamin('vid','__message')+controller.NAV_FORM_PARAMETERS:params.pop(param,None)returnself._cw.build_url(self._cw.relative_path(includeparams=False),**params)classModifyAction(action.Action):__regid__='edit'__select__=(action.Action.__select__&one_line_rset()&(has_permission('update')|has_editable_relation('add')))title=_('modify')category='mainactions'order=10defurl(self):entity=self.cw_rset.get_entity(self.cw_rowor0,self.cw_color0)returnentity.absolute_url(vid='edition')classMultipleEditAction(action.Action):__regid__='muledit'# XXX get strange conflicts if id='edit'__select__=(action.Action.__select__&multi_lines_rset()&one_etype_rset()&has_permission('update'))title=_('modify')category='mainactions'order=10defurl(self):returnself._cw.build_url('view',rql=self.cw_rset.rql,vid='muledit')# generic "more" actions #######################################################classManagePermissionsAction(action.Action):__regid__='managepermission'__select__=(action.Action.__select__&one_line_rset()&non_final_entity()&match_user_groups('managers'))title=_('manage permissions')category='moreactions'order=15@classmethoddef__registered__(cls,reg):if'require_permission'inreg.schema:cls.__select__=(one_line_rset()&non_final_entity()&(match_user_groups('managers')|relation_possible('require_permission','subject','CWPermission',action='add')))returnsuper(ManagePermissionsAction,cls).__registered__(reg)defurl(self):returnself.cw_rset.get_entity(self.cw_rowor0,self.cw_color0).absolute_url(vid='security')classDeleteAction(action.Action):__regid__='delete'__select__=action.Action.__select__&has_permission('delete')title=_('delete')category='moreactions'order=20defurl(self):iflen(self.cw_rset)==1:entity=self.cw_rset.get_entity(self.cw_rowor0,self.cw_color0)returnself._cw.build_url(entity.rest_path(),vid='deleteconf')returnself._cw.build_url(rql=self.cw_rset.printable_rql(),vid='deleteconf')classCopyAction(action.Action):__regid__='copy'__select__=(action.Action.__select__&one_line_rset()&has_permission('add'))title=_('copy')category='moreactions'order=30defurl(self):entity=self.cw_rset.get_entity(self.cw_rowor0,self.cw_color0)returnentity.absolute_url(vid='copy')classAddNewAction(MultipleEditAction):"""when we're seeing more than one entity with the same type, propose to add a new one """__regid__='addentity'__select__=(action.Action.__select__&(addable_etype_empty_rset()|(multi_lines_rset()&one_etype_rset()&has_add_permission())))category='moreactions'order=40@propertydefrsettype(self):ifself.cw_rset:returnself.cw_rset.description[0][0]returnself.cw_rset._searched_etype@propertydeftitle(self):returnself._cw.__('add a %s'%self.rsettype)# generated msgiddefurl(self):returnself._cw.build_url('add/%s'%self.rsettype)classAddRelatedActions(action.Action):"""fill 'addrelated' sub-menu of the actions box"""__regid__='addrelated'__select__=action.Action.__select__&one_line_rset()&non_final_entity()submenu=_('addrelated')order=20deffill_menu(self,box,menu):# when there is only one item in the sub-menu, replace the sub-menu by# item's title prefixed by 'add'menu.label_prefix=self._cw._('add')super(AddRelatedActions,self).fill_menu(box,menu)defactual_actions(self):entity=self.cw_rset.get_entity(self.cw_rowor0,self.cw_color0)eschema=entity.e_schemaforrschema,teschema,xinself.add_related_schemas(entity):ifx=='subject':label='add %s%s%s%s'%(eschema,rschema,teschema,x)url=self.linkto_url(entity,rschema,teschema,'object')else:label='add %s%s%s%s'%(teschema,rschema,eschema,x)url=self.linkto_url(entity,rschema,teschema,'subject')yieldself.build_action(self._cw._(label),url)defadd_related_schemas(self,entity):"""this is actually used ui method to generate 'addrelated' actions from the schema. If you don't want any auto-generated actions, you should overrides this method to return an empty list. If you only want some, you can configure them by using uicfg.actionbox_appearsin_addmenu """appearsin_addmenu=uicfg.actionbox_appearsin_addmenureq=self._cweschema=entity.e_schemaforrole,rschemasin(('subject',eschema.subject_relations()),('object',eschema.object_relations())):forrschemainrschemas:ifrschema.final:continueforteschemainrschema.targets(eschema,role):ifnotappearsin_addmenu.etype_get(eschema,rschema,role,teschema):continuerdef=rschema.role_rdef(eschema,teschema,role)# check the relation can be added# XXX consider autoform_permissions_overrides?ifrole=='subject'andnotrdef.has_perm(req,'add',fromeid=entity.eid):continueifrole=='object'andnotrdef.has_perm(req,'add',toeid=entity.eid):continue# check the target types can be added as wellifteschema.may_have_permission('add',req):yieldrschema,teschema,roledeflinkto_url(self,entity,rtype,etype,target):returnself._cw.build_url('add/%s'%etype,__linkto='%s:%s:%s'%(rtype,entity.eid,target),__redirectpath=entity.rest_path(),# should not be url quoted!__redirectvid=self._cw.form.get('vid',''))classViewSameCWEType(action.Action):"""when displaying the schema of a CWEType, offer to list entities of that type """__regid__='entitiesoftype'__select__=one_line_rset()&implements('CWEType')category='mainactions'order=40@propertydefetype(self):returnself.cw_rset.get_entity(0,0).name@propertydeftitle(self):returnself._cw.__('view all %s')%display_name(self._cw,self.etype,'plural').lower()defurl(self):returnself._cw.build_url(self.etype)# logged user actions #########################################################classUserPreferencesAction(action.Action):__regid__='myprefs'__select__=authenticated_user()title=_('user preferences')category='useractions'order=10defurl(self):returnself._cw.build_url(self.__regid__)classUserInfoAction(action.Action):__regid__='myinfos'__select__=authenticated_user()title=_('personnal informations')category='useractions'order=20defurl(self):returnself._cw.build_url('cwuser/%s'%self._cw.user.login,vid='edition')classLogoutAction(action.Action):__regid__='logout'__select__=authenticated_user()title=_('logout')category='useractions'order=30defurl(self):returnself._cw.build_url(self.__regid__)# site actions ################################################################classManagersAction(action.Action):__abstract__=True__select__=match_user_groups('managers')category='siteactions'defurl(self):returnself._cw.build_url(self.__regid__)classSiteConfigurationAction(ManagersAction):__regid__='siteconfig'title=_('site configuration')order=10classManageAction(ManagersAction):__regid__='manage'title=_('manage')order=20classSiteInfoAction(ManagersAction):__regid__='siteinfo'__select__=match_user_groups('users','managers')title=_('info')order=30# footer actions ###############################################################classPoweredByAction(action.Action):__regid__='poweredby'__select__=yes()category='footer'order=3title=_('powered by CubicWeb')defurl(self):return'http://www.cubicweb.org'## default actions ui configuration ###########################################addmenu=uicfg.actionbox_appearsin_addmenuaddmenu.tag_subject_of(('*','require_permission','*'),False)addmenu.tag_object_of(('*','relation_type','CWRType'),True)addmenu.tag_object_of(('*','from_entity','CWEType'),False)addmenu.tag_object_of(('*','to_entity','CWEType'),False)addmenu.tag_object_of(('*','in_group','CWGroup'),True)addmenu.tag_object_of(('*','bookmarked_by','CWUser'),True)