Esempio n. 1
0
 def test_invalid_calls(self):
     """checks invalid calls raise a ValueError"""
     # mixing named and positional arguments should fail
     with self.assertRaises(ValueError) as cm:
         match_form_params('list', x='1', y='2')
     self.assertEqual(str(cm.exception),
                      "match_form_params() can't be called with both "
                      "positional and named arguments")
     # using a dict as first and unique argument should fail
     with self.assertRaises(ValueError) as cm:
         match_form_params({'x': 1})
     self.assertEqual(str(cm.exception),
                      "match_form_params() positional arguments must be strings")
Esempio n. 2
0
    def test_keyonly_match(self):
        """test standard usage: ``match_form_params('param1', 'param2')``

        ``param1`` and ``param2`` must be specified in request's form.
        """
        web_request = self.admin_access.web_request
        vid_selector = match_form_params('vid')
        vid_subvid_selector = match_form_params('vid', 'subvid')
        # no parameter => KO,KO
        with web_request() as req:
            self.assertEqual(vid_selector(None, req), 0)
            self.assertEqual(vid_subvid_selector(None, req), 0)
        # one expected parameter found => OK,KO
        with web_request(vid='foo') as req:
            self.assertEqual(vid_selector(None, req), 1)
            self.assertEqual(vid_subvid_selector(None, req), 0)
        # all expected parameters found => OK,OK
        with web_request(vid='foo', subvid='bar') as req:
            self.assertEqual(vid_selector(None, req), 1)
            self.assertEqual(vid_subvid_selector(None, req), 2)
Esempio n. 3
0
class BreadCrumbLinkToVComponent(BreadCrumbEntityVComponent):
    __select__ = basecomponents.HeaderComponent.__select__ & match_form_params(
        '__linkto')

    def render(self, w, **kwargs):
        eid = self._cw.list_form_param('__linkto')[0].split(':')[1]
        entity = self._cw.entity_from_eid(eid)
        ecmp = self._cw.vreg[self.__registry__].select(self.__regid__,
                                                       self._cw,
                                                       entity=entity,
                                                       **kwargs)
        ecmp.render(w, **kwargs)
Esempio n. 4
0
class AddRelationView(component.EditRelationMixIn, View):
    """base class for view which let add entities linked by a given relation

    subclasses should define at least id, rtype and target class attributes.
    """
    __registry__ = 'views'
    __regid__ = 'xaddrelation'
    __select__ = (match_form_params('rtype', 'target')
                  | match_kwargs('rtype', 'target'))
    cw_property_defs = {}  # don't want to inherit this from Box
    expected_kwargs = form_params = ('rtype', 'target')

    def cell_call(self, row, col, rtype=None, target=None, etype=None):
        self.rtype = rtype or self._cw.form['rtype']
        self.target = target or self._cw.form['target']
        self.etype = etype or self._cw.form.get('etype')
        entity = self.cw_rset.get_entity(row, col)
        rschema = self._cw.vreg.schema.rschema(self.rtype)
        if not self.etype:
            if self.target == 'object':
                etypes = rschema.objects(entity.e_schema)
            else:
                etypes = rschema.subjects(entity.e_schema)
            if len(etypes) == 1:
                self.etype = etypes[0]
        self.w(u'<div id="%s">' % self.domid)
        self.w(
            u'<h1>%s</h1>' % self._cw._('relation %(relname)s of %(ent)s') % {
                'relname': rschema.display_name(self._cw, role(self)),
                'ent': entity.view('incontext')
            })
        self.w(u'<ul class="list-unstyled">')
        for boxitem in self.unrelated_boxitems(entity):
            self.w('<li>%s</li>' % boxitem)
        self.w(u'</ul></div>')

    def unrelated_entities(self, entity):
        """returns the list of unrelated entities

        if etype is not defined on the Box's class, the default
        behaviour is to use the entity's appropraite vocabulary function
        """
        # use entity.unrelated if we've been asked for a particular etype
        if getattr(self, 'etype', None):
            rset = entity.unrelated(self.rtype,
                                    self.etype,
                                    role(self),
                                    ordermethod='fetch_order')
            self.paginate(self._cw, rset=rset, w=self.w)
            return rset.entities()
        super(AddRelationView, self).unrelated_entities(self)
Esempio n. 5
0
class MailBugReportController(Controller):
    __regid__ = 'reportbug'
    __select__ = match_form_params('description')

    def publish(self, rset=None):
        req = self._cw
        desc = req.form['description']
        # The description is generated and signed by cubicweb itself, check
        # description's signature so we don't want to send spam here
        sign = req.form.get('__signature', '')
        if not (sign and req.vreg.config.check_text_sign(desc, sign)):
            raise Forbidden('Invalid content')
        self.sendmail(req.vreg.config['submit-mail'],
                      req._('%s error report') % req.vreg.config.appid, desc)
        raise Redirect(req.build_url(__message=req._('bug report sent')))
Esempio n. 6
0
    def test_keyvalue_match_two_parameters(self):
        """test dict usage: ``match_form_params(param1=value1, param2=value2)``

        ``param1`` and ``param2`` must be specified in the request's form and
        their respective value must be ``value1`` and ``value2``.
        """
        web_request = self.admin_access.web_request
        vid_subvid_selector = match_form_params(vid='list', subvid='tsearch')
        # missing one expected parameter => KO
        with web_request(vid='list') as req:
            self.assertEqual(vid_subvid_selector(None, req), 0)
        # expected parameters found but values are incorrect => KO
        with web_request(vid='list', subvid='foo') as req:
            self.assertEqual(vid_subvid_selector(None, req), 0)
        # expected parameters found and values are correct => OK
        with web_request(vid='list', subvid='tsearch') as req:
            self.assertEqual(vid_subvid_selector(None, req), 2)
Esempio n. 7
0
class ChangeStateFormView(form.FormViewMixIn, EntityView):
    __regid__ = 'statuschange'
    title = _('status change')
    __select__ = (one_line_rset()
                  & match_form_params('treid')
                  & adaptable('IWorkflowable'))

    def cell_call(self, row, col):
        entity = self.cw_rset.get_entity(row, col)
        transition = self._cw.entity_from_eid(self._cw.form['treid'])
        form = self.get_form(entity, transition)
        self.w(u'<h4>%s %s</h4>\n' %
               (self._cw._(transition.name), entity.view('oneline')))
        msg = self._cw._('status will change from %(st1)s to %(st2)s') % {
            'st1': entity.cw_adapt_to('IWorkflowable').printable_state,
            'st2': self._cw._(transition.destination(entity).name)
        }
        self.w(u'<p>%s</p>\n' % msg)
        form.render(w=self.w)

    def redirectpath(self, entity):
        return entity.rest_path()

    def get_form(self, entity, transition, **kwargs):
        # XXX used to specify both rset/row/col and entity in case implements
        # selector (and not is_instance) is used on custom form
        form = self._cw.vreg['forms'].select(
            'changestate',
            self._cw,
            entity=entity,
            transition=transition,
            redirect_path=self.redirectpath(entity),
            **kwargs)
        trinfo = self._cw.vreg['etypes'].etype_class('TrInfo')(self._cw)
        trinfo.eid = next(self._cw.varmaker)
        subform = self._cw.vreg['forms'].select('edition',
                                                self._cw,
                                                entity=trinfo,
                                                mainform=False)
        subform.field_by_name('wf_info_for', 'subject').value = entity.eid
        trfield = subform.field_by_name('by_transition', 'subject')
        trfield.widget = fwdgs.HiddenInput()
        trfield.value = transition.eid
        form.add_subform(subform)
        return form
Esempio n. 8
0
    def test_keyvalue_multiple_match(self):
        """test dict usage with multiple values

        i.e. as in ``match_form_params(param1=('value1', 'value2'))``

        ``param1`` must be specified in the request's form and its value
        must be either ``value1`` or ``value2``.
        """
        web_request = self.admin_access.web_request
        vid_subvid_selector = match_form_params(vid='list', subvid=('tsearch', 'listitem'))
        # expected parameters found and values correct => OK
        with web_request(vid='list', subvid='tsearch') as req:
            self.assertEqual(vid_subvid_selector(None, req), 2)
        with web_request(vid='list', subvid='listitem') as req:
            self.assertEqual(vid_subvid_selector(None, req), 2)
        # expected parameters found but values are incorrect => OK
        with web_request(vid='list', subvid='foo') as req:
            self.assertEqual(vid_subvid_selector(None, req), 0)
Esempio n. 9
0
    def test_keyvalue_match_one_parameter(self):
        """test dict usage: ``match_form_params(param1=value1)``

        ``param1`` must be specified in the request's form and its value
        must be ``value1``.
        """
        web_request = self.admin_access.web_request
        # test both positional and named parameters
        vid_selector = match_form_params(vid='foo')
        # no parameter => should fail
        with web_request() as req:
            self.assertEqual(vid_selector(None, req), 0)
        # expected parameter found with expected value => OK
        with web_request(vid='foo', subvid='bar') as req:
            self.assertEqual(vid_selector(None, req), 1)
        # expected parameter found but value is incorrect => KO
        with web_request(vid='bar') as req:
            self.assertEqual(vid_selector(None, req), 0)
Esempio n. 10
0
class UndoController(Controller):
    __regid__ = 'undo'
    __select__ = authenticated_user() & match_form_params('txuuid')

    def publish(self, rset=None):
        txuuid = self._cw.form['txuuid']
        try:
            self._cw.cnx.undo_transaction(txuuid)
        except UndoTransactionException as exc:
            errors = exc.errors
            #This will cause a rollback in main_publish
            raise ValidationError(None, {None: '\n'.join(errors)})
        else:
            self.redirect()  # Will raise Redirect

    def redirect(self, msg=None):
        req = self._cw
        msg = msg or req._("transaction undone")
        self._redirect({'_cwmsgid': req.set_redirect_message(msg)})
Esempio n. 11
0
class InlineHelpImageView(StartupView):
    __regid__ = 'wdocimages'
    __select__ = match_form_params('fid')
    binary = True
    templatable = False
    content_type = 'image/png'

    def call(self):
        fid = self._cw.form['fid']
        for lang in chain((self._cw.lang, self._cw.vreg.property_value('ui.language')),
                          self._cw.vreg.config.available_languages()):
            rid = join('images', '%s_%s.png' % (fid, lang))
            resourcedir = self._cw.vreg.config.locate_doc_file(rid)
            if resourcedir:
                break
        else:
            raise NotFound
        with io.open(join(resourcedir, rid)) as f:
            self.w(f.read())
Esempio n. 12
0
class UnrelatedDivs(EntityView):
    __regid__ = 'unrelateddivs'
    __select__ = match_form_params('relation')

    def cell_call(self, row, col):
        entity = self.cw_rset.get_entity(row, col)
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
        rschema = self._cw.vreg.schema.rschema(relname)
        hidden = 'hidden' in self._cw.form
        is_cell = 'is_cell' in self._cw.form
        self.w(
            self.build_unrelated_select_div(entity,
                                            rschema,
                                            role,
                                            is_cell=is_cell,
                                            hidden=hidden))

    def build_unrelated_select_div(self,
                                   entity,
                                   rschema,
                                   role,
                                   is_cell=False,
                                   hidden=True):
        options = []
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
        selectid = 'select%s_%s_%s' % (rschema.type, role, entity.eid)
        if rschema.symmetric or role == 'subject':
            targettypes = rschema.objects(entity.e_schema)
            etypes = '/'.join(
                sorted(etype.display_name(self._cw) for etype in targettypes))
        else:
            targettypes = rschema.subjects(entity.e_schema)
            etypes = '/'.join(
                sorted(etype.display_name(self._cw) for etype in targettypes))
        etypes = uilib.cut(
            etypes, self._cw.property_value('navigation.short-line-size'))
        options.append('<option>%s %s</option>' %
                       (self._cw._('select a'), etypes))
        options += self._get_select_options(entity, rschema, role)
        options += self._get_search_options(entity, rschema, role, targettypes)
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
        return u"""\
<div class="%s" id="%s">
  <select id="%s"
          onchange="javascript: addPendingInsert(this.options[this.selectedIndex], %s, %s, '%s');">
    %s
  </select>
</div>
""" % (hidden and 'hidden' or '', divid, selectid,
        xml_escape(json_dumps(entity.eid)), is_cell and 'true'
        or 'null', relname, '\n'.join(options))

    def _get_select_options(self, entity, rschema, role):
        """add options to search among all entities of each possible type"""
        options = []
        pending_inserts = get_pending_inserts(self._cw, entity.eid)
        rtype = rschema.type
        form = self._cw.vreg['forms'].select('edition',
                                             self._cw,
                                             entity=entity)
        field = form.field_by_name(rschema, role, entity.e_schema)
        limit = self._cw.property_value('navigation.combobox-limit')
        # NOTE: expect 'limit' arg on choices method of relation field
        for eview, reid in field.vocabulary(form, limit=limit):
            if reid is None:
                if eview:  # skip blank value
                    options.append(
                        '<option class="separator">-- %s --</option>' %
                        xml_escape(eview))
            elif reid != ff.INTERNAL_FIELD_VALUE:
                optionid = relation_id(entity.eid, rtype, role, reid)
                if optionid not in pending_inserts:
                    # prefix option's id with letters to make valid XHTML wise
                    options.append('<option id="id%s" value="%s">%s</option>' %
                                   (optionid, reid, xml_escape(eview)))
        return options

    def _get_search_options(self, entity, rschema, role, targettypes):
        """add options to search among all entities of each possible type"""
        options = []
        _ = self._cw._
        for eschema in targettypes:
            mode = '%s:%s:%s:%s' % (role, entity.eid, rschema.type, eschema)
            url = self._cw.build_url(entity.rest_path(),
                                     vid='search-associate',
                                     __mode=mode)
            options.append((eschema.display_name(self._cw),
                            '<option value="%s">%s %s</option>' %
                            (xml_escape(url), _('Search for'),
                             eschema.display_name(self._cw))))
        return [o for l, o in sorted(options)]
Esempio n. 13
0
class InlineHelpView(StartupView):
    __select__ = match_form_params('fid')
    __regid__ = 'wdoc'
    title = _('site documentation')

    def call(self):
        fid = self._cw.form['fid']
        vreg = self._cw.vreg
        for lang in chain((self._cw.lang, vreg.property_value('ui.language')),
                          vreg.config.available_languages()):
            rid = '%s_%s.rst' % (fid, lang)
            resourcedir = vreg.config.locate_doc_file(rid)
            if resourcedir:
                break
        else:
            raise NotFound
        self.tocindex = build_toc(vreg.config)
        try:
            node, parent = self.tocindex[fid]
        except KeyError:
            node, parent = None, None
        else:
            self.navigation_links(node, parent)
            self.w(u'<div class="hr"></div>')
            self.w(u'<h1>%s</h1>' % (title_for_lang(node, self._cw.lang)))
        with io.open(join(resourcedir, rid)) as f:
            self.w(rest_publish(self, f.read()))
        if node is not None:
            self.subsections_links(node)
            self.w(u'<div class="hr"></div>')
            self.navigation_links(node, parent)

    def navigation_links(self, node, parent):
        if parent is None:
            return
        brothers = subsections(parent)
        self.w(u'<div class="docnav">\n')
        previousidx = brothers.index(node) - 1
        if previousidx >= 0:
            self.navsection(brothers[previousidx], 'prev')
        self.navsection(parent, 'up')
        nextidx = brothers.index(node) + 1
        if nextidx < len(brothers):
            self.navsection(brothers[nextidx], 'next')
        self.w(u'</div>\n')

    navinfo = {'prev': ('', 'data/previous.png', _('i18nprevnext_previous')),
               'next': ('', 'data/next.png', _('i18nprevnext_next')),
               'up': ('', 'data/up.png', _('i18nprevnext_up'))}

    def navsection(self, node, navtype):
        htmlclass, imgpath, msgid = self.navinfo[navtype]
        self.w(u'<span class="%s">' % htmlclass)
        self.w(u'%s : ' % self._cw._(msgid))
        self.w(u'<a href="%s">%s</a>' % (
            self._cw.build_url('doc/' + node.attrib['resource']),
            title_for_lang(node, self._cw.lang)))
        self.w(u'</span>\n')

    def subsections_links(self, node, first=True):
        sub = subsections(node)
        if not sub:
            return
        if first:
            self.w(u'<div class="hr"></div>')
        self.w(u'<ul class="docsum">')
        for child in sub:
            self.w(u'<li><a href="%s">%s</a>' % (
                self._cw.build_url('doc/' + child.attrib['resource']),
                title_for_lang(child, self._cw.lang)))
            self.subsections_links(child, False)
            self.w(u'</li>')
        self.w(u'</ul>\n')