# HG changeset patch # User Adrien Di Mascio # Date 1234900605 -3600 # Node ID 35133d86970bea84b676e74762bb809b6b4c3a8d # Parent cddfbdee0eb311ad3fb514431ab8ce88be454e94 move EProperty management views into eproperties.py diff -r cddfbdee0eb3 -r 35133d86970b web/views/eproperties.py --- a/web/views/eproperties.py Tue Feb 17 20:39:09 2009 +0100 +++ b/web/views/eproperties.py Tue Feb 17 20:56:45 2009 +0100 @@ -7,9 +7,250 @@ """ __docformat__ = "restructuredtext en" -from cubicweb.selectors import implements +from logilab.mtconverter import html_escape + +from logilab.common.decorators import cached + +from cubicweb.selectors import (one_line_rset, none_rset, implements, + match_user_groups, chainfirst, chainall) +from cubicweb.common.utils import UStringIO +from cubicweb.common.view import StartupView +from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs from cubicweb.web.views import baseviews +from cubicweb.web.form import FormMixIn + +_ = unicode + +# some string we want to be internationalizable for nicer display of eproperty +# groups +_('navigation') +_('ui') +_('actions') +_('boxes') +_('components') +_('contentnavigation') class EPropertyPrimaryView(baseviews.PrimaryView): __selectors__ = implements('EProperty') skip_none = False + + +def make_togglable_link(nodeid, label, cookiename): + """builds a HTML link that switches the visibility & remembers it""" + action = u"javascript: toggle_and_remember_visibility('%s', '%s')" % \ + (nodeid, cookiename) + return u'%s' % (action, label) + +def css_class(someclass): + return someclass and 'class="%s"' % someclass or '' + +class SystemEPropertiesForm(FormMixIn, StartupView): + id = 'systemepropertiesform' + __selectors__ = (none_rset, match_user_groups('managers')) + + title = _('site configuration') + controller = 'edit' + category = 'startupview' + + def linkable(self): + return True + + def url(self): + """return the url associated with this view. We can omit rql here""" + return self.build_url('view', vid=self.id) + + def _cookie_name(self, somestr): + return str('%s_property_%s' % (self.config.appid, somestr)) + + def _group_status(self, group, default=u'hidden'): + cookies = self.req.get_cookie() + cookiename = self._cookie_name(group) + cookie = cookies.get(cookiename) + if cookie is None: + cookies[cookiename] = default + self.req.set_cookie(cookies, cookiename, maxage=None) + status = default + else: + status = cookie.value + return status + + def call(self, **kwargs): + """The default view representing the application's index""" + self.req.add_js(('cubicweb.edition.js', 'cubicweb.preferences.js')) + self.req.add_css('cubicweb.preferences.css') + vreg = self.vreg + values = self.defined_keys + groupedopts = {} + mainopts = {} + # "self.id=='systemepropertiesform'" to skip site wide properties on + # user's preference but not site's configuration + for key in vreg.user_property_keys(self.id=='systemepropertiesform'): + parts = key.split('.') + if parts[0] in vreg: + # appobject configuration + reg, oid, propid = parts + groupedopts.setdefault(reg, {}).setdefault(oid, []).append(key) + else: + mainopts.setdefault(parts[0], []).append(key) + # precompute form to consume error message + for group, keys in mainopts.items(): + mainopts[group] = self.form(keys, False) + for group, objects in groupedopts.items(): + for oid, keys in objects.items(): + groupedopts[group][oid] = self.form(keys, True) + + w = self.w + req = self.req + _ = req._ + w(u'

%s

\n' % _(self.title)) + w(self.error_message()) + for label, group, form in sorted((_(g), g, f) + for g, f in mainopts.iteritems()): + status = css_class(self._group_status(group)) #'hidden' (collapsed), or '' (open) ? + w(u'

%s

\n' % + (make_togglable_link('fieldset_' + group, label, + self._cookie_name(group)))) + w(u'
' % (group, status)) + w(u'
') + w(form) + w(u'
') + for label, group, objects in sorted((_(g), g, o) + for g, o in groupedopts.iteritems()): + status = css_class(self._group_status(group)) + w(u'

%s

\n' % + (make_togglable_link('fieldset_' + group, label, + self._cookie_name(group)))) + w(u'
' % (group, status)) + for label, oid, form in sorted((self.req.__('%s_%s' % (group, o)), o, f) + for o, f in objects.iteritems()): + w(u'
') + w(u'%s\n' % label) + docmsgid = '%s_%s_description' % (group, oid) + doc = _(docmsgid) + if doc != docmsgid: + w(u'

%s

' % html_escape(doc)) + w(form) + w(u'
') + w(u'
') + + @property + @cached + def eprops_rset(self): + return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U') + + @property + def defined_keys(self): + values = {} + for i, entity in enumerate(self.eprops_rset.entities()): + values[entity.pkey] = i + return values + + def entity_for_key(self, key): + values = self.defined_keys + if key in values: + entity = self.eprops_rset.get_entity(values[key], 0) + else: + entity = self.vreg.etype_class('EProperty')(self.req, None, None) + entity.eid = self.req.varmaker.next() + entity['value'] = self.vreg.property_value(key) + return entity + + def form(self, keys, splitlabel=False): + stream = UStringIO() + w = stream.write + w(u'
\n' % self.build_url()) + w(u'
\n') + w(u'\n' + % html_escape(self.req.url())) + w(u'\n' % self.id) + path = self.req.relative_path() + if '?' in path: + path, params = path.split('?', 1) + w(u'\n' + % html_escape(params)) + w(u'\n' % path) + #w(u'\n') + w(u'\n' + % self.req._('changes applied')) + w(u'
\n') + + w(u'\n') + for key in keys: + w(u'\n') + self.form_row(w, key, splitlabel) + w(u'\n') + w(u'
\n') + w(u'
\n') + w(self.button_ok()) + w(self.button_cancel()) + w(u'
\n') + w(u'
\n') + w(u'
\n') + return stream.getvalue() + + def form_row(self, w, key, splitlabel): + entity = self.entity_for_key(key) + eid = entity.eid + if splitlabel: + w(u'%s' % self.req._(key.split('.')[-1])) + else: + w(u'%s' % self.req._(key)) + wdg = self.vreg.property_value_widget(key, req=self.req) + error = wdg.render_error(entity) + w(u'' % (error and 'error' or '')) + w(error) + self.form_row_hiddens(w, entity, key) + w(wdg.edit_render(entity)) + w(u'\n') + w(u'%s' % wdg.render_help(entity)) + return entity + + def form_row_hiddens(self, w, entity, key): + eid = entity.eid + w(u'' % eid) + w(u'' % eid_param('__type', eid)) + w(u'' % (eid_param('pkey', eid), key)) + w(u'' % (eid_param('edits-pkey', eid), '')) + + + +def is_user_prefs(cls, req, rset, row, col): + return req.user.eid == rset[row or 0 ][col or 0] + + +class EPropertiesForm(SystemEPropertiesForm): + id = 'epropertiesform' + __selectors__ = ( + implements('EUser'), + # we don't want guests to be able to come here + match_user_groups('users', 'managers'), + chainfirst(none_rset), + chainall(one_line_rset, is_user_prefs), + chainall(one_line_rset, match_user_groups('managers')) + ) + + title = _('preferences') + + @property + def user(self): + if self.rset is None: + return self.req.user + return self.rset.get_entity(self.row or 0, self.col or 0) + + @property + @cached + def eprops_rset(self): + return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V,' + 'P for_user U, U eid %(x)s', {'x': self.user.eid}) + + def form_row_hiddens(self, w, entity, key): + super(EPropertiesForm, self).form_row_hiddens(w, entity, key) + # if user is in the managers group and the property is being created, + # we have to set for_user explicitly + if not entity.has_eid() and self.user.matching_groups('managers'): + eid = entity.eid + w(u'' + % (eid_param('edits-for_user', eid), INTERNAL_FIELD_VALUE)) + w(u'' + % (eid_param('for_user', eid), self.user.eid)) + diff -r cddfbdee0eb3 -r 35133d86970b web/views/management.py --- a/web/views/management.py Tue Feb 17 20:39:09 2009 +0100 +++ b/web/views/management.py Tue Feb 17 20:56:45 2009 +0100 @@ -9,16 +9,11 @@ from logilab.mtconverter import html_escape -from logilab.common.decorators import cached - -from cubicweb.selectors import (yes, one_line_rset, none_rset, - match_user_groups, chainfirst, chainall) -from cubicweb.common.utils import UStringIO +from cubicweb.selectors import yes, none_rset, match_user_groups from cubicweb.common.view import AnyRsetView, StartupView, EntityView from cubicweb.common.uilib import html_traceback, rest_traceback from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs from cubicweb.web.widgets import StaticComboBoxWidget -from cubicweb.web.form import FormMixIn _ = unicode @@ -150,8 +145,8 @@ newperm.eid = self.req.varmaker.next() w(u'

%s

' % _('add a new permission')) begin_form(w, newperm, 'security', entity.rest_path()) - w(u'' - % eid_param('edito-require_permission', newperm.eid)) + w(u'' + % (eid_param('edito-require_permission', newperm.eid), INTERNAL_FIELD_VALUE)) w(u'' % (eid_param('require_permission', newperm.eid), entity.eid)) w(u'\n') @@ -179,7 +174,7 @@ class ErrorView(AnyRsetView): """default view when no result has been found""" - __selectors__ = (yes,) + __selectors__ = yes id = 'error' def page_title(self): @@ -273,238 +268,6 @@ binfo += '\n' return binfo -# some string we want to be internationalizable for nicer display of eproperty -# groups -_('navigation') -_('ui') -_('actions') -_('boxes') -_('components') -_('contentnavigation') - - -def make_togglable_link(nodeid, label, cookiename): - """builds a HTML link that switches the visibility & remembers it""" - action = u"javascript: toggle_and_remember_visibility('%s', '%s')" % \ - (nodeid, cookiename) - return u'%s' % (action, label) - -def css_class(someclass): - return someclass and 'class="%s"' % someclass or '' - -class SystemEPropertiesForm(FormMixIn, StartupView): - id = 'systemepropertiesform' - __selectors__ = (none_rset, match_user_groups('managers'),) - - title = _('site configuration') - controller = 'edit' - category = 'startupview' - - def linkable(self): - return True - - def url(self): - """return the url associated with this view. We can omit rql here""" - return self.build_url('view', vid=self.id) - - def _cookie_name(self, somestr): - return str('%s_property_%s' % (self.config.appid, somestr)) - - def _group_status(self, group, default=u'hidden'): - cookies = self.req.get_cookie() - cookiename = self._cookie_name(group) - cookie = cookies.get(cookiename) - if cookie is None: - cookies[cookiename] = default - self.req.set_cookie(cookies, cookiename, maxage=None) - status = default - else: - status = cookie.value - return status - - def call(self, **kwargs): - """The default view representing the application's index""" - self.req.add_js(('cubicweb.edition.js', 'cubicweb.preferences.js')) - self.req.add_css('cubicweb.preferences.css') - vreg = self.vreg - values = self.defined_keys - groupedopts = {} - mainopts = {} - # "self.id=='systemepropertiesform'" to skip site wide properties on - # user's preference but not site's configuration - for key in vreg.user_property_keys(self.id=='systemepropertiesform'): - parts = key.split('.') - if parts[0] in vreg: - # appobject configuration - reg, oid, propid = parts - groupedopts.setdefault(reg, {}).setdefault(oid, []).append(key) - else: - mainopts.setdefault(parts[0], []).append(key) - # precompute form to consume error message - for group, keys in mainopts.items(): - mainopts[group] = self.form(keys, False) - for group, objects in groupedopts.items(): - for oid, keys in objects.items(): - groupedopts[group][oid] = self.form(keys, True) - - w = self.w - req = self.req - _ = req._ - w(u'

%s

\n' % _(self.title)) - w(self.error_message()) - for label, group, form in sorted((_(g), g, f) - for g, f in mainopts.iteritems()): - status = css_class(self._group_status(group)) #'hidden' (collapsed), or '' (open) ? - w(u'

%s

\n' % - (make_togglable_link('fieldset_' + group, label, - self._cookie_name(group)))) - w(u'
' % (group, status)) - w(u'
') - w(form) - w(u'
') - for label, group, objects in sorted((_(g), g, o) - for g, o in groupedopts.iteritems()): - status = css_class(self._group_status(group)) - w(u'

%s

\n' % - (make_togglable_link('fieldset_' + group, label, - self._cookie_name(group)))) - w(u'
' % (group, status)) - for label, oid, form in sorted((self.req.__('%s_%s' % (group, o)), o, f) - for o, f in objects.iteritems()): - w(u'
') - w(u'%s\n' % label) - docmsgid = '%s_%s_description' % (group, oid) - doc = _(docmsgid) - if doc != docmsgid: - w(u'

%s

' % html_escape(doc)) - w(form) - w(u'
') - w(u'
') - - @property - @cached - def eprops_rset(self): - return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U') - - @property - def defined_keys(self): - values = {} - for i, entity in enumerate(self.eprops_rset.entities()): - values[entity.pkey] = i - return values - - def entity_for_key(self, key): - values = self.defined_keys - if key in values: - entity = self.eprops_rset.get_entity(values[key], 0) - else: - entity = self.vreg.etype_class('EProperty')(self.req, None, None) - entity.eid = self.req.varmaker.next() - entity['value'] = self.vreg.property_value(key) - return entity - - def form(self, keys, splitlabel=False): - stream = UStringIO() - w = stream.write - w(u'\n' % self.build_url()) - w(u'
\n') - w(u'\n' - % html_escape(self.req.url())) - w(u'\n' % self.id) - path = self.req.relative_path() - if '?' in path: - path, params = path.split('?', 1) - w(u'\n' - % html_escape(params)) - w(u'\n' % path) - #w(u'\n') - w(u'\n' - % self.req._('changes applied')) - w(u'
\n') - - w(u'\n') - for key in keys: - w(u'\n') - self.form_row(w, key, splitlabel) - w(u'\n') - w(u'
\n') - w(u'
\n') - w(self.button_ok()) - w(self.button_cancel()) - w(u'
\n') - w(u'\n') - w(u'\n') - return stream.getvalue() - - def form_row(self, w, key, splitlabel): - entity = self.entity_for_key(key) - eid = entity.eid - if splitlabel: - w(u'%s' % self.req._(key.split('.')[-1])) - else: - w(u'%s' % self.req._(key)) - wdg = self.vreg.property_value_widget(key, req=self.req) - error = wdg.render_error(entity) - w(u'' % (error and 'error' or '')) - w(error) - self.form_row_hiddens(w, entity, key) - w(wdg.edit_render(entity)) - w(u'\n') - w(u'%s' % wdg.render_help(entity)) - return entity - - def form_row_hiddens(self, w, entity, key): - eid = entity.eid - w(u'' % eid) - w(u'' % eid_param('__type', eid)) - w(u'' % (eid_param('pkey', eid), key)) - w(u'' % (eid_param('edits-pkey', eid), '')) - - - -def is_user_prefs(cls, req, rset, row, col): - return req.user.eid == rset[row or 0 ][col or 0] - -class EPropertiesForm(SystemEPropertiesForm): - id = 'epropertiesform' - __selectors__ = ( - # we don't want guests to be able to come here - match_user_groups('users', 'managers'), - chainfirst(none_rset), - chainall(one_line_rset, is_user_prefs), - chainall(one_line_rset, match_user_groups('managers')) - ) - - __selectors__ = (implements('EUser',)) - - title = _('preferences') - - @property - def user(self): - if self.rset is None: - return self.req.user - return self.rset.get_entity(self.row or 0, self.col or 0) - - @property - @cached - def eprops_rset(self): - return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V,' - 'P for_user U, U eid %(x)s', {'x': self.user.eid}) - - def form_row_hiddens(self, w, entity, key): - super(EPropertiesForm, self).form_row_hiddens(w, entity, key) - # if user is in the managers group and the property is being created, - # we have to set for_user explicitly - if not entity.has_eid() and self.user.matching_groups('managers'): - eid = entity.eid - w(u'' - % (eid_param('edits-for_user', eid), INTERNAL_FIELD_VALUE)) - w(u'' - % (eid_param('for_user', eid), self.user.eid)) - - - - class ProcessInformationView(StartupView): id = 'info' __selectors__ = (none_rset, match_user_groups('managers'),)