--- /usr/lib/python2.3/site-packages/MoinMoin/packages.py.orig 2006-06-03 20:41:07.000000000 +0200 +++ packages.py 2006-06-17 09:13:18.610148848 +0200 @@ -4,15 +4,22 @@ @copyright: 2005 by MoinMoin:AlexanderSchremmer @license: GNU GPL, see COPYING for details. + 2005-2006 R.Bauer AddAttachment, DelAttachment, RenamePage added + AddRevision changed to ignore ACLs + For these four logging operations added + this must be done for the others too """ -import os +import os, codecs import sys import zipfile from MoinMoin import config, wikiutil, caching from MoinMoin.Page import Page from MoinMoin.PageEditor import PageEditor +from MoinMoin.util import filesys +from MoinMoin.logfile import editlog, eventlog + MOIN_PACKAGE_FILE = 'MOIN_PACKAGE' MAX_VERSION = 1 @@ -36,9 +43,70 @@ """ Raised when the script problem occurs at runtime. """ class ScriptExit(Exception): - """ Raised by the script commands when the script should quit. """ + -# Parsing and (un)quoting for script files + """ Raised by the script commands when the script should quit. """ +def event_logfile(self,pagename,pagefile): + # add event log entry + + filename = self.request.rootpage.getPagePath('event-log', isfile=1) + eventtype = 'SAVENEW' + + mtime_usecs = wikiutil.timestamp2version(os.path.getmtime(pagefile)) + + elog = eventlog.EventLog(self.request) + elog.add(self.request, eventtype, {'pagename': pagename}, 1, mtime_usecs) + +def edit_logfile_append(self,pagename,pagefile,rev,action,logname='edit-log',comment=u'',author=u"Scripting Subsystem"): + glog = editlog.EditLog(self.request, uid_override=author) + pagelog = Page(self.request, pagename).getPagePath(logname, use_underlay=0, isfile=1) + llog = editlog.EditLog(self.request, filename=pagelog, + uid_override=author) + mtime_usecs = wikiutil.timestamp2version(os.path.getmtime(pagefile)) + host = '::1' + extra = u'' + glog.add(self.request, mtime_usecs, rev, action, pagename, host, comment) + llog.add(self.request, mtime_usecs, rev, action, pagename, host, extra, comment) + event_logfile(self,pagename,pagefile) + + +def write_this_page(self,page,pagename,rev,filename,action,author): + pagedir = Page(self.request, pagename).getPagePath("", check_create=1) + revdir = os.path.join(pagedir, 'revisions') + cfn = os.path.join(pagedir,'current') + clfn = os.path.join(pagedir,'current-locked') + + pagelog = Page(self.request, pagename).getPagePath('edit-log', use_underlay=0, isfile=1) + + if not os.path.exists(pagedir): # new page, create and init pagedir + os.mkdir(pagedir) + os.chmod(pagedir, 0777 & config.umask) + + if not os.path.exists(revdir): + os.mkdir(revdir) + os.chmod(revdir, 0777 & config.umask) + + f = open(cfn, 'w') + f.write('%08d\n' % rev) + f.close() + os.chmod(cfn, 0666 & config.umask) + + revstr = '%08d' % rev + f = open(clfn, 'w') + f.write(revstr+'\n') + f.close() + + pagefile = os.path.join(revdir, revstr) + f = codecs.open(pagefile, 'wb', config.charset) + f.write(self.extract_file(filename)) + f.close() + os.chmod(pagefile, 0666 & config.umask) + + filesys.rename(clfn, cfn) + page.clean_acl_cache() + + edit_logfile_append(self,pagename,pagefile,rev,action,logname='edit-log',comment=u'',author=author) + def packLine(list, separator="|"): return '|'.join([x.replace('\\', '\\\\').replace(separator, '\\' + separator) for x in list]) @@ -197,9 +265,62 @@ self.msg += package.msg + def do_addattachment(self,filename,pagename,author=u"Scripting Subsystem", comment=u""): + """ + Installs an attachment + + @param pagename: Page where the file is attached. Or in 2.0, the file itself. + @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) + """ + _ = self.request.getText + + attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) + filename = wikiutil.taintfilename(filename) + target = os.path.join(attachments,filename) + + page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) + rev = page.current_rev() + path = page.getPagePath(check_create=0) + + if not os.path.exists(target): + self._extractToFile(filename, target) + if os.path.exists(target): + os.chmod(target, config.umask ) + action = 'ATTNEW' + edit_logfile_append(self,pagename,path,rev,action,logname='edit-log', + comment=u'%(filename)s' % {"filename":filename},author=author) + self.msg += u"%(filename)s attached \n" % {"filename": filename} + else: + self.msg += u"%(filename)s not attached \n" % {"filename":filename} + + def do_delattachment(self,filename,pagename,author=u"Scripting Subsystem", comment=u""): + """ + Removes an attachment + + @param pagename: Page where the file is attached. Or in 2.0, the file itself. + @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) + """ + _ = self.request.getText + + attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) + filename = wikiutil.taintfilename(filename) + target = os.path.join(attachments,filename) + + page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) + rev = page.current_rev() + path = page.getPagePath(check_create=0) + + if os.path.exists(target): + os.remove(target) + action = 'ATTDEL' + edit_logfile_append(self,pagename,path,rev,action,logname='edit-log', + comment=u'%(filename)s' % {"filename":filename},author=author) + self.msg += u"%(filename)s removed \n" % {"filename":filename} + else: + self.msg += u"%(filename)s not exists \n" % {"filename":filename} + def do_addrevision(self, filename, pagename, author=u"Scripting Subsystem", comment=u"", trivial = u"No"): """ Adds a revision to a page. - @param filename: name of the file in this package @param pagename: name of the target page @param author: user name of the editor (optional) @@ -208,15 +329,28 @@ """ _ = self.request.getText trivial = self._toBoolean(trivial) - + page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) - try: - page.saveText(self.extract_file(filename).decode("utf-8"), 0, trivial=trivial, comment=comment) - except PageEditor.Unchanged: - pass - + rev = page.current_rev() + + if not page.exists() : + rev = 1 + action = 'SAVENEW' + write_this_page(self,page,pagename,rev,filename,action,author) + self.msg += u"new Page %(page)s added\n" % {"page":pagename} + else: + body = page.get_raw_body() + new_text = self.extract_file(filename) + if body != new_text: + rev += 1 + action = 'SAVE' + write_this_page(self,page,pagename,rev,filename,action,author) + + self.msg += u"new revision of %(page)s added\n" % {"page":pagename} + else: + self.msg += u"Page %(page)s not changed\n" % {"page":pagename} page.clean_acl_cache() - + def do_deletepage(self, pagename, comment="Deleted by the scripting subsystem."): """ Marks a page as deleted (like the DeletePage action). @@ -230,6 +364,92 @@ page.deletePage(comment) + def do_renamepage(self,pagename,newpagename,author=u"Scripting Subsystem", comment=u""): + _ = self.request.getText + + newpage = PageEditor(self.request, newpagename) + + # Check whether a page with the new name already exists + if newpage.exists(includeDeleted=0): + self.msg = u'Could not rename page because new page %(newpagename)s already exists\n' % { + 'newpagename': newpagename} + return + + page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) + path = page.getPagePath(check_create=0) + rev = page.current_rev() + + # Get old page text + savetext = page.get_raw_body() + # add comment + savetext = u"## page was renamed from %s\n%s" % (pagename, savetext) + + oldpath = page.getPagePath(check_create=0) + newpath = newpage.getPagePath(check_create=0) + + + # Rename page + + # NOTE: might fail if another process created newpagename just + # NOW, while you read this comment. Rename is atomic for files - + # but for directories, rename will fail if the directory + # exists. We should have global edit-lock to avoid this. + # See http://docs.python.org/lib/os-file-dir.html + try: + os.rename(oldpath, newpath) + + self.newpage = newpage + self.msg = u'%(pagename)s renamed to %(newpagename)s\n' % { + "pagename":pagename, + "newpagename":newpagename} + + action = 'SAVENEW' + + revstr = '%08d' % rev + newpagedir = Page(self.request, newpagename).getPagePath("", check_create=1) + + revdir = os.path.join(newpagedir, 'revisions') + oldpagefile = os.path.join(revdir, revstr) + + rev += 1 + revstr = '%08d' % rev + newpagedir = Page(self.request, newpagename).getPagePath("", check_create=1) + revdir = os.path.join(newpagedir, 'revisions') + newpagefile = os.path.join(revdir, revstr) + + f = open(newpagefile,'w') + f.write(savetext) + f.close() + os.chmod(newpagefile, 0666 & config.umask) + + cfn = os.path.join(newpagedir,'current') + f = open(cfn, 'w') + f.write('%08d\n' % rev) + f.close() + os.chmod(cfn, 0666 & config.umask) + + clfn = os.path.join(newpagedir,'current-locked') + f = open(clfn, 'w') + f.write(revstr+'\n') + f.close() + os.chmod(clfn, 0666 & config.umask) + + edit_logfile_append(self,newpagename,newpath,rev,action,logname='edit-log', + comment=u'Renamed from %(pagename)s' % {"pagename": pagename},author=author) + event_logfile(self,newpagename,newpagefile) + + return + + 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=0): + self.msg = u'Could not rename page because new page %(newpagename)s already exists\n' % { + 'newpagename': newpagename} + return + else: + self.msg = u'Could not rename page because of file systemerror: %s.' % unicode(err) + def do_replaceunderlay(self, filename, pagename): """ Overwrites underlay pages. Implementational detail: This needs to be @@ -438,3 +658,4 @@ print "Installation failed." if package.msg: print package.msg +