srcanamdw/codescanner/pyinstaller/ArchiveViewer.py
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 #! /usr/bin/env python
       
     2 # Viewer for archives packaged by archive.py
       
     3 # Copyright (C) 2005, Giovanni Bajo
       
     4 # Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
       
     5 #
       
     6 # This program is free software; you can redistribute it and/or
       
     7 # modify it under the terms of the GNU General Public License
       
     8 # as published by the Free Software Foundation; either version 2
       
     9 # of the License, or (at your option) any later version.
       
    10 #
       
    11 # This program is distributed in the hope that it will be useful,
       
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    14 # GNU General Public License for more details.
       
    15 #
       
    16 # You should have received a copy of the GNU General Public License
       
    17 # along with this program; if not, write to the Free Software
       
    18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
       
    19 import archive
       
    20 import carchive
       
    21 import sys, string, tempfile, os
       
    22 try:
       
    23     import zlib
       
    24 except ImportError:
       
    25     zlib = archive.DummyZlib()
       
    26 import pprint
       
    27 
       
    28 stack = []
       
    29 cleanup = []
       
    30 
       
    31 def main():
       
    32     global stack
       
    33     name = sys.argv[1]
       
    34     arch = getArchive(name)
       
    35     stack.append((name, arch))
       
    36     show(name, arch)
       
    37 
       
    38     while 1:
       
    39         toks = string.split(raw_input('? '), ' ', 1)
       
    40         if not toks:
       
    41             usage()
       
    42             continue
       
    43         if len(toks) == 1:
       
    44             cmd = toks[0]
       
    45             arg = ''
       
    46         else:
       
    47             cmd, arg = toks
       
    48         cmd = string.upper(cmd)
       
    49         if cmd == 'U':
       
    50             if len(stack) > 1:
       
    51                 arch = stack[-1][1]
       
    52                 arch.lib.close()
       
    53                 del stack[-1]
       
    54             nm, arch = stack[-1]
       
    55             show(nm, arch)
       
    56         elif cmd == 'O':
       
    57             if not arg:
       
    58                 arg = raw_input('open name? ')
       
    59             arg = string.strip(arg)
       
    60             arch = getArchive(arg)
       
    61             if arch is None:
       
    62                 print arg, "not found"
       
    63                 continue
       
    64             stack.append((arg, arch))
       
    65             show(arg, arch)
       
    66         elif cmd == 'X':
       
    67             if not arg:
       
    68                 arg = raw_input('extract name? ')
       
    69             arg = string.strip(arg)
       
    70             data = getData(arg, arch)
       
    71             if data is None:
       
    72                 print "Not found"
       
    73                 continue
       
    74             fnm = raw_input('to filename? ')
       
    75             if not fnm:
       
    76                 print `data`
       
    77             else:
       
    78                 open(fnm, 'wb').write(data)
       
    79         elif cmd == 'Q':
       
    80             break
       
    81         else:
       
    82             usage()
       
    83     for (nm, arch) in stack:
       
    84         arch.lib.close()
       
    85     stack = []
       
    86     for fnm in cleanup:
       
    87         try:
       
    88             os.remove(fnm)
       
    89         except Exception, e:
       
    90             print "couldn't delete", fnm, e.args
       
    91 def usage():
       
    92     print "U: go Up one level"
       
    93     print "O <nm>: open embedded archive nm"
       
    94     print "X <nm>: extract nm"
       
    95     print "Q: quit"
       
    96 def getArchive(nm):
       
    97     if not stack:
       
    98         if string.lower(nm[-4:]) == '.pyz':
       
    99             return ZlibArchive(nm)
       
   100         return carchive.CArchive(nm)
       
   101     parent = stack[-1][1]
       
   102     try:
       
   103         return parent.openEmbedded(nm)
       
   104     except KeyError, e:
       
   105         return None
       
   106     except (ValueError, RuntimeError):
       
   107         ndx = parent.toc.find(nm)
       
   108         dpos, dlen, ulen, flag, typcd, nm = parent.toc[ndx]
       
   109         x, data = parent.extract(ndx)
       
   110         tfnm = tempfile.mktemp()
       
   111         cleanup.append(tfnm)
       
   112         open(tfnm, 'wb').write(data)
       
   113         if typcd == 'z':
       
   114             return ZlibArchive(tfnm)
       
   115         else:
       
   116             return carchive.CArchive(tfnm)
       
   117 
       
   118 def getData(nm, arch):
       
   119     if type(arch.toc) is type({}):
       
   120         (ispkg, pos, lngth) = arch.toc.get(nm, (0, None, 0))
       
   121         if pos is None:
       
   122             return None
       
   123         arch.lib.seek(arch.start + pos)
       
   124         return zlib.decompress(arch.lib.read(lngth))
       
   125     ndx = arch.toc.find(nm)
       
   126     dpos, dlen, ulen, flag, typcd, nm = arch.toc[ndx]
       
   127     x, data = arch.extract(ndx)
       
   128     return data
       
   129 
       
   130 def show(nm, arch):
       
   131     if type(arch.toc) == type({}):
       
   132         print " Name: (ispkg, pos, len)"
       
   133         toc = arch.toc
       
   134     else:
       
   135         print " pos, length, uncompressed, iscompressed, type, name"
       
   136         toc = arch.toc.data
       
   137     pprint.pprint(toc)
       
   138 
       
   139 class ZlibArchive(archive.ZlibArchive):
       
   140     def checkmagic(self):
       
   141         """ Overridable.
       
   142             Check to see if the file object self.lib actually has a file
       
   143             we understand.
       
   144         """
       
   145         self.lib.seek(self.start)	#default - magic is at start of file
       
   146         if self.lib.read(len(self.MAGIC)) != self.MAGIC:
       
   147             raise RuntimeError, "%s is not a valid %s archive file" \
       
   148               % (self.path, self.__class__.__name__)
       
   149         if self.lib.read(len(self.pymagic)) != self.pymagic:
       
   150             print "Warning: pyz is from a different Python version"
       
   151         self.lib.read(4)
       
   152 
       
   153 if __name__ == '__main__':
       
   154     main()
       
   155