def create_form(self): """ Create the complete HTML form code. """ _ = self._ form = self.make_form( html.Text( _('As a superuser, you can temporarily ' 'assume the identity of another user.'))) ticket = wikiutil.createTicket(self.request) self.make_row(_('Select User'), [self._user_select()], valign="top") form.append( html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) if not self._only: buttons = [ html.INPUT(type="submit", name="select_user", value=_('Select User')), ' ', ] else: buttons = [] buttons.append( html.INPUT(type="submit", name="cancel", value=_('Cancel'))) self.make_row('', buttons) return unicode(form)
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='recoverpass')) 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( _("Username"))))) row.append(html.TD().append(html.INPUT(type="text", size="36", name="name"))) 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"))) row = html.TR() tbl.append(row) row.append(html.TD()) td = html.TD() row.append(td) td.append( html.INPUT(type="submit", name="account_sendmail", value=_('Mail me my account data'))) return unicode(ret)
def _get_account_name(self, request, form, msg=None): # now we need to ask the user for a new username # that they want to use on this wiki # XXX: request nickname from OP and suggest using it # (if it isn't in use yet) logging.debug("running _get_account_name") _ = request.getText form.append(html.INPUT(type='hidden', name='oidstage', value='2')) table = html.TABLE(border='0') form.append(table) td = html.TD(colspan=2) td.append( html.Raw( _("""Please choose an account name now. If you choose an existing account name you will be asked for the password and be able to associate the account with your OpenID."""))) table.append(html.TR().append(td)) if msg: td = html.TD(colspan='2') td.append(html.P().append(html.STRONG().append(html.Raw(msg)))) table.append(html.TR().append(td)) td1 = html.TD() td1.append(html.STRONG().append(html.Raw(_('Name')))) td2 = html.TD() td2.append(html.INPUT(type='text', name='username')) table.append(html.TR().append(td1).append(td2)) td1 = html.TD() td2 = html.TD() td2.append( html.INPUT(type='submit', name='submit', value=_('Choose this name'))) table.append(html.TR().append(td1).append(td2))
def _associate_account(self, request, form, accountname, msg=None): _ = request.getText form.append(html.INPUT(type='hidden', name='oidstage', value='3')) table = html.TABLE(border='0') form.append(table) td = html.TD(colspan=2) td.append( html.Raw( _("""The username you have chosen is already taken. If it is your username, enter your password below to associate the username with your OpenID. Otherwise, please choose a different username and leave the password field blank."""))) table.append(html.TR().append(td)) if msg: td.append(html.P().append(html.STRONG().append(html.Raw(msg)))) td1 = html.TD() td1.append(html.STRONG().append(html.Raw(_('Name')))) td2 = html.TD() td2.append(html.INPUT(type='text', name='username', value=accountname)) table.append(html.TR().append(td1).append(td2)) td1 = html.TD() td1.append(html.STRONG().append(html.Raw(_('Password')))) td2 = html.TD() td2.append(html.INPUT(type='password', name='password')) table.append(html.TR().append(td1).append(td2)) td1 = html.TD() td2 = html.TD() td2.append( html.INPUT(type='submit', name='submit', value=_('Associate this name'))) table.append(html.TR().append(td1).append(td2))
def create_form(self, create_only=False, recover_only=False): """ Create the complete HTML form code. """ _ = self._ form = self.make_form( html.Text( _("To change your password, " "enter a new password twice."))) self.make_row(_('Password'), [html.INPUT(type="password", size=36, name="password1")]) self.make_row(_('Password repeat'), [html.INPUT(type="password", size=36, name="password2")]) ticket = wikiutil.createTicket(self.request) form.append( html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) # Add buttons self.make_row('', [ html.INPUT(type="submit", name='save', value=_("Change password")), ' ', html.INPUT(type="submit", name='cancel', value=_("Cancel")), ]) return unicode(form)
def _sorry_no_identity(self): request = self.request _ = self._ request.theme.send_title(_("OpenID not served"), pagename=request.page.page_name) # Start content (important for RTL support) request.write(request.formatter.startContent("content")) request.write(request.formatter.paragraph(1)) request.write(_(''' Unfortunately you have not created your homepage yet. Therefore, we cannot serve an OpenID for you. Please create your homepage first and then reload this page or click the button below to cancel this verification.''')) request.write(request.formatter.paragraph(0)) form = html.FORM(method='POST', action=request.page.url(request)) form.append(html.INPUT(type='hidden', name='action', value='serveopenid')) nonce = randomString(32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') form.append(html.INPUT(type='hidden', name='nonce', value=nonce)) request.session['openidserver.nonce'] = nonce form.append(html.INPUT(type='submit', name='dontapprove', value=_("Cancel"))) request.write(unicode(form)) request.write(request.formatter.endContent()) request.theme.send_footer(request.page.page_name) request.theme.send_closing_html()
def handle_multistage(self): """Handle a multistage request. If the auth handler wants a multistage request, we now set up the login form for that. """ _ = self._ request = self.request form = html.FORM(method='POST', name='logincontinue', action=self.pagename) form.append(html.INPUT(type='hidden', name='action', value='login')) form.append(html.INPUT(type='hidden', name='login', value='1')) form.append( html.INPUT(type='hidden', name='stage', value=request._login_multistage_name)) request.theme.send_title(_("Login"), pagename=self.pagename) # Start content (important for RTL support) request.write(request.formatter.startContent("content")) extra = request._login_multistage(request, form) request.write(unicode(form)) if extra: request.write(extra) request.write(request.formatter.endContent()) request.theme.send_footer(self.pagename) request.theme.send_closing_html()
def make_form(self, explanation=None): ''' To have a consistent UI, use this method for most preferences forms and then call make_row(). See existing plugins, e.g. changepass.py. ''' action = self.request.page.url(self.request) _form = html.FORM(action=action) _form.append(html.INPUT(type="hidden", name="action", value="userprefs")) _form.append(html.INPUT(type="hidden", name="handler", value=self.name)) self._table = html.TABLE(border="0") # Use the user interface language and direction lang_attr = self.request.theme.ui_lang_attr() _form.append(html.Raw('<div class="userpref"%s>' % lang_attr)) para = html.P() _form.append(para) if explanation: para.append(explanation) para.append(self._table) _form.append(html.Raw("</div>")) return _form
def _make_form(self): action = "%s%s" % (self.request.script_root, self.request.path) _form = html.FORM(action=action) _form.append(html.INPUT(type="hidden", name="action", value="userprefs")) _form.append(html.INPUT(type="hidden", name="handler", value="oid")) ticket = wikiutil.createTicket(self.request) _form.append(html.INPUT(type="hidden", name="ticket", value=ticket)) return _form
def _make_form(self): action = "%s%s" % (self.request.script_root, self.request.path) _form = html.FORM(action=action) _form.append( html.INPUT(type="hidden", name="action", value="userprefs")) _form.append(html.INPUT(type="hidden", name="handler", value="oidserv")) return _form
def _addoidform(self): _ = self.request.getText form = self._make_form() # go back to this page form.append(html.INPUT(type="hidden", name="sub", value="oid")) label = _("Add OpenID") form.append(html.INPUT(type="text", size="32", name="openid_identifier", id="openididentifier")) form.append(html.BR()) form.append(html.INPUT(type="submit", name="add", value=label)) self._make_row(_('Add OpenID'), [form])
def _oidlist(self): _ = self.request.getText form = self._make_form() for oid in self.request.user.openids: name = "rm-%s" % hash_new('sha1', oid).hexdigest() form.append(html.INPUT(type="checkbox", name=name, id=name)) form.append(html.LABEL(for_=name).append(html.Text(oid))) form.append(html.BR()) self._make_row(_("Current OpenIDs"), [form], valign='top') label = _("Remove selected") form.append(html.BR()) form.append(html.INPUT(type="submit", name="remove", value=label))
def _trust_root_list(self): _ = self.request.getText form = self._make_form() for root in self.request.user.openid_trusted_roots: display = base64.decodestring(root) name = 'rm-%s' % root form.append(html.INPUT(type="checkbox", name=name, id=name)) form.append(html.LABEL(for_=name).append(html.Text(display))) form.append(html.BR()) self._make_row(_("Trusted websites"), [form], valign='top') label = _("Remove selected") form.append(html.BR()) form.append(html.INPUT(type="submit", name="remove", value=label))
def create_form(self, create_only=False, recover_only=False): r = self.request ss = self.cfg.session_service format_time = lambda x: self.request.user.getFormattedDateTime( x) if x else x form = self.make_form(html.Text("Active sessions for your account")) ticket = wikiutil.createTicket(self.request) form.append( html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) self._table.append(html.TR().extend([ html.TD().extend([""]), html.TD().extend([html.B().append("From IP")]), html.TD().extend([html.B().append("Login Date")]), html.TD().extend([html.B().append("Expiration")]), html.TD().extend([html.B().append("User Agent")]), ])) for sid in ss.get_all_session_ids(r): session = ss.get_session(r, sid) if session.get("user.id") != r.user.id: continue self._table.append(html.TR().extend([ html.TD().extend( [html.INPUT(type="checkbox", name="session.%s" % sid)]), html.TD().extend([session.get("from_ip")]), html.TD().extend([format_time(session.get("started"))]), html.TD().extend([format_time(session.get("expires"))]), html.TD().extend([session.get("from_ua")]), ])) form.append( unicode( html.INPUT(type="submit", name='save', value="Delete Sessions"))) form.append( unicode(html.INPUT(type="submit", name='cancel', value="Cancel"))) #form.append(repr(r.in_headers)) return unicode(form)
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)
def _event_select(self): """ Create event subscription list. """ _ = self._ types = [] if self.cfg.mail_enabled and self.request.user.email: types.append(('email', _("'''Email'''", wiki=True))) if self.cfg.jabber_enabled and self.request.user.jid: types.append(('jabber', _("'''Jabber'''", wiki=True))) table = html.TABLE() header = html.TR() table.append(header) for name, descr in types: header.append(html.TH().append(html.Raw(descr))) header.append( html.TH(align='left').append( html.Raw(_("'''Event type'''", wiki=True)))) event_list = events.get_subscribable_events() super = self.request.user.isSuperUser() # Create a list of (value, name) tuples for display as radiobuttons # Only include super-user visible events if current user has these rights. # It's cosmetic - the check for super-user rights should be performed # in event handling code as well! allowed = [] for key in event_list.keys(): if not event_list[key]['superuser'] or super: allowed.append((key, event_list[key]['desc'])) for evname, evdescr in allowed: tr = html.TR() table.append(tr) for notiftype, notifdescr in types: checked = evname in getattr(self.request.user, '%s_subscribed_events' % notiftype) tr.append(html.TD().append( html.INPUT(type='checkbox', checked=checked, name='subscribe:%s:%s' % (notiftype, evname)))) tr.append(html.TD().append(html.Raw( self.request.getText(evdescr)))) return table
def _create_token_form(request, name=None, token=None): _ = request.getText url = request.page.url(request) ret = html.FORM(action=url) ret.append(html.INPUT(type='hidden', name='action', value='recoverpass')) 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(_("Recovery token"))))) value = token or '' row.append(html.TD().append( html.INPUT(type='text', size="36", name="token", value=value))) row = html.TR() tbl.append(row) row.append(html.TD().append(html.STRONG().append(html.Text( _("Username"))))) value = name or '' row.append(html.TD().append( html.INPUT(type='text', size="36", name="name", value=value))) row = html.TR() tbl.append(row) row.append(html.TD().append(html.STRONG().append( html.Text(_("New password"))))) row.append(html.TD().append( html.INPUT(type="password", size="36", name="password"))) row = html.TR() tbl.append(row) row.append(html.TD().append(html.STRONG().append( html.Text(_("New password (repeat)"))))) row.append(html.TD().append( html.INPUT(type="password", size="36", name="password_repeat"))) row = html.TR() tbl.append(row) row.append(html.TD()) td = html.TD() row.append(td) td.append( html.INPUT(type="submit", name="recover", value=_('Reset my password'))) return unicode(ret)
def create_form(self): """ Create the complete HTML form code. """ _ = self._ self._form = self.make_form( _('Select the events you want to be notified about.')) self._form.append( html.INPUT(type="hidden", name="action", value="userprefs")) self._form.append( html.INPUT(type="hidden", name="handler", value="prefs")) ticket = wikiutil.createTicket(self.request) self._form.append( html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) if (not (self.cfg.mail_enabled and self.request.user.email) and not (self.cfg.jabber_enabled and self.request.user.jid)): self.make_row('', [ html.Text( _("Before you can be notified, you need to provide a way" " to contact you in the general preferences.")) ]) self.make_row( '', [html.INPUT(type="submit", name="cancel", value=_("Cancel"))]) return unicode(self._form) self.make_row(_('Subscribed events'), [self._event_select()]) # Get list of subscribe pages, DO NOT sort! it should # stay in the order the user entered it in his input # box. notifylist = self.request.user.getSubscriptionList() self.make_row(html.Raw( _('Subscribed wiki pages<<BR>>(one regex per line)', wiki=True)), [ html.TEXTAREA(name="subscribed_pages", rows="6", cols="50").append('\n'.join(notifylist)), ], valign="top") # Add buttons self.make_row('', [ html.INPUT(type="submit", name="save", value=_("Save")), ' ', html.INPUT(type="submit", name="cancel", value=_("Cancel")) ]) return unicode(self._form)
def create_form(self): """ Create the complete HTML form code. """ _ = self._ ret = html.P() # Use the user interface language and direction lang_attr = self.request.theme.ui_lang_attr() ret.append(html.Raw('<div %s>' % lang_attr)) self._table = html.TABLE(border="0") ret.append(self._table) ret.append(html.Raw("</div>")) request = self.request if hasattr(request.user, 'openid_trusted_roots') and request.user.openid_trusted_roots: self._trust_root_list() form = self._make_form() label = _("Cancel") form.append(html.INPUT(type="submit", name='cancel', value=label)) self._make_row('', [form]) return unicode(ret)
def create_form(self): """ Create the complete HTML form code. """ _ = self._ ret = html.P() # Use the user interface language and direction lang_attr = self.request.theme.ui_lang_attr() ret.append(html.Raw('<div %s>' % lang_attr)) self._table = html.TABLE(border="0") ret.append(self._table) ret.append(html.Raw("</div>")) request = self.request if 'openid.prefs.form_html' in request.session: txt = _('OpenID verification requires that you click this button:') # create JS to automatically submit the form if possible submitjs = """<script type="text/javascript"> <!--// document.getElementById("openid_message").submit(); //--> </script> """ oidhtml = request.session['openid.prefs.form_html'] del request.session['openid.prefs.form_html'] return ''.join([txt, oidhtml, submitjs]) if hasattr(request.user, 'openids') and request.user.openids: self._oidlist() self._addoidform() form = self._make_form() label = _("Cancel") form.append(html.INPUT(type="submit", name='cancel', value=label)) self._make_row('', [form]) return unicode(ret)
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> <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(''' <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(''' <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()
def do_user_browser(request): """ Browser for SystemAdmin macro. """ _ = request.getText groups = request.groups data = TupleDataset() data.columns = [ Column('name', label=_('Username')), Column('groups', label=_('Member of Groups')), Column('email', label=_('Email')), Column('jabber', label=_('Jabber')), Column('action', label=_('Action')), ] class UserAccount(object): # namedtuple is >= 2.6 :-( def __init__(self, **kw): for k, v in kw.items(): setattr(self, k, v) def __repr__(self): return "<UserAccount %r>" % self.__dict__ accounts = [] for uid in user.getUserList(request): # be careful and just create a list of what we really need, # not sure if we can keep lots of User objects instantiated # in parallel (open files? too big?) u = user.User(request, uid) accounts.append(UserAccount(name=u.name, email=u.email, jid=u.jid, disabled=u.disabled)) def sortkey(account): # enabled accounts at top, sorted by name return (account.disabled, account.name) # Iterate over user accounts for account in sorted(accounts, key=sortkey): account_groups = set(groups.groups_with_member(account.name)) wiki_groups = set([group for group in account_groups if isinstance(groups[group], WikiGroup)]) other_groups = list(account_groups - wiki_groups) # First show groups that are defined in wikipages linking to it # after show groups from other backends. grouppage_links = ', '.join([Page(request, group_name).link_to(request) for group_name in wiki_groups] + other_groups) userhomepage = Page(request, account.name) if userhomepage.exists(): namelink = userhomepage.link_to(request) else: namelink = wikiutil.escape(account.name) # creates the POST data for account disable/enable val = "1" text=_('Disable user') if account.disabled: text=_('Enable user') val = "0" namelink += " (%s)" % _("disabled") url = request.page.url(request) ret = html.FORM(action=url) ret.append(html.INPUT(type='hidden', name='action', value='userprofile')) ticket = wikiutil.createTicket(request, action='userprofile') ret.append(html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) ret.append(html.INPUT(type='hidden', name='name', value=account.name)) ret.append(html.INPUT(type='hidden', name='key', value="disabled")) ret.append(html.INPUT(type='hidden', name='val', value=val)) ret.append(html.INPUT(type='submit', name='userprofile', value=text)) enable_disable_link = unicode(unicode(ret)) # creates the POST data for recoverpass url = request.page.url(request) ret = html.FORM(action=url) ret.append(html.INPUT(type='hidden', name='action', value='recoverpass')) ret.append(html.INPUT(type='hidden', name='email', value=account.email)) ret.append(html.INPUT(type='hidden', name='account_sendmail', value="1")) ret.append(html.INPUT(type='hidden', name='sysadm', value="users")) ret.append(html.INPUT(type='submit', name='recoverpass', value=_('Mail account data'))) recoverpass_link = unicode(unicode(ret)) if account.email: email_link = (request.formatter.url(1, 'mailto:' + account.email, css='mailto') + request.formatter.text(account.email) + request.formatter.url(0)) else: email_link = '' if account.jid: jabber_link = (request.formatter.url(1, 'xmpp:' + account.jid, css='mailto') + request.formatter.text(account.jid) + request.formatter.url(0)) else: jabber_link = '' data.addRow(( (request.formatter.rawHTML(namelink), account.name), request.formatter.rawHTML(grouppage_links), email_link, jabber_link, recoverpass_link + enable_disable_link )) if data: from MoinMoin.widget.browser import DataBrowserWidget browser = DataBrowserWidget(request) browser.setData(data) return browser.render() # No data return ''
def show_decide_page(self, identity, username, openidreq): request = self.request _ = self._ if not request.user.valid or username != request.user.name: request.makeForbidden(403, _('''You need to manually go to your OpenID provider wiki and log in before you can use your OpenID. MoinMoin will never allow you to enter your password here. Once you have logged in, simply reload this page.''')) return request.theme.send_title(_("OpenID Trust verification"), pagename=request.page.page_name) # Start content (important for RTL support) request.write(request.formatter.startContent("content")) request.write(request.formatter.paragraph(1)) request.write(_('The site %s has asked for your identity.') % openidreq.trust_root) request.write(request.formatter.paragraph(0)) request.write(request.formatter.paragraph(1)) request.write(_(''' If you approve, the site represented by the trust root below will be told that you control the identity URL %s. (If you are using a delegated identity, the site will take care of reversing the delegation on its own.)''') % openidreq.identity) request.write(request.formatter.paragraph(0)) form = html.FORM(method='POST', action=request.page.url(request)) form.append(html.INPUT(type='hidden', name='action', value='serveopenid')) form.append(html.INPUT(type='hidden', name='openid.identity', value=openidreq.identity)) form.append(html.INPUT(type='hidden', name='openid.return_to', value=openidreq.return_to)) form.append(html.INPUT(type='hidden', name='openid.trust_root', value=openidreq.trust_root)) form.append(html.INPUT(type='hidden', name='openid.mode', value=openidreq.mode)) form.append(html.INPUT(type='hidden', name='name', value=username)) nonce = randomString(32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') form.append(html.INPUT(type='hidden', name='nonce', value=nonce)) request.session['openidserver.nonce'] = nonce table = html.TABLE() form.append(table) tr = html.TR() table.append(tr) tr.append(html.TD().append(html.STRONG().append(html.Text(_('Trust root'))))) tr.append(html.TD().append(html.Text(openidreq.trust_root))) tr = html.TR() table.append(tr) tr.append(html.TD().append(html.STRONG().append(html.Text(_('Identity URL'))))) tr.append(html.TD().append(html.Text(identity))) tr = html.TR() table.append(tr) tr.append(html.TD().append(html.STRONG().append(html.Text(_('Name'))))) tr.append(html.TD().append(html.Text(username))) tr = html.TR() table.append(tr) tr.append(html.TD().append(html.STRONG().append(html.Text(_('Remember decision'))))) td = html.TD() tr.append(td) td.append(html.INPUT(type='checkbox', name='remember', value='yes')) td.append(html.Text(_('Remember this trust decision and don\'t ask again'))) tr = html.TR() table.append(tr) tr.append(html.TD()) td = html.TD() tr.append(td) td.append(html.INPUT(type='submit', name='approve', value=_("Approve"))) td.append(html.INPUT(type='submit', name='dontapprove', value=_("Don't approve"))) request.write(unicode(form)) request.write(request.formatter.endContent()) request.theme.send_footer(request.page.page_name) request.theme.send_closing_html()
def do_user_browser(request): """ Browser for SystemAdmin macro. """ _ = request.getText groups = request.groups data = TupleDataset() data.columns = [ Column('name', label=_('Username')), Column('groups', label=_('Member of Groups')), Column('email', label=_('Email')), Column('jabber', label=_('Jabber')), Column('action', label=_('Action')), ] # Iterate over users for uid in user.getUserList(request): account = user.User(request, uid) account_groups = set(groups.groups_with_member(account.name)) wiki_groups = set([group for group in account_groups if isinstance(groups[group], WikiGroup)]) other_groups = list(account_groups - wiki_groups) # First show groups that are defined in wikipages linking to it # after show groups from other backends. grouppage_links = ', '.join([Page(request, group_name).link_to(request) for group_name in wiki_groups] + other_groups) userhomepage = Page(request, account.name) if userhomepage.exists(): namelink = userhomepage.link_to(request) else: namelink = wikiutil.escape(account.name) # creates the POST data for account disable/enable val = "1" text=_('Disable user') if account.disabled: text=_('Enable user') val = "0" namelink += " (%s)" % _("disabled") url = request.page.url(request) ret = html.FORM(action=url) ret.append(html.INPUT(type='hidden', name='action', value='userprofile')) ticket = wikiutil.createTicket(request, action='userprofile') ret.append(html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) ret.append(html.INPUT(type='hidden', name='name', value=account.name)) ret.append(html.INPUT(type='hidden', name='key', value="disabled")) ret.append(html.INPUT(type='hidden', name='val', value=val)) ret.append(html.INPUT(type='submit', name='userprofile', value=text)) enable_disable_link = unicode(unicode(ret)) # creates the POST data for recoverpass url = request.page.url(request) ret = html.FORM(action=url) ret.append(html.INPUT(type='hidden', name='action', value='recoverpass')) ret.append(html.INPUT(type='hidden', name='email', value=account.email)) ret.append(html.INPUT(type='hidden', name='account_sendmail', value="1")) ret.append(html.INPUT(type='hidden', name='sysadm', value="users")) ret.append(html.INPUT(type='submit', name='recoverpass', value=_('Mail account data'))) recoverpass_link = unicode(unicode(ret)) if account.email: email_link = (request.formatter.url(1, 'mailto:' + account.email, css='mailto') + request.formatter.text(account.email) + request.formatter.url(0)) else: email_link = '' if account.jid: jabber_link = (request.formatter.url(1, 'xmpp:' + account.jid, css='mailto') + request.formatter.text(account.jid) + request.formatter.url(0)) else: jabber_link = '' data.addRow(( (request.formatter.rawHTML(namelink), account.name), request.formatter.rawHTML(grouppage_links), email_link, jabber_link, recoverpass_link + enable_disable_link )) if data: from MoinMoin.widget.browser import DataBrowserWidget browser = DataBrowserWidget(request) browser.setData(data, sort_columns=[0]) return browser.render() # No data return ''
def asHTML(self): """ Create the complete HTML form code. """ _ = self._ request = self.request action = "%s%s" % (request.script_root, request.path) hints = [] for authm in request.cfg.auth: hint = authm.login_hint(request) if hint: hints.append(hint) self._form = html.FORM(action=action, name="loginform", id="loginform") self._table = html.TABLE(border="0") # Use the user interface language and direction lang_attr = request.theme.ui_lang_attr() self._form.append(html.Raw('<div class="userpref"%s>' % lang_attr)) self._form.append( html.INPUT(type="hidden", name="action", value="login")) self._form.append(self._table) for hint in hints: self._form.append(html.P().append(html.Raw(hint))) self._form.append(html.Raw("</div>")) cfg = request.cfg if 'username' in cfg.auth_login_inputs: self.make_row(_('Name'), [ html.INPUT( type="text", size="32", name="name", ), ]) if 'password' in cfg.auth_login_inputs: self.make_row(_('Password'), [ html.INPUT( type="password", size="32", name="password", ), ]) # Restrict type of input available for OpenID input # based on wiki configuration. if 'openid_identifier' in cfg.auth_login_inputs: if len(cfg.openidrp_allowed_op) == 1: self.make_row(_('OpenID'), [ html.INPUT(type="hidden", name="openid_identifier", value=cfg.openidrp_allowed_op[0]), ]) elif len(cfg.openidrp_allowed_op) > 1: op_select = html.SELECT(name="openid_identifier", id="openididentifier") for op_uri in cfg.openidrp_allowed_op: op_select.append( html.OPTION(value=op_uri).append(html.Raw(op_uri))) self.make_row(_('OpenID'), [ op_select, ]) else: self.make_row(_('OpenID'), [ html.INPUT(type="text", size="32", name="openid_identifier", id="openididentifier"), ]) # Need both hidden field and submit values for auto-submit to work self.make_row('', [ html.INPUT(type="hidden", name="login", value=_('Login')), html.INPUT(type="submit", name='login', value=_('Login')), ]) # Automatically submit the form if only a single OpenID Provider is allowed if 'openid_identifier' in cfg.auth_login_inputs and len( cfg.openidrp_allowed_op) == 1: self._form.append("""<script type="text/javascript"> <!--// document.getElementById("loginform").submit(); //--> </script> """) return unicode(self._form)
def advanced_ui(macro): """ Returns the code for the advanced search user interface @param macro: current macro instance """ _ = macro._ f = macro.formatter request = macro.request disabledIfMoinSearch = not request.cfg.xapian_search and \ ' disabled="disabled"' or '' search_boxes = ''.join([ f.table_row(1), f.table_cell(1, attrs={ 'rowspan': '5', 'class': 'searchfor' }), f.text(_('Search for items')), f.table_cell(0), ''.join([ ''.join([ f.table_row(1), f.table_cell(1), f.text(txt), f.table_cell(0), f.table_cell(1), f.rawHTML(input_field), f.table_cell(0), f.table_row(0), ]) for txt, input_field in ( (_('containing all the following terms'), '<input type="text" name="and_terms" size="30" value="%s">' % (form_get(request, 'and_terms', escaped=True) or form_get(request, 'value', escaped=True))), (_('containing one or more of the following terms'), '<input type="text" name="or_terms" size="30" value="%s">' % form_get(request, 'or_terms', escaped=True)), (_('not containing the following terms'), '<input type="text" name="not_terms" size="30" value="%s">' % form_get(request, 'not_terms', escaped=True)), #('containing only one of the following terms', # '<input type="text" name="xor_terms" size="30" value="%s">' # % form_get(request, 'xor_terms', escaped=True)), # TODO: dropdown-box? (_('last modified since (e.g. 2 weeks before)'), '<input type="text" name="mtime" size="30" value="%s">' % form_get(request, 'mtime', escaped=True)), ) ]) ]) # category selection categories = form_get(request, 'categories') c_select = makeSelection('categories', [('', _('any category'))] + [(cat, '%s' % cat) for cat in getCategories(request)], categories, 3, True) # language selection searchedlang = form_get(request, 'language') langs = dict([(lang, lmeta['x-language-in-english']) for lang, lmeta in languages.items()]) userlang = macro.request.lang lang_select = makeSelection('language', [('', _('any language')), (userlang, langs[userlang])] + sorted(langs.items(), key=lambda i: i[1]), searchedlang, 3, True) # mimetype selection # mimetypes.types_map has non-ascii encoded bytestrings sometimes! coding = sys.getdefaultencoding( ) # same call used by stdlib mimetypes.py on win32 if coding == 'ascii': # we might get 'ascii' coding = 'utf-8' # but we upgrade to utf-8, which is sometimes used for /etc/mime.types decode = lambda s: s.decode(coding, 'replace' ) # use 'replace' -> never crash mimetype = form_get(request, 'mimetype') mt_select = makeSelection( 'mimetype', [('', _('any mimetype'))] + [(type, 'all %s files' % type) for type in getMimetypes()] + [(decode(m[1]), '*%s - %s' % (decode(m[0]), decode(m[1]))) for m in sorted(mimetypes.types_map.items())], mimetype, 3, True) # misc search options (checkboxes) search_options = ''.join([ ''.join([ f.table_row(1), f.table_cell(1, attrs={'class': 'searchfor'}), txt[0], f.table_cell(0), f.table_cell(1, colspan=2), unicode(txt[1]), txt[2], f.table_cell(0), f.table_row(0), ]) for txt in ((_('Categories'), unicode(c_select), ''), (_('Language'), unicode(lang_select), ''), (_('File Type'), unicode(mt_select), ''), ('', html.INPUT(type='checkbox', name='titlesearch', value='1', checked=form_get(request, 'titlesearch', escaped=True), id='titlesearch'), '<label for="titlesearch">%s</label>' % _('Search only in titles')), ('', html.INPUT(type='checkbox', name='case', value='1', checked=form_get(request, 'case', escaped=True), id='case'), '<label for="case">%s</label>' % _('Case-sensitive search')), ('', html.INPUT(type='checkbox', name='excludeunderlay', value='1', checked=form_get(request, 'excludeunderlay', escaped=True), id='excludeunderlay'), '<label for="excludeunderlay">%s</label>' % _('Exclude underlay')), ('', html.INPUT(type='checkbox', name='nosystemitems', value='1', checked=form_get(request, 'nosystemitems', escaped=True), id='nosystempages'), '<label for="nosystempages">%s</label>' % _('No system items')), ('', html.INPUT(type='checkbox', name='historysearch', value='1', checked=form_get(request, 'historysearch', escaped=True), disabled=(not request.cfg.xapian_search or not request.cfg.xapian_index_history), id='historysearch'), '<label for="historysearch">%s</label>' % _('Search in all page revisions'))) ]) # the dialogue return f.rawHTML('\n'.join([ u'<form method="get" action="%s">' % macro.request.href(macro.request.formatter.page.page_name), u'<div>', u'<input type="hidden" name="action" value="fullsearch">', u'<input type="hidden" name="advancedsearch" value="1">', f.table(1, attrs={'tableclass': 'advancedsearch'}), search_boxes, search_options, f.table_row(1), f.table_cell(1, attrs={ 'class': 'submit', 'colspan': '3' }), u'<input type="submit" value="%s">' % _('Go get it!'), f.table_cell(0), f.table_row(0), f.table(0), u'</div>', u'</form>', ]))
def create_form(self): """ Create the complete HTML form code. """ _ = self._ request = self.request self._form = self.make_form() if request.user.valid: buttons = [('save', _('Save')), ('cancel', _('Cancel')), ] uf_remove = self.cfg.user_form_remove uf_disable = self.cfg.user_form_disable for attr in request.user.auth_attribs: uf_disable.append(attr) for key, label, type, length, textafter in self.cfg.user_form_fields: default = self.cfg.user_form_defaults[key] if not key in uf_remove: if key in uf_disable: self.make_row(_(label), [html.INPUT(type=type, size=length, name=key, disabled="disabled", value=getattr(request.user, key)), ' ', _(textafter), ]) else: self.make_row(_(label), [html.INPUT(type=type, size=length, name=key, value=getattr(request.user, key)), ' ', _(textafter), ]) if not self.cfg.theme_force and not "theme_name" in self.cfg.user_form_remove: self.make_row(_('Preferred theme'), [self._theme_select()]) if not self.cfg.editor_force: if not "editor_default" in self.cfg.user_form_remove: self.make_row(_('Editor Preference'), [self._editor_default_select()]) if not "editor_ui" in self.cfg.user_form_remove: self.make_row(_('Editor shown on UI'), [self._editor_ui_select()]) if not "tz_offset" in self.cfg.user_form_remove: self.make_row(_('Time zone'), [ _('Your time is'), ' ', self._tz_select(), html.BR(), _('Server time is'), ' ', time.strftime(self.cfg.datetime_fmt, util.timefuncs.tmtuple()), ' (UTC)', ]) if not "datetime_fmt" in self.cfg.user_form_remove: self.make_row(_('Date format'), [self._dtfmt_select()]) if not "language" in self.cfg.user_form_remove: self.make_row(_('Preferred language'), [self._lang_select()]) # boolean user options bool_options = [] checkbox_fields = self.cfg.user_checkbox_fields checkbox_fields.sort(lambda a, b: cmp(a[1](_), b[1](_))) for key, label in checkbox_fields: if not key in self.cfg.user_checkbox_remove: bool_options.extend([ html.INPUT(type="checkbox", name=key, value="1", checked=getattr(request.user, key, 0), disabled=key in self.cfg.user_checkbox_disable and True or None), ' ', label(_), html.BR(), ]) self.make_row(_('General options'), bool_options, valign="top") self.make_row(_('Quick links'), [ html.TEXTAREA(name="quicklinks", rows="6", cols="50") .append('\n'.join(request.user.getQuickLinks())), ], valign="top") self._form.append(html.INPUT(type="hidden", name="action", value="userprefs")) self._form.append(html.INPUT(type="hidden", name="handler", value="prefs")) ticket = wikiutil.createTicket(request) self._form.append(html.INPUT(type="hidden", name="ticket", value="%s" % ticket)) # Add buttons button_cell = [] for name, label in buttons: if not name in self.cfg.user_form_remove: button_cell.extend([ html.INPUT(type="submit", name=name, value=label), ' ', ]) self.make_row('', button_cell) return unicode(self._form)
def history(page, pagename, request): # show history as default _ = request.getText default_count, limit_max_count = request.cfg.history_count[0:2] paging = request.cfg.history_paging try: max_count = int(request.values.get('max_count', default_count)) except ValueError: max_count = default_count max_count = max(1, min(max_count, limit_max_count)) # read in the complete log of this page log = editlog.EditLog(request, rootpagename=pagename) offset = 0 paging_info_html = "" paging_nav_html = "" count_select_html = "" f = request.formatter if paging: log_size = log.lines() try: offset = int(request.values.get('offset', 0)) except ValueError: offset = 0 offset = max(min(offset, log_size - 1), 0) paging_info_html += f.paragraph(1, css_class="searchstats info-paging-info") + _("Showing page edit history entries from '''%(start_offset)d''' to '''%(end_offset)d''' out of '''%(total_count)d''' entries total.", wiki=True) % { 'start_offset': log_size - min(log_size, offset + max_count) + 1, 'end_offset': log_size - offset, 'total_count': log_size, } + f.paragraph(0) # generating offset navigating links if max_count < log_size or offset != 0: offset_links = [] cur_offset = max_count near_count = 5 # request.cfg.pagination_size min_offset = max(0, (offset + max_count - 1) / max_count - near_count) max_offset = min((log_size - 1) / max_count, offset / max_count + near_count) offset_added = False def add_offset_link(offset, caption=None): offset_links.append(f.table_cell(1, css_class="info-offset-item") + page.link_to(request, on=1, querystr={ 'action': 'info', 'offset': str(offset), 'max_count': str(max_count), }, css_class="info-offset-nav-link", rel="nofollow") + f.text(caption or str(log_size - offset)) + page.link_to(request, on=0) + f.table_cell(0) ) # link to previous page - only if not at start if offset > 0: add_offset_link(((offset - 1) / max_count) * max_count, _("Newer")) # link to beggining of event log - if min_offset is not minimal if min_offset > 0: add_offset_link(0) # adding gap only if min_offset not explicitly following beginning if min_offset > 1: offset_links.append(f.table_cell(1, css_class="info-offset-gap") + f.text(u'\u2026') + f.table_cell(0)) # generating near pages links for cur_offset in range(min_offset, max_offset + 1): # note that current offset may be not multiple of max_count, # so we check whether we should add current offset marker like this if not offset_added and offset <= cur_offset * max_count: # current info history view offset offset_links.append(f.table_cell(1, css_class="info-offset-item info-cur-offset") + f.text(str(log_size - offset)) + f.table_cell(0)) offset_added = True # add link, if not at this offset if offset != cur_offset * max_count: add_offset_link(cur_offset * max_count) # link to the last page of event log if max_offset < (log_size - 1) / max_count: if max_offset < (log_size - 1) / max_count - 1: offset_links.append(f.table_cell(1, css_class="info-offset-gap") + f.text(u'\u2026') + f.table_cell(0)) add_offset_link(((log_size - 1) / max_count) * max_count) # special case - if offset is greater than max_offset * max_count if offset > max_offset * max_count: offset_links.append(f.table_cell(1, css_class="info-offset-item info-cur-offset") + f.text(str(log_size - offset)) + f.table_cell(0)) # link to next page if offset < (log_size - max_count): add_offset_link(((offset + max_count) / max_count) * max_count, _("Older")) # generating html paging_nav_html += "".join([ f.table(1, css_class="searchpages"), f.table_row(1), "".join(offset_links), f.table_row(0), f.table(0), ]) # generating max_count switcher # we do it only in case history_count has additional values if len(request.cfg.history_count) > 2: max_count_possibilities = list(set(request.cfg.history_count)) max_count_possibilities.sort() max_count_html = [] cur_count_added = False for count in max_count_possibilities: # max count value can be not in list of predefined values if max_count <= count and not cur_count_added: max_count_html.append("".join([ f.span(1, css_class="info-count-item info-cur-count"), f.text(str(max_count)), f.span(0), ])) cur_count_added = True # checking for limit_max_count to prevent showing unavailable options if max_count != count and count <= limit_max_count: max_count_html.append("".join([ f.span(1, css_class="info-count-item"), page.link_to(request, on=1, querystr={ 'action': 'info', 'offset': str(offset), 'max_count': str(count), }, css_class="info-count-link", rel="nofollow"), f.text(str(count)), page.link_to(request, on=0), f.span(0), ])) count_select_html += "".join([ f.span(1, css_class="info-count-selector"), f.text(" ("), f.text(_("%s items per page")) % (f.span(1, css_class="info-count-selector info-count-selector-divider") + f.text(" | ") + f.span(0)).join(max_count_html), f.text(")"), f.span(0), ]) # open log for this page from MoinMoin.util.dataset import TupleDataset, Column history = TupleDataset() history.columns = [ Column('rev', label='#', align='right'), Column('mtime', label=_('Date'), align='right'), Column('size', label=_('Size'), align='right'), Column('diff', label='<input type="submit" value="%s">' % (_("Diff"))), Column('editor', label=_('Editor'), hidden=not request.cfg.show_names), Column('comment', label=_('Comment')), Column('action', label=_('Action')), ] # generate history list def render_action(text, query, **kw): kw.update(dict(rel='nofollow')) return page.link_to(request, text, querystr=query, **kw) def render_file_action(text, pagename, filename, request, do): url = AttachFile.getAttachUrl(pagename, filename, request, do=do) if url: f = request.formatter link = f.url(1, url) + f.text(text) + f.url(0) return link may_write = request.user.may.write(pagename) may_delete = request.user.may.delete(pagename) count = 0 pgactioncount = 0 for line in log.reverse(): count += 1 if paging and count <= offset: continue rev = int(line.rev) actions = [] if line.action in ('SAVE', 'SAVENEW', 'SAVE/REVERT', 'SAVE/RENAME', ): size = page.size(rev=rev) actions.append(render_action(_('view'), {'action': 'recall', 'rev': '%d' % rev})) if pgactioncount == 0: rchecked = ' checked="checked"' lchecked = '' elif pgactioncount == 1: lchecked = ' checked="checked"' rchecked = '' else: lchecked = rchecked = '' diff = '<input type="radio" name="rev1" value="%d"%s><input type="radio" name="rev2" value="%d"%s>' % (rev, lchecked, rev, rchecked) if rev > 1: diff += render_action(' ' + _('to previous'), {'action': 'diff', 'rev1': rev-1, 'rev2': rev}) comment = line.comment if not comment: if '/REVERT' in line.action: comment = _("Revert to revision %(rev)d.") % {'rev': int(line.extra)} elif '/RENAME' in line.action: comment = _("Renamed from '%(oldpagename)s'.") % {'oldpagename': line.extra} pgactioncount += 1 else: # ATT* rev = '-' diff = '-' filename = wikiutil.url_unquote(line.extra) comment = "%s: %s %s" % (line.action, filename, line.comment) if AttachFile.exists(request, pagename, filename): size = AttachFile.size(request, pagename, filename) actions.append(render_file_action(_('view'), pagename, filename, request, do='view')) actions.append(render_file_action(_('get'), pagename, filename, request, do='get')) if may_delete: actions.append(render_file_action(_('del'), pagename, filename, request, do='del')) if may_write: actions.append(render_file_action(_('edit'), pagename, filename, request, do='modify')) else: size = 0 history.addRow(( rev, request.user.getFormattedDateTime(wikiutil.version2timestamp(line.ed_time_usecs)), str(size), diff, line.getEditor(request) or _("N/A"), wikiutil.escape(comment) or ' ', " ".join(a for a in actions if a), )) if (count >= max_count + offset) or (paging and count >= log_size): break # print version history from MoinMoin.widget.browser import DataBrowserWidget request.write(unicode(html.H2().append(_('Revision History')))) if not count: # there was no entry in logfile request.write(_('No log entries found.')) return history_table = DataBrowserWidget(request) history_table.setData(history) div = html.DIV(id="page-history") div.append(html.INPUT(type="hidden", name="action", value="diff")) div.append(history_table.render(method="GET")) form = html.FORM(method="GET", action="") if paging: form.append(f.div(1, css_class="info-paging-info") + paging_info_html + count_select_html + f.div(0)) form.append("".join([ f.div(1, css_class="info-paging-nav info-paging-nav-top"), paging_nav_html, f.div(0), ])) form.append(div) if paging: form.append("".join([ f.div(1, css_class="info-paging-nav info-paging-nav-bottom"), paging_nav_html, f.div(0) ])) request.write(unicode(form))