Attachment 'AttachFile-1.3.5.unzipwithsubdir.patch'
Download 1 --- AttachFile.py.orig 2005-11-23 13:53:27.173617264 -0600
2 +++ AttachFile.py 2005-11-23 15:31:18.690011096 -0600
3 @@ -20,10 +20,12 @@
4
5 @copyright: 2001 by Ken Sugino (sugino@mediaone.net)
6 @copyright: 2001-2004 by Jürgen Hermann <jh@web.de>
7 + @copyright: 2005 ReimarBauer added zip file extension based on patch for 1.3.4 and DesktopEdition 1.3.4-2 by AlexanderSchremmer
8 + @copyright: 2005 DiegoOngaro at ETSZONE <diego@etszone.com> Added an exception to zip file unpacking for single subdirectory cases
9 @license: GNU GPL, see COPYING for details.
10 """
11
12 -import os, mimetypes, time, urllib
13 +import os, mimetypes, time, urllib, zipfile
14 from MoinMoin import config, user, util, wikiutil
15 from MoinMoin.Page import Page
16 from MoinMoin.util import MoinMoinNoFooter, filesys, web
17 @@ -203,6 +205,7 @@
18 label_get = _("get")
19 label_edit = _("edit")
20 label_view = _("view")
21 + label_unzip = _("unzip")
22
23 for file in files:
24 fsize = float(os.stat(os.path.join(attach_dir,file).encode(config.charset))[6]) # in byte
25 @@ -218,6 +221,7 @@
26 'urlfile': urlfile, 'label_del': label_del,
27 'base': base, 'label_edit': label_edit,
28 'label_view': label_view,
29 + 'label_unzip': label_unzip,
30 'get_url': get_url, 'label_get': label_get,
31 'file': wikiutil.escape(file), 'fsize': fsize,
32 'pagename': pagename}
33 @@ -232,6 +236,11 @@
34 else:
35 viewlink = '<a href="%(baseurl)s/%(urlpagename)s?action=%(action)s&do=view&target=%(urlfile)s">%(label_view)s</a>' % parmdict
36
37 + if (zipfile.is_zipfile(os.path.join(attach_dir,file).encode(config.charset)) and
38 + request.user.may.read(pagename) and request.user.may.delete(pagename)
39 + and request.user.may.write(pagename)):
40 + viewlink += ' | <a href="%(baseurl)s/%(urlpagename)s?action=%(action)s&do=unzip&target=%(urlfile)s">%(label_unzip)s</a>' % parmdict
41 +
42 parmdict['viewlink'] = viewlink
43 parmdict['del_link'] = del_link
44 str = str + ('<li>[%(del_link)s'
45 @@ -261,6 +270,29 @@
46 def error_msg(pagename, request, msg):
47 Page(request, pagename).send_page(request, msg=msg)
48
49 +def _subdir_exception(zf):
50 + """
51 + Checks for the existance of one common subdirectory shared among
52 + all files in the zip file. If this is the case, returns a dict of
53 + original names to modified names so that such files can be unpacked
54 + as the user would expect.
55 + """
56 +
57 + b = zf.namelist()
58 + if not '/' in b[0]:
59 + return (False, 0) #No directory
60 + slashoffset = b[0].index('/')
61 + directory = b[0][:slashoffset]
62 + for origname in b:
63 + if '/' in origname and origname.rindex('/') != slashoffset:
64 + return (False, 1) #Multiple directories or different length directory
65 + for origname in b:
66 + if origname[:slashoffset] != directory:
67 + return (False, 2) #One, same-length, but different directory
68 + names = {}
69 + for origname in b:
70 + names[origname] = origname[slashoffset+1:]
71 + return (True, names) #Returns dict of {origname: safename}
72
73 #############################################################################
74 ### Create parts of the Web interface
75 @@ -419,6 +451,11 @@
76 get_file(pagename, request)
77 else:
78 msg = _('You are not allowed to get attachments from this page.')
79 + elif request.form['do'][0] == 'unzip':
80 + if request.user.may.delete(pagename) and request.user.may.read(pagename) and request.user.may.write(pagename):
81 + unzip_file(pagename, request)
82 + else:
83 + msg = _('You are not allowed to unzip attachments of this page.')
84 elif request.form['do'][0] == 'view':
85 if request.user.may.read(pagename):
86 view_file(pagename, request)
87 @@ -587,6 +624,81 @@
88
89 raise MoinMoinNoFooter
90
91 +def unzip_file(pagename, request):
92 + _ = request.getText
93 + valid_pathname = lambda name: (name.find('/') == -1) and (name.find('\\') == -1)
94 +
95 + filename, fpath = _access_file(pagename, request)
96 + if not filename: return # error msg already sent in _access_file
97 +
98 + attachment_path = getAttachDir(request, pagename)
99 + single_file_size = 2.0 * 1000**2
100 + attachments_file_space = 200.0 * 1000**2
101 +
102 + files = _get_files(request, pagename)
103 +
104 + msg = ""
105 + if files:
106 + fsize = 0.0
107 + for file in files:
108 + fsize += float(os.stat(getFilename(request, pagename, file))[6]) # in byte
109 +
110 + available_attachments_file_space = attachments_file_space - fsize
111 +
112 + if zipfile.is_zipfile(fpath):
113 + zf = zipfile.ZipFile(fpath)
114 + sum_size_over_all_valid_files = 0.0
115 + subdir_exception = _subdir_exception(zf)
116 + if not subdir_exception[0]:
117 + #Convert normal zf.namelist() to {origname:finalname} dict
118 + namelist = {}
119 + for name in zf.namelist():
120 + namelist[name] = name
121 + else:
122 + #Use _subdir_exception()'s {origname:finalname} dict
123 + namelist = subdir_exception[1]
124 +
125 + for (origname, finalname) in namelist.iteritems():
126 + if valid_pathname(finalname):
127 + sum_size_over_all_valid_files += zf.getinfo(origname).file_size
128 +
129 + if sum_size_over_all_valid_files < available_attachments_file_space:
130 + valid_name = False
131 + for (origname, finalname) in namelist.iteritems():
132 + if valid_pathname(finalname):
133 + zi = zf.getinfo(origname)
134 + if zi.file_size < single_file_size:
135 + new_file = getFilename(request, pagename, finalname)
136 + if not os.path.exists(new_file):
137 + outfile = open(new_file, 'wb')
138 + outfile.write(zf.read(origname))
139 + outfile.close()
140 + # it's not allowed to zip a zip file so it is dropped
141 + if zipfile.is_zipfile(new_file):
142 + os.unlink(new_file)
143 + else:
144 + valid_name = True
145 + os.chmod(new_file, 0666 & config.umask)
146 + _addLogEntry(request, 'ATTNEW', pagename, new_file)
147 +
148 + if valid_name:
149 + msg=_("Attachment '%(filename)s' unzipped.") % {'filename': filename}
150 + else:
151 + msg=_("Attachment '%(filename)s' not unzipped because the "
152 + "files are too big, .zip files only, exist already or "
153 + "reside in folders.") % {'filename': filename}
154 + else:
155 + msg=_("Attachment '%(filename)s' could not be unzipped because"
156 + " the resulting files would be too large (%(space)d kB"
157 + " missing).") % {'filename': filename,
158 + 'space': (sum_size_over_all_valid_files -
159 + available_attachments_file_space) / 1000}
160 + else:
161 + msg = _('The file %(target) is not a .zip file.' % target)
162 +
163 + upload_form(pagename, request, msg=wikiutil.escape(msg))
164 +
165 +
166 def send_viewfile(pagename, request):
167 _ = request.getText
168
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.