scripts/x

Sun, 29 Oct 2006 20:03:12 -0500

author
brett
date
Sun, 29 Oct 2006 20:03:12 -0500
branch
trunk
changeset 2
1570351bf863
parent 1
a86a0cb0dd57
child 5
36f352abd093
permissions
-rwxr-xr-x

[svn] Fix a small bug that would crash the program if an archive was empty.

Make basename calculation more robust.

Go ahead and run .exe files through the ZipExtractor. Need to cope more
gracefully when it doesn't work, but I've lost momentum for tonight.

1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
1 #!/usr/bin/env python
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
2 #
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
3 # x -- Intelligently extract various archive types.
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
4 # Copyright (c) 2006 Brett Smith <brettcsmith@brettcsmith.org>.
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
5 #
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
6 # This program is free software; you can redistribute it and/or modify it
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
7 # under the terms of the GNU General Public License as published by the
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
8 # Free Software Foundation; either version 2 of the License, or (at your
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
9 # option) any later version.
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
10 #
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful, but
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
14 # Public License for more details.
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
15 #
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
16 # You should have received a copy of the GNU General Public License along
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
17 # with this program; if not, write to the Free Software Foundation, Inc.,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
18 # 51 Franklin Street, 5th Floor, Boston, MA, 02111.
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
19
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
20 import mimetypes
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
21 import os
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
22 import subprocess
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
23 import sys
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
24 import tempfile
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
25
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
26 from cStringIO import StringIO
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
27
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
28 mimetypes.encodings_map.setdefault('.bz2', 'bzip2')
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
29
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
30 MATCHING_DIRECTORY = 1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
31 ONE_DIRECTORY = 2
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
32 BOMB = 3
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
33 EMPTY = 4
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
34
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
35 class ExtractorError(Exception):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
36 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
37
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
38
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
39 class ProcessStreamer(object):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
40 def __init__(self, command, stdin, description="checking contents",
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
41 stderr=None):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
42 self.process = subprocess.Popen(command, bufsize=1, stdin=stdin,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
43 stdout=subprocess.PIPE, stderr=stderr)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
44 self.command = ' '.join(command)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
45 self.description = description
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
46
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
47 def __iter__(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
48 return self
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
49
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
50 def next(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
51 line = self.process.stdout.readline()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
52 if line:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
53 return line.rstrip('\n')
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
54 else:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
55 raise StopIteration
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
56
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
57 def stop(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
58 while self.process.stdout.readline():
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
59 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
60 self.process.stdout.close()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
61 status = self.process.wait()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
62 if status != 0:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
63 raise ExtractorError("%s error: '%s' returned status code %s" %
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
64 (self.description, self.command, status))
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
65 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
66 self.process.stderr.close()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
67 except AttributeError:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
68 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
69
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
70
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
71 class BaseExtractor(object):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
72 decoders = {'bzip2': 'bzcat', 'gzip': 'zcat', 'compress': 'zcat'}
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
73
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
74 def __init__(self, filename, mimetype, encoding):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
75 self.filename = filename
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
76 self.mimetype = mimetype
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
77 self.encoding = encoding
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
78 self.archive = open(filename, 'r')
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
79 if encoding:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
80 self.pipe([self.decoders[encoding]], "decoding")
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
81 self.prepare()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
82
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
83 def run(self, command, description="extraction", stdout=None, stderr=None,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
84 stdin=None, string_output=True):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
85 process = subprocess.Popen(command, stdin=stdin, stdout=stdout,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
86 stderr=stderr)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
87 status = process.wait()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
88 if status != 0:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
89 raise ExtractorError("%s error: '%s' returned status code %s" %
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
90 (description, ' '.join(command), status))
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
91 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
92 process.stderr.close()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
93 except AttributeError:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
94 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
95 output = process.stdout
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
96 if string_output:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
97 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
98 output = output.read(-1)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
99 process.stdout.close()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
100 except AttributeError:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
101 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
102 return output
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
103
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
104 def pipe(self, command, description, stderr=None):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
105 output = tempfile.TemporaryFile()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
106 self.run(command, description, output, stderr, self.archive, False)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
107 self.archive.close()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
108 self.archive = output
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
109 self.archive.flush()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
110
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
111 def prepare(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
112 pass
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
113
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
114 def check_contents(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
115 self.archive.seek(0, 0)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
116 filenames = self.get_filenames()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
117 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
118 first_part = filenames.next().split('/', 1)[0] + '/'
2
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
119 except StopIteration:
1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
120 filenames.stop()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
121 return EMPTY
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
122 for filename in filenames:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
123 if not filename.startswith(first_part):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
124 filenames.stop()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
125 return BOMB
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
126 filenames.stop()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
127 if self.basename() == first_part[:-1]:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
128 return MATCHING_DIRECTORY
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
129 return ONE_DIRECTORY
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
130
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
131 def basename(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
132 pieces = self.filename.split('.')
2
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
133 extension = '.' + pieces[-1]
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
134 if mimetypes.encodings_map.has_key(extension):
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
135 pieces.pop()
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
136 extension = '.' + pieces[-1]
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
137 if (mimetypes.types_map.has_key(extension) or
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
138 mimetypes.common_types.has_key(extension) or
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
139 mimetypes.suffix_map.has_key(extension)):
1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
140 pieces.pop()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
141 return '.'.join(pieces)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
142
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
143 def extract(self, path):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
144 self.archive.seek(0, 0)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
145 self.extract_archive()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
146
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
147
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
148 class TarExtractor(BaseExtractor):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
149 def get_filenames(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
150 return ProcessStreamer(['tar', '-t'], self.archive)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
151
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
152 def extract_archive(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
153 self.run(['tar', '-x'], stdin=self.archive)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
154
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
155
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
156 class ZipExtractor(BaseExtractor):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
157 def __init__(self, filename, mimetype, encoding):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
158 self.filename = filename
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
159 self.mimetype = mimetype
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
160 self.encoding = encoding
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
161 self.archive = StringIO()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
162
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
163 def get_filenames(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
164 return ProcessStreamer(['zipinfo', '-1', self.filename], None)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
165
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
166 def extract(self, path):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
167 self.run(['unzip', '-q', os.path.join(path, self.filename)])
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
168
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
169
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
170 class CpioExtractor(BaseExtractor):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
171 def get_filenames(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
172 return ProcessStreamer(['cpio', '-t'], self.archive,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
173 stderr=subprocess.PIPE)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
174
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
175 def extract_archive(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
176 self.run(['cpio', '-i', '--make-directories',
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
177 '--no-absolute-filenames'],
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
178 stderr=subprocess.PIPE, stdin=self.archive)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
179
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
180
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
181 class RPMExtractor(CpioExtractor):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
182 def prepare(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
183 self.pipe(['rpm2cpio', '-'], "rpm2cpio")
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
184
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
185 def basename(self):
2
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
186 pieces = self.filename.rsplit('.', 2)
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
187 if len(pieces) == 1:
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
188 return pieces[0]
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
189 elif pieces[-1] != 'rpm':
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
190 return BaseExtractor.basename(self)
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
191 pieces.pop()
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
192 if len(pieces) == 1:
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
193 return pieces[0]
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
194 elif len(pieces[-1]) < 6:
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
195 pieces.pop()
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
196 return '.'.join(pieces)
1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
197
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
198 def check_contents(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
199 return BOMB
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
200
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
201
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
202 class DebExtractor(TarExtractor):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
203 def prepare(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
204 self.pipe(['ar', 'p', self.filename, 'data.tar.gz'],
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
205 "data.tar.gz extraction")
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
206 self.archive.seek(0, 0)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
207 self.pipe(['zcat'], "data.tar.gz decompression")
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
208
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
209 def basename(self):
2
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
210 pieces = self.filename.rsplit('_', 1)
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
211 if len(pieces) == 1:
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
212 return pieces[0]
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
213 elif (len(pieces[-1]) > 10) or (not pieces[-1].endswith('.deb')):
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
214 return BaseExtractor.basename(self)
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
215 return pieces[0]
1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
216
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
217 def check_contents(self):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
218 return BOMB
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
219
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
220
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
221 extractor_map = {'application/x-tar': TarExtractor,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
222 'application/zip': ZipExtractor,
2
1570351bf863 [svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents: 1
diff changeset
223 'application/x-msdos-program': ZipExtractor,
1
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
224 'application/x-debian-package': DebExtractor,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
225 'application/x-redhat-package-manager': RPMExtractor,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
226 'application/x-shar': None,
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
227 'application/x-cpio': CpioExtractor}
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
228
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
229 def show_error(filename, message):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
230 print >>sys.stderr, "%s: %s" % (filename, message)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
231
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
232 def main(arguments):
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
233 for filename in arguments:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
234 mimetype, encoding = mimetypes.guess_type(filename)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
235 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
236 handler = extractor_map[mimetype]
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
237 except KeyError:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
238 show_error(filename, "doesn't look like an archive")
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
239 continue
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
240 extractor = handler(filename, mimetype, encoding)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
241 contents = extractor.check_contents()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
242 path = '.'
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
243 if contents == BOMB:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
244 directory = extractor.basename()
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
245 try:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
246 os.mkdir(directory)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
247 except OSError, error:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
248 show_error(filename, "could not create %s: %s" %
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
249 (error.filename, error.strerror))
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
250 continue
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
251 os.chdir(directory)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
252 path = '..'
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
253 extractor.extract(path)
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
254 if contents == BOMB:
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
255 os.chdir('..')
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
256
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
257 if __name__ == '__main__':
a86a0cb0dd57 [svn] Repository reorganization to make tags easy
brett
parents:
diff changeset
258 main(sys.argv[1:])

mercurial