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&amp;do=view&amp;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&amp;do=unzip&amp;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.
  • [get | view] (2005-08-05 11:29:52, 28.4 KB) [[attachment:AttachFile-1.3.5-rb.py]]
  • [get | view] (2005-08-05 11:28:28, 5.8 KB) [[attachment:AttachFile-1.3.5.patch]]
  • [get | view] (2005-11-23 21:34:41, 7.4 KB) [[attachment:AttachFile-1.3.5.unzipwithsubdir.patch]]
  • [get | view] (2005-11-23 22:32:32, 4.0 KB) [[attachment:AttachFile-1.5.zipsubdir.patch]]
  • [get | view] (2005-04-08 08:23:38, 28.1 KB) [[attachment:AttachFile.py]]
  • [get | view] (2005-04-30 20:43:59, 0.5 KB) [[attachment:UploadDir.zip]]
  • [get | view] (2005-04-08 08:40:55, 9.5 KB) [[attachment:patch_AttachFile.py]]
  • [get | view] (2005-04-07 20:25:41, 4.3 KB) [[attachment:unzip1.png]]
  • [get | view] (2005-04-07 20:25:54, 5.3 KB) [[attachment:unzip2.png]]
  • [get | view] (2005-04-07 20:26:07, 3.3 KB) [[attachment:unzip3a.png]]
  • [get | view] (2005-04-07 20:26:24, 17.3 KB) [[attachment:unzip3b.png]]
  • [get | view] (2005-04-07 20:26:37, 5.4 KB) [[attachment:unzip4.png]]
  • [get | view] (2005-04-07 20:26:49, 4.6 KB) [[attachment:unzip5.png]]
  • [get | view] (2005-04-07 20:27:01, 4.8 KB) [[attachment:unzip6.png]]
  • [get | view] (2005-04-07 20:27:15, 5.2 KB) [[attachment:unzip7.png]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.