Ejemplo n.º 1
0
class CWPropertiesForm(SystemCWPropertiesForm):
    """user's preferences properties edition form"""
    __regid__ = 'propertiesform'
    __select__ = ((none_rset() & match_user_groups('users', 'managers'))
                  | (one_line_rset() & match_user_groups('users')
                     & logged_user_in_rset())
                  | (one_line_rset() & match_user_groups('managers')
                     & is_instance('CWUser')))

    title = _('user preferences')

    @property
    def user(self):
        if self.cw_rset is None:
            return self._cw.user
        return self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)

    @property
    @cached
    def cwprops_rset(self):
        return self._cw.execute(
            'Any P,K,V WHERE P is CWProperty, P pkey K, P value V,'
            'P for_user U, U eid %(x)s', {'x': self.user.eid})

    def form_row(self, form, key, splitlabel):
        subform = super(CWPropertiesForm, self).form_row(form, key, splitlabel)
        # if user is in the managers group and the property is being created,
        # we have to set for_user explicitly
        if not subform.edited_entity.has_eid() and self.user.matching_groups(
                'managers'):
            subform.add_hidden('for_user',
                               self.user.eid,
                               eidparam=True,
                               role='subject')
        return subform
Ejemplo n.º 2
0
class EntityStartupView(EntityView):
    """base class for entity views which may also be applied to None
    result set (usually a default rql is provided by the view class)
    """
    __select__ = none_rset() | non_final_entity()

    default_rql = None

    def __init__(self, req, rset=None, **kwargs):
        super(EntityStartupView, self).__init__(req, rset=rset, **kwargs)
        if rset is None:
            # this instance is not in the "entityview" category
            self.category = 'startupview'

    def startup_rql(self):
        """return some rql to be executed if the result set is None"""
        return self.default_rql

    def no_entities(self, **kwargs):
        """override to display something when no entities were found"""
        pass

    def call(self, **kwargs):
        """override call to execute rql returned by the .startup_rql method if
        necessary
        """
        rset = self.cw_rset
        if rset is None:
            rset = self.cw_rset = self._cw.execute(self.startup_rql())
        if rset:
            for i in range(len(rset)):
                self.wview(self.__regid__, rset, row=i, **kwargs)
        else:
            self.no_entities(**kwargs)
Ejemplo n.º 3
0
class DownloadOWLSchemaAction(Action):
    __regid__ = 'download_as_owl'
    __select__ = none_rset() & match_view('schema')

    category = 'mainactions'
    title = _('download schema as owl')

    def url(self):
        return self._cw.build_url('view', vid='owl')
Ejemplo n.º 4
0
class StartupView(View):
    """base class for views which doesn't need a particular result set to be
    displayed (so they can always be displayed!)
    """
    __select__ = none_rset()

    category = _('startupview')

    def html_headers(self):
        """return a list of html headers (eg something to be inserted between
        <head> and </head> of the returned page

        by default startup views are indexed
        """
        return []
Ejemplo n.º 5
0
class CwStats(View):
    """A textual stats output for monitoring tools such as munin """

    __regid__ = 'processinfo'
    content_type = 'text/plain'
    templatable = False
    __select__ = none_rset() & match_user_groups('users', 'managers')

    def call(self):
        stats = self._cw.call_service('repo_stats')
        stats['threads'] = ', '.join(sorted(stats['threads']))
        for k in stats:
            if k in ('extid_cache_size', 'type_source_cache_size'):
                continue
            if k.endswith('_cache_size'):
                stats[k] = '%s / %s' % (stats[k]['size'], stats[k]['maxsize'])
        results = []
        for element in stats:
            results.append(u'%s %s' % (element, stats[element]))
        self.w(u'\n'.join(results))
Ejemplo n.º 6
0
class ProcessInformationView(StartupView):
    """display various web server /repository information"""
    __regid__ = 'info'
    __select__ = none_rset() & match_user_groups('managers', 'users')

    title = _('server information')
    cache_max_age = 0

    def call(self, **kwargs):
        req = self._cw
        dtformat = req.property_value('ui.datetime-format')
        _ = req._
        w = self.w
        repo = req.cnx.repo
        # generic instance information
        w(u'<h2>%s</h2>' % _('Instance'))
        pyvalue = ((_('config type'), self._cw.vreg.config.name),
                   (_('config mode'), self._cw.vreg.config.mode),
                   (_('instance home'), self._cw.vreg.config.apphome))
        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
        vcconf = repo.get_versions()
        w(u'<h3>%s</h3>' % _('versions configuration'))
        missing = _('no version information')
        pyvalue = [('CubicWeb', vcconf.get('cubicweb', missing))]
        pyvalue += [(cube, vcconf.get(cube, missing))
                    for cube in sorted(self._cw.vreg.config.cubes())]
        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
        # repository information
        w(u'<h2>%s</h2>' % _('Repository'))
        w(u'<h3>%s</h3>' % _('resources usage'))
        stats = self._cw.call_service('repo_stats')
        stats['threads'] = ', '.join(sorted(stats['threads']))
        for k in stats:
            if k == 'type_cache_size':
                continue
            if k.endswith('_cache_size'):
                stats[k] = '%s / %s' % (stats[k]['size'], stats[k]['maxsize'])

        def format_stat(sname, sval):
            return '%s %s' % (xml_escape(
                str(sval)), sname.endswith('percent') and '%' or '')

        pyvalue = [(sname, format_stat(sname, sval))
                   for sname, sval in sorted(stats.items())]
        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
        # web server information
        w(u'<h2>%s</h2>' % _('Web server'))
        pyvalue = ((_('base url'), req.base_url()), (_('data directory url'),
                                                     req.datadir_url))
        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
        from cubicweb.web.application import SESSION_MANAGER
        if SESSION_MANAGER is not None and req.user.is_in_group('managers'):
            sessions = SESSION_MANAGER.current_sessions()
            w(u'<h3>%s</h3>' % _('opened web sessions'))
            if sessions:
                w(u'<ul>')
                for session in sessions:
                    last_usage_time = session.mtime
                    w(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'))
Ejemplo n.º 7
0
class SystemCWPropertiesForm(FormViewMixIn, StartupView):
    """site-wide properties edition form"""
    __regid__ = 'systempropertiesform'
    __select__ = none_rset() & match_user_groups('managers')
    form_buttons = [SubmitButton()]

    title = _('site configuration')
    category = 'startupview'

    def linkable(self):
        return True

    def url(self):
        """return the url associated with this view. We can omit rql here"""
        return self._cw.build_url('view', vid=self.__regid__)

    def _cookie_name(self, somestr):
        return str('%s_property_%s' % (self._cw.vreg.config.appid, somestr))

    def _group_status(self, group, default=u'hidden'):
        """return css class name 'hidden' (collapsed), or '' (open)"""
        cookies = self._cw.get_cookie()
        cookiename = self._cookie_name(group)
        cookie = cookies.get(cookiename)
        if cookie is None:
            self._cw.set_cookie(cookiename, default, maxage=None)
            status = default
        else:
            status = cookie.value
        return status

    def call(self, **kwargs):
        self._cw.add_js(('cubicweb.preferences.js', 'cubicweb.edition.js',
                         'cubicweb.ajax.js'))
        self._cw.add_css('cubicweb.preferences.css')
        values = self.defined_keys
        mainopts, groupedopts = self.group_properties()
        # precompute all forms first to consume error message
        mainforms, groupedforms = self.build_forms(mainopts, groupedopts)
        _ = self._cw._
        self.w(u'<h1>%s</h1>\n' % _(self.title))
        for label, group, form in sorted(
            (_(g), g, f) for g, f in mainforms.items()):
            self.wrap_main_form(group, label, form)
        for label, group, objects in sorted(
            (_(g), g, o) for g, o in groupedforms.items()):
            self.wrap_grouped_form(group, label, objects)

    @property
    @cached
    def cwprops_rset(self):
        return self._cw.execute('Any P,K,V WHERE P is CWProperty, P pkey K, '
                                'P value V, NOT P for_user U')

    @property
    def defined_keys(self):
        values = {}
        for i, entity in enumerate(self.cwprops_rset.entities()):
            values[entity.pkey] = i
        return values

    def group_properties(self):
        mainopts, groupedopts = {}, {}
        vreg = self._cw.vreg
        # "self._regid__=='systempropertiesform'" to skip site wide properties on
        # user's preference but not site's configuration
        for key in vreg.user_property_keys(
                self.__regid__ == 'systempropertiesform'):
            parts = key.split('.')
            if parts[0] in vreg and len(parts) >= 3:
                # appobject configuration
                reg = parts[0]
                propid = parts[-1]
                oid = '.'.join(parts[1:-1])
                groupedopts.setdefault(reg, {}).setdefault(oid, []).append(key)
            else:
                mainopts.setdefault(parts[0], []).append(key)
        return mainopts, groupedopts

    def build_forms(self, mainopts, groupedopts):
        mainforms, groupedforms = {}, {}
        for group, keys in mainopts.items():
            mainforms[group] = self.form(group, keys, False)
        for group, objects in groupedopts.items():
            groupedforms[group] = {}
            for oid, keys in objects.items():
                groupedforms[group][oid] = self.form(group + '_' + oid, keys,
                                                     True)
        return mainforms, groupedforms

    def entity_for_key(self, key):
        values = self.defined_keys
        if key in values:
            entity = self.cwprops_rset.get_entity(values[key], 0)
        else:
            entity = self._cw.vreg['etypes'].etype_class('CWProperty')(
                self._cw)
            entity.eid = next(self._cw.varmaker)
            entity.cw_attr_cache['pkey'] = key
            entity.cw_attr_cache['value'] = self._cw.vreg.property_value(key)
        return entity

    def form(self, formid, keys, splitlabel=False):
        form = self._cw.vreg['forms'].select(
            'composite',
            self._cw,
            domid=formid,
            action=self._cw.build_url(),
            form_buttons=self.form_buttons,
            onsubmit="return validatePrefsForm('%s')" % formid,
            submitmsg=self._cw._('changes applied'))
        path = self._cw.relative_path()
        if '?' in path:
            path, params = path.split('?', 1)
            form.add_hidden('__redirectparams', params)
        form.add_hidden('__redirectpath', path)
        for key in keys:
            self.form_row(form, key, splitlabel)
        renderer = self._cw.vreg['formrenderers'].select(
            'cwproperties', self._cw, display_progress_div=False)
        data = []
        form.render(w=data.append, renderer=renderer)
        return u'\n'.join(data)

    def form_row(self, form, key, splitlabel):
        entity = self.entity_for_key(key)
        if splitlabel:
            label = key.split('.')[-1]
        else:
            label = key
        subform = self._cw.vreg['forms'].select('base',
                                                self._cw,
                                                entity=entity,
                                                mainform=False)
        subform.append_field(
            PropertyValueField(name='value',
                               label=label,
                               role='subject',
                               eidparam=True))
        subform.add_hidden('pkey', key, eidparam=True, role='subject')
        form.add_subform(subform)
        return subform

    def wrap_main_form(self, group, label, form):
        status = css_class(self._group_status(group))
        self.w(u'<div class="propertiesform">%s</div>\n' %
               (make_togglable_link('fieldset_' + group, label)))
        self.w(u'<div id="fieldset_%s" %s>' % (group, status))
        self.w(u'<fieldset class="preferences">')
        self.w(form)
        self.w(u'</fieldset></div>')

    def wrap_grouped_form(self, group, label, objects):
        status = css_class(self._group_status(group))
        self.w(u'<div class="propertiesform">%s</div>\n' %
               (make_togglable_link('fieldset_' + group, label)))
        self.w(u'<div id="fieldset_%s" %s>' % (group, status))
        sorted_objects = sorted((self._cw.__('%s_%s' % (group, o)), o, f)
                                for o, f in objects.items())
        for label, oid, form in sorted_objects:
            self.wrap_object_form(group, oid, label, form)
        self.w(u'</div>')

    def wrap_object_form(self, group, oid, label, form):
        w = self.w
        w(u'<div class="component">')
        w(u'''<div class="componentLink"><a href="javascript:$.noop();"
                   onclick="javascript:toggleVisibility('field_%(oid)s_%(group)s')"
                   class="componentTitle">%(label)s</a>''' % {
            'label': label,
            'oid': oid,
            'group': group
        })
        w(u''' (<div class="openlink"><a href="javascript:$.noop();"
                onclick="javascript:openFieldset('fieldset_%(group)s')">%(label)s</a></div>)'''
          % {
              'label': self._cw._('open all'),
              'group': group
          })
        w(u'</div>')
        docmsgid = '%s_%s_description' % (group, oid)
        doc = self._cw._(docmsgid)
        if doc != docmsgid:
            w(u'<div class="helper">%s</div>' % xml_escape(doc).capitalize())
        w(u'</div>')
        w(u'<fieldset id="field_%(oid)s_%(group)s" class="%(group)s preferences hidden">'
          % {
              'oid': oid,
              'group': group
          })
        w(form)
        w(u'</fieldset>')
Ejemplo n.º 8
0
class SupervisionEmailView(Component):
    """view implementing the email API for data changes supervision notification
    """
    __regid__ = 'supervision_notif'
    __select__ = none_rset()

    def recipients(self):
        return self._cw.vreg.config['supervising-addrs']

    def subject(self):
        return self._cw._(
            '[%s supervision] changes summary') % self._cw.vreg.config.appid

    def call(self, changes):
        user = self._cw.user
        self.w(
            self._cw._('user %s has made the following change(s):\n\n') %
            user.login)
        for event, changedescr in filter_changes(changes):
            self.w(u'* ')
            getattr(self, event)(changedescr)
            self.w(u'\n\n')

    def _entity_context(self, entity):
        return {
            'eid': entity.eid,
            'etype': entity.dc_type().lower(),
            'title': entity.dc_title()
        }

    def add_entity(self, changedescr):
        msg = self._cw._('added %(etype)s #%(eid)s (%(title)s)')
        self.w(u'%s\n' % (msg % self._entity_context(changedescr.entity)))
        self.w(u'  %s' % changedescr.entity.absolute_url())

    def update_entity(self, changedescr):
        msg = self._cw._('updated %(etype)s #%(eid)s (%(title)s)')
        self.w(u'%s\n' % (msg % self._entity_context(changedescr.entity)))
        # XXX print changes
        self.w(u'  %s' % changedescr.entity.absolute_url())

    def delete_entity(self, args):
        eid, etype, title = args
        msg = self._cw._('deleted %(etype)s #%(eid)s (%(title)s)')
        etype = display_name(self._cw, etype).lower()
        self.w(msg % locals())

    def change_state(self, args):
        _ = self._cw._
        entity, fromstate, tostate = args
        msg = _('changed state of %(etype)s #%(eid)s (%(title)s)')
        self.w(u'%s\n' % (msg % self._entity_context(entity)))
        self.w(
            _('  from state %(fromstate)s to state %(tostate)s\n' % {
                'fromstate': _(fromstate.name),
                'tostate': _(tostate.name)
            }))
        self.w(u'  %s' % entity.absolute_url())

    def _relation_context(self, changedescr):
        cnx = self._cw

        def describe(eid):
            try:
                return cnx._(cnx.entity_type(eid)).lower()
            except UnknownEid:
                # may occurs when an entity has been deleted from an external
                # source and we're cleaning its relation
                return cnx._('unknown external entity')

        eidfrom, rtype, eidto = changedescr.eidfrom, changedescr.rtype, changedescr.eidto
        return {
            'rtype': cnx._(rtype),
            'eidfrom': eidfrom,
            'frometype': describe(eidfrom),
            'eidto': eidto,
            'toetype': describe(eidto)
        }

    def add_relation(self, changedescr):
        msg = self._cw._(
            'added relation %(rtype)s from %(frometype)s #%(eidfrom)s to %(toetype)s #%(eidto)s'
        )
        self.w(msg % self._relation_context(changedescr))

    def delete_relation(self, changedescr):
        msg = self._cw._(
            'deleted relation %(rtype)s from %(frometype)s #%(eidfrom)s to %(toetype)s #%(eidto)s'
        )
        self.w(msg % self._relation_context(changedescr))