"""Set of HTML base actions:organization: Logilab:copyright: 2001-2009 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"_=unicodefromcubicweb.appobjectimportobjectify_selectorfromcubicweb.selectorsimport(EntitySelector,yes,one_line_rset,two_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,)fromcubicweb.webimportuicfg,controllerfromcubicweb.web.actionimportActionfromcubicweb.web.viewsimportlinksearch_select_url,vid_from_rsetfromcubicweb.web.views.autoformimportAutomaticEntityFormclasshas_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 anywayfordummyinAutomaticEntityForm.esrelations_by_category(entity,'generic','add',strict=True):return1forrschema,targetschemas,roleinAutomaticEntityForm.erelations_by_category(entity,('primary','secondary'),'add',strict=True):ifnotrschema.is_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,cls.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=cls.schema.eschema(rset._searched_etype)ifnot(eschema.is_final()oreschema.is_subobject(strict=True)) \andeschema.has_perm(req,'add'):return1return0# generic 'main' actions #######################################################classSelectAction(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. """id='select'__select__=match_search_state('linksearch')&nonempty_rset()&match_searched_etype()title=_('select')category='mainactions'order=0defurl(self):returnlinksearch_select_url(self.req,self.rset)classCancelSelectAction(Action):id='cancel'__select__=match_search_state('linksearch')title=_('cancel select')category='mainactions'order=10defurl(self):target,eid,r_type,searched_type=self.req.search_state[1]returnself.build_url(str(eid),vid='edition',__mode='normal')classViewAction(Action):id='view'__select__=(match_search_state('normal')&match_user_groups('users','managers')&view_is_not_default_view()&non_final_entity())title=_('view')category='mainactions'order=0defurl(self):params=self.req.form.copy()forparamin('vid','__message')+controller.NAV_FORM_PARAMETERS:params.pop(param,None)returnself.build_url(self.req.relative_path(includeparams=False),**params)classModifyAction(Action):id='edit'__select__=(match_search_state('normal')&one_line_rset()&(has_permission('update')|has_editable_relation('add')))title=_('modify')category='mainactions'order=10defurl(self):entity=self.rset.get_entity(self.rowor0,self.color0)returnentity.absolute_url(vid='edition')classMultipleEditAction(Action):id='muledit'# XXX get strange conflicts if id='edit'__select__=(match_search_state('normal')&two_lines_rset()&one_etype_rset()&has_permission('update'))title=_('modify')category='mainactions'order=10defurl(self):returnself.build_url('view',rql=self.rset.rql,vid='muledit')# generic "more" actions #######################################################classManagePermissionsAction(Action):id='managepermission'__select__=one_line_rset()&non_final_entity()&match_user_groups('managers')title=_('manage permissions')category='moreactions'order=15@classmethoddefregistered(cls,vreg):super(ManagePermissionsAction,cls).registered(vreg)if'require_permission'invreg.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(vreg)defurl(self):returnself.rset.get_entity(self.rowor0,self.color0).absolute_url(vid='security')classDeleteAction(Action):id='delete'__select__=has_permission('delete')title=_('delete')category='moreactions'order=20defurl(self):iflen(self.rset)==1:entity=self.rset.get_entity(self.rowor0,self.color0)returnself.build_url(entity.rest_path(),vid='deleteconf')returnself.build_url(rql=self.rset.printable_rql(),vid='deleteconf')classCopyAction(Action):id='copy'__select__=one_line_rset()&has_permission('add')title=_('copy')category='moreactions'order=30defurl(self):entity=self.rset.get_entity(self.rowor0,self.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 """id='addentity'__select__=(match_search_state('normal')&(addable_etype_empty_rset()|(two_lines_rset()&one_etype_rset&has_add_permission())))category='moreactions'order=40@propertydefrsettype(self):ifself.rset:returnself.rset.description[0][0]returnself.rset._searched_etype@propertydeftitle(self):returnself.req.__('add a %s'%self.rsettype)# generated msgiddefurl(self):returnself.build_url('add/%s'%self.rsettype)classAddRelatedActions(Action):"""fill 'addrelated' sub-menu of the actions box"""id='addrelated'__select__=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.req._('add')super(AddRelatedActions,self).fill_menu(box,menu)defactual_actions(self):entity=self.rset.get_entity(self.rowor0,self.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.req._(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.reqeschema=entity.e_schemaforrole,rschemasin(('subject',eschema.subject_relations()),('object',eschema.object_relations())):forrschemainrschemas:ifrschema.is_final():continue# check the relation can be added as well# XXX consider autoform_permissions_overrides?ifrole=='subject'andnotrschema.has_perm(req,'add',fromeid=entity.eid):continueifrole=='object'andnotrschema.has_perm(req,'add',toeid=entity.eid):continue# check the target types can be added as wellforteschemainrschema.targets(eschema,role):ifnotappearsin_addmenu.etype_get(eschema,rschema,role,teschema):continueifteschema.has_local_role('add')orteschema.has_perm(req,'add'):yieldrschema,teschema,roledeflinkto_url(self,entity,rtype,etype,target):returnself.build_url('add/%s'%etype,__linkto='%s:%s:%s'%(rtype,entity.eid,target),__redirectpath=entity.rest_path(),# should not be url quoted!__redirectvid=self.req.form.get('vid',''))# logged user actions #########################################################classUserPreferencesAction(Action):id='myprefs'__select__=authenticated_user()title=_('user preferences')category='useractions'order=10defurl(self):returnself.build_url(self.id)classUserInfoAction(Action):id='myinfos'__select__=authenticated_user()title=_('personnal informations')category='useractions'order=20defurl(self):returnself.build_url('cwuser/%s'%self.req.user.login,vid='edition')classLogoutAction(Action):id='logout'__select__=authenticated_user()title=_('logout')category='useractions'order=30defurl(self):returnself.build_url(self.id)# site actions ################################################################classManagersAction(Action):__abstract__=True__select__=match_user_groups('managers')category='siteactions'defurl(self):returnself.build_url(self.id)classSiteConfigurationAction(ManagersAction):id='siteconfig'title=_('site configuration')order=10classManageAction(ManagersAction):id='manage'title=_('manage')order=20classSiteInfoAction(ManagersAction):id='siteinfo'title=_('info')order=30__select__=match_user_groups('users','managers')classPoweredByAction(Action):id='poweredby'__select__=yes()category='footer'order=3title=_('powered by CubicWeb')defurl(self):return'http://www.cubicweb.org'fromlogilab.common.deprecationimportclass_movedfromcubicweb.web.views.bookmarkimportFollowActionFollowAction=class_moved(FollowAction)## default actions ui configuration ###########################################addmenu=uicfg.actionbox_appearsin_addmenuaddmenu.tag_subject_of(('*','is','*'),False)addmenu.tag_object_of(('*','is','*'),False)addmenu.tag_subject_of(('*','is_instance_of','*'),False)addmenu.tag_object_of(('*','is_instance_of','*'),False)addmenu.tag_subject_of(('*','identity','*'),False)addmenu.tag_object_of(('*','identity','*'),False)addmenu.tag_subject_of(('*','owned_by','*'),False)addmenu.tag_subject_of(('*','created_by','*'),False)addmenu.tag_subject_of(('*','require_permission','*'),False)addmenu.tag_subject_of(('*','wf_info_for','*'),False)addmenu.tag_object_of(('*','wf_info_for','*'),False)addmenu.tag_object_of(('*','state_of','CWEType'),True)addmenu.tag_object_of(('*','transition_of','CWEType'),True)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(('*','owned_by','CWUser'),False)addmenu.tag_object_of(('*','created_by','CWUser'),False)addmenu.tag_object_of(('*','bookmarked_by','CWUser'),True)addmenu.tag_subject_of(('Transition','destination_state','*'),True)addmenu.tag_object_of(('*','allowed_transition','Transition'),True)addmenu.tag_object_of(('*','destination_state','State'),True)addmenu.tag_subject_of(('State','allowed_transition','*'),True)