Attachment 'package.patch'
Download 1 --- moin-1.6.orig/MoinMoin/script/export/package.py 1970-01-01 02:00:00.000000000 +0200
2 +++ moin-1.6/MoinMoin/script/export/package.py 2007-12-09 13:06:10.000000000 +0200
3 @@ -0,0 +1,85 @@
4 +# -*- coding: iso-8859-1 -*-
5 +"""
6 + MoinMoin - Create a MoinMoin package from wiki pages specified.
7 +
8 + You must run this script as owner of the wiki files, usually this is the
9 + web server user.
10 +
11 + @copyright: 2002-2004 Juergen Hermann <jh@web.de>,
12 + 2005-2006 MoinMoin:ThomasWaldmann,
13 + 2007 Federico Lorenzi
14 + @license: GNU GPL, see COPYING for details.
15 +
16 +"""
17 +
18 +import codecs, errno, os, re, shutil, sys, time
19 +
20 +from MoinMoin import config, wikiutil, Page, user
21 +from MoinMoin import script
22 +
23 +
24 +class PluginScript(script.MoinScript):
25 + """ Create package class """
26 +
27 + def __init__(self, argv=None, def_values=None):
28 + script.MoinScript.__init__(self, argv, def_values)
29 + self.parser.add_option(
30 + "-p", "--pages", dest="pages",
31 + help="List of pages to package. Can be regular expressions, comma seperated lists, or a lone * for everything."
32 + )
33 + self.parser.add_option(
34 + "-o", "--output", dest="output",
35 + help="Output file for the package."
36 + )
37 + self.parser.add_option(
38 + "-s", "--search", dest="search",
39 + help="Search string to match."
40 + )
41 +
42 + self.parser.add_option(
43 + "-u", "--user", dest="package_user",
44 + help="User as whom the package operation will be performed as. "
45 + )
46 +
47 + def mainloop(self):
48 + """ moin-package's main code. """
49 +
50 + # Initalize request
51 + self.init_request()
52 + request = self.request
53 + _ = self.request.getText
54 +
55 + # Check our command line args
56 + if self.options.pages and self.options.search:
57 + script.fatal(_("Options --pages and --search are mutually exclusive!"))
58 + elif not self.options.output:
59 + script.fatal(_("You must specify an output file!"))
60 + elif not self.options.pages and not self.options.search:
61 + script.log(_("No pages specified using --pages or --search, assuming full package."))
62 +
63 + # Sanity checks
64 + if os.path.exists(self.options.output):
65 + script.fatal(_("Output file already exists! Cowardly refusing to continue!"))
66 +
67 + # Check for user
68 + if self.options.package_user:
69 + request.user = user.User(request, name=self.options.package_user)
70 +
71 + # Import PackagePages here, as we now have an initalized request.
72 + from MoinMoin.action.PackagePages import PackagePages
73 +
74 + # Perform actual packaging.
75 + package = PackagePages(request.rootpage.page_name, request)
76 + packageoutput = open(self.options.output, "wb")
77 + if self.options.search:
78 + packagedata = package.collectpackage(package.searchpackage(request,
79 + self.options.search), packageoutput)
80 + elif self.options.pages:
81 + packagedata = package.collectpackage(self.options.pages.split(","), packageoutput)
82 + else:
83 + packagedata = package.collectpackage(request.rootpage.getPageList(
84 + include_underlay=False,
85 + filter=lambda name: not wikiutil.isSystemPage(request, name)),
86 + packageoutput)
87 + if packagedata:
88 + script.fatal(packagedata)
89 --- moin-1.6.orig/MoinMoin/action/PackagePages.py 2007-12-01 02:09:09.000000000 +0200
90 +++ moin-1.6/MoinMoin/action/PackagePages.py 2007-12-09 12:48:33.000000000 +0200
91 @@ -20,6 +20,7 @@
92 from MoinMoin.packages import MOIN_PACKAGE_FILE, packLine, unpackLine
93 from MoinMoin.action import AttachFile
94 from MoinMoin.action.AttachFile import _get_files
95 +from MoinMoin.search import searchPages
96
97 class ActionError(Exception):
98 pass
99 @@ -60,10 +61,9 @@
100 return self.page.send_page(msg=e.args[0])
101
102 def package(self):
103 - """ Packages pages. """
104 + """ Calls collectpackage() with the arguments specified. """
105 _ = self.request.getText
106 form = self.request.form
107 - COMPRESSION_LEVEL = zipfile.ZIP_DEFLATED
108
109 # Get new name from form and normalize.
110 pagelist = form.get('pagelist', [u''])[0]
111 @@ -72,17 +72,6 @@
112 if not form.get('submit', [None])[0]:
113 raise ActionError(self.makeform())
114
115 - pages = []
116 - for pagename in unpackLine(pagelist, ","):
117 - pagename = self.request.normalizePagename(pagename)
118 - if pagename:
119 - page = Page(self.request, pagename)
120 - if page.exists() and self.request.user.may.read(pagename):
121 - pages.append(page)
122 - if not pages:
123 - raise ActionError(self.makeform(_('No pages like "%s"!', formatted=False) % wikiutil.escape(pagelist)))
124 -
125 - pagelist = ', '.join([getattr(page, "page_name") for page in pages])
126 target = wikiutil.taintfilename(packagename)
127
128 if not target:
129 @@ -95,35 +84,14 @@
130 raise ActionError(_("Attachment '%(target)s' (remote name '%(filename)s') already exists.", formatted=False) % {
131 'target': wikiutil.escape(target), 'filename': wikiutil.escape(target)})
132
133 - zf = zipfile.ZipFile(fpath, "w", COMPRESSION_LEVEL)
134 -
135 - cnt = 0
136 - script = [packLine(['MoinMoinPackage', '1']),
137 - ]
138 -
139 - for page in pages:
140 - cnt += 1
141 - files = _get_files(self.request, page.page_name)
142 - script.append(packLine(["AddRevision", str(cnt), page.page_name, user.getUserIdentification(self.request), "Created by the PackagePages action."]))
143 -
144 - timestamp = wikiutil.version2timestamp(page.mtime_usecs())
145 - zi = zipfile.ZipInfo(filename=str(cnt), date_time=datetime.fromtimestamp(timestamp).timetuple()[:6])
146 - zi.compress_type = COMPRESSION_LEVEL
147 - zf.writestr(zi, page.get_raw_body().encode("utf-8"))
148 - for attname in files:
149 - if attname != packagename:
150 - cnt += 1
151 - zipname = "%d_attachment" % cnt
152 - script.append(packLine(["AddAttachment", zipname, attname, page.page_name, user.getUserIdentification(self.request), "Created by the PackagePages action."]))
153 - filename = AttachFile.getFilename(self.request, page.page_name, attname)
154 - zf.write(filename.encode("cp437"), zipname)
155 - script += [packLine(['Print', 'Thank you for using PackagePages!'])]
156 -
157 - zf.writestr(MOIN_PACKAGE_FILE, u"\n".join(script).encode("utf-8"))
158 - zf.close()
159 -
160 + # Generate a package
161 + output = open(fpath, "wb")
162 + package = self.collectpackage(unpackLine(pagelist, ","), output, target)
163 +
164 + if package:
165 + raise ActionError(self.makeform(package))
166 +
167 _addLogEntry(self.request, 'ATTNEW', self.pagename, target)
168 -
169 raise ActionError(_("Created the package %s containing the pages %s.", formatted=False) % (wikiutil.escape(target), wikiutil.escape(pagelist)))
170
171 def makeform(self, error=""):
172 @@ -174,6 +142,77 @@
173
174 return Dialog(self.request, content=form)
175
176 + def searchpackage(self, request, searchkey):
177 + """ Search MoinMoin for the string specified and return a list of
178 + matching pages, provided they are not system pages and not
179 + present in the underlay.
180 +
181 + @param request: current request
182 + @param searchkey: string to search for
183 + @rtype: list
184 + @return: list of pages matching searchkey
185 + """
186 +
187 + pagelist = searchPages(request, searchkey)
188 +
189 + titles = []
190 + for title in pagelist.hits:
191 + if not wikiutil.isSystemPage(request, title.page_name) or not title.page.getPageStatus()[0]:
192 + titles.append(title.page_name)
193 + return titles
194 +
195 + def collectpackage(self, pagelist, fileobject, pkgname=""):
196 + """ Expects a list of pages as an argument, and fileobject to be an open
197 + file object, which a zipfile will get written to.
198 +
199 + @param pagelist: pages to package
200 + @param fileobject: open file object to write to
201 + @param pkgname: optional file name, to prevent self packaging
202 + @rtype: string or None
203 + @return: error message, if one happened
204 + """
205 + _ = self.request.getText
206 + form = self.request.form
207 + COMPRESSION_LEVEL = zipfile.ZIP_DEFLATED
208 +
209 + pages = []
210 + for pagename in pagelist:
211 + pagename = self.request.normalizePagename(pagename)
212 + if pagename:
213 + page = Page(self.request, pagename)
214 + if page.exists() and self.request.user.may.read(pagename):
215 + pages.append(page)
216 + if not pages:
217 + return (_('No pages like "%s"!', formatted=False) % wikiutil.escape(pagelist))
218 +
219 + # Set zipfile output
220 + zf = zipfile.ZipFile(fileobject, "w", COMPRESSION_LEVEL)
221 +
222 + cnt = 0
223 + userid = user.getUserIdentification(self.request)
224 + script = [packLine(['MoinMoinPackage', '1']), ]
225 +
226 + for page in pages:
227 + cnt += 1
228 + files = _get_files(self.request, page.page_name)
229 + script.append(packLine(["AddRevision", str(cnt), page.page_name, userid, "Created by the PackagePages action."]))
230 +
231 + timestamp = wikiutil.version2timestamp(page.mtime_usecs())
232 + zi = zipfile.ZipInfo(filename=str(cnt), date_time=datetime.fromtimestamp(timestamp).timetuple()[:6])
233 + zi.compress_type = COMPRESSION_LEVEL
234 + zf.writestr(zi, page.get_raw_body().encode("utf-8"))
235 + for attname in files:
236 + if attname != pkgname:
237 + cnt += 1
238 + zipname = "%d_attachment" % cnt
239 + script.append(packLine(["AddAttachment", zipname, attname, page.page_name, userid, "Created by the PackagePages action."]))
240 + filename = AttachFile.getFilename(self.request, page.page_name, attname)
241 + zf.write(filename.encode("cp437"), zipname)
242 + script += [packLine(['Print', 'Thank you for using PackagePages!'])]
243 +
244 + zf.writestr(MOIN_PACKAGE_FILE, u"\n".join(script).encode("utf-8"))
245 + zf.close()
246 +
247 def execute(pagename, request):
248 """ Glue code for actions """
249 PackagePages(pagename, request).render()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.