Short description

We do often use the packages routine to setup pages including attachments. -- ReimarBauer 2006-06-03 19:22:57

AddAttachment|attachment file name included in zip file |PageName|UserName|Comment

DelAttachment|attachment file name|PageName|UserName|Comment

RenamePage|PageName|NewPageName|UserName|Comment

AddRevision changes the user given from the command file so ACLs do work.

And for these four actions log entries are written.

   1 # HG changeset patch
   2 # User ReimarBauer <R.Bauer@fz-juelich.de>
   3 # Node ID 1fbf6795947a2497ca90a2bcfa7c8550e994a329
   4 # Parent  9dcfb8f3652473459b7a2e5f727718666ae99b37
   5 added funtionality of AddAtachment, DelAttachment, RenamePage and comments for 
   6 Addrevision and ignoring of empty lines by len(line) == 0 may be it would be better here to check if there are the wanted colums.
   7 
   8 diff -r 9dcfb8f36524 -r 1fbf6795947a MoinMoin/packages.py
   9 --- a/MoinMoin/packages.py	Sun Jul 09 10:55:43 2006 +0200
  10 +++ b/MoinMoin/packages.py	Sun Jul 09 22:21:51 2006 +0200
  11 @@ -6,16 +6,19 @@
  12      @license: GNU GPL, see COPYING for details.
  13  """
  14  
  15 -import os
  16 +import os, codecs
  17  import sys
  18  import zipfile
  19  
  20 -from MoinMoin import config, wikiutil, caching
  21 +from MoinMoin import config, wikiutil, caching, user, storage
  22  from MoinMoin.Page import Page
  23  from MoinMoin.PageEditor import PageEditor
  24 +from MoinMoin.util import filesys
  25 +from MoinMoin.logfile import editlog, eventlog
  26  
  27  MOIN_PACKAGE_FILE = 'MOIN_PACKAGE'
  28  MAX_VERSION = 1
  29 +
  30  
  31  # Exceptions
  32  class PackageException(Exception):
  33 @@ -37,6 +40,26 @@ class RuntimeScriptException(ScriptExcep
  34  
  35  class ScriptExit(Exception):
  36      """ Raised by the script commands when the script should quit. """
  37 +
  38 +def event_logfile(self, pagename, pagefile):
  39 +    # add event log entry
  40 +    filename = self.request.rootpage.getPagePath('event-log', isfile=1)
  41 +    eventtype = 'SAVENEW'
  42 +    mtime_usecs = wikiutil.timestamp2version(os.path.getmtime(pagefile))
  43 +    elog = eventlog.EventLog(self.request)
  44 +    elog.add(self.request, eventtype, {'pagename': pagename}, 1, mtime_usecs)
  45 +
  46 +def edit_logfile_append(self, pagename, pagefile, rev, action, logname='edit-log', comment=u'', author=u"Scripting Subsystem"):
  47 +    glog = editlog.EditLog(self.request, uid_override=author)
  48 +    pagelog = Page(self.request, pagename).getPagePath(logname, use_underlay=0, isfile=1)
  49 +    llog = editlog.EditLog(self.request, filename=pagelog,
  50 +                               uid_override=author)
  51 +    mtime_usecs = wikiutil.timestamp2version(os.path.getmtime(pagefile))
  52 +    host = '::1'
  53 +    extra = u''
  54 +    glog.add(self.request, mtime_usecs, rev, action, pagename, host, comment)
  55 +    llog.add(self.request, mtime_usecs, rev, action, pagename, host, extra, comment)
  56 +    event_logfile(self, pagename, pagefile)
  57  
  58  # Parsing and (un)quoting for script files
  59  def packLine(list, separator="|"):
  60 @@ -95,6 +118,55 @@ class ScriptEngine:
  61          #Satisfy pylint
  62          self.msg = getattr(self, "msg", "")
  63          self.request = getattr(self, "request", None)
  64 +    def do_addattachment(self, filename, pagename, author=u"Scripting Subsystem", comment=u""):
  65 +        """
  66 +        Installs an attachment
  67 +
  68 +        @param pagename: Page where the file is attached. Or in 2.0, the file itself.
  69 +        @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0)
  70 +        """
  71 +        _ = self.request.getText
  72 +
  73 +        attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1)
  74 +        filename = wikiutil.taintfilename(filename)
  75 +        target = os.path.join(attachments, filename)
  76 +        page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author)
  77 +        rev = page.current_rev()
  78 +        path = page.getPagePath(check_create=0)
  79 +        if not os.path.exists(target):
  80 +           self._extractToFile(filename, target)
  81 +           if os.path.exists(target):
  82 +              os.chmod(target, config.umask )
  83 +              action = 'ATTNEW'
  84 +              edit_logfile_append(self, pagename, path, rev, action, logname='edit-log',
  85 +                      comment=u'%(filename)s' % {"filename":filename}, author=author)
  86 +              self.msg += u"%(filename)s attached \n" % {"filename": filename}
  87 +        else:
  88 +           self.msg += u"%(filename)s not attached \n" % {"filename":filename}
  89 +
  90 +    def do_delattachment(self, filename, pagename, author=u"Scripting Subsystem", comment=u""):
  91 +        """
  92 +        Removes an attachment
  93 +
  94 +        @param pagename: Page where the file is attached. Or in 2.0, the file itself.
  95 +        @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0)
  96 +        """
  97 +        _ = self.request.getText
  98 +
  99 +        attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1)
 100 +        filename = wikiutil.taintfilename(filename)
 101 +        target = os.path.join(attachments, filename)
 102 +        page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author)
 103 +        rev = page.current_rev()
 104 +        path = page.getPagePath(check_create=0)
 105 +        if os.path.exists(target):
 106 +              os.remove(target)
 107 +              action = 'ATTDEL'
 108 +              edit_logfile_append(self, pagename, path, rev, action, logname='edit-log',
 109 +                      comment=u'%(filename)s' % {"filename":filename}, author=author)
 110 +              self.msg += u"%(filename)s removed \n" % {"filename":filename}
 111 +        else:
 112 +           self.msg += u"%(filename)s not exists \n" % {"filename":filename}
 113  
 114      def do_print(self, *param):
 115          """ Prints the parameters into output of the script. """
 116 @@ -215,14 +287,40 @@ class ScriptEngine:
 117          """
 118          _ = self.request.getText
 119          trivial = str2boolean(trivial)
 120 -
 121 +        uid = user.getUserId(self.request, author)
 122 +        theuser = user.User(self.request, uid)
 123 +        self.request.user = theuser
 124          page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author)
 125          try:
 126              page.saveText(self.extract_file(filename).decode("utf-8"), 0, trivial=trivial, comment=comment)
 127 +            self.msg += u"%(pagename)s added \n" % {"pagename": pagename}
 128          except PageEditor.Unchanged:
 129              pass
 130 -
 131          page.clean_acl_cache()
 132 +
 133 +    def do_renamepage(self, pagename, newpagename, author=u"Scripting Subsystem", comment=u""):
 134 +        page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author)
 135 +        newpage = PageEditor(self.request, newpagename)
 136 +        newpagedir = Page(self.request, newpagename).getPagePath("", check_create=1)
 137 +        newpath = newpage.getPagePath(check_create=0)
 138 +        if newpage.exists(includeDeleted=0):
 139 +             self.msg = u'Could not rename page because new page %(newpagename)s already exists\n' % {
 140 +                            'newpagename': newpagename}
 141 +             return
 142 +        rev, err = storage.renamepage(self, pagename, newpagename, author=u"Scripting Subsystem", comment=u"")
 143 +        revstr = '%08d' % rev
 144 +        revdir = os.path.join(newpagedir, 'revisions')
 145 +        newpagefile = os.path.join(revdir, revstr)
 146 +        if rev < 0:
 147 +            self.msg = u'Could not rename page because of file systemerror: %s.' % unicode(err)
 148 +            return
 149 +        action = 'SAVENEW'
 150 +        edit_logfile_append(self, newpagename, newpath, rev, action, logname='edit-log',
 151 +                  comment=u'Renamed from %(pagename)s' % {"pagename": pagename}, author=author)
 152 +        event_logfile(self, newpagename, newpagefile)
 153 +        self.msg = u'%(pagename)s renamed to %(newpagename)s\n' % {
 154 +                    "pagename":pagename,
 155 +                    "newpagename":newpagename}
 156  
 157      def do_deletepage(self, pagename, comment="Deleted by the scripting subsystem."):
 158          """ Marks a page as deleted (like the DeletePage action).
 159 @@ -301,7 +399,7 @@ class ScriptEngine:
 160                  self.goto -= 1
 161                  continue
 162  
 163 -            if line.startswith("#"):
 164 +            if line.startswith("#") or len(line) == 0:
 165                  continue
 166              elements = unpackLine(line)
 167              fnname = elements[0].strip().lower()
 168 @@ -448,4 +546,3 @@ Example:
 169  
 170  if __name__ == '__main__':
 171      main()
 172 -
 173 diff -r 9dcfb8f36524 -r 1fbf6795947a MoinMoin/storage.py
 174 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 175 +++ b/MoinMoin/storage.py	Sun Jul 09 22:21:51 2006 +0200
 176 @@ -0,0 +1,64 @@
 177 +"""
 178 +rename page called from packages
 179 +
 180 +copyright Reimar Bauer, 2006-07-08
 181 +
 182 +License GPL
 183 +"""
 184 +import os
 185 +
 186 +from MoinMoin import config
 187 +from MoinMoin.Page import Page
 188 +from MoinMoin.PageEditor import PageEditor
 189 +
 190 +def renamepage(self, pagename, newpagename, author=u"Scripting Subsystem", comment=u""):
 191 +
 192 +    _ = self.request.getText
 193 +    err = 0
 194 +    newpage = PageEditor(self.request, newpagename)
 195 +
 196 +    # Check whether a page with the new name already exists
 197 +    page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author)
 198 +    path = page.getPagePath(check_create=0)
 199 +    rev = page.current_rev()
 200 +    # Get old page text
 201 +    savetext = page.get_raw_body()
 202 +    # add comment
 203 +    savetext = u"## page was renamed from %s\n%s" % (pagename, savetext)
 204 +    oldpath = page.getPagePath(check_create=0)
 205 +    newpath = newpage.getPagePath(check_create=0)
 206 +    # Rename page
 207 +
 208 +    # NOTE: might fail if another process created newpagename just
 209 +    # NOW, while you read this comment. Rename is atomic for files -
 210 +    # but for directories, rename will fail if the directory
 211 +    # exists. We should have global edit-lock to avoid this.
 212 +    # See http://docs.python.org/lib/os-file-dir.html
 213 +    try:
 214 +        os.rename(oldpath, newpath)
 215 +        revstr = '%08d' % rev
 216 +        newpagedir = Page(self.request, newpagename).getPagePath("", check_create=1)
 217 +        revdir = os.path.join(newpagedir, 'revisions')
 218 +        rev += 1
 219 +        revstr = '%08d' % rev
 220 +        newpagedir = Page(self.request, newpagename).getPagePath("", check_create=1)
 221 +        revdir = os.path.join(newpagedir, 'revisions')
 222 +        newpagefile = os.path.join(revdir, revstr)
 223 +
 224 +        f = open(newpagefile, 'w'
 225 +        f.write(savetext)
 226 +        f.close()
 227 +        os.chmod(newpagefile, 0666 & config.umask)
 228 +        cfn = os.path.join(newpagedir, 'current')
 229 +        f = open(cfn, 'w')
 230 +        f.write('%08d\n' % rev)
 231 +        f.close()
 232 +        os.chmod(cfn, 0666 & config.umask)
 233 +        clfn = os.path.join(newpagedir, 'current-locked')
 234 +        f = open(clfn, 'w')
 235 +        f.write(revstr+'\n')
 236 +        f.close()
 237 +        os.chmod(clfn, 0666 & config.umask)
 238 +        return rev, err
 239 +    except OSError, err:
 240 +        return rev * (-1), err
 241 
packages_20060709.patch

Discussion

Please use PageEditor methods instead of write_this_page

PageEditor method saveText used because self.request.user could be set to the users name.

Please factor the actual rename code out of the method into a new method so it can be replaced with the interface to the new storage code more easily.

added with some changes to PackagePages action and storage module from above removed


CategoryFeatureImplemented

MoinMoin: FeatureRequests/PackagesNeedsAddAttachmentAndMore (last edited 2007-10-29 19:17:09 by localhost)