Ejemplo n.º 1
0
def _create_form(request):
    _ = request.getText
    url = request.page.url(request)
    ret = html.FORM(action=url)
    ret.append(
        html.INPUT(type='hidden', name='action', value='CreateNewAccount'))
    lang_attr = request.theme.ui_lang_attr()
    ret.append(html.Raw('<div class="userpref"%s>' % lang_attr))
    tbl = html.TABLE(border="0")
    ret.append(tbl)
    ret.append(html.Raw('</div>'))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(html.Text(_("Name")))))
    cell = html.TD()
    row.append(cell)
    cell.append(html.INPUT(type="text", size="36", name="name"))
    cell.append(html.Text(' ' + _("(Use FirstnameLastname)")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(html.Text(
        _("Password")))))
    row.append(html.TD().append(
        html.INPUT(type="password", size="36", name="password1")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(
        html.Text(_("Password repeat")))))
    row.append(html.TD().append(
        html.INPUT(type="password", size="36", name="password2")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(html.Text(_("Email")))))
    row.append(html.TD().append(
        html.INPUT(type="text", size="36", name="email")))

    textcha = TextCha(request)
    if textcha.is_enabled():
        row = html.TR()
        tbl.append(row)
        row.append(html.TD().append(html.STRONG().append(
            html.Text(_('TextCha (required)')))))
        td = html.TD()
        if textcha:
            td.append(textcha.render())
        row.append(td)

    row = html.TR()
    tbl.append(row)
    row.append(html.TD())
    td = html.TD()
    row.append(td)
    td.append(
        html.INPUT(type="submit", name="create", value=_('Create Profile')))

    return unicode(ret)
Ejemplo n.º 2
0
def _create_form(request):
    _ = request.getText
    url = request.page.url(request)
    ret = html.FORM(action=url)
    ret.append(html.INPUT(type='hidden', name='action', value='newaccount'))
    lang_attr = request.theme.ui_lang_attr()
    ret.append(html.Raw('<div class="userpref"%s>' % lang_attr))
    tbl = html.TABLE(border="0")
    ret.append(tbl)
    ret.append(html.Raw('</div>'))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(
                                  html.Text(_("Name")))))
    cell = html.TD()
    row.append(cell)
    cell.append(html.INPUT(type="text", size="36", name="name"))
    cell.append(html.Text(' ' + _("(Use FirstnameLastname)")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(
                                  html.Text(_("Password")))))
    row.append(html.TD().append(html.INPUT(type="password", size="36",
                                           name="password1")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(
                                  html.Text(_("Password repeat")))))
    row.append(html.TD().append(html.INPUT(type="password", size="36",
                                           name="password2")))

    row = html.TR()
    tbl.append(row)
    row.append(html.TD().append(html.STRONG().append(html.Text(_("Email")))))
    row.append(html.TD().append(html.INPUT(type="text", size="36",
                                           name="email")))

    textcha = TextCha(request)
    if textcha.is_enabled():
        row = html.TR()
        tbl.append(row)
        row.append(html.TD().append(html.STRONG().append(
                                      html.Text(_('TextCha (required)')))))
        td = html.TD()
        if textcha:
            td.append(textcha.render())
        row.append(td)

    row = html.TR()
    tbl.append(row)
    row.append(html.TD())
    td = html.TD()
    row.append(td)
    td.append(html.INPUT(type="submit", name="create",
                         value=_('Create Profile')))

    return unicode(ret)
Ejemplo n.º 3
0
 def test_amend_form(self):
     # textchas are disabled for 'some_locale'
     flaskg.user.profile[LOCALE] = 'some_locale'
     test_form = TextChaizedForm()
     test_form['textcha_question'].value = None
     textcha_obj = TextCha(test_form)
     # before calling amend_form
     assert not textcha_obj.form['textcha_question'].optional
     assert not textcha_obj.form['textcha'].optional
     # on calling amend_form
     textcha_obj.amend_form()
     assert textcha_obj.form['textcha_question'].optional
     assert textcha_obj.form['textcha'].optional
Ejemplo n.º 4
0
 def test_amend_form(self):
     # textchas are disabled for 'some_locale'
     flaskg.user.profile[LOCALE] = 'some_locale'
     test_form = TextChaizedForm()
     test_form['textcha_question'].value = None
     textcha_obj = TextCha(test_form)
     # before calling amend_form
     assert not textcha_obj.form['textcha_question'].optional
     assert not textcha_obj.form['textcha'].optional
     # on calling amend_form
     textcha_obj.amend_form()
     assert textcha_obj.form['textcha_question'].optional
     assert textcha_obj.form['textcha'].optional
Ejemplo n.º 5
0
    def do_action(self):
        """ copy this page to "pagename" """
        _ = self._
        # Currently we only check TextCha for upload (this is what spammers ususally do),
        # but it could be extended to more/all attachment write access
        if not TextCha(self.request).check_answer_from_form():
            return status, _('TextCha: Wrong answer! Go back and try again...')

        form = self.form
        newpagename = form.get('newpagename', u'')
        newpagename = wikiutil.normalize_pagename(newpagename, self.cfg)
        comment = form.get('comment', u'')
        comment = wikiutil.clean_input(comment)

        self.page = PageEditor(self.request, self.pagename)
        success, msgs = self.page.copyPage(newpagename, comment)

        copy_subpages = 0
        try:
            copy_subpages = int(form['copy_subpages'])
        except:
            pass

        if copy_subpages and self.subpages or (not self.users_subpages
                                               and self.subpages):
            for name in self.subpages:
                self.page = PageEditor(self.request, name)
                new_subpagename = name.replace(self.pagename, newpagename, 1)
                success_i, msg = self.page.copyPage(new_subpagename, comment)
                msgs = "%s %s" % (msgs, msg)

        self.newpagename = newpagename  # keep there for finish
        return success, msgs
Ejemplo n.º 6
0
Archivo: Load.py Proyecto: aahlad/soar
    def get_form_html(self, buttons_html):
        _ = self._
        return """
<h2>%(headline)s</h2>
<p>%(explanation)s</p>
<dl>
<dt>%(upload_label_file)s</dt>
<dd><input type="file" name="file" size="50" value=""></dd>
<dt>%(upload_label_rename)s</dt>
<dd><input type="text" name="rename" size="50" value="%(pagename)s"></dd>
<dt>%(upload_label_comment)s</dt>
<dd><input type="text" name="comment" size="80" maxlength="200"></dd>
</dl>
%(textcha)s
<p>
<input type="hidden" name="action" value="%(action_name)s">
<input type="hidden" name="do" value="upload">
</p>
<td class="buttons">
%(buttons_html)s
</td>""" % {
    'headline': _("Upload page content"),
    'explanation': _("You can upload content for the page named below. "
                     "If you change the page name, you can also upload content for another page. "
                     "If the page name is empty, we derive the page name from the file name."),
    'upload_label_file': _('File to load page content from'),
    'upload_label_comment': _('Comment'),
    'upload_label_rename': _('Page name'),
    'pagename': wikiutil.escape(self.pagename, quote=1),
    'buttons_html': buttons_html,
    'action_name': self.form_trigger,
    'textcha': TextCha(self.request).render(),
}
Ejemplo n.º 7
0
    def test_textcha(self):
        """ test for textchas and its attributes """
        test_form = TextChaizedForm()
        test_form['textcha_question'].value = None

        textcha_obj = TextCha(test_form)

        # test for textcha
        test_textchas = textcha_obj.textchas
        expected_textchas = {
            'Good Question': 'Good Answer',
            'What is the question?': 'Test_Answer',
        }
        assert test_textchas == expected_textchas
        # test for the question
        test_question = textcha_obj.question
        possible_questions = ['Good Question', 'What is the question?']
        assert test_question in possible_questions
        # test for answer_re
        possible_answers = ['Good Answer', 'Test_Answer']
        result_answer1 = textcha_obj.answer_re.match(
            expected_textchas[test_question])
        test_answer = result_answer1.group()
        assert test_answer in possible_answers
        # invalid value
        result_answer2 = textcha_obj.answer_re.match('Bad Answer')
        assert not result_answer2
        # test for answer_regex
        result_answer = textcha_obj.answer_regex
        assert result_answer in possible_answers

        # when question is specified earlier
        test_signature = 'fb5a8cc203b07b66637aafa7b0647da17e249e9c'
        test_form[
            'textcha_question'].value = 'What is the question? 9876543210' + test_signature
        textcha_obj = TextCha(test_form)
        # test for the question
        test_question = textcha_obj.question
        expected_question = 'What is the question?'
        assert test_question == expected_question
        # test the answer
        test_answer = textcha_obj.answer_regex
        assert test_answer == 'Test_Answer'
        assert test_signature == textcha_obj.signature
        assert textcha_obj.timestamp == 9876543210
Ejemplo n.º 8
0
def _create_user(request):
    _ = request.getText
    form = request.form

    if request.method != 'POST':
        return

    if not wikiutil.checkTicket(request, form.get('ticket', '')):
        return

    if not TextCha(request).check_answer_from_form():
        return _('TextCha: Wrong answer! Go back and try again...')

    # Create user profile
    theuser = user.User(request, auth_method="new-user")

    # Require non-empty name
    try:
        theuser.name = form['name']
    except KeyError:
        return _("Empty user name. Please enter a user name.")

    # Don't allow creating users with invalid names
    if not user.isValidName(request, theuser.name):
        return _("""Invalid user name {{{'%s'}}}.
Name may contain any Unicode alpha numeric character, with optional one
space between words. Group page name is not allowed.""",
                 wiki=True) % wikiutil.escape(theuser.name)

    # Name required to be unique. Check if name belong to another user.
    if user.getUserId(request, theuser.name):
        return _("This user name already belongs to somebody else.")

    # try to get the password and pw repeat
    password = form.get('password1', '')
    password2 = form.get('password2', '')

    # Check if password is given and matches with password repeat
    if password != password2:
        return _("Passwords don't match!")
    if not password:
        return _("Please specify a password!")

    pw_checker = request.cfg.password_checker
    if pw_checker:
        pw_error = pw_checker(request, theuser.name, password)
        if pw_error:
            return _("Password not acceptable: %s") % wikiutil.escape(pw_error)

    # Encode password
    if password and not password.startswith('{SHA}'):
        try:
            theuser.enc_password = user.encodePassword(password)
        except UnicodeError, err:
            # Should never happen
            return "Can't encode password: %s" % wikiutil.escape(str(err))
Ejemplo n.º 9
0
    def from_request(cls, request):
        """
        Construct an instance from :request.

        Since the mapping from HTTP form (unlike from an Item instance) to
        Flatland Form is straightforward, there should be rarely any need to
        override this class method.
        """
        form = cls.from_flat(request.form.items() + request.files.items())
        TextCha(form).amend_form()
        return form
Ejemplo n.º 10
0
    def from_item(cls, item):
        """
        Construct an instance from :item.

        This class method is not supposed to be overriden; subclasses should
        overrride the _load method instead.
        """
        form = cls.from_defaults()
        TextCha(form).amend_form()
        form._load(item)
        return form
Ejemplo n.º 11
0
    def _select_itemtype(self):
        """
        TODO: Here we bypass the code that allows a user to select an itemtype just before
        creating a new item:

            Default - Wiki item
            User profile - User profile item (not implemented yet!)
            Blog - Blog item
            Blog entry - Blog entry item
            Ticket - Ticket item

        Blogs and Tickets are broken, why User Profile is here is an undocumented mystery (it is
        probably no longer required).

        If you want to work on tickets or blogs, create a new branch and revert the change
        made on or about 2017-07-04:
        """
        # if this is a subitem, verify all parent items exist
        try:
            _verify_parents(self, self.name, self.meta[NAMESPACE])
        except MissingParentError as e:
            flash(str(e), "error")
            form = CreateItemForm().from_defaults()
            TextCha(form).amend_form()
            form['target'] = self.fqname.fullname
            return render_template(
                'create_new_item.html',
                fqname=self.fqname,
                form=form,
            )

        return render_template(
            'modify_select_contenttype.html',
            fqname=self.fqname,
            item_name=self.name,
            itemtype='default',  # create a normal wiki item
            group_names=content_registry.group_names,
            groups=content_registry.groups,
        )
        # dead code, see above
        return render_template(
            'modify_select_itemtype.html',
            item=self,
            item_name=self.name,
            fqname=self.fqname,
            itemtypes=item_registry.shown_entries,
        )
Ejemplo n.º 12
0
Archivo: Load.py Proyecto: aahlad/soar
    def do_action(self):
        """ Load """
        status = False
        _ = self._
        form = self.form
        request = self.request
        # Currently we only check TextCha for upload (this is what spammers ususally do),
        # but it could be extended to more/all attachment write access
        if not TextCha(request).check_answer_from_form():
            return status, _('TextCha: Wrong answer! Go back and try again...')

        comment = form.get('comment', u'')
        comment = wikiutil.clean_input(comment)

        file_upload = request.files.get('file')
        if not file_upload:
            # This might happen when trying to upload file names
            # with non-ascii characters on Safari.
            return False, _("No file content. Delete non ASCII characters from the file name and try again.")

        filename = file_upload.filename
        rename = form.get('rename', '').strip()
        if rename:
            target = rename
        else:
            target = filename

        target = wikiutil.clean_input(target)

        if target:
            filecontent = file_upload.stream.read() # XXX reads complete file into memory!
            filecontent = wikiutil.decodeUnknownInput(filecontent)

            self.pagename = target
            pg = PageEditor(request, self.pagename)
            try:
                msg = pg.saveText(filecontent, 0, comment=comment)
                status = True
            except pg.EditConflict, e:
                msg = e.message
            except pg.SaveError, msg:
                msg = unicode(msg)
Ejemplo n.º 13
0
    def sendEditor(self, **kw):
        """ Send the editor form page.

        @keyword preview: if given, show this text in preview mode
        @keyword staytop: don't go to #preview
        @keyword comment: comment field (when preview is true)
        """
        from MoinMoin import i18n
        from MoinMoin.action import SpellCheck

        request = self.request
        form = request.form
        _ = self._

        raw_body = ''
        msg = None
        conflict_msg = None
        edit_lock_message = None
        preview = kw.get('preview', None)
        staytop = kw.get('staytop', 0)

        # check edit permissions
        if not request.user.may.write(self.page_name):
            msg = _('You are not allowed to edit this page.')
        elif not self.isWritable():
            msg = _('Page is immutable!')
        elif self.rev:
            # Trying to edit an old version, this is not possible via
            # the web interface, but catch it just in case...
            msg = _('Cannot edit old revisions!')
        else:
            # try to acquire edit lock
            ok, edit_lock_message = self.lock.acquire()
            if not ok:
                # failed to get the lock
                if preview is not None:
                    edit_lock_message = _('The lock you held timed out. Be prepared for editing conflicts!'
                        ) + "<br>" + edit_lock_message
                else:
                    msg = edit_lock_message

        # Did one of the prechecks fail?
        if msg:
            request.theme.add_msg(msg, "error")
            self.send_page()
            return

        # Emit http_headers after checks (send_page)
        request.disableHttpCaching(level=2)

        # check if we want to load a draft
        use_draft = None
        if 'button_load_draft' in form:
            wanted_draft_timestamp = int(form.get('draft_ts', '0'))
            if wanted_draft_timestamp:
                draft = self._load_draft()
                if draft is not None:
                    draft_timestamp, draft_rev, draft_text = draft
                    if draft_timestamp == wanted_draft_timestamp:
                        use_draft = draft_text

        # Check for draft / normal / preview submit
        if use_draft is not None:
            title = _('Draft of "%(pagename)s"')
            # Propagate original revision
            rev = int(form['draft_rev'])
            self.set_raw_body(use_draft, modified=1)
            preview = use_draft
        elif preview is None:
            title = _('Edit "%(pagename)s"')
        else:
            title = _('Preview of "%(pagename)s"')
            # Propagate original revision
            rev = request.rev
            self.set_raw_body(preview, modified=1)

        # send header stuff
        lock_timeout = self.lock.timeout / 60
        lock_page = wikiutil.escape(self.page_name, quote=1)
        lock_expire = _("Your edit lock on %(lock_page)s has expired!") % {'lock_page': lock_page}
        lock_mins = _("Your edit lock on %(lock_page)s will expire in # minutes.") % {'lock_page': lock_page}
        lock_secs = _("Your edit lock on %(lock_page)s will expire in # seconds.") % {'lock_page': lock_page}

        # get request parameters
        try:
            text_rows = int(form['rows'])
        except StandardError:
            text_rows = self.cfg.edit_rows
            if request.user.valid:
                text_rows = int(request.user.edit_rows)

        if preview is not None:
            # Check for editing conflicts
            if not self.exists():
                # page does not exist, are we creating it?
                if rev:
                    conflict_msg = _('Someone else deleted this page while you were editing!')
            elif rev != self.current_rev():
                conflict_msg = _('Someone else changed this page while you were editing!')
                if self.mergeEditConflict(rev):
                    conflict_msg = _("""Someone else saved this page while you were editing!
Please review the page and save then. Do not save this page as it is!""")
                    rev = self.current_rev()
            if conflict_msg:
                # We don't show preview when in conflict
                preview = None

        elif self.exists():
            # revision of existing page
            rev = self.current_rev()
        else:
            # page creation
            rev = 0

        self.setConflict(bool(conflict_msg))

        # Page editing is done using user language
        request.setContentLanguage(request.lang)

        # Get the text body for the editor field.
        # TODO: what about deleted pages? show the text of the last revision or use the template?
        if preview is not None:
            raw_body = self.get_raw_body()
            if use_draft:
                request.write(_("[Content loaded from draft]"), '<br>')
        elif self.exists():
            # If the page exists, we get the text from the page.
            # TODO: maybe warn if template argument was ignored because the page exists?
            raw_body = self.get_raw_body()
        elif 'template' in request.values:
            # If the page does not exist, we try to get the content from the template parameter.
            template_page = wikiutil.unquoteWikiname(request.values['template'])
            template_page_escaped = wikiutil.escape(template_page)
            if request.user.may.read(template_page):
                raw_body = Page(request, template_page).get_raw_body()
                if raw_body:
                    request.write(_("[Content of new page loaded from %s]") % (template_page_escaped, ), '<br>')
                else:
                    request.write(_("[Template %s not found]") % (template_page_escaped, ), '<br>')
            else:
                request.write(_("[You may not read %s]") % (template_page_escaped, ), '<br>')

        # Make backup on previews - but not for new empty pages
        if not use_draft and preview and raw_body:
            self._save_draft(raw_body, rev)

        draft_message = None
        loadable_draft = False
        if preview is None:
            draft = self._load_draft()
            if draft is not None:
                draft_timestamp, draft_rev, draft_text = draft
                if draft_text != raw_body:
                    loadable_draft = True
                    page_rev = rev
                    draft_timestamp_str = request.user.getFormattedDateTime(draft_timestamp)
                    draft_message = _(u"'''<<BR>>Your draft based on revision %(draft_rev)d (saved %(draft_timestamp_str)s) can be loaded instead of the current revision %(page_rev)d by using the load draft button - in case you lost your last edit somehow without saving it.''' A draft gets saved for you when you do a preview, cancel an edit or unsuccessfully save.", wiki=True, percent=True) % locals()

        # Setup status message
        status = [kw.get('msg', ''), conflict_msg, edit_lock_message, draft_message]
        status = [msg for msg in status if msg]
        status = ' '.join(status)
        status = Status(request, content=status)

        request.theme.add_msg(status, "error")
        request.theme.send_title(
            title % {'pagename': self.split_title(), },
            page=self,
            html_head=self.lock.locktype and (
                PageEditor._countdown_js % {
                     'countdown_script': request.theme.externalScript('countdown'),
                     'lock_timeout': lock_timeout,
                     'lock_expire': lock_expire,
                     'lock_mins': lock_mins,
                     'lock_secs': lock_secs,
                    }) or '',
            editor_mode=1,
            allow_doubleclick=1,
        )

        request.write(request.formatter.startContent("content"))

        # Generate default content for new pages
        if not raw_body:
            raw_body = _('Describe %s here.') % (self.page_name, )

        # send form
        request.write('<form id="editor" method="post" action="%s#preview">' % (
                request.href(self.page_name)
            ))

        # yet another weird workaround for broken IE6 (it expands the text
        # editor area to the right after you begin to type...). IE sucks...
        # http://fplanque.net/2003/Articles/iecsstextarea/
        request.write('<fieldset style="border:none;padding:0;">')

        request.write(unicode(html.INPUT(type="hidden", name="action", value="edit")))

        # Send revision of the page our edit is based on
        request.write('<input type="hidden" name="rev" value="%d">' % (rev, ))

        # Add src format (e.g. 'wiki') into a hidden form field, so that
        # we can load the correct converter after POSTing.
        request.write('<input type="hidden" name="format" value="%s">' % self.pi['format'])

        # Create and send a ticket, so we can check the POST
        request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(request))

        # Save backto in a hidden input
        backto = request.values.get('backto')
        if backto:
            request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))

        # button bar
        button_spellcheck = '<input class="button" type="submit" name="button_spellcheck" value="%s">' % _('Check Spelling')

        save_button_text = _('Save Changes')
        cancel_button_text = _('Cancel')

        if self.cfg.page_license_enabled:
            request.write('<p><em>', _(
"""By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s.
If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""", wiki=True) % {
                'save_button_text': save_button_text,
                'cancel_button_text': cancel_button_text,
                'license_link': wikiutil.getLocalizedPage(request, self.cfg.page_license_page).link_to(request),
            }, '</em></p>')

        request.write('''
<input class="button" type="submit" name="button_save" value="%s">
<input class="button" type="submit" name="button_preview" value="%s">
<input class="button" type="submit" name="button_switch" value="%s">
''' % (save_button_text, _('Preview'), _('Text mode'), ))

        if loadable_draft:
            request.write('''
<input class="button" type="submit" name="button_load_draft" value="%s" onClick="flgChange = false;">
<input type="hidden" name="draft_ts" value="%d">
<input type="hidden" name="draft_rev" value="%d">
''' % (_('Load Draft'), draft_timestamp, draft_rev))

        request.write('''
%s
<input class="button" type="submit" name="button_cancel" value="%s">
<input type="hidden" name="editor" value="gui">
''' % (button_spellcheck, cancel_button_text, ))
        if self.cfg.mail_enabled:
            request.write('''
<script type="text/javascript">
    function toggle_trivial(CheckedBox)
    {
        TrivialBoxes = document.getElementsByName("trivial");
        for (var i = 0; i < TrivialBoxes.length; i++)
            TrivialBoxes[i].checked = CheckedBox.checked;
    }
</script>
&nbsp;
<input type="checkbox" name="trivial" id="chktrivialtop" value="1" %(checked)s onclick="toggle_trivial(this)">
<label for="chktrivialtop">%(label)s</label>
''' % {
          'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
          'label': _("Trivial change"),
       })

        from MoinMoin.security.textcha import TextCha
        request.write(TextCha(request).render())

        self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor

        # Add textarea with page text
        lang = self.pi.get('language', request.cfg.language_default)
        contentlangdirection = i18n.getDirection(lang) # 'ltr' or 'rtl'
        uilanguage = request.lang
        url_prefix_static = request.cfg.url_prefix_static
        url_prefix_local = request.cfg.url_prefix_local
        wikipage = wikiutil.quoteWikinameURL(self.page_name)
        fckbasepath = request.cfg.url_prefix_fckeditor
        wikiurl = request.script_root + '/'
        themepath = '%s/%s' % (url_prefix_static, request.theme.name)
        smileypath = themepath + '/img'
        # auto-generating a list for SmileyImages does NOT work from here!
        text_rows = int(request.user.edit_rows)
        if not text_rows:
            # if no specific value is given for editor height, but 0, we
            # compute the rows from the raw_body line count plus some
            # extra rows for adding new text in the editor. Maybe this helps
            # with the "double slider" usability issue, esp. for devices like
            # the iphone where you can't operate both sliders.
            current_rows = len(raw_body.split('\n'))
            text_rows = max(10, int(current_rows * 1.5))
        editor_size = text_rows * 22 # 22 height_pixels/line
        word_rule = self.word_rule()

        request.write("""
<script type="text/javascript" src="%(fckbasepath)s/fckeditor.js"></script>
<script type="text/javascript">
<!--
    var oFCKeditor = new FCKeditor( 'savetext', '100%%', %(editor_size)s, 'MoinDefault' ) ;
    oFCKeditor.BasePath= '%(fckbasepath)s/' ;
    oFCKeditor.Config['WikiBasePath'] = '%(wikiurl)s' ;
    oFCKeditor.Config['WikiPage'] = '%(wikipage)s' ;
    oFCKeditor.Config['PluginsPath'] = '%(url_prefix_local)s/applets/moinFCKplugins/' ;
    oFCKeditor.Config['CustomConfigurationsPath'] = '%(url_prefix_local)s/applets/moinfckconfig.js'  ;
    oFCKeditor.Config['WordRule'] = %(word_rule)s ;
    oFCKeditor.Config['SmileyPath'] = '%(smileypath)s/' ;
    oFCKeditor.Config['EditorAreaCSS'] = '%(themepath)s/css/common.css' ;
    oFCKeditor.Config['SkinPath'] = '%(fckbasepath)s/editor/skins/silver/' ;
    oFCKeditor.Config['AutoDetectLanguage'] = false ;
    oFCKeditor.Config['DefaultLanguage'] = '%(uilanguage)s' ;
    oFCKeditor.Config['ContentLangDirection']  = '%(contentlangdirection)s' ;
    oFCKeditor.Value= """ % locals())

        from MoinMoin.formatter.text_gedit import Formatter
        self.formatter = Formatter(request)
        self.formatter.page = self
        output = request.redirectedOutput(self.send_page_content, request, raw_body, format=self.pi['format'], do_cache=False)
        output = repr(output)
        if output[0] == 'u':
            output = output[1:]
        request.write(output)
        request.write(""" ;
    oFCKeditor.Create() ;
//-->
</script>
""")
        request.write("<p>")
        request.write(_("Comment:"),
            ' <input id="editor-comment" type="text" name="comment" value="%s" size="80" maxlength="200">' % (
                wikiutil.escape(kw.get('comment', ''), 1), ))
        request.write("</p>")

        # Category selection
        filterfn = self.cfg.cache.page_category_regexact.search
        cat_pages = request.rootpage.getPageList(filter=filterfn)
        cat_pages.sort()
        cat_pages = [wikiutil.pagelinkmarkup(p) for p in cat_pages]
        cat_pages.insert(0, ('', _('<No addition>')))
        request.write("<p>")
        request.write(_('Add to: %(category)s') % {
            'category': unicode(web.makeSelection('category', cat_pages)),
        })
        if self.cfg.mail_enabled:
            request.write('''
&nbsp;
<input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s onclick="toggle_trivial(this)">
<label for="chktrivial">%(label)s</label> ''' % {
                'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
                'label': _("Trivial change"),
                })

        request.write('''
&nbsp;
<input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
<label for="chkrstrip">%(label)s</label>
</p> ''' % {
            'checked': ('', 'checked')[form.get('rstrip', '0') == '1'],
            'label': _('Remove trailing whitespace from each line')
            })

        request.write("</p>")

        badwords_re = None
        if preview is not None:
            if 'button_spellcheck' in form or 'button_newwords' in form:
                badwords, badwords_re, msg = SpellCheck.checkSpelling(self, request, own_form=0)
                request.write("<p>%s</p>" % msg)
        request.write('</fieldset>')
        request.write("</form>")

        if preview is not None:
            if staytop:
                content_id = 'previewbelow'
            else:
                content_id = 'preview'
            self.send_page(content_id=content_id, content_only=1, hilite_re=badwords_re)

        request.write(request.formatter.endContent()) # end content div
        request.theme.send_footer(self.page_name)
        request.theme.send_closing_html()
Ejemplo n.º 14
0
def execute(pagename, request):
    """ edit a page """
    _ = request.getText

    if 'button_preview' in request.form and 'button_spellcheck' in request.form:
        # multiple buttons pressed at once? must be some spammer/bot
        check_surge_protect(request, kick=True)  # get rid of him
        return

    if not request.user.may.write(pagename):
        page = wikiutil.getLocalizedPage(request, 'PermissionDeniedPage')
        page.body = _('You are not allowed to edit this page.')
        page.page_name = pagename
        page.send_page(send_special=True)
        return

    valideditors = [
        'text',
        'gui',
    ]
    editor = ''
    if request.user.valid:
        editor = request.user.editor_default
    if editor not in valideditors:
        editor = request.cfg.editor_default

    editorparam = request.values.get('editor', editor)
    if editorparam == "guipossible":
        lasteditor = editor
    elif editorparam == "textonly":
        editor = lasteditor = 'text'
    else:
        editor = lasteditor = editorparam

    if request.cfg.editor_force:
        editor = request.cfg.editor_default

    # if it is still nothing valid, we just use the text editor
    if editor not in valideditors:
        editor = 'text'

    rev = request.rev or 0
    savetext = request.form.get('savetext')
    comment = request.form.get('comment', u'')
    category = request.form.get('category')
    rstrip = int(request.form.get('rstrip', '0'))
    trivial = int(request.form.get('trivial', '0'))
    ideastatus = int(request.form.get('ideastatus', '0'))

    if 'button_switch' in request.form:
        if editor == 'text':
            editor = 'gui'
        else:  # 'gui'
            editor = 'text'

    # load right editor class
    if editor == 'gui':
        from MoinMoin.PageGraphicalEditor import PageGraphicalEditor
        pg = PageGraphicalEditor(request, pagename)
    else:  # 'text'
        from MoinMoin.PageEditor import PageEditor
        pg = PageEditor(request, pagename)

    # is invoked without savetext start editing
    if savetext is None or 'button_load_draft' in request.form:
        pg.sendEditor()
        return

    # did user hit cancel button?
    cancelled = 'button_cancel' in request.form

    from MoinMoin.error import ConvertError
    try:
        if lasteditor == 'gui':
            # convert input from Graphical editor
            format = request.form.get('format', 'wiki')
            if format == 'wiki':
                converter_name = 'text_html_text_moin_wiki'
            else:
                converter_name = 'undefined'  # XXX we don't have other converters yet
            convert = wikiutil.importPlugin(request.cfg, "converter",
                                            converter_name, 'convert')
            savetext = convert(request, pagename, savetext)

        # IMPORTANT: normalize text from the form. This should be done in
        # one place before we manipulate the text.
        savetext = pg.normalizeText(savetext, stripspaces=rstrip)
    except ConvertError:
        # we don't want to throw an exception if user cancelled anyway
        if not cancelled:
            raise

    if cancelled:
        pg.sendCancel(savetext or "", rev)
        pagedir = pg.getPagePath(check_create=0)
        import os
        if not os.listdir(pagedir):
            os.removedirs(pagedir)
        return

    comment = wikiutil.clean_input(comment)

    # Add category

    # TODO: this code does not work with extended links, and is doing
    # things behind your back, and in general not needed. Either we have
    # a full interface for categories (add, delete) or just add them by
    # markup.

    if category and category != _('<No addition>'):  # opera 8.5 needs this
        # strip trailing whitespace
        savetext = savetext.rstrip()

        # Add category separator if last non-empty line contains
        # non-categories.
        lines = [line for line in savetext.splitlines() if line]
        if lines:

            #TODO: this code is broken, will not work for extended links
            #categories, e.g ["category hebrew"]
            categories = lines[-1].split()

            if categories:
                confirmed = wikiutil.filterCategoryPages(request, categories)
                if len(confirmed) < len(categories):
                    # This was not a categories line, add separator
                    savetext += u'\n----\n'

        # Add new category
        if savetext and savetext[-1] != u'\n':
            savetext += ' '
        savetext += category + u'\n'  # Should end with newline!

    if (request.cfg.edit_ticketing and
            not wikiutil.checkTicket(request, request.form.get('ticket', ''))):
        request.theme.add_msg(
            _('Please use the interactive user interface to use action %(actionname)s!'
              ) % {'actionname': 'edit'}, "error")
        pg.sendEditor(preview=savetext, comment=comment, staytop=1)

    # Preview, spellcheck or spellcheck add new words
    elif ('button_preview' in request.form
          or 'button_spellcheck' in request.form
          or 'button_newwords' in request.form):
        pg.sendEditor(preview=savetext, comment=comment)

    # Preview with mode switch
    elif 'button_switch' in request.form:
        pg.sendEditor(preview=savetext, comment=comment, staytop=1)

    # Save new text
    else:
        try:
            from MoinMoin.security.textcha import TextCha
            if not TextCha(request).check_answer_from_form():
                raise pg.SaveError(
                    _('TextCha: Wrong answer! Try again below...'))
            if request.cfg.comment_required and not comment:
                raise pg.SaveError(
                    _('Supplying a comment is mandatory.  Write a comment below and try again...'
                      ))
            savemsg = pg.saveText(savetext,
                                  rev,
                                  trivial=trivial,
                                  comment=comment)
        except pg.EditConflict, e:
            msg = e.message

            # Handle conflict and send editor
            pg.set_raw_body(savetext, modified=1)

            pg.mergeEditConflict(rev)
            # We don't send preview when we do merge conflict
            pg.sendEditor(msg=msg, comment=comment)
            return

        except pg.SaveError, msg:
            # Show the error message
            request.theme.add_msg(unicode(msg), "error")
            # And show the editor again
            pg.sendEditor(preview=savetext, comment=comment, staytop=1)
            return
Ejemplo n.º 15
0
    def get_form_html(self, buttons_html):
        _ = self._
        if self.users_subpages:
            subpages = ' '.join(
                [wikiutil.escape(page) for page in self.users_subpages])

            d = {
                'textcha':
                TextCha(self.request).render(),
                'subpage':
                subpages,
                'subpages_checked':
                ('', 'checked'
                 )[self.request.args.get('subpages_checked', '0') == '1'],
                'subpage_label':
                _('Copy all /subpages too?'),
                'pagename':
                wikiutil.escape(self.pagename, True),
                'newname_label':
                _("New name"),
                'comment_label':
                _("Optional reason for the copying"),
                'buttons_html':
                buttons_html,
                'querytext':
                _('Really copy this page?')
            }

            return '''
<strong>%(querytext)s</strong>
<br>
<br>
%(textcha)s
<table>
    <tr>
    <dd>
        %(subpage_label)s<input type="checkbox" name="copy_subpages" value="1" %(subpages_checked)s>
    </dd>
    <dd>
        <class="label"><subpage> %(subpage)s</subpage>
    </dd>
    </tr>
</table>
<table>
    <tr>
        <td class="label"><label>%(newname_label)s</label></td>
        <td class="content">
            <input type="text" name="newpagename" value="%(pagename)s" size="80">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(comment_label)s</label></td>
        <td class="content">
            <input type="text" name="comment" size="80" maxlength="200">
        </td>
    </tr>
    <tr>
        <td></td>
        <td class="buttons">
            %(buttons_html)s
        </td>
    </tr>
</table>
''' % d

        else:
            d = {
                'textcha': TextCha(self.request).render(),
                'pagename': wikiutil.escape(self.pagename, True),
                'newname_label': _("New name"),
                'comment_label': _("Optional reason for the copying"),
                'buttons_html': buttons_html,
            }
            return '''
%(textcha)s
<table>
    <tr>
        <td class="label"><label>%(newname_label)s</label></td>
        <td class="content">
            <input type="text" name="newpagename" value="%(pagename)s" size="80">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(comment_label)s</label></td>
        <td class="content">
            <input type="text" name="comment" size="80" maxlength="200">
        </td>
    </tr>
    <tr>
        <td></td>
        <td class="buttons">
            %(buttons_html)s
        </td>
    </tr>
</table>
''' % d
Ejemplo n.º 16
0
def send_uploadform(pagename, request):
    """ Send the HTML code for the list of already stored attachments and
        the file upload form.
    """
    _ = request.getText

    if not request.user.may.read(pagename):
        request.write('<p>%s</p>' %
                      _('You are not allowed to view this page.'))
        return

    writeable = request.user.may.write(pagename)

    # First send out the upload new attachment form on top of everything else.
    # This avoids usability issues if you have to scroll down a lot to upload
    # a new file when the page already has lots of attachments:
    if writeable:
        request.write('<h2>' + _("New Attachment") + '</h2>')
        request.write(
            """
<form action="%(url)s" method="POST" enctype="multipart/form-data">
<dl>
<dt>%(upload_label_file)s</dt>
<dd><input type="file" name="file" size="50"></dd>
<dt>%(upload_label_target)s</dt>
<dd><input type="text" name="target" size="50" value="%(target)s"></dd>
<dt>%(upload_label_overwrite)s</dt>
<dd><input type="checkbox" name="overwrite" value="1" %(overwrite_checked)s></dd>
</dl>
%(textcha)s
<p>
<input type="hidden" name="action" value="%(action_name)s">
<input type="hidden" name="do" value="upload">
<input type="hidden" name="ticket" value="%(ticket)s">
<input type="submit" value="%(upload_button)s">
</p>
</form>
""" % {
                'url':
                request.href(pagename),
                'action_name':
                action_name,
                'upload_label_file':
                _('File to upload'),
                'upload_label_target':
                _('Rename to'),
                'target':
                wikiutil.escape(request.values.get('target', ''), 1),
                'upload_label_overwrite':
                _('Overwrite existing attachment of same name'),
                'overwrite_checked':
                ('', 'checked')[request.form.get('overwrite', '0') == '1'],
                'upload_button':
                _('Upload'),
                'textcha':
                TextCha(request).render(),
                'ticket':
                wikiutil.createTicket(request),
            })

    request.write('<h2>' + _("Attached Files") + '</h2>')
    request.write(_get_filelist(request, pagename))

    if not writeable:
        request.write('<p>%s</p>' %
                      _('You are not allowed to attach a file to this page.'))
Ejemplo n.º 17
0
def _do_upload(pagename, request):
    _ = request.getText

    if not wikiutil.checkTicket(request, request.form.get('ticket', '')):
        return _(
            'Please use the interactive user interface to use action %(actionname)s!'
        ) % {
            'actionname': 'AttachFile.upload'
        }

    # Currently we only check TextCha for upload (this is what spammers ususally do),
    # but it could be extended to more/all attachment write access
    if not TextCha(request).check_answer_from_form():
        return _('TextCha: Wrong answer! Go back and try again...')

    form = request.form

    file_upload = request.files.get('file')
    if not file_upload:
        # This might happen when trying to upload file names
        # with non-ascii characters on Safari.
        return _(
            "No file content. Delete non ASCII characters from the file name and try again."
        )

    try:
        overwrite = int(form.get('overwrite', '0'))
    except:
        overwrite = 0

    if not request.user.may.write(pagename):
        return _('You are not allowed to attach a file to this page.')

    if overwrite and not request.user.may.delete(pagename):
        return _(
            'You are not allowed to overwrite a file attachment of this page.')

    target = form.get('target', u'').strip()
    if not target:
        target = file_upload.filename or u''

    target = wikiutil.clean_input(target)

    if not target:
        return _("Filename of attachment not specified!")

    # add the attachment
    try:
        target, bytes = add_attachment(request,
                                       pagename,
                                       target,
                                       file_upload.stream,
                                       overwrite=overwrite)
        msg = _("Attachment '%(target)s' (remote name '%(filename)s')"
                " with %(bytes)d bytes saved.") % {
                    'target': target,
                    'filename': file_upload.filename,
                    'bytes': bytes
                }
    except AttachmentAlreadyExists:
        msg = _(
            "Attachment '%(target)s' (remote name '%(filename)s') already exists."
        ) % {
            'target': target,
            'filename': file_upload.filename
        }

    # return attachment list
    upload_form(pagename, request, msg)