web/views/actions.py
changeset 0 b97547f5f1fa
child 237 3df2e0ae2eba
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """Set of HTML base actions
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 """
       
     7 __docformat__ = "restructuredtext en"
       
     8 
       
     9 from cubicweb import UnknownEid
       
    10 from cubicweb.common.selectors import *
       
    11 
       
    12 from cubicweb.web.action import (Action, EntityAction,  LinkToEntityAction,
       
    13                               LinkToEntityAction2)
       
    14 from cubicweb.web.views import linksearch_select_url, linksearch_match
       
    15 from cubicweb.web.views.baseviews import vid_from_rset
       
    16 
       
    17 _ = unicode
       
    18 
       
    19 
       
    20 class SelectAction(EntityAction):
       
    21     """base class for link search actions. By default apply on
       
    22     any size entity result search it the current state is 'linksearch'
       
    23     if accept match.
       
    24     """
       
    25     category = 'mainactions'    
       
    26     __selectors__ = (searchstate_accept_selector,)
       
    27     search_states = ('linksearch',)
       
    28     order = 0
       
    29     
       
    30     id = 'select'
       
    31     title = _('select')
       
    32     
       
    33     @classmethod
       
    34     def accept_rset(cls, req, rset, row, col):
       
    35         return linksearch_match(req, rset)
       
    36     
       
    37     def url(self):
       
    38         return linksearch_select_url(self.req, self.rset)
       
    39 
       
    40 
       
    41 class CancelSelectAction(Action):
       
    42     category = 'mainactions'
       
    43     search_states = ('linksearch',)
       
    44     order = 10
       
    45     
       
    46     id = 'cancel'
       
    47     title = _('cancel select')
       
    48     
       
    49     def url(self):
       
    50         target, link_eid, r_type, searched_type = self.req.search_state[1]
       
    51         return self.build_url(rql="Any X WHERE X eid %s" % link_eid,
       
    52                               vid='edition', __mode='normal')
       
    53 
       
    54 
       
    55 class ViewAction(Action):
       
    56     category = 'mainactions'    
       
    57     __selectors__ = (in_group_selector, searchstate_accept_selector)
       
    58     require_groups = ('users', 'managers')
       
    59     order = 0
       
    60     
       
    61     id = 'view'
       
    62     title = _('view')
       
    63     
       
    64     @classmethod
       
    65     def accept_rset(cls, req, rset, row, col):
       
    66         # interesting if it propose another view than the current one
       
    67         vid = req.form.get('vid')
       
    68         if vid and vid != vid_from_rset(req, rset, cls.schema):
       
    69             return 1
       
    70         return 0
       
    71     
       
    72     def url(self):
       
    73         params = self.req.form.copy()
       
    74         params.pop('vid', None)
       
    75         params.pop('__message', None)
       
    76         return self.build_url(self.req.relative_path(includeparams=False), **params)
       
    77 
       
    78 
       
    79 class ModifyAction(EntityAction):
       
    80     category = 'mainactions'
       
    81     __selectors__ = (onelinerset_selector, searchstate_accept_selector)
       
    82     #__selectors__ = searchstate_accept_selector,
       
    83     schema_action = 'update'
       
    84     order = 10
       
    85     
       
    86     id = 'edit'
       
    87     title = _('modify')
       
    88     
       
    89     @classmethod
       
    90     def has_permission(cls, entity, action):
       
    91         if entity.has_perm(action):
       
    92             return True
       
    93         # if user has no update right but it can modify some relation,
       
    94         # display action anyway
       
    95         for dummy in entity.srelations_by_category(('generic', 'metadata'), 'add'):
       
    96             return True
       
    97         for rschema, targetschemas, role in entity.relations_by_category(('primary', 'secondary'), 'add'):
       
    98             if not rschema.is_final():
       
    99                 return True
       
   100         return False
       
   101 
       
   102     def url(self):
       
   103         entity = self.rset.get_entity(self.row or 0, self.col or 0)
       
   104         return entity.absolute_url(vid='edition')
       
   105 
       
   106     
       
   107 class DeleteAction(EntityAction):
       
   108     category = 'moreactions' 
       
   109     __selectors__ = (searchstate_accept_selector,)
       
   110     schema_action = 'delete'
       
   111     order = 20
       
   112     
       
   113     id = 'delete'
       
   114     title = _('delete')
       
   115     
       
   116     def url(self):
       
   117         if len(self.rset) == 1:
       
   118             entity = self.rset.get_entity(0, 0)
       
   119             return self.build_url(entity.rest_path(), vid='deleteconf')
       
   120         return self.build_url(rql=self.rset.printable_rql(), vid='deleteconf')
       
   121     
       
   122         
       
   123 class CopyAction(EntityAction):
       
   124     category = 'moreactions'
       
   125     schema_action = 'add'
       
   126     order = 30
       
   127     
       
   128     id = 'copy'
       
   129     title = _('copy')
       
   130     
       
   131     def url(self):
       
   132         entity = self.rset.get_entity(self.row or 0, self.col or 0)
       
   133         return entity.absolute_url(vid='copy')
       
   134         
       
   135 
       
   136 class MultipleEditAction(EntityAction):
       
   137     category = 'mainactions'
       
   138     __selectors__ = (twolinerset_selector, oneetyperset_selector,
       
   139                      searchstate_accept_selector)
       
   140     schema_action = 'update'
       
   141     order = 10
       
   142     
       
   143     id = 'muledit' # XXX get strange conflicts if id='edit'
       
   144     title = _('modify')
       
   145     
       
   146     def url(self):
       
   147         return self.build_url('view', rql=self.rset.rql, vid='muledit')
       
   148 
       
   149 
       
   150 class AddNewAction(MultipleEditAction):
       
   151     """when we're seeing more than one entity with the same type, propose to
       
   152     add a new one
       
   153     """
       
   154     category = 'moreactions'
       
   155     
       
   156     def etype_rset_selector(cls, req, rset, **kwargs):
       
   157         if rset is not None and not rset.rowcount:
       
   158             rqlst = rset.syntax_tree()
       
   159             if len(rqlst.children) > 1:
       
   160                 return 0
       
   161             select = rqlst.children[0]
       
   162             if len(select.defined_vars) == 1 and len(select.solutions) == 1:
       
   163                     rset._searched_etype = select.solutions[0].itervalues().next()
       
   164                     eschema = cls.schema.eschema(rset._searched_etype)
       
   165                     if not eschema.is_final() and eschema.has_perm(req, 'add'):
       
   166                         return 1
       
   167         return 0
       
   168 
       
   169     def has_add_perm_selector(cls, req, rset, **kwargs):
       
   170         eschema = cls.schema.eschema(rset.description[0][0])
       
   171         if not eschema.is_final() and eschema.has_perm(req, 'add'):
       
   172             return 1
       
   173         return 0
       
   174     __selectors__ = (searchstate_selector,
       
   175                      chainfirst(etype_rset_selector,
       
   176                                 chainall(twolinerset_selector, oneetyperset_selector,
       
   177                                          has_add_perm_selector)))
       
   178     order = 40
       
   179     id = 'addentity'
       
   180 
       
   181     @property
       
   182     def rsettype(self):
       
   183         if self.rset:
       
   184             return self.rset.description[0][0]
       
   185         return self.rset._searched_etype
       
   186 
       
   187     @property
       
   188     def title(self):
       
   189         return self.req.__('add a %s' % self.rsettype) # generated msgid
       
   190 
       
   191     def url(self):
       
   192         return self.build_url('add/%s' % self.rsettype)
       
   193 
       
   194 
       
   195 class FollowAction(EntityAction):
       
   196     category = 'mainactions'
       
   197     accepts = ('Bookmark',)
       
   198     
       
   199     id = 'follow'
       
   200     title = _('follow')
       
   201     
       
   202     def url(self):
       
   203         return self.rset.get_entity(self.row or 0, self.col or 0).actual_url()
       
   204 
       
   205 class UserPreferencesAction(Action):
       
   206     category = 'useractions'
       
   207     __selectors__ = not_anonymous_selector,
       
   208     order = 10
       
   209     
       
   210     id = 'myprefs'
       
   211     title = _('user preferences')
       
   212 
       
   213     def url(self):
       
   214         return self.build_url(self.id)
       
   215 
       
   216 class UserPreferencesEntityAction(EntityAction):
       
   217     __selectors__ = EntityAction.__selectors__ + (onelinerset_selector, in_group_selector,)
       
   218     require_groups = ('owners', 'managers')
       
   219     category = 'mainactions'
       
   220     accepts = ('EUser',)
       
   221     
       
   222     id = 'prefs'
       
   223     title = _('preferences')
       
   224     
       
   225     def url(self):
       
   226         login = self.rset.get_entity(self.row or 0, self.col or 0).login
       
   227         return self.build_url('euser/%s'%login, vid='epropertiesform')
       
   228 
       
   229 class UserInfoAction(Action):
       
   230     category = 'useractions'
       
   231     __selectors__ = not_anonymous_selector,
       
   232     order = 20
       
   233     
       
   234     id = 'myinfos'
       
   235     title = _('personnal informations')
       
   236 
       
   237     def url(self):
       
   238         return self.build_url('euser/%s'%self.req.user.login, vid='edition')
       
   239 
       
   240 class LogoutAction(Action):
       
   241     category = 'useractions'
       
   242     __selectors__ = not_anonymous_selector,
       
   243     order = 30
       
   244     
       
   245     id = 'logout'
       
   246     title = _('logout')
       
   247 
       
   248     def url(self):
       
   249         return self.build_url(self.id)
       
   250     
       
   251 
       
   252 class ManagersAction(Action):
       
   253     category = 'siteactions'
       
   254     __abstract__ = True
       
   255     __selectors__ = in_group_selector,
       
   256     require_groups = ('managers',)
       
   257 
       
   258     def url(self):
       
   259         return self.build_url(self.id)
       
   260     
       
   261 class SiteConfigurationAction(ManagersAction):
       
   262     order = 10
       
   263     
       
   264     id = 'siteconfig'
       
   265     title = _('site configuration')
       
   266     
       
   267 class ManageAction(ManagersAction):
       
   268     order = 20
       
   269     
       
   270     id = 'manage'
       
   271     title = _('manage')
       
   272 
       
   273 
       
   274 class ViewSchemaAction(Action):
       
   275     category = 'siteactions'
       
   276     __selectors__ = yes_selector,
       
   277     order = 30
       
   278     
       
   279     id = 'schema'
       
   280     title = _("site schema")
       
   281 
       
   282     def url(self):
       
   283         return self.build_url(self.id)
       
   284