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
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.
Ok, changed -- ReimarBauer 2006-07-09 20:26:23
Needs to be connected to AttachFile -- ReimarBauer 2006-11-30 20:27:25
Rename Page needs to be checked if there is another method available. -- ReimarBauer 2007-01-07 10:33:47
added with some changes to PackagePages action and storage module from above removed