def get_error_404(self, req): """ Show a simple error 404 page. """ return Response(render_template(req, 'not_found.html', self.globalcontext), status=404)
def _insert_comments(self, req, url, context, mode): """ Insert inline comments into a page context. """ if 'body' not in context: return comment_url = '@comments/%s/' % url page_id = self.env.get_real_filename(url)[:-4] tx = context['body'] all_comments = Comment.get_for_page(page_id) global_comments = [] for name, comments in groupby(all_comments, lambda x: x.associated_name): if not name: global_comments.extend(comments) continue comments = list(comments) if not comments: continue tx = re.sub( '<!--#%s#-->' % name, render_template( req, 'inlinecomments.html', { 'comments': comments, 'id': name, 'comment_url': comment_url, 'mode': mode }), tx) if mode == 'bottom': global_comments.extend(comments) if mode == 'inline': # replace all markers for items without comments tx = re.sub('<!--#([^#]*)#-->', (lambda match: render_template( req, 'inlinecomments.html', { 'id': match.group(1), 'mode': 'inline', 'comment_url': comment_url }, )), tx) tx += render_template(req, 'comments.html', { 'comments': global_comments, 'comment_url': comment_url }) context['body'] = tx
def get_special_page(self, req, name): yield '@' + name filename = path.join(self.data_root, name + '.fpickle') f = open(filename, 'rb') try: context = pickle.load(f) finally: f.close() yield render_template(req, name + '.html', self.globalcontext, context)
def get_special_page(self, req, name): yield '@'+name filename = path.join(self.data_root, name + '.fpickle') f = open(filename, 'rb') try: context = pickle.load(f) finally: f.close() yield render_template(req, name+'.html', self.globalcontext, context)
def _insert_comments(self, req, url, context, mode): """ Insert inline comments into a page context. """ if 'body' not in context: return comment_url = '@comments/%s/' % url page_id = self.env.get_real_filename(url)[:-4] tx = context['body'] all_comments = Comment.get_for_page(page_id) global_comments = [] for name, comments in groupby(all_comments, lambda x: x.associated_name): if not name: global_comments.extend(comments) continue comments = list(comments) if not comments: continue tx = re.sub('<!--#%s#-->' % name, render_template(req, 'inlinecomments.html', { 'comments': comments, 'id': name, 'comment_url': comment_url, 'mode': mode}), tx) if mode == 'bottom': global_comments.extend(comments) if mode == 'inline': # replace all markers for items without comments tx = re.sub('<!--#([^#]*)#-->', (lambda match: render_template(req, 'inlinecomments.html', { 'id': match.group(1), 'mode': 'inline', 'comment_url': comment_url },)), tx) tx += render_template(req, 'comments.html', { 'comments': global_comments, 'comment_url': comment_url }) context['body'] = tx
def suggest_changes(self, req, page): """ Show a "suggest changes" form. """ page_id, contents = self.get_page_source(page) return Response(render_template(req, 'edit.html', self.globalcontext, dict( contents=contents, pagename=page, doctitle=self.globalcontext['titles'].get(page_id+'.rst') or 'this page', submiturl=relative_uri('/@edit/'+page+'/', '/@submit/'+page), )))
def get_keyword_matches(self, req, term=None, avoid_fuzzy=False, is_error_page=False): """ Find keyword matches. If there is an exact match, just redirect: http://docs.python.org/os.path.exists would automatically redirect to http://docs.python.org/library/os.path/#os.path.exists. Else, show a page with close matches. Module references are processed first so that "os.path" is handled as a module and not as member of os. """ if term is None: term = req.path.strip('/') matches = self.env.find_keyword(term, avoid_fuzzy) # if avoid_fuzzy is False matches can be None if matches is None: return if isinstance(matches, tuple): url = get_target_uri(matches[1]) if matches[0] != 'module': url += '#' + matches[2] return RedirectResponse(url) else: # get some close matches close_matches = [] good_matches = 0 for ratio, type, filename, anchorname, desc in matches: link = get_target_uri(filename) if type != 'module': link += '#' + anchorname good_match = ratio > 0.75 good_matches += good_match close_matches.append({ 'href': relative_uri(req.path, link), 'title': anchorname, 'good_match': good_match, 'type': self.pretty_type.get(type, type), 'description': desc, }) return Response(render_template( req, 'keyword_not_found.html', { 'close_matches': close_matches, 'good_matches_count': good_matches, 'keyword': term }, self.globalcontext), status=404)
def get_module_index(self, req): """ Get the module index or redirect to a module from the module index. """ most_frequent = heapq.nlargest(30, self.freqmodules.iteritems(), lambda x: x[1]) if most_frequent: base_count = most_frequent[-1][1] most_frequent = [{ 'name': x[0], 'size': 100 + math.log((x[1] - base_count) + 1) * 20, 'count': x[1] } for x in sorted(most_frequent)] showpf = None newpf = req.args.get('newpf') sesspf = req.session.get('pf') if newpf or sesspf: yield NoCache if newpf: req.session['pf'] = showpf = req.args.getlist('pf') else: showpf = sesspf else: if most_frequent != self.last_most_frequent: self.cache.pop('@modindex', None) yield '@modindex' filename = path.join(self.data_root, 'modindex.fpickle') f = open(filename, 'rb') try: context = pickle.load(f) finally: f.close() if showpf: entries = context['modindexentries'] i = 0 while i < len(entries): if entries[i][6]: for pform in entries[i][6]: if pform in showpf: break else: del entries[i] continue i += 1 context['freqentries'] = most_frequent context['showpf'] = showpf or context['platforms'] self.last_most_frequent = most_frequent yield render_template(req, 'modindex.html', self.globalcontext, context)
def get_keyword_matches(self, req, term=None, avoid_fuzzy=False, is_error_page=False): """ Find keyword matches. If there is an exact match, just redirect: http://docs.python.org/os.path.exists would automatically redirect to http://docs.python.org/library/os.path/#os.path.exists. Else, show a page with close matches. Module references are processed first so that "os.path" is handled as a module and not as member of os. """ if term is None: term = req.path.strip('/') matches = self.env.find_keyword(term, avoid_fuzzy) # if avoid_fuzzy is False matches can be None if matches is None: return if isinstance(matches, tuple): url = get_target_uri(matches[1]) if matches[0] != 'module': url += '#' + matches[2] return RedirectResponse(url) else: # get some close matches close_matches = [] good_matches = 0 for ratio, type, filename, anchorname, desc in matches: link = get_target_uri(filename) if type != 'module': link += '#' + anchorname good_match = ratio > 0.75 good_matches += good_match close_matches.append({ 'href': relative_uri(req.path, link), 'title': anchorname, 'good_match': good_match, 'type': self.pretty_type.get(type, type), 'description': desc, }) return Response(render_template(req, 'keyword_not_found.html', { 'close_matches': close_matches, 'good_matches_count': good_matches, 'keyword': term }, self.globalcontext), status=404)
def suggest_changes(self, req, page): """ Show a "suggest changes" form. """ page_id, contents = self.get_page_source(page) return Response( render_template( req, 'edit.html', self.globalcontext, dict( contents=contents, pagename=page, doctitle=self.globalcontext['titles'].get(page_id + '.rst') or 'this page', submiturl=relative_uri('/@edit/' + page + '/', '/@submit/' + page), )))
def do_login(self, req): """ Display login form and do the login procedure. """ if req.user is not None: return RedirectResponse('@admin/') login_failed = False if req.method == 'POST': if req.form.get('cancel'): return RedirectResponse('') username = req.form.get('username') password = req.form.get('password') if self.userdb.check_password(username, password): req.login(username) return RedirectResponse('@admin/') login_failed = True return Response(render_template(req, 'admin/login.html', { 'login_failed': login_failed }))
def do_change_password(self, req): """ Allows the user to change his password. """ change_failed = change_successful = False if req.method == 'POST': if req.form.get('cancel'): return RedirectResponse('@admin/') pw = req.form.get('pw1') if pw and pw == req.form.get('pw2'): self.userdb.set_password(req.user, pw) self.userdb.save() change_successful = True else: change_failed = True return Response(render_template(req, 'admin/change_password.html', { 'change_failed': change_failed, 'change_successful': change_successful }))
def do_login(self, req): """ Display login form and do the login procedure. """ if req.user is not None: return RedirectResponse('@admin/') login_failed = False if req.method == 'POST': if req.form.get('cancel'): return RedirectResponse('') username = req.form.get('username') password = req.form.get('password') if self.userdb.check_password(username, password): req.login(username) return RedirectResponse('@admin/') login_failed = True return Response( render_template(req, 'admin/login.html', {'login_failed': login_failed}))
def do_change_password(self, req): """ Allows the user to change his password. """ change_failed = change_successful = False if req.method == 'POST': if req.form.get('cancel'): return RedirectResponse('@admin/') pw = req.form.get('pw1') if pw and pw == req.form.get('pw2'): self.userdb.set_password(req.user, pw) self.userdb.save() change_successful = True else: change_failed = True return Response( render_template( req, 'admin/change_password.html', { 'change_failed': change_failed, 'change_successful': change_successful }))
def dispatch(self, req, page): """ Dispatch the requests for the current user in the admin panel. """ is_logged_in = req.user is not None if is_logged_in: privileges = self.userdb.privileges[req.user] is_master_admin = 'master' in privileges can_change_password = '******' not in privileges else: privileges = set() can_change_password = is_master_admin = False # login and logout if page == 'login': return self.do_login(req) elif not is_logged_in: return RedirectResponse('@admin/login/') elif page == 'logout': return self.do_logout(req) # account maintance elif page == 'change_password' and can_change_password: return self.do_change_password(req) elif page == 'manage_users' and is_master_admin: return self.do_manage_users(req) # moderate comments elif page.split('/')[0] == 'moderate_comments': return self.do_moderate_comments(req, page[18:]) # missing page elif page != '': raise NotFound() return Response( render_template( req, 'admin/index.html', { 'is_master_admin': is_master_admin, 'can_change_password': can_change_password }))
def get_page(self, req, url): """ Show the requested documentation page or raise an `NotFound` exception to display a page with close matches. """ page_id = self.env.get_real_filename(url)[:-4] if page_id is None: raise NotFound(show_keyword_matches=True) # increment view count of all modules on that page for modname in self.env.filemodules.get(page_id+'.rst', ()): self.freqmodules[modname] = self.freqmodules.get(modname, 0) + 1 # comments enabled? comments = self.env.metadata[page_id+'.rst'].get('nocomments', False) # how does the user want to view comments? commentmode = comments and req.session.get('comments', 'inline') or '' # show "old URL" message? -> no caching possible oldurl = req.args.get('oldurl') if oldurl: yield NoCache else: # there must be different cache entries per comment mode yield page_id + '|' + commentmode # cache miss; load the page and render it filename = path.join(self.data_root, page_id + '.fpickle') f = open(filename, 'rb') try: context = pickle.load(f) finally: f.close() # add comments to paqe text if commentmode != 'none': self._insert_comments(req, url, context, commentmode) yield render_template(req, 'page.html', self.globalcontext, context, {'oldurl': oldurl})
def get_settings_page(self, req): """ Handle the settings page. """ referer = req.environ.get('HTTP_REFERER') or '' if referer: base = get_base_uri(req.environ) if not referer.startswith(base): referer = '' else: referer = referer[len(base):] referer = referer.split('?')[0] or referer if req.method == 'POST': if req.form.get('cancel'): if req.form.get('referer'): return RedirectResponse(req.form['referer']) return RedirectResponse('') new_style = req.form.get('design') if new_style and new_style in known_designs: req.session['design'] = new_style new_comments = req.form.get('comments') if new_comments and new_comments in comments_methods: req.session['comments'] = new_comments if req.form.get('goback') and req.form.get('referer'): return RedirectResponse(req.form['referer']) # else display the same page again referer = '' context = { 'known_designs': sorted(known_designs.iteritems()), 'comments_methods': comments_methods.items(), 'curdesign': req.session.get('design') or 'default', 'curcomments': req.session.get('comments') or 'inline', 'referer': referer, } return Response(render_template(req, 'settings.html', self.globalcontext, context))
def get_settings_page(self, req): """ Handle the settings page. """ referer = req.environ.get('HTTP_REFERER') or '' if referer: base = get_base_uri(req.environ) if not referer.startswith(base): referer = '' else: referer = referer[len(base):] referer = referer.split('?')[0] or referer if req.method == 'POST': if req.form.get('cancel'): if req.form.get('referer'): return RedirectResponse(req.form['referer']) return RedirectResponse('') new_style = req.form.get('design') if new_style and new_style in known_designs: req.session['design'] = new_style new_comments = req.form.get('comments') if new_comments and new_comments in comments_methods: req.session['comments'] = new_comments if req.form.get('goback') and req.form.get('referer'): return RedirectResponse(req.form['referer']) # else display the same page again referer = '' context = { 'known_designs': sorted(known_designs.iteritems()), 'comments_methods': comments_methods.items(), 'curdesign': req.session.get('design') or 'default', 'curcomments': req.session.get('comments') or 'inline', 'referer': referer, } return Response( render_template(req, 'settings.html', self.globalcontext, context))
def get_page(self, req, url): """ Show the requested documentation page or raise an `NotFound` exception to display a page with close matches. """ page_id = self.env.get_real_filename(url)[:-4] if page_id is None: raise NotFound(show_keyword_matches=True) # increment view count of all modules on that page for modname in self.env.filemodules.get(page_id + '.rst', ()): self.freqmodules[modname] = self.freqmodules.get(modname, 0) + 1 # comments enabled? comments = self.env.metadata[page_id + '.rst'].get('nocomments', False) # how does the user want to view comments? commentmode = comments and req.session.get('comments', 'inline') or '' # show "old URL" message? -> no caching possible oldurl = req.args.get('oldurl') if oldurl: yield NoCache else: # there must be different cache entries per comment mode yield page_id + '|' + commentmode # cache miss; load the page and render it filename = path.join(self.data_root, page_id + '.fpickle') f = open(filename, 'rb') try: context = pickle.load(f) finally: f.close() # add comments to paqe text if commentmode != 'none': self._insert_comments(req, url, context, commentmode) yield render_template(req, 'page.html', self.globalcontext, context, {'oldurl': oldurl})
def dispatch(self, req, page): """ Dispatch the requests for the current user in the admin panel. """ is_logged_in = req.user is not None if is_logged_in: privileges = self.userdb.privileges[req.user] is_master_admin = 'master' in privileges can_change_password = '******' not in privileges else: privileges = set() can_change_password = is_master_admin = False # login and logout if page == 'login': return self.do_login(req) elif not is_logged_in: return RedirectResponse('@admin/login/') elif page == 'logout': return self.do_logout(req) # account maintance elif page == 'change_password' and can_change_password: return self.do_change_password(req) elif page == 'manage_users' and is_master_admin: return self.do_manage_users(req) # moderate comments elif page.split('/')[0] == 'moderate_comments': return self.do_moderate_comments(req, page[18:]) # missing page elif page != '': raise NotFound() return Response(render_template(req, 'admin/index.html', { 'is_master_admin': is_master_admin, 'can_change_password': can_change_password }))
def show_comment_form(self, req, page): """ Show the "new comment" form. """ page_id = self.env.get_real_filename(page)[:-4] ajax_mode = req.args.get('mode') == 'ajax' target = req.args.get('target') page_comment_mode = not target form_error = preview = None title = req.form.get('title', '').strip() if 'author' in req.form: author = req.form['author'] else: author = req.session.get('author', '') if 'author_mail' in req.form: author_mail = req.form['author_mail'] else: author_mail = req.session.get('author_mail', '') comment_body = req.form.get('comment_body', '') fields = (title, author, author_mail, comment_body) if req.method == 'POST': if req.form.get('preview'): preview = Comment(page_id, target, title, author, author_mail, comment_body) # 'homepage' is a forbidden field to thwart bots elif req.form.get('homepage') or self.antispam.is_spam(fields): form_error = 'Your text contains blocked URLs or words.' else: if not all(fields): form_error = 'You have to fill out all fields.' elif _mail_re.search(author_mail) is None: form_error = 'You have to provide a valid e-mail address.' elif len(comment_body) < 20: form_error = 'You comment is too short ' \ '(must have at least 20 characters).' else: # '|none' can stay since it doesn't include comments self.cache.pop(page_id + '|inline', None) self.cache.pop(page_id + '|bottom', None) comment = Comment(page_id, target, title, author, author_mail, comment_body) comment.save() req.session['author'] = author req.session['author_mail'] = author_mail if ajax_mode: return JSONResponse({'posted': True, 'error': False, 'commentID': comment.comment_id}) return RedirectResponse(comment.url) output = render_template(req, '_commentform.html', { 'ajax_mode': ajax_mode, 'preview': preview, 'suggest_url': '@edit/%s/' % page, 'comments_form': { 'target': target, 'title': title, 'author': author, 'author_mail': author_mail, 'comment_body': comment_body, 'error': form_error } }) if ajax_mode: return JSONResponse({ 'body': output, 'error': bool(form_error), 'posted': False }) return Response(render_template(req, 'commentform.html', { 'form': output }))
def show_comment_form(self, req, page): """ Show the "new comment" form. """ page_id = self.env.get_real_filename(page)[:-4] ajax_mode = req.args.get('mode') == 'ajax' target = req.args.get('target') page_comment_mode = not target form_error = preview = None title = req.form.get('title', '').strip() if 'author' in req.form: author = req.form['author'] else: author = req.session.get('author', '') if 'author_mail' in req.form: author_mail = req.form['author_mail'] else: author_mail = req.session.get('author_mail', '') comment_body = req.form.get('comment_body', '') fields = (title, author, author_mail, comment_body) if req.method == 'POST': if req.form.get('preview'): preview = Comment(page_id, target, title, author, author_mail, comment_body) # 'homepage' is a forbidden field to thwart bots elif req.form.get('homepage') or self.antispam.is_spam(fields): form_error = 'Your text contains blocked URLs or words.' else: if not all(fields): form_error = 'You have to fill out all fields.' elif _mail_re.search(author_mail) is None: form_error = 'You have to provide a valid e-mail address.' elif len(comment_body) < 20: form_error = 'You comment is too short ' \ '(must have at least 20 characters).' else: # '|none' can stay since it doesn't include comments self.cache.pop(page_id + '|inline', None) self.cache.pop(page_id + '|bottom', None) comment = Comment(page_id, target, title, author, author_mail, comment_body) comment.save() req.session['author'] = author req.session['author_mail'] = author_mail if ajax_mode: return JSONResponse({ 'posted': True, 'error': False, 'commentID': comment.comment_id }) return RedirectResponse(comment.url) output = render_template( req, '_commentform.html', { 'ajax_mode': ajax_mode, 'preview': preview, 'suggest_url': '@edit/%s/' % page, 'comments_form': { 'target': target, 'title': title, 'author': author, 'author_mail': author_mail, 'comment_body': comment_body, 'error': form_error } }) if ajax_mode: return JSONResponse({ 'body': output, 'error': bool(form_error), 'posted': False }) return Response( render_template(req, 'commentform.html', {'form': output}))
def submit_changes(self, req, page): """ Submit the suggested changes as a patch. """ if req.method != 'POST': # only available via POST raise NotFound() if req.form.get('cancel'): # handle cancel requests directly return RedirectResponse(page) # raises NotFound if page doesn't exist page_id, orig_contents = self.get_page_source(page) author = req.form.get('name') email = req.form.get('email') summary = req.form.get('summary') contents = req.form.get('contents') fields = (author, email, summary, contents) form_error = None rendered = None if not all(fields): form_error = 'You have to fill out all fields.' elif not _mail_re.search(email): form_error = 'You have to provide a valid e-mail address.' elif req.form.get('homepage') or self.antispam.is_spam(fields): form_error = 'Your text contains blocked URLs or words.' else: if req.form.get('preview'): rendered = self._generate_preview(page_id, contents) else: asctime = time.asctime() contents = contents.splitlines() orig_contents = orig_contents.splitlines() diffname = 'suggestion on %s by %s <%s>' % (asctime, author, email) diff = difflib.unified_diff(orig_contents, contents, n=3, fromfile=page_id, tofile=diffname, lineterm='') diff_text = '\n'.join(diff) try: mail = Email( self.config['patch_mail_from'], 'Python Documentation Patches', self.config['patch_mail_to'], '', 'Patch for %s by %s' % (page_id, author), PATCH_MESSAGE % locals(), self.config['patch_mail_smtp'], ) mail.attachments.add_string('patch.diff', diff_text, 'text/x-diff') mail.send() except: import traceback traceback.print_exc() # XXX: how to report? pass return Response(render_template(req, 'submitted.html', self.globalcontext, dict( backlink=relative_uri('/@submit/'+page+'/', page+'/') ))) return Response(render_template(req, 'edit.html', self.globalcontext, dict( contents=contents, author=author, email=email, summary=summary, pagename=page, form_error=form_error, rendered=rendered, submiturl=relative_uri('/@edit/'+page+'/', '/@submit/'+page), )))
def submit_changes(self, req, page): """ Submit the suggested changes as a patch. """ if req.method != 'POST': # only available via POST raise NotFound() if req.form.get('cancel'): # handle cancel requests directly return RedirectResponse(page) # raises NotFound if page doesn't exist page_id, orig_contents = self.get_page_source(page) author = req.form.get('name') email = req.form.get('email') summary = req.form.get('summary') contents = req.form.get('contents') fields = (author, email, summary, contents) form_error = None rendered = None if not all(fields): form_error = 'You have to fill out all fields.' elif not _mail_re.search(email): form_error = 'You have to provide a valid e-mail address.' elif req.form.get('homepage') or self.antispam.is_spam(fields): form_error = 'Your text contains blocked URLs or words.' else: if req.form.get('preview'): rendered = self._generate_preview(page_id, contents) else: asctime = time.asctime() contents = contents.splitlines() orig_contents = orig_contents.splitlines() diffname = 'suggestion on %s by %s <%s>' % (asctime, author, email) diff = difflib.unified_diff(orig_contents, contents, n=3, fromfile=page_id, tofile=diffname, lineterm='') diff_text = '\n'.join(diff) try: mail = Email( self.config['patch_mail_from'], 'Python Documentation Patches', self.config['patch_mail_to'], '', 'Patch for %s by %s' % (page_id, author), PATCH_MESSAGE % locals(), self.config['patch_mail_smtp'], ) mail.attachments.add_string('patch.diff', diff_text, 'text/x-diff') mail.send() except: import traceback traceback.print_exc() # XXX: how to report? pass return Response( render_template( req, 'submitted.html', self.globalcontext, dict(backlink=relative_uri('/@submit/' + page + '/', page + '/')))) return Response( render_template( req, 'edit.html', self.globalcontext, dict( contents=contents, author=author, email=email, summary=summary, pagename=page, form_error=form_error, rendered=rendered, submiturl=relative_uri('/@edit/' + page + '/', '/@submit/' + page), )))
def do_moderate_comments(self, req, url): """ Comment moderation panel. """ if url == 'recent_comments': details_for = None recent_comments = Comment.get_recent(20) else: details_for = url and self.env.get_real_filename(url) or None recent_comments = None to_delete = set() edit_detail = None if 'edit' in req.args: try: edit_detail = Comment.get(int(req.args['edit'])) except ValueError: pass if req.method == 'POST': for item in req.form.getlist('delete'): try: to_delete.add(int(item)) except ValueError: pass if req.form.get('cancel'): return RedirectResponse('@admin/') elif req.form.get('confirmed'): for comment_id in to_delete: try: Comment.get(comment_id).delete() except ValueError: pass return RedirectResponse(req.path) elif req.form.get('aborted'): return RedirectResponse(req.path) elif req.form.get('edit') and not to_delete: if 'delete_this' in req.form: try: to_delete.add(req.form['delete_this']) except ValueError: pass else: try: edit_detail = c = Comment.get(int(req.args['edit'])) except ValueError: pass else: if req.form.get('view'): return RedirectResponse(c.url) c.author = req.form.get('author', '') c.author_mail = req.form.get('author_mail', '') c.title = req.form.get('title', '') c.comment_body = req.form.get('comment_body', '') c.save() self.app.cache.pop(edit_detail.associated_page, None) return RedirectResponse(req.path) return Response( render_template( req, 'admin/moderate_comments.html', { 'pages_with_comments': [ { 'page_id': page_id, 'title': page_id, #XXX: get title somehow 'has_details': details_for == page_id, 'comments': comments } for page_id, comments in Comment.get_overview( details_for) ], 'recent_comments': recent_comments, 'to_delete': to_delete, 'ask_confirmation': req.method == 'POST' and to_delete, 'edit_detail': edit_detail }))
def do_moderate_comments(self, req, url): """ Comment moderation panel. """ if url == 'recent_comments': details_for = None recent_comments = Comment.get_recent(20) else: details_for = url and self.env.get_real_filename(url) or None recent_comments = None to_delete = set() edit_detail = None if 'edit' in req.args: try: edit_detail = Comment.get(int(req.args['edit'])) except ValueError: pass if req.method == 'POST': for item in req.form.getlist('delete'): try: to_delete.add(int(item)) except ValueError: pass if req.form.get('cancel'): return RedirectResponse('@admin/') elif req.form.get('confirmed'): for comment_id in to_delete: try: Comment.get(comment_id).delete() except ValueError: pass return RedirectResponse(req.path) elif req.form.get('aborted'): return RedirectResponse(req.path) elif req.form.get('edit') and not to_delete: if 'delete_this' in req.form: try: to_delete.add(req.form['delete_this']) except ValueError: pass else: try: edit_detail = c = Comment.get(int(req.args['edit'])) except ValueError: pass else: if req.form.get('view'): return RedirectResponse(c.url) c.author = req.form.get('author', '') c.author_mail = req.form.get('author_mail', '') c.title = req.form.get('title', '') c.comment_body = req.form.get('comment_body', '') c.save() self.app.cache.pop(edit_detail.associated_page, None) return RedirectResponse(req.path) return Response(render_template(req, 'admin/moderate_comments.html', { 'pages_with_comments': [{ 'page_id': page_id, 'title': page_id, #XXX: get title somehow 'has_details': details_for == page_id, 'comments': comments } for page_id, comments in Comment.get_overview(details_for)], 'recent_comments': recent_comments, 'to_delete': to_delete, 'ask_confirmation': req.method == 'POST' and to_delete, 'edit_detail': edit_detail }))
def do_manage_users(self, req): """ Manage other user accounts. Requires master privileges. """ add_user_mode = False user_privileges = {} users = sorted((user, []) for user in self.userdb.users) to_delete = set() generated_user = generated_password = None user_exists = False if req.method == 'POST': for item in req.form.getlist('delete'): try: to_delete.add(item) except ValueError: pass for name, item in req.form.iteritems(): if name.startswith('privileges-'): user_privileges[name[11:]] = [x.strip() for x in item.split(',')] if req.form.get('cancel'): return RedirectResponse('@admin/') elif req.form.get('add_user'): username = req.form.get('username') if username: if username in self.userdb.users: user_exists = username else: generated_password = self.userdb.add_user(username) self.userdb.save() generated_user = username else: add_user_mode = True elif req.form.get('aborted'): return RedirectResponse('@admin/manage_users/') users = {} for user in self.userdb.users: if user not in user_privileges: users[user] = sorted(self.userdb.privileges[user]) else: users[user] = user_privileges[user] new_users = users.copy() for user in to_delete: new_users.pop(user, None) self_destruction = req.user not in new_users or \ 'master' not in new_users[req.user] if req.method == 'POST' and (not to_delete or (to_delete and req.form.get('confirmed'))) and \ req.form.get('update'): old_users = self.userdb.users.copy() for user in old_users: if user not in new_users: del self.userdb.users[user] else: self.userdb.privileges[user].clear() self.userdb.privileges[user].update(new_users[user]) self.userdb.save() return RedirectResponse('@admin/manage_users/') return Response(render_template(req, 'admin/manage_users.html', { 'users': users, 'add_user_mode': add_user_mode, 'to_delete': to_delete, 'ask_confirmation': req.method == 'POST' and to_delete \ and not self_destruction, 'generated_user': generated_user, 'generated_password': generated_password, 'self_destruction': self_destruction, 'user_exists': user_exists }))
def do_manage_users(self, req): """ Manage other user accounts. Requires master privileges. """ add_user_mode = False user_privileges = {} users = sorted((user, []) for user in self.userdb.users) to_delete = set() generated_user = generated_password = None user_exists = False if req.method == 'POST': for item in req.form.getlist('delete'): try: to_delete.add(item) except ValueError: pass for name, item in req.form.iteritems(): if name.startswith('privileges-'): user_privileges[name[11:]] = [ x.strip() for x in item.split(',') ] if req.form.get('cancel'): return RedirectResponse('@admin/') elif req.form.get('add_user'): username = req.form.get('username') if username: if username in self.userdb.users: user_exists = username else: generated_password = self.userdb.add_user(username) self.userdb.save() generated_user = username else: add_user_mode = True elif req.form.get('aborted'): return RedirectResponse('@admin/manage_users/') users = {} for user in self.userdb.users: if user not in user_privileges: users[user] = sorted(self.userdb.privileges[user]) else: users[user] = user_privileges[user] new_users = users.copy() for user in to_delete: new_users.pop(user, None) self_destruction = req.user not in new_users or \ 'master' not in new_users[req.user] if req.method == 'POST' and (not to_delete or (to_delete and req.form.get('confirmed'))) and \ req.form.get('update'): old_users = self.userdb.users.copy() for user in old_users: if user not in new_users: del self.userdb.users[user] else: self.userdb.privileges[user].clear() self.userdb.privileges[user].update(new_users[user]) self.userdb.save() return RedirectResponse('@admin/manage_users/') return Response(render_template(req, 'admin/manage_users.html', { 'users': users, 'add_user_mode': add_user_mode, 'to_delete': to_delete, 'ask_confirmation': req.method == 'POST' and to_delete \ and not self_destruction, 'generated_user': generated_user, 'generated_password': generated_password, 'self_destruction': self_destruction, 'user_exists': user_exists }))