Mercurial > moin > 1.9
changeset 1858:970140d46ae1
merged main
author | Thomas Waldmann <tw AT waldmann-edv DOT de> |
---|---|
date | Thu, 08 Mar 2007 14:32:22 +0100 |
parents | 659070e5e4d3 (current diff) 763fb3eba3b3 (diff) |
children | 327b23c27532 |
files | MoinMoin/Page.py |
diffstat | 7 files changed, 261 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/MoinMoin/Page.py Thu Mar 08 14:31:48 2007 +0100 +++ b/MoinMoin/Page.py Thu Mar 08 14:32:22 2007 +0100 @@ -1728,7 +1728,7 @@ request.clock.stop('getPageList') return pages - def getPageDict(self, user=None, exists=1, filter=None): + def getPageDict(self, user=None, exists=1, filter=None, include_underlay=True): """ Return a dictionary of filtered page objects readable by user Invoke getPageList then create a dict from the page list. See @@ -1741,7 +1741,7 @@ @return: user readable pages """ pages = {} - for name in self.getPageList(user=user, exists=exists, filter=filter): + for name in self.getPageList(user=user, exists=exists, filter=filter, include_underlay=include_underlay): pages[name] = Page(self.request, name) return pages
--- a/MoinMoin/PageEditor.py Thu Mar 08 14:31:48 2007 +0100 +++ b/MoinMoin/PageEditor.py Thu Mar 08 14:32:22 2007 +0100 @@ -487,6 +487,68 @@ page = backto and Page(request, backto) or self page.send_page(msg=_('Edit was cancelled.')) + def copyPage(self, newpagename, comment=None): + """ + Copy the current version of the page (keeping the backups, logs and attachments). + + @param comment: Comment given by user + @rtype: unicode + @return: success flag, error message + """ + request = self.request + _ = self._ + + if not newpagename: + return False, _("You can't copy to an empty pagename.") + + newpage = PageEditor(request, newpagename) + + pageexists_error = _("""'''A page with the name {{{'%s'}}} already exists.''' +Try a different name.""") % (newpagename,) + + # Check whether a page with the new name already exists + if newpage.exists(includeDeleted=1): + return False, pageexists_error + + # Get old page text + savetext = self.get_raw_body() + + oldpath = self.getPagePath(check_create=0) + newpath = newpage.getPagePath(check_create=0) + + # Copy page + # NOTE: might fail if another process created newpagename just + try: + filesys.copytree(oldpath, newpath) + self.error = None + if not comment: + comment = u"## page was copied from %s" % self.page_name + if request.user.may.write(newpagename): + # If current user has write access + # Save page text with a comment about the old name + savetext = u"## page was copied from %s\n%s" % (self.page_name, savetext) + newpage.saveText(savetext, 0, comment=comment, index=0, extra=self.page_name, action='SAVE') + else: + # if user is not able to write to the page itselfs we set a log entry only + from MoinMoin import packages + rev = newpage.current_rev() + packages.edit_logfile_append(self, newpagename, newpath, rev, 'SAVENEW', logname='edit-log', + comment=comment, author=u"CopyPage action") + + if request.cfg.xapian_search: + from MoinMoin.search.Xapian import Index + index = Index(request) + if index.exists(): + index.update_page(newpagename) + return True, None + except OSError, err: + # Try to understand what happened. Maybe its better to check + # the error code, but I just reused the available code above... + if newpage.exists(includeDeleted=1): + return False, pageexists_error + else: + return False, _('Could not copy page because of file system error: %s.') % unicode(err) + def renamePage(self, newpagename, comment=None): """ Rename the current version of the page (making a backup before deletion @@ -498,6 +560,12 @@ """ request = self.request _ = self._ + + if not (request.user.may.delete(self.page_name) + and request.user.may.write(newpagename)): + msg = _('You are not allowed to rename this page!') + raise self.AccessDenied, msg + if not newpagename: return False, _("You can't rename to an empty pagename.") @@ -583,7 +651,8 @@ _('Page "%s" was successfully deleted!') % (self.page_name,)) except self.SaveError, message: - # XXX Error handling + # XXX do not only catch base class SaveError here, but + # also the derived classes, so we can give better err msgs success = False msg = "SaveError has occured in PageEditor.deletePage. We need locking there." @@ -622,7 +691,7 @@ else: querystr = {} pagelink = request.getQualifiedURL(self.url(request, querystr, relative=False)) - + mailBody = _("Dear Wiki user,\n\n" 'You have subscribed to a wiki page or wiki category on "%(sitename)s" for change notification.\n\n' "The following page has been changed by %(editor)s:\n" @@ -852,7 +921,8 @@ return pragmas - def copypage(self): + def copy_underlay_page(self): + # renamed from copypage to avoid conflicts with copyPage """ Copy a page from underlay directory to page directory """ @@ -883,7 +953,7 @@ #is_deprecated = self._get_pragmas(text).has_key("deprecated") was_deprecated = self._get_pragmas(self.get_raw_body()).has_key("deprecated") - self.copypage() + self.copy_underlay_page() # remember conflict state self.setConflict(wikiutil.containsConflictMarker(text))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MoinMoin/action/CopyPage.py Thu Mar 08 14:32:22 2007 +0100 @@ -0,0 +1,170 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - CopyPage action + + This action allows you to copy a page. + + @copyright: 2007 ReimarBauer + @license: GNU GPL, see COPYING for details. +""" +import re +from MoinMoin import wikiutil +from MoinMoin.Page import Page +from MoinMoin.PageEditor import PageEditor +from MoinMoin.action import ActionBase + +class CopyPage(ActionBase): + """ Copy page action + + Note: the action name is the class name + """ + def __init__(self, pagename, request): + ActionBase.__init__(self, pagename, request) + self.use_ticket = True + _ = self._ + self.form_trigger = 'copy' + self.form_trigger_label = _('Copy Page') + filterfn = re.compile(pagename).match + pages = request.rootpage.getPageList(user='', exists=1, filter=filterfn) + self.subpages = [] + self.users_subpages = [] + subpage = pagename + '/' + for name in pages: + if name.startswith(subpage): + self.subpages.append(name) + if self.request.user.may.read(name): + self.users_subpages.append(name) + + def is_allowed(self): + may = self.request.user.may + return may.read(self.pagename) + + def check_condition(self): + _ = self._ + if not self.page.exists(): + return _('This page is already deleted or was never created!') + else: + return None + + def do_action(self): + """ copy this page to "pagename" """ + _ = self._ + form = self.form + newpagename = form.get('newpagename', [u''])[0] + newpagename = self.request.normalizePagename(newpagename) + comment = form.get('comment', [u''])[0] + comment = wikiutil.clean_comment(comment) + + self.page = PageEditor(self.request, self.pagename) + success, msg = self.page.copyPage(newpagename, comment) + + copy_subpages = 0 + if form.has_key('copy_subpages'): + try: + copy_subpages = int(form['copy_subpages'][0]) + except: + pass + + if copy_subpages and self.subpages or (not self.users_subpages and self.subpages): + for name in self.subpages: + self.page = PageEditor(self.request, name) + new_subpagename = name.replace(self.pagename, newpagename, 1) + success_i, msg = self.page.copyPage(new_subpagename, comment) + + self.newpagename = newpagename # keep there for finish + return success, msg + + def do_action_finish(self, success): + if success: + url = Page(self.request, self.newpagename).url(self.request, relative=False) + self.request.http_redirect(url) + self.request.finish() + else: + self.render_msg(self.make_form()) + + def get_form_html(self, buttons_html): + _ = self._ + if self.users_subpages: + subpages = ' '.join(self.users_subpages) + + d = { + 'subpage': subpages, + 'subpages_checked':('', 'checked')[self.request.form.get('subpages_checked', ['0'])[0] == '1'], + 'subpage_label': _('Copy all /subpages too?'), + 'pagename': wikiutil.escape(self.pagename), + 'newname_label': _("New name"), + 'comment_label': _("Optional reason for the copying"), + 'buttons_html': buttons_html, + 'querytext': _('Really copy this page?') + } + + return ''' +<strong>%(querytext)s</strong> +<br> +<br> +<table> + <tr> + <dd> + %(subpage_label)s<input type="checkbox" name="copy_subpages" value="1" %(subpages_checked)s> + </dd> + <dd> + <class="label"><subpage> %(subpage)s</subpage> + </dd> + </tr> +</table> +<table> + <tr> + <td class="label"><label>%(newname_label)s</label></td> + <td class="content"> + <input type="text" name="newpagename" value="%(pagename)s"> + </td> + </tr> + <tr> + <td class="label"><label>%(comment_label)s</label></td> + <td class="content"> + <input type="text" name="comment" maxlength="200"> + </td> + </tr> + <tr> + <td></td> + <td class="buttons"> + %(buttons_html)s + </td> + </tr> +</table> +''' % d + + else: + d = { + 'pagename': wikiutil.escape(self.pagename), + 'newname_label': _("New name"), + 'comment_label': _("Optional reason for the copying"), + 'buttons_html': buttons_html, + } + return ''' +<table> + <tr> + <td class="label"><label>%(newname_label)s</label></td> + <td class="content"> + <input type="text" name="newpagename" value="%(pagename)s"> + </td> + </tr> + <tr> + <td class="label"><label>%(comment_label)s</label></td> + <td class="content"> + <input type="text" name="comment" maxlength="200"> + </td> + </tr> + <tr> + <td></td> + <td class="buttons"> + %(buttons_html)s + </td> + </tr> +</table> +''' % d + +def execute(pagename, request): + """ Glue code for actions """ + CopyPage(pagename, request).render() +
--- a/MoinMoin/action/sitemap.py Thu Mar 08 14:31:48 2007 +0100 +++ b/MoinMoin/action/sitemap.py Thu Mar 08 14:32:22 2007 +0100 @@ -70,7 +70,7 @@ request.write("""<?xml version="1.0" encoding="UTF-8"?>\r\n""") result = [] - result.append("""<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">\n""") + result.append("""<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""") # we include the / url as an important and often changed URL result.append(make_url_xml({ @@ -82,7 +82,11 @@ })) # Get page dict readable by current user - pages = request.rootpage.getPageDict() + try: + underlay = int(form.get('underlay', [1])[0]) + except ValueError: + underlay = 1 + pages = request.rootpage.getPageDict(include_underlay=underlay) pagelist = pages.keys() pagelist.sort() for name in pagelist:
--- a/MoinMoin/server/STANDALONE.py Thu Mar 08 14:31:48 2007 +0100 +++ b/MoinMoin/server/STANDALONE.py Thu Mar 08 14:32:22 2007 +0100 @@ -273,8 +273,9 @@ staticExpire = 365 * 24 * 3600 # 1 year expiry for static files def __init__(self, request, client_address, server): - self.server_version = "MoinMoin %s %s" % (version.revision, - server.__class__.__name__) + self.server_version = "MoinMoin %s %s %s" % (version.release, + version.revision, + server.__class__.__name__) self.expires = 0 SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
--- a/MoinMoin/theme/__init__.py Thu Mar 08 14:31:48 2007 +0100 +++ b/MoinMoin/theme/__init__.py Thu Mar 08 14:32:22 2007 +0100 @@ -314,7 +314,7 @@ request = self.request fmt = request.formatter title = None - + # Handle [pagename title] or [url title] formats if text.startswith('[') and text.endswith(']'): text = text[1:-1].strip() @@ -363,7 +363,7 @@ page = wikiutil.getLocalizedPage(request, pagename) else: page = Page(request, pagename) - + if not title: title = page.split_title() title = self.shortenPagename(title) @@ -900,6 +900,7 @@ 'LocalSiteMap', '__separator__', 'RenamePage', + 'CopyPage', 'DeletePage', '__separator__', 'MyPages', @@ -921,6 +922,7 @@ 'refresh': _('Delete Cache', formatted=False), 'SpellCheck': _('Check Spelling', formatted=False), # rename action! 'RenamePage': _('Rename Page', formatted=False), + 'CopyPage': _('Copy Page', formatted=False), 'DeletePage': _('Delete Page', formatted=False), 'LikePages': _('Like Pages', formatted=False), 'LocalSiteMap': _('Local Site Map', formatted=False),
--- a/docs/CHANGES Thu Mar 08 14:31:48 2007 +0100 +++ b/docs/CHANGES Thu Mar 08 14:32:22 2007 +0100 @@ -334,6 +334,8 @@ patch. * autofilters for databrowser widget. Thanks to Johannes Berg for the patch. * action DeletePage and RenamePage could now be used for subpages of a page too + * Added Action CopyPage so you can use now an existing page or page hierarchy as template for a new page, see FeatureRequests/CloneOrCopyPages + TODO: we need a copy icon in RC Bugfixes: * on action "info" page, "revert" link will not be displayed for empty page