Short description

It would be fine to have the possibility to upload multiple files at once. At the moment only one file could be selected for uploading. Probably this could be changed. File renaming for multiple files does not matter in this case. This would be very useful for the Gallery2 parser. -- ReimarBauer 2005-03-26 09:05:58

Its not difficult, simply provide multiple file input elements, there are sites that use up to 10 files uploads.

Windows or mac user does not know how to create tarballs, but zip files can be created in Mac OS X with no additional software (same in XP?), available on Linux too (GPL?). Maybe support both.

This is a necessary feature when you're working on long or complicated documents via the wiki, that require lots of screenshots or other attachments, e.g. documentation. This was the first thing we added into our TWiki installation. File uploads via web browsers is so finicky that one larger upload was safer than multiple small ones on the same form, and when you're attaching fifty or more screenshots, it's definitely necessary. However, even this is suboptimal, and we wished for alternatives, like uploading of attachments via WebDAV, or using a client-side utility.

/RulesForUnzip and patch and tests and example


-- ReimarBauer 2005-03-28 18:11:45

Exploding a zipfile can be dangerous. So I would prefer another solution. -- ThomasWaldmann 2005-03-28 22:10:49

Yes, we had to insert of a bunch of security checks in our TWiki version. We checked the size of each file to make sure people couldn't bomb the wiki with a 500K zip that unzips to a 500MB file. Since attachments can't have subdirectories, we also ignore those completely so you can't unzip to any random path that the web site as write access to, we ignore extra unix permissions, things like that.

Wouldn't do any good; TWiki is a Perl wiki. :) The security issues we dealt with specifically were:

    elif request.form['do'][0] == 'unzip':
        if request.user.may.delete(pagename) and request.user.may.read(pagename):
            attachment_path = getAttachDir(request, pagename)
            files = _get_files(request, pagename)


            fsize =0.0
            if files:
               for file in files:
                   fsize += float(os.stat(os.path.join(attachment_path,file).encode(config.charset))[6]) # in byte

            single_file_size=10.0*1024*1024
            attachments_file_space=100.0*1024*1024
            avalaible_attachments_file_space=attachments_file_space-fsize

            target=request.form['target'][0]
            file=attachment_path+'/'+target
            if zipfile.is_zipfile(file):
               zf = zipfile.ZipFile(file)
               sum_size_over_all_valid_files=0.0
               for name in zf.namelist():
                  if ((string.find(name,'/') == -1) and (string.find(name,'\\') == -1)):
                       zi = zf.getinfo(name)
                       sum_size_over_all_valid_files+=zi.file_size

               if (sum_size_over_all_valid_files < avalaible_attachments_file_space):

                   valid_name=[]
                   for name in zf.namelist():
                       if ((string.find(name,'/') == -1) and (string.find(name,'\\') == -1)):
                           zi = zf.getinfo(name)
                           if (zi.file_size < (single_file_size)):
                               new_file=os.path.join(attachment_path, name).encode(config.charset)
                               if not os.path.exists(new_file):
                                   outfile = open(new_file, 'wb')
                                   outfile.write(zf.read(name))
                                   outfile.flush()
                                   outfile.close()
                               # it's not allowed to zip a zip file so this is dropped
                                   if zipfile.is_zipfile(new_file):
                                      os.unlink(new_file)
                                   else:
                                      valid_name.append(name)
                                      os.chmod(new_file, 0666 & config.umask)
                                      _addLogEntry(request, 'ATTNEW', pagename, new_file)

                   if (len(valid_name) > 0):
                      upload_form(pagename, request, msg=_("Attachment '%(filename)s' unziped.") %
                                     {'filename': target})
                   else:
                      upload_form(pagename, request, msg=_("Attachment '%(filename)s' not unziped because result to big or included zip file or file exists.") %
                                     {'filename': target})
               else:
                 upload_form(pagename, request, msg=_("Attachment '%(filename)s' could not be unziped because result to big (%(space)d kB missing).") %
                             {'filename': target,
                              'space':(sum_size_over_all_valid_files-avalaible_attachments_file_space)/1024})

            else:
               msg = _('file '+target+' is no zip file!')
        else:
            msg = _('You are not allowed to unzip attachments of this page.')

When it is ready, attach a unified diff in order to make it easier for others to merge it.

Please add also tests for all important cases that show that this code really works.

We should note that the famous 42.zip will not affect this code because it is based on stacked .zip files.


The zip mechanism is nice but not very end-user friendly. Plus, sites on the web have set the bar higher by being able to upload multiple files relatively easily. It would be very very nice to have some way to do this directly with MoinMoin. Any clever ideas on this? How about an optional Java helper applet like some sites use? It would be nice to select multiple files or say all files in a directory.

A better place as this would be a new FeatureRequests. Please move it to a separate page -- ReimarBauer 2007-04-26 21:40:32


CategoryFeatureRequestImplemented

MoinMoin: FeatureRequests/UploadMultipleAttachmentFiles (last edited 2007-10-29 19:19:52 by localhost)