sbsv2/raptor/util/install-windows/unzip.py
changeset 0 044383f39525
child 3 e1eecf4d390d
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 # The MIT License
       
     2 # Copyright (c) 2003 Doug Tolton
       
     3 #
       
     4 # Permission is hereby granted, free of charge, to any person obtaining a copy
       
     5 # of this software and associated documentation files (the "Software"), to deal
       
     6 # in the Software without restriction, including without limitation the rights
       
     7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
     8 # copies of the Software, and to permit persons to whom the Software is
       
     9 # furnished to do so, subject to the following conditions:
       
    10 # 
       
    11 # The above copyright notice and this permission notice shall be included in
       
    12 # all copies or substantial portions of the Software.
       
    13 # 
       
    14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    20 # THE SOFTWARE.
       
    21 #
       
    22 #
       
    23 
       
    24 """ unzip.py
       
    25     Version: 1.1
       
    26 
       
    27     Extract a zip file to the directory provided
       
    28     It first creates the directory structure to house the files
       
    29     then it extracts the files to it.
       
    30 
       
    31     Sample usage:
       
    32     Windows command line
       
    33     unzip.py -p 10 -z c:\testfile.zip -o c:\testoutput
       
    34     
       
    35     Linux command line
       
    36     unzip.py -p 10 -z /tmp/testfile.zip -o /tmp/testoutput
       
    37 
       
    38     Python class:
       
    39     import unzip
       
    40     un = unzip.unzip()
       
    41     un.extract(r'c:\testfile.zip', r'c:\testoutput') # Windows
       
    42     un.extract(r'/tmp/testfile.zip', '/tmp/testoutput') # Linux
       
    43     
       
    44     By Doug Tolton
       
    45     
       
    46     Taken from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252508
       
    47     
       
    48     Updated by Daniel Jacobs to be OS-neutral and more stable.
       
    49 """
       
    50 
       
    51 import sys
       
    52 import zipfile
       
    53 import os
       
    54 import os.path
       
    55 import getopt
       
    56 import errno
       
    57 
       
    58 class unzip:
       
    59     def __init__(self, verbose = False, percent = 10):
       
    60         self.verbose = verbose
       
    61         self.percent = percent
       
    62         
       
    63     def extract(self, file, dir):
       
    64         """ Extract all the files in the zip file, "file" to the directory "dir" with full path names."""
       
    65         if not dir.endswith(':') and not os.path.exists(dir):
       
    66             self._makedir(dir)
       
    67 
       
    68         zf = zipfile.ZipFile(file)
       
    69 
       
    70         # create directory structure to house files
       
    71         self._createstructure(file, dir)
       
    72 
       
    73         num_files = len(zf.namelist())
       
    74         percent = self.percent
       
    75         divisions = 100 / percent
       
    76         perc = int(num_files / divisions)
       
    77 
       
    78         # extract files to directory structure
       
    79         for i, name in enumerate(zf.namelist()):
       
    80 
       
    81             if self.verbose == True:
       
    82                 print "Extracting %s" % name
       
    83             elif perc > 0 and (i % perc) == 0 and i > 0:
       
    84                 complete = int (i / perc) * percent
       
    85                 print "%s%% complete" % complete
       
    86 
       
    87             if not name.endswith('/'):
       
    88                 # Normalise the path so that it is correct for the current OS
       
    89                 localdirname = os.path.normpath(os.path.join(dir, os.path.dirname(name)))
       
    90                 
       
    91                 # Ensure that the directory hierarchy that contains the files exists so that 
       
    92                 # writing to the file is valid. Note: some zip tools omit directory information 
       
    93                 # and this will cause problems when trying to write file to non-existent directories.
       
    94                 self._makedir(localdirname)
       
    95                     
       
    96                 # Write the file
       
    97                 outfile = open(os.path.join(localdirname, os.path.basename(name)), 'wb')
       
    98                 outfile.write(zf.read(name))
       
    99                 outfile.flush()
       
   100                 outfile.close()
       
   101         
       
   102         zf.close()
       
   103 
       
   104 
       
   105     def _createstructure(self, file, dir):
       
   106         self._makedirs(self._listdirs(file), dir)
       
   107 
       
   108 
       
   109     def _makedirs(self, directories, basedir):
       
   110         """ Create any directories that don't currently exist """
       
   111         for dir in directories:
       
   112             curdir = os.path.join(basedir, dir)
       
   113             # Normalise path for current OS.
       
   114             curdir = os.path.normpath(curdir)
       
   115             self._makedir(curdir) 
       
   116             
       
   117     
       
   118     def _makedir(self, directory):
       
   119         """ Create a directory "safely", catching the "file exists" exception if the 
       
   120         directory has been created by another process. Creates all parent directories
       
   121         recursively as requied. """
       
   122         if not os.path.exists(directory):
       
   123             # In multi-threaded uses, it is possible that this directory 
       
   124             # has been made in the meantime. Catch this exception.
       
   125             try:
       
   126                 os.makedirs(directory)
       
   127             except OSError, aOSError:
       
   128                 # If the OSError is that the file exists then we are OK - this
       
   129                 # might occur in a multi-threaded or multi-process environment;
       
   130                 # otherwise re-raise the exception since it's something else bad.
       
   131                 if aOSError.errno != errno.EEXIST:
       
   132                     raise aOSError
       
   133 
       
   134     def _listdirs(self, file):
       
   135         """ Grabs all the directories in the zip structure
       
   136         This is necessary to create the structure before trying
       
   137         to extract the file to it. """
       
   138         zf = zipfile.ZipFile(file)
       
   139 
       
   140         dirs = []
       
   141 
       
   142         for name in zf.namelist():
       
   143             if name.endswith('/'):
       
   144                 if self.verbose == True:
       
   145                     print "Directory \"" + name + "\" will be made."
       
   146                 dirs.append(name)
       
   147         
       
   148         zf.close()
       
   149         return dirs
       
   150 
       
   151 def usage():
       
   152     print """usage: unzip.py -z <zipfile> -o <targetdir>
       
   153     <zipfile> is the source zipfile to extract
       
   154     <targetdir> is the target destination
       
   155 
       
   156     -z zipfile to extract
       
   157     -o target location
       
   158     -p sets the percentage notification
       
   159     -v sets the extraction to verbose (overrides -p)
       
   160 
       
   161     long options also work:
       
   162     --verbose
       
   163     --percent=10
       
   164     --zipfile=<zipfile>
       
   165     --outdir=<targetdir>"""
       
   166     
       
   167 
       
   168 def main():
       
   169     shortargs = 'vhp:z:o:'
       
   170     longargs = ['verbose', 'help', 'percent=', 'zipfile=', 'outdir=']
       
   171 
       
   172     unzipper = unzip()
       
   173 
       
   174     try:
       
   175         opts, args = getopt.getopt(sys.argv[1:], shortargs, longargs)
       
   176     except getopt.GetoptError:
       
   177         usage()
       
   178         sys.exit(2)
       
   179 
       
   180     zipsource = ""
       
   181     zipdest = ""
       
   182 
       
   183     for o, a in opts:
       
   184         if o in ("-v", "--verbose"):
       
   185             unzipper.verbose = True
       
   186         if o in ("-p", "--percent"):
       
   187             if not unzipper.verbose == True:
       
   188                 unzipper.percent = int(a)
       
   189         if o in ("-z", "--zipfile"):
       
   190             zipsource = a
       
   191         if o in ("-o", "--outdir"):
       
   192             zipdest = a
       
   193         if o in ("-h", "--help"):
       
   194             usage()
       
   195             sys.exit()
       
   196 
       
   197     if zipsource == "" or zipdest == "":
       
   198         usage()
       
   199         sys.exit()
       
   200             
       
   201     unzipper.extract(zipsource, zipdest)
       
   202 
       
   203 if __name__ == '__main__': main()