Sun, 20 Jul 2008 20:45:54 -0400
Don't show errors from failed extractors unless they all fail.
If dtrx has to try different extractors before finding and using the right
one, the user shouldn't see error messages from the failed extractors;
those are just confusing. Just like the Application decides whether to say
particular extractors failed at all, this patch makes it also decide
whether or not to show the stderr from those extractors.
1 | 1 | #!/usr/bin/env python |
2 | # | |
19 | 3 | # dtrx -- Intelligently extract various archive types. |
54 | 4 | # Copyright (c) 2006, 2007, 2008 Brett Smith <brettcsmith@brettcsmith.org>. |
1 | 5 | # |
6 | # This program is free software; you can redistribute it and/or modify it | |
7 | # under the terms of the GNU General Public License as published by the | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
8 | # Free Software Foundation; either version 3 of the License, or (at your |
1 | 9 | # option) any later version. |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, but | |
12 | # WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
14 | # Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License along | |
42 | 17 | # with this program; if not, see <http://www.gnu.org/licenses/>. |
1 | 18 | |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
19 | # Python 2.3 string methods: 'rfind', 'rindex', 'rjust', 'rstrip' |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
20 | |
5 | 21 | import errno |
48 | 22 | import glob |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
23 | import logging |
1 | 24 | import mimetypes |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
25 | import optparse |
1 | 26 | import os |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
27 | import re |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
28 | import shutil |
48 | 29 | import signal |
15
28dbd52a8bb8
[svn] Add a -f/--flat option, which will extract the archive contents into the
brett
parents:
14
diff
changeset
|
30 | import stat |
1 | 31 | import subprocess |
32 | import sys | |
33 | import tempfile | |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
34 | import textwrap |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
35 | import traceback |
1 | 36 | |
48 | 37 | from sets import Set as set |
36
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
38 | |
74
dd577317bccb
Updates for 6.1 release.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
73
diff
changeset
|
39 | VERSION = "6.1" |
19 | 40 | VERSION_BANNER = """dtrx version %s |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
41 | Copyright (c) 2006, 2007, 2008 Brett Smith <brettcsmith@brettcsmith.org> |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
42 | |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
43 | This program is free software; you can redistribute it and/or modify it |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
44 | under the terms of the GNU General Public License as published by the |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
45 | Free Software Foundation; either version 3 of the License, or (at your |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
46 | option) any later version. |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
47 | |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
48 | This program is distributed in the hope that it will be useful, but |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
49 | WITHOUT ANY WARRANTY; without even the implied warranty of |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
50 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
51 | Public License for more details.""" % (VERSION,) |
1 | 52 | |
53 | MATCHING_DIRECTORY = 1 | |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
54 | ONE_ENTRY_KNOWN = 2 |
1 | 55 | BOMB = 3 |
56 | EMPTY = 4 | |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
57 | ONE_ENTRY_FILE = 'file' |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
58 | ONE_ENTRY_DIRECTORY = 'directory' |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
59 | |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
60 | ONE_ENTRY_UNKNOWN = [ONE_ENTRY_FILE, ONE_ENTRY_DIRECTORY] |
1 | 61 | |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
62 | EXTRACT_HERE = 1 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
63 | EXTRACT_WRAP = 2 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
64 | EXTRACT_RENAME = 3 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
65 | |
23
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
66 | RECURSE_ALWAYS = 1 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
67 | RECURSE_ONCE = 2 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
68 | RECURSE_NOT_NOW = 3 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
69 | RECURSE_NEVER = 4 |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
70 | RECURSE_LIST = 5 |
23
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
71 | |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
72 | mimetypes.encodings_map.setdefault('.bz2', 'bzip2') |
34
a8f875e02c83
[svn] Add support for LZMA compression. Holy crap that was easy.
brett
parents:
33
diff
changeset
|
73 | mimetypes.encodings_map.setdefault('.lzma', 'lzma') |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
74 | mimetypes.types_map.setdefault('.gem', 'application/x-ruby-gem') |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
75 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
76 | logger = logging.getLogger('dtrx-log') |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
77 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
78 | class FilenameChecker(object): |
58 | 79 | free_func = os.open |
80 | free_args = (os.O_CREAT | os.O_EXCL,) | |
81 | free_close = os.close | |
82 | ||
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
83 | def __init__(self, original_name): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
84 | self.original_name = original_name |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
85 | |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
86 | def is_free(self, filename): |
58 | 87 | try: |
88 | result = self.free_func(filename, *self.free_args) | |
89 | except OSError, error: | |
90 | if error.errno == errno.EEXIST: | |
91 | return False | |
92 | raise | |
93 | if self.free_close: | |
94 | self.free_close(result) | |
95 | return True | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
96 | |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
97 | def create(self): |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
98 | fd, filename = tempfile.mkstemp(prefix=self.original_name + '.', |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
99 | dir='.') |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
100 | os.close(fd) |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
101 | return filename |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
102 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
103 | def check(self): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
104 | for suffix in [''] + ['.%s' % (x,) for x in range(1, 10)]: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
105 | filename = '%s%s' % (self.original_name, suffix) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
106 | if self.is_free(filename): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
107 | return filename |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
108 | return self.create() |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
109 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
110 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
111 | class DirectoryChecker(FilenameChecker): |
58 | 112 | free_func = os.mkdir |
113 | free_args = () | |
114 | free_close = None | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
115 | |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
116 | def create(self): |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
117 | return tempfile.mkdtemp(prefix=self.original_name + '.', dir='.') |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
118 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
119 | |
1 | 120 | class ExtractorError(Exception): |
121 | pass | |
122 | ||
123 | ||
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
124 | class ExtractorUnusable(Exception): |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
125 | pass |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
126 | |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
127 | |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
128 | EXTRACTION_ERRORS = (ExtractorError, ExtractorUnusable, OSError, IOError) |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
129 | |
1 | 130 | class BaseExtractor(object): |
34
a8f875e02c83
[svn] Add support for LZMA compression. Holy crap that was easy.
brett
parents:
33
diff
changeset
|
131 | decoders = {'bzip2': 'bzcat', 'gzip': 'zcat', 'compress': 'zcat', |
a8f875e02c83
[svn] Add support for LZMA compression. Holy crap that was easy.
brett
parents:
33
diff
changeset
|
132 | 'lzma': 'lzcat'} |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
133 | name_checker = DirectoryChecker |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
134 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
135 | def __init__(self, filename, encoding): |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
136 | if encoding and (not self.decoders.has_key(encoding)): |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
137 | raise ValueError("unrecognized encoding %s" % (encoding,)) |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
138 | self.filename = os.path.realpath(filename) |
1 | 139 | self.encoding = encoding |
69
35a2f45cdd3b
Count files in the archive and report that in the recursion prompt.
Brett Smith <brett@brettcsmith.org>
parents:
66
diff
changeset
|
140 | self.file_count = 0 |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
141 | self.included_archives = [] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
142 | self.target = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
143 | self.content_type = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
144 | self.content_name = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
145 | self.pipes = [] |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
146 | self.stderr = tempfile.TemporaryFile() |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
147 | self.exit_codes = [] |
5 | 148 | try: |
149 | self.archive = open(filename, 'r') | |
150 | except (IOError, OSError), error: | |
151 | raise ExtractorError("could not open %s: %s" % | |
152 | (filename, error.strerror)) | |
1 | 153 | if encoding: |
154 | self.pipe([self.decoders[encoding]], "decoding") | |
155 | self.prepare() | |
156 | ||
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
157 | def pipe(self, command, description="extraction"): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
158 | self.pipes.append((command, description)) |
1 | 159 | |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
160 | def first_bad_exit_code(self): |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
161 | for index, code in enumerate(self.exit_codes): |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
162 | if code != 0: |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
163 | return index |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
164 | return None |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
165 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
166 | def run_pipes(self, final_stdout=None): |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
167 | if not self.pipes: |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
168 | return |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
169 | elif final_stdout is None: |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
170 | # FIXME: Buffering this might be dumb. |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
171 | final_stdout = tempfile.TemporaryFile() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
172 | num_pipes = len(self.pipes) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
173 | last_pipe = num_pipes - 1 |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
174 | processes = [] |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
175 | for index, command in enumerate([pipe[0] for pipe in self.pipes]): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
176 | if index == 0: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
177 | stdin = self.archive |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
178 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
179 | stdin = processes[-1].stdout |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
180 | if index == last_pipe: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
181 | stdout = final_stdout |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
182 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
183 | stdout = subprocess.PIPE |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
184 | try: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
185 | processes.append(subprocess.Popen(command, stdin=stdin, |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
186 | stdout=stdout, |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
187 | stderr=self.stderr)) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
188 | except OSError, error: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
189 | if error.errno == errno.ENOENT: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
190 | raise ExtractorUnusable("could not run %s" % (command[0],)) |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
191 | raise |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
192 | self.exit_codes = [pipe.wait() for pipe in processes] |
1 | 193 | self.archive.close() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
194 | for index in range(last_pipe): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
195 | processes[index].stdout.close() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
196 | self.archive = final_stdout |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
197 | |
1 | 198 | def prepare(self): |
199 | pass | |
200 | ||
47 | 201 | def check_included_archives(self): |
202 | if (self.content_name is None) or (not self.content_name.endswith('/')): | |
203 | self.included_root = './' | |
204 | else: | |
205 | self.included_root = self.content_name | |
206 | start_index = len(self.included_root) | |
207 | for path, dirname, filenames in os.walk(self.included_root): | |
69
35a2f45cdd3b
Count files in the archive and report that in the recursion prompt.
Brett Smith <brett@brettcsmith.org>
parents:
66
diff
changeset
|
208 | self.file_count += len(filenames) |
47 | 209 | path = path[start_index:] |
210 | for filename in filenames: | |
211 | if (ExtractorBuilder.try_by_mimetype(filename) or | |
212 | ExtractorBuilder.try_by_extension(filename)): | |
213 | self.included_archives.append(os.path.join(path, filename)) | |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
214 | |
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
215 | def check_contents(self): |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
216 | self.contents = os.listdir('.') |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
217 | if not self.contents: |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
218 | self.content_type = EMPTY |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
219 | elif len(self.contents) == 1: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
220 | if self.basename() == self.contents[0]: |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
221 | self.content_type = MATCHING_DIRECTORY |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
222 | elif os.path.isdir(self.contents[0]): |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
223 | self.content_type = ONE_ENTRY_DIRECTORY |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
224 | else: |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
225 | self.content_type = ONE_ENTRY_FILE |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
226 | self.content_name = self.contents[0] |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
227 | if os.path.isdir(self.contents[0]): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
228 | self.content_name += '/' |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
229 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
230 | self.content_type = BOMB |
47 | 231 | self.check_included_archives() |
1 | 232 | |
233 | def basename(self): | |
5 | 234 | pieces = os.path.basename(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
|
235 | extension = '.' + pieces[-1] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
236 | 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
|
237 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
238 | extension = '.' + pieces[-1] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
239 | 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
|
240 | 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
|
241 | mimetypes.suffix_map.has_key(extension)): |
1 | 242 | pieces.pop() |
243 | return '.'.join(pieces) | |
244 | ||
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
245 | def get_stderr(self): |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
246 | self.stderr.seek(0, 0) |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
247 | errors = self.stderr.read(-1) |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
248 | self.stderr.close() |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
249 | return errors |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
250 | |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
251 | def check_success(self, got_output): |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
252 | error_index = self.first_bad_exit_code() |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
253 | if (not got_output) and (error_index is not None): |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
254 | command = ' '.join(self.pipes[error_index][0]) |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
255 | raise ExtractorError("%s error: '%s' returned status code %s" % |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
256 | (self.pipes[error_index][1], command, |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
257 | self.exit_codes[error_index])) |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
258 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
259 | def extract(self): |
40
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
260 | try: |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
261 | self.target = tempfile.mkdtemp(prefix='.dtrx-', dir='.') |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
262 | except (OSError, IOError), error: |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
263 | raise ExtractorError("cannot extract here: %s" % (error.strerror,)) |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
264 | old_path = os.path.realpath(os.curdir) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
265 | os.chdir(self.target) |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
266 | try: |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
267 | self.archive.seek(0, 0) |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
268 | self.extract_archive() |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
269 | self.check_contents() |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
270 | self.check_success(self.content_type != EMPTY) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
271 | except EXTRACTION_ERRORS: |
48 | 272 | self.archive.close() |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
273 | os.chdir(old_path) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
274 | shutil.rmtree(self.target, ignore_errors=True) |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
275 | raise |
48 | 276 | self.archive.close() |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
277 | os.chdir(old_path) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
278 | |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
279 | def get_filenames(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
280 | self.run_pipes() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
281 | self.archive.seek(0, 0) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
282 | while True: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
283 | line = self.archive.readline() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
284 | if not line: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
285 | self.archive.close() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
286 | return |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
287 | yield line.rstrip('\n') |
1 | 288 | |
289 | ||
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
290 | class CompressionExtractor(BaseExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
291 | file_type = 'compressed file' |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
292 | name_checker = FilenameChecker |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
293 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
294 | def basename(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
295 | pieces = os.path.basename(self.filename).split('.') |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
296 | extension = '.' + pieces[-1] |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
297 | if mimetypes.encodings_map.has_key(extension): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
298 | pieces.pop() |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
299 | return '.'.join(pieces) |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
300 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
301 | def get_filenames(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
302 | yield self.basename() |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
303 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
304 | def extract(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
305 | self.content_type = ONE_ENTRY_KNOWN |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
306 | self.content_name = self.basename() |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
307 | self.contents = None |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
308 | self.included_root = './' |
40
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
309 | try: |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
310 | output_fd, self.target = tempfile.mkstemp(prefix='.dtrx-', dir='.') |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
311 | except (OSError, IOError), error: |
ee6a869f8da1
[svn] Be a little nicer about explaining that we can't extract to the current
brett
parents:
39
diff
changeset
|
312 | raise ExtractorError("cannot extract here: %s" % (error.strerror,)) |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
313 | self.run_pipes(output_fd) |
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
314 | os.close(output_fd) |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
315 | try: |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
316 | self.check_success(os.stat(self.target)[stat.ST_SIZE] > 0) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
317 | except EXTRACTION_ERRORS: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
318 | os.unlink(self.target) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
319 | raise |
62
17d845dacff5
Deal with partially extracted tarballs.
Brett Smith <brett@brettcsmith.org>
parents:
59
diff
changeset
|
320 | |
1 | 321 | class TarExtractor(BaseExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
322 | file_type = 'tar file' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
323 | |
1 | 324 | def get_filenames(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
325 | self.pipe(['tar', '-t'], "listing") |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
326 | return BaseExtractor.get_filenames(self) |
1 | 327 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
328 | def extract_archive(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
329 | self.pipe(['tar', '-x']) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
330 | self.run_pipes() |
1 | 331 | |
332 | ||
333 | class CpioExtractor(BaseExtractor): | |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
334 | file_type = 'cpio file' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
335 | |
1 | 336 | def get_filenames(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
337 | self.pipe(['cpio', '-t'], "listing") |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
338 | return BaseExtractor.get_filenames(self) |
1 | 339 | |
340 | def extract_archive(self): | |
76
705642fcb92c
Give extraction stderr more context, and suppress normal cpio stderr junk.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
74
diff
changeset
|
341 | self.pipe(['cpio', '-i', '--make-directories', '--quiet', |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
342 | '--no-absolute-filenames']) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
343 | self.run_pipes() |
1 | 344 | |
345 | ||
346 | class RPMExtractor(CpioExtractor): | |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
347 | file_type = 'RPM' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
348 | |
1 | 349 | def prepare(self): |
350 | self.pipe(['rpm2cpio', '-'], "rpm2cpio") | |
351 | ||
352 | def basename(self): | |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
353 | pieces = os.path.basename(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
|
354 | 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
|
355 | return pieces[0] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
356 | 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
|
357 | 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
|
358 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
359 | 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
|
360 | return pieces[0] |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
361 | elif len(pieces[-1]) < 8: |
2
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
362 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
363 | return '.'.join(pieces) |
1 | 364 | |
365 | def check_contents(self): | |
47 | 366 | self.check_included_archives() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
367 | self.content_type = BOMB |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
368 | |
1 | 369 | |
370 | class DebExtractor(TarExtractor): | |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
371 | file_type = 'Debian package' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
372 | |
1 | 373 | def prepare(self): |
374 | self.pipe(['ar', 'p', self.filename, 'data.tar.gz'], | |
375 | "data.tar.gz extraction") | |
376 | self.pipe(['zcat'], "data.tar.gz decompression") | |
377 | ||
378 | def basename(self): | |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
379 | pieces = os.path.basename(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
|
380 | 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
|
381 | return pieces[0] |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
382 | last_piece = pieces.pop() |
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
383 | if (len(last_piece) > 10) or (not last_piece.endswith('.deb')): |
2
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
384 | return BaseExtractor.basename(self) |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
385 | return '_'.join(pieces) |
1 | 386 | |
387 | def check_contents(self): | |
47 | 388 | self.check_included_archives() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
389 | self.content_type = BOMB |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
390 | |
1 | 391 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
392 | class DebMetadataExtractor(DebExtractor): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
393 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
394 | self.pipe(['ar', 'p', self.filename, 'control.tar.gz'], |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
395 | "control.tar.gz extraction") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
396 | self.pipe(['zcat'], "control.tar.gz decompression") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
397 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
398 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
399 | class GemExtractor(TarExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
400 | file_type = 'Ruby gem' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
401 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
402 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
403 | self.pipe(['tar', '-xO', 'data.tar.gz'], "data.tar.gz extraction") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
404 | self.pipe(['zcat'], "data.tar.gz decompression") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
405 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
406 | def check_contents(self): |
47 | 407 | self.check_included_archives() |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
408 | self.content_type = BOMB |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
409 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
410 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
411 | class GemMetadataExtractor(CompressionExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
412 | file_type = 'Ruby gem' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
413 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
414 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
415 | self.pipe(['tar', '-xO', 'metadata.gz'], "metadata.gz extraction") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
416 | self.pipe(['zcat'], "metadata.gz decompression") |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
417 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
418 | def basename(self): |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
419 | return os.path.basename(self.filename) + '-metadata.txt' |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
420 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
421 | |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
422 | class NoPipeExtractor(BaseExtractor): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
423 | # Some extraction tools won't accept the archive from stdin. With |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
424 | # these, the piping infrastructure we normally set up generally doesn't |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
425 | # work, at least at first. We can still use most of it; we just don't |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
426 | # want to seed self.archive with the archive file, since that sucks up |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
427 | # memory. So instead we seed it with /dev/null, and specify the |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
428 | # filename on the command line as necessary. We also open the actual |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
429 | # file with os.open, to make sure we can actually do it (permissions |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
430 | # are good, etc.). This class doesn't do anything by itself; it's just |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
431 | # meant to be a base class for extractors that rely on these dumb |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
432 | # tools. |
32 | 433 | def __init__(self, filename, encoding): |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
434 | os.close(os.open(filename, os.O_RDONLY)) |
32 | 435 | BaseExtractor.__init__(self, '/dev/null', None) |
436 | self.filename = os.path.realpath(filename) | |
437 | ||
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
438 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
439 | class ZipExtractor(NoPipeExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
440 | file_type = 'Zip file' |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
441 | |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
442 | def get_filenames(self): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
443 | self.pipe(['zipinfo', '-1', self.filename], "listing") |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
444 | return BaseExtractor.get_filenames(self) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
445 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
446 | def extract_archive(self): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
447 | self.pipe(['unzip', '-q', self.filename]) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
448 | self.run_pipes() |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
449 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
450 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
451 | class SevenExtractor(NoPipeExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
452 | file_type = '7z file' |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
453 | border_re = re.compile('^[- ]+$') |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
454 | |
32 | 455 | def get_filenames(self): |
456 | self.pipe(['7z', 'l', self.filename], "listing") | |
457 | self.run_pipes() | |
458 | self.archive.seek(0, 0) | |
459 | fn_index = None | |
460 | for line in self.archive: | |
461 | if self.border_re.match(line): | |
462 | if fn_index is not None: | |
463 | break | |
464 | else: | |
465 | fn_index = line.rindex(' ') + 1 | |
466 | elif fn_index is not None: | |
467 | yield line[fn_index:-1] | |
468 | self.archive.close() | |
469 | ||
470 | def extract_archive(self): | |
471 | self.pipe(['7z', 'x', self.filename]) | |
472 | self.run_pipes() | |
473 | ||
474 | ||
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
475 | class CABExtractor(NoPipeExtractor): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
476 | file_type = 'CAB archive' |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
477 | border_re = re.compile(r'^[-\+]+$') |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
478 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
479 | def get_filenames(self): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
480 | self.pipe(['cabextract', '-l', self.filename], "listing") |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
481 | self.run_pipes() |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
482 | self.archive.seek(0, 0) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
483 | fn_index = None |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
484 | for line in self.archive: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
485 | if self.border_re.match(line): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
486 | break |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
487 | for line in self.archive: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
488 | try: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
489 | yield line.split(' | ', 2)[2].rstrip('\n') |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
490 | except IndexError: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
491 | break |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
492 | self.archive.close() |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
493 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
494 | def extract_archive(self): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
495 | self.pipe(['cabextract', '-q', self.filename]) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
496 | self.run_pipes() |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
497 | |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
498 | |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
499 | class ShieldExtractor(NoPipeExtractor): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
500 | file_type = 'InstallShield archive' |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
501 | prefix_re = re.compile(r'^\s+\d+\s+') |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
502 | end_re = re.compile(r'^\s+-+\s+-+\s*$') |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
503 | |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
504 | def get_filenames(self): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
505 | self.pipe(['unshield', 'l', self.filename], "listing") |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
506 | self.run_pipes() |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
507 | self.archive.seek(0, 0) |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
508 | for line in self.archive: |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
509 | if self.end_re.match(line): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
510 | break |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
511 | else: |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
512 | match = self.prefix_re.match(line) |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
513 | if match: |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
514 | yield line[match.end():].rstrip('\n') |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
515 | self.archive.close() |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
516 | |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
517 | def extract_archive(self): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
518 | self.pipe(['unshield', 'x', self.filename]) |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
519 | self.run_pipes() |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
520 | |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
521 | def basename(self): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
522 | result = NoPipeExtractor.basename(self) |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
523 | if result.endswith('.hdr'): |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
524 | result = result[:-4] |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
525 | return result |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
526 | |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
527 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
528 | class BaseHandler(object): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
529 | def __init__(self, extractor, options): |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
530 | self.extractor = extractor |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
531 | self.options = options |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
532 | self.target = None |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
533 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
534 | def handle(self): |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
535 | command = 'find' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
536 | status = subprocess.call(['find', self.extractor.target, '-type', 'd', |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
537 | '-exec', 'chmod', 'u+rwx', '{}', ';']) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
538 | if status == 0: |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
539 | command = 'chmod' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
540 | status = subprocess.call(['chmod', '-R', 'u+rwX', |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
541 | self.extractor.target]) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
542 | if status != 0: |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
543 | return "%s returned with exit status %s" % (command, status) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
544 | return self.organize() |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
545 | |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
546 | def set_target(self, target, checker): |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
547 | self.target = checker(target).check() |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
548 | if self.target != target: |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
549 | logger.warning("extracting %s to %s" % |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
550 | (self.extractor.filename, self.target)) |
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
551 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
552 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
553 | # The "where to extract" table, with options and archive types. |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
554 | # This dictates the contents of each can_handle method. |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
555 | # |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
556 | # Flat Overwrite None |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
557 | # File basename basename FilenameChecked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
558 | # Match . . tempdir + checked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
559 | # Bomb . basename DirectoryChecked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
560 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
561 | class FlatHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
562 | def can_handle(contents, options): |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
563 | return ((options.flat and (contents != ONE_ENTRY_KNOWN)) or |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
564 | (options.overwrite and (contents == MATCHING_DIRECTORY))) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
565 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
566 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
567 | def organize(self): |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
568 | self.target = '.' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
569 | for curdir, dirs, filenames in os.walk(self.extractor.target, |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
570 | topdown=False): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
571 | path_parts = curdir.split(os.sep) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
572 | if path_parts[0] == '.': |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
573 | del path_parts[1] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
574 | else: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
575 | del path_parts[0] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
576 | newdir = os.path.join(*path_parts) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
577 | if not os.path.isdir(newdir): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
578 | os.makedirs(newdir) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
579 | for filename in filenames: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
580 | os.rename(os.path.join(curdir, filename), |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
581 | os.path.join(newdir, filename)) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
582 | os.rmdir(curdir) |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
583 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
584 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
585 | class OverwriteHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
586 | def can_handle(contents, options): |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
587 | return ((options.flat and (contents == ONE_ENTRY_KNOWN)) or |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
588 | (options.overwrite and (contents != MATCHING_DIRECTORY))) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
589 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
590 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
591 | def organize(self): |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
592 | self.target = self.extractor.basename() |
51
f1789e6586d8
[svn] Don't try to rmtree when overwriting just a file.
brett
parents:
49
diff
changeset
|
593 | if os.path.isdir(self.target): |
f1789e6586d8
[svn] Don't try to rmtree when overwriting just a file.
brett
parents:
49
diff
changeset
|
594 | shutil.rmtree(self.target) |
48 | 595 | os.rename(self.extractor.target, self.target) |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
596 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
597 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
598 | class MatchHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
599 | def can_handle(contents, options): |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
600 | return ((contents == MATCHING_DIRECTORY) or |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
601 | ((contents in ONE_ENTRY_UNKNOWN) and |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
602 | options.one_entry_policy.ok_for_match())) |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
603 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
604 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
605 | def organize(self): |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
606 | source = os.path.join(self.extractor.target, |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
607 | os.listdir(self.extractor.target)[0]) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
608 | if os.path.isdir(source): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
609 | checker = DirectoryChecker |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
610 | else: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
611 | checker = FilenameChecker |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
612 | if self.options.one_entry_policy == EXTRACT_HERE: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
613 | destination = self.extractor.content_name.rstrip('/') |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
614 | else: |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
615 | destination = self.extractor.basename() |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
616 | self.set_target(destination, checker) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
617 | if os.path.isdir(self.extractor.target): |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
618 | os.rename(source, self.target) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
619 | os.rmdir(self.extractor.target) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
620 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
621 | os.rename(self.extractor.target, self.target) |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
622 | self.extractor.included_root = './' |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
623 | |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
624 | |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
625 | class EmptyHandler(object): |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
626 | def can_handle(contents, options): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
627 | return contents == EMPTY |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
628 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
629 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
630 | def __init__(self, extractor, options): pass |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
631 | def handle(self): pass |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
632 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
633 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
634 | class BombHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
635 | def can_handle(contents, options): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
636 | return True |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
637 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
638 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
639 | def organize(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
640 | basename = self.extractor.basename() |
41
e3675644bbb6
[svn] Minor clean-ups. The most important of these is that we now have a better
brett
parents:
40
diff
changeset
|
641 | self.set_target(basename, self.extractor.name_checker) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
642 | os.rename(self.extractor.target, self.target) |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
643 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
644 | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
645 | class BasePolicy(object): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
646 | def __init__(self, options): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
647 | self.current_policy = None |
26 | 648 | if options.batch: |
649 | self.permanent_policy = self.answers[''] | |
650 | else: | |
651 | self.permanent_policy = None | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
652 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
653 | def ask_question(self, question): |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
654 | question = question + self.choices |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
655 | while True: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
656 | print "\n".join(question) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
657 | try: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
658 | answer = raw_input(self.prompt) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
659 | except EOFError: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
660 | return self.answers[''] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
661 | try: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
662 | return self.answers[answer.lower()] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
663 | except KeyError: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
664 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
665 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
666 | def __cmp__(self, other): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
667 | return cmp(self.current_policy, other) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
668 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
669 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
670 | class OneEntryPolicy(BasePolicy): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
671 | answers = {'h': EXTRACT_HERE, 'i': EXTRACT_WRAP, 'r': EXTRACT_RENAME, |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
672 | '': EXTRACT_WRAP} |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
673 | choices = ["You can:", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
674 | " * extract it Inside another directory", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
675 | " * extract it and Rename the directory", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
676 | " * extract it Here"] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
677 | prompt = "What do you want to do? (I/r/h) " |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
678 | |
66
af0b822b012e
Don't prompt for one entry handling with -f.
Brett Smith <brett@brettcsmith.org>
parents:
65
diff
changeset
|
679 | def __init__(self, options): |
af0b822b012e
Don't prompt for one entry handling with -f.
Brett Smith <brett@brettcsmith.org>
parents:
65
diff
changeset
|
680 | BasePolicy.__init__(self, options) |
af0b822b012e
Don't prompt for one entry handling with -f.
Brett Smith <brett@brettcsmith.org>
parents:
65
diff
changeset
|
681 | if options.flat: |
af0b822b012e
Don't prompt for one entry handling with -f.
Brett Smith <brett@brettcsmith.org>
parents:
65
diff
changeset
|
682 | self.permanent_policy = EXTRACT_HERE |
af0b822b012e
Don't prompt for one entry handling with -f.
Brett Smith <brett@brettcsmith.org>
parents:
65
diff
changeset
|
683 | |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
684 | def prep(self, archive_filename, extractor): |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
685 | question = ["%s contains one %s, but it has a weird name." % |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
686 | (archive_filename, extractor.content_type)] |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
687 | question.append(" Expected: " + extractor.basename()) |
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
688 | question.append(" Actual: " + extractor.content_name) |
26 | 689 | self.current_policy = (self.permanent_policy or |
690 | self.ask_question(question)) | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
691 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
692 | def ok_for_match(self): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
693 | return self.current_policy in (EXTRACT_RENAME, EXTRACT_HERE) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
694 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
695 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
696 | class RecursionPolicy(BasePolicy): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
697 | answers = {'o': RECURSE_ONCE, 'a': RECURSE_ALWAYS, 'n': RECURSE_NOT_NOW, |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
698 | 'v': RECURSE_NEVER, 'l': RECURSE_LIST, '': RECURSE_NOT_NOW} |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
699 | choices = ["You can:", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
700 | " * Always extract included archives", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
701 | " * extract included archives this Once", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
702 | " * choose Not to extract included archives", |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
703 | " * neVer extract included archives", |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
704 | " * List included archives"] |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
705 | prompt = "What do you want to do? (a/o/N/v/l) " |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
706 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
707 | def __init__(self, options): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
708 | BasePolicy.__init__(self, options) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
709 | if options.show_list: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
710 | self.permanent_policy = RECURSE_NEVER |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
711 | elif options.recursive: |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
712 | self.permanent_policy = RECURSE_ALWAYS |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
713 | |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
714 | def prep(self, current_filename, target, extractor): |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
715 | archive_count = len(extractor.included_archives) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
716 | if (self.permanent_policy is not None) or (archive_count == 0): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
717 | self.current_policy = self.permanent_policy or RECURSE_NOT_NOW |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
718 | return |
69
35a2f45cdd3b
Count files in the archive and report that in the recursion prompt.
Brett Smith <brett@brettcsmith.org>
parents:
66
diff
changeset
|
719 | question = (("%s contains %s other archive file(s), " + |
70
48d2421a3178
Tweak wording of recursion question, and TODO.
Brett Smith <brett@brettcsmith.org>
parents:
69
diff
changeset
|
720 | "out of %s file(s) total.") % |
69
35a2f45cdd3b
Count files in the archive and report that in the recursion prompt.
Brett Smith <brett@brettcsmith.org>
parents:
66
diff
changeset
|
721 | (current_filename, archive_count, extractor.file_count)) |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
722 | question = textwrap.wrap(question) |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
723 | if target == '.': |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
724 | target = '' |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
725 | included_root = extractor.included_root |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
726 | if included_root == './': |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
727 | included_root = '' |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
728 | while True: |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
729 | self.current_policy = self.ask_question(question) |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
730 | if self.current_policy != RECURSE_LIST: |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
731 | break |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
732 | print ("\n%s\n" % |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
733 | '\n'.join([os.path.join(target, included_root, filename) |
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
734 | for filename in extractor.included_archives])) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
735 | if self.current_policy in (RECURSE_ALWAYS, RECURSE_NEVER): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
736 | self.permanent_policy = self.current_policy |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
737 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
738 | def ok_to_recurse(self): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
739 | return self.current_policy in (RECURSE_ALWAYS, RECURSE_ONCE) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
740 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
741 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
742 | class ExtractorBuilder(object): |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
743 | extractor_map = {'tar': (TarExtractor, None), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
744 | 'zip': (ZipExtractor, None), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
745 | 'deb': (DebExtractor, DebMetadataExtractor), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
746 | 'rpm': (RPMExtractor, None), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
747 | 'cpio': (CpioExtractor, None), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
748 | 'gem': (GemExtractor, GemMetadataExtractor), |
32 | 749 | 'compress': (CompressionExtractor, None), |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
750 | '7z': (SevenExtractor, None), |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
751 | 'cab': (CABExtractor, None), |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
752 | 'shield': (ShieldExtractor, None)} |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
753 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
754 | mimetype_map = {} |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
755 | for mapping in (('tar', 'x-tar'), |
59
7a0aafe2fe87
[svn] Find self-extracting archives by their file magic only, not extension/mimetype.
brett
parents:
58
diff
changeset
|
756 | ('zip', 'zip'), |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
757 | ('deb', 'x-debian-package'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
758 | ('rpm', 'x-redhat-package-manager', 'x-rpm'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
759 | ('cpio', 'x-cpio'), |
32 | 760 | ('gem', 'x-ruby-gem'), |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
761 | ('7z', 'x-7z-compressed'), |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
762 | ('cab', 'x-cab'), |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
763 | ('shield', 'x-cab')): |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
764 | for mimetype in mapping[1:]: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
765 | if '/' not in mimetype: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
766 | mimetype = 'application/' + mimetype |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
767 | mimetype_map[mimetype] = mapping[0] |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
768 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
769 | magic_mime_map = {} |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
770 | for mapping in (('deb', 'Debian binary package'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
771 | ('cpio', 'cpio archive'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
772 | ('tar', 'POSIX tar archive'), |
59
7a0aafe2fe87
[svn] Find self-extracting archives by their file magic only, not extension/mimetype.
brett
parents:
58
diff
changeset
|
773 | ('zip', '(Zip|ZIP self-extracting) archive'), |
32 | 774 | ('rpm', 'RPM'), |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
775 | ('7z', '7-zip archive'), |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
776 | ('cab', 'Microsoft Cabinet archive'), |
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
777 | ('shield', 'InstallShield CAB')): |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
778 | for pattern in mapping[1:]: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
779 | magic_mime_map[re.compile(pattern)] = mapping[0] |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
780 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
781 | magic_encoding_map = {} |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
782 | for mapping in (('bzip2', 'bzip2 compressed'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
783 | ('gzip', 'gzip compressed')): |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
784 | for pattern in mapping[1:]: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
785 | magic_encoding_map[re.compile(pattern)] = mapping[0] |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
786 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
787 | extension_map = {} |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
788 | for mapping in (('tar', 'bzip2', 'tar.bz2'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
789 | ('tar', 'gzip', 'tar.gz', 'tgz'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
790 | ('tar', None, 'tar'), |
59
7a0aafe2fe87
[svn] Find self-extracting archives by their file magic only, not extension/mimetype.
brett
parents:
58
diff
changeset
|
791 | ('zip', None, 'zip'), |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
792 | ('deb', None, 'deb'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
793 | ('rpm', None, 'rpm'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
794 | ('cpio', None, 'cpio'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
795 | ('gem', None, 'gem'), |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
796 | ('compress', 'gzip', 'Z', 'gz'), |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
797 | ('compress', 'bzip2', 'bz2'), |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
798 | ('compress', 'lzma', 'lzma'), |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
799 | ('7z', None, '7z'), |
73
a4fff3df2242
Don't assume .exe files are Cabinet archives just by extension.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
72
diff
changeset
|
800 | ('cab', None, 'cab'), |
72
c4cfaf634bb9
Add support for InstallShield archives.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
71
diff
changeset
|
801 | ('shield', None, 'cab', 'hdr')): |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
802 | for extension in mapping[2:]: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
803 | extension_map.setdefault(extension, []).append(mapping[:2]) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
804 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
805 | def __init__(self, filename, options): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
806 | self.filename = filename |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
807 | self.options = options |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
808 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
809 | def build_extractor(self, archive_type, encoding): |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
810 | extractors = self.extractor_map[archive_type] |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
811 | if self.options.metadata and (extractors[1] is not None): |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
812 | extractor = extractors[1] |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
813 | else: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
814 | extractor = extractors[0] |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
815 | return extractor(self.filename, encoding) |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
816 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
817 | def get_extractor(self): |
48 | 818 | tried_types = set() |
36
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
819 | # As smart as it is, the magic test can't go first, because at least |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
820 | # on my system it just recognizes gem files as tar files. I guess |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
821 | # it's possible for the opposite problem to occur -- where the mimetype |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
822 | # or extension suggests something less than ideal -- but it seems less |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
823 | # likely so I'm sticking with this. |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
824 | for func_name in ('mimetype', 'extension', 'magic'): |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
825 | logger.debug("getting extractors by %s" % (func_name,)) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
826 | extractor_types = \ |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
827 | getattr(self, 'try_by_' + func_name)(self.filename) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
828 | logger.debug("done getting extractors") |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
829 | for ext_args in extractor_types: |
36
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
830 | if ext_args in tried_types: |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
831 | continue |
4bf2508d9b9e
[svn] Small optimization to be nice to the system: don't try a given extractor
brett
parents:
35
diff
changeset
|
832 | tried_types.add(ext_args) |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
833 | logger.debug("trying %s extractor from %s" % |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
834 | (ext_args, func_name)) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
835 | yield self.build_extractor(*ext_args) |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
836 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
837 | def try_by_mimetype(cls, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
838 | mimetype, encoding = mimetypes.guess_type(filename) |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
839 | try: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
840 | return [(cls.mimetype_map[mimetype], encoding)] |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
841 | except KeyError: |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
842 | if encoding: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
843 | return [('compress', encoding)] |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
844 | return [] |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
845 | try_by_mimetype = classmethod(try_by_mimetype) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
846 | |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
847 | def magic_map_matches(cls, output, magic_map): |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
848 | return [result for regexp, result in magic_map.items() |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
849 | if regexp.search(output)] |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
850 | magic_map_matches = classmethod(magic_map_matches) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
851 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
852 | def try_by_magic(cls, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
853 | process = subprocess.Popen(['file', '-z', filename], |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
854 | stdout=subprocess.PIPE) |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
855 | status = process.wait() |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
856 | if status != 0: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
857 | return [] |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
858 | output = process.stdout.readline() |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
859 | process.stdout.close() |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
860 | if output.startswith('%s: ' % filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
861 | output = output[len(filename) + 2:] |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
862 | mimes = cls.magic_map_matches(output, cls.magic_mime_map) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
863 | encodings = cls.magic_map_matches(output, cls.magic_encoding_map) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
864 | if mimes and not encodings: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
865 | encodings = [None] |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
866 | elif encodings and not mimes: |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
867 | mimes = ['compress'] |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
868 | return [(m, e) for m in mimes for e in encodings] |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
869 | try_by_magic = classmethod(try_by_magic) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
870 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
871 | def try_by_extension(cls, filename): |
43
4591a32eedc8
[svn] Sadly Python 2.3 does not have an rsplit method on strings.
brett
parents:
42
diff
changeset
|
872 | parts = filename.split('.')[-2:] |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
873 | results = [] |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
874 | while parts: |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
875 | results.extend(cls.extension_map.get('.'.join(parts), [])) |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
876 | del parts[0] |
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
877 | return results |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
878 | try_by_extension = classmethod(try_by_extension) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
879 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
880 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
881 | class BaseAction(object): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
882 | def __init__(self, options, filenames): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
883 | self.options = options |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
884 | self.filenames = filenames |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
885 | self.target = None |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
886 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
887 | def report(self, function, *args): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
888 | try: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
889 | error = function(*args) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
890 | except EXTRACTION_ERRORS, exception: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
891 | error = str(exception) |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
892 | logger.debug(''.join(traceback.format_exception(*sys.exc_info()))) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
893 | return error |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
894 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
895 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
896 | class ExtractionAction(BaseAction): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
897 | handlers = [FlatHandler, OverwriteHandler, MatchHandler, EmptyHandler, |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
898 | BombHandler] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
899 | |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
900 | def __init__(self, options, filenames): |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
901 | BaseAction.__init__(self, options, filenames) |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
902 | self.did_print = False |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
903 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
904 | def get_handler(self, extractor): |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
905 | if extractor.content_type in ONE_ENTRY_UNKNOWN: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
906 | self.options.one_entry_policy.prep(self.current_filename, |
65
0aea49161478
Make the wording on the One Entry question a little clearer.
Brett Smith <brett@brettcsmith.org>
parents:
62
diff
changeset
|
907 | extractor) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
908 | for handler in self.handlers: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
909 | if handler.can_handle(extractor.content_type, self.options): |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
910 | logger.debug("using %s handler" % (handler.__name__,)) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
911 | self.current_handler = handler(extractor, self.options) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
912 | break |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
913 | |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
914 | def show_extraction(self, extractor): |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
915 | if self.options.log_level > logging.INFO: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
916 | return |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
917 | elif self.did_print: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
918 | |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
919 | else: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
920 | self.did_print = True |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
921 | print "%s:" % (self.current_filename,) |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
922 | if extractor.contents is None: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
923 | print self.current_handler.target |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
924 | return |
55
494516c027c4
[svn] Stupid Python 2.3 doesn't support [].sort(reverse=True).
brett
parents:
54
diff
changeset
|
925 | def reverser(x, y): |
494516c027c4
[svn] Stupid Python 2.3 doesn't support [].sort(reverse=True).
brett
parents:
54
diff
changeset
|
926 | return cmp(y, x) |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
927 | if self.current_handler.target == '.': |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
928 | filenames = extractor.contents |
55
494516c027c4
[svn] Stupid Python 2.3 doesn't support [].sort(reverse=True).
brett
parents:
54
diff
changeset
|
929 | filenames.sort(reverser) |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
930 | else: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
931 | filenames = [self.current_handler.target] |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
932 | pathjoin = os.path.join |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
933 | isdir = os.path.isdir |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
934 | while filenames: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
935 | filename = filenames.pop() |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
936 | if isdir(filename): |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
937 | print "%s/" % (filename,) |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
938 | new_filenames = os.listdir(filename) |
55
494516c027c4
[svn] Stupid Python 2.3 doesn't support [].sort(reverse=True).
brett
parents:
54
diff
changeset
|
939 | new_filenames.sort(reverser) |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
940 | filenames.extend([pathjoin(filename, new_filename) |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
941 | for new_filename in new_filenames]) |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
942 | else: |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
943 | print filename |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
944 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
945 | def run(self, filename, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
946 | self.current_filename = filename |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
947 | error = (self.report(extractor.extract) or |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
948 | self.report(self.get_handler, extractor) or |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
949 | self.report(self.current_handler.handle) or |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
950 | self.report(self.show_extraction, extractor)) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
951 | if not error: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
952 | self.target = self.current_handler.target |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
953 | return error |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
954 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
955 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
956 | class ListAction(BaseAction): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
957 | def __init__(self, options, filenames): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
958 | BaseAction.__init__(self, options, filenames) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
959 | self.count = 0 |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
960 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
961 | def get_list(self, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
962 | # Note: The reason I'm getting all the filenames up front is |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
963 | # because if we run into trouble partway through the archive, we'll |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
964 | # try another extractor. So before we display anything we have to |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
965 | # be sure this one is successful. We maybe don't have to be quite |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
966 | # this conservative but this is the easy way out for now. |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
967 | self.filelist = list(extractor.get_filenames()) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
968 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
969 | def show_list(self, filename): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
970 | self.count += 1 |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
971 | if len(self.filenames) != 1: |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
972 | if self.count > 1: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
973 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
974 | print "%s:" % (filename,) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
975 | print '\n'.join(self.filelist) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
976 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
977 | def run(self, filename, extractor): |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
978 | return (self.report(self.get_list, extractor) or |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
979 | self.report(self.show_list, filename)) |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
980 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
981 | |
5 | 982 | class ExtractorApplication(object): |
983 | def __init__(self, arguments): | |
48 | 984 | for signal_num in (signal.SIGINT, signal.SIGTERM): |
985 | signal.signal(signal_num, self.abort) | |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
986 | self.parse_options(arguments) |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
987 | self.setup_logger() |
5 | 988 | self.successes = [] |
989 | self.failures = [] | |
990 | ||
77
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
991 | def clean_destination(self, dest_name): |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
992 | try: |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
993 | os.unlink(dest_name) |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
994 | except OSError, error: |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
995 | if error.errno == errno.EISDIR: |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
996 | shutil.rmtree(dest_name, ignore_errors=True) |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
997 | |
48 | 998 | def abort(self, signal_num, frame): |
999 | signal.signal(signal_num, signal.SIG_IGN) | |
1000 | ||
49 | 1001 | logger.debug("traceback:\n" + |
1002 | ''.join(traceback.format_stack(frame)).rstrip()) | |
48 | 1003 | logger.debug("got signal %s; cleaning up" % (signal_num,)) |
1004 | clean_targets = set([os.path.realpath('.')]) | |
1005 | if hasattr(self, 'current_directory'): | |
1006 | clean_targets.add(os.path.realpath(self.current_directory)) | |
1007 | for directory in clean_targets: | |
1008 | os.chdir(directory) | |
1009 | for path in glob.glob('.dtrx-*'): | |
77
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
1010 | self.clean_destination(path) |
48 | 1011 | sys.exit(1) |
1012 | ||
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1013 | def parse_options(self, arguments): |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1014 | parser = optparse.OptionParser( |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1015 | usage="%prog [options] archive [archive2 ...]", |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1016 | description="Intelligent archive extractor", |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1017 | version=VERSION_BANNER |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1018 | ) |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1019 | parser.add_option('-r', '--recursive', dest='recursive', |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1020 | action='store_true', default=False, |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1021 | help='extract archives contained in the ones listed') |
13
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1022 | parser.add_option('-q', '--quiet', dest='quiet', |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1023 | action='count', default=3, |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1024 | help='suppress warning/error messages') |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1025 | parser.add_option('-v', '--verbose', dest='verbose', |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1026 | action='count', default=0, |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
1027 | help='be verbose/print debugging information') |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
1028 | parser.add_option('-o', '--overwrite', dest='overwrite', |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
1029 | action='store_true', default=False, |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
1030 | help='overwrite any existing target directory') |
15
28dbd52a8bb8
[svn] Add a -f/--flat option, which will extract the archive contents into the
brett
parents:
14
diff
changeset
|
1031 | parser.add_option('-f', '--flat', '--no-directory', dest='flat', |
28dbd52a8bb8
[svn] Add a -f/--flat option, which will extract the archive contents into the
brett
parents:
14
diff
changeset
|
1032 | action='store_true', default=False, |
28dbd52a8bb8
[svn] Add a -f/--flat option, which will extract the archive contents into the
brett
parents:
14
diff
changeset
|
1033 | help="don't put contents in their own directory") |
19 | 1034 | parser.add_option('-l', '-t', '--list', '--table', dest='show_list', |
1035 | action='store_true', default=False, | |
1036 | help="list contents of archives on standard output") | |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
1037 | parser.add_option('-n', '--noninteractive', dest='batch', |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
1038 | action='store_true', default=False, |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
1039 | help="don't ask how to handle special cases") |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
1040 | parser.add_option('-m', '--metadata', dest='metadata', |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
1041 | action='store_true', default=False, |
35
957b402d4b90
[svn] Add support for extracting CAB archives. Because the CAB archive I was
brett
parents:
34
diff
changeset
|
1042 | help="extract metadata from a .deb/.gem") |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1043 | self.options, filenames = parser.parse_args(arguments) |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1044 | if not filenames: |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1045 | parser.error("you did not list any archives") |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
1046 | # This makes WARNING is the default. |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
1047 | self.options.log_level = (10 * (self.options.quiet - |
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
1048 | self.options.verbose)) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
1049 | self.options.one_entry_policy = OneEntryPolicy(self.options) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
1050 | self.options.recursion_policy = RecursionPolicy(self.options) |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1051 | self.archives = {os.path.realpath(os.curdir): filenames} |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
1052 | |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
1053 | def setup_logger(self): |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
1054 | logging.getLogger().setLevel(self.options.log_level) |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
1055 | handler = logging.StreamHandler() |
52
cf191f957fd0
[svn] Make just one -v print a list of filenames, a la tar.
brett
parents:
51
diff
changeset
|
1056 | handler.setLevel(self.options.log_level) |
19 | 1057 | formatter = logging.Formatter("dtrx: %(levelname)s: %(message)s") |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
1058 | handler.setFormatter(formatter) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
1059 | logger.addHandler(handler) |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
1060 | logger.debug("logger is set up") |
1 | 1061 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
1062 | def recurse(self, filename, extractor, action): |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
1063 | self.options.recursion_policy.prep(filename, action.target, extractor) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
1064 | if self.options.recursion_policy.ok_to_recurse(): |
53
cd853ddb224c
[svn] Add interactive option to list recursive archives when found.
brett
parents:
52
diff
changeset
|
1065 | for filename in extractor.included_archives: |
71
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1066 | logger.debug("recursing with %s archive" % |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1067 | (extractor.content_type,)) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
1068 | tail_path, basename = os.path.split(filename) |
71
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1069 | path_args = [self.current_directory, extractor.included_root, |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1070 | tail_path] |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1071 | logger.debug("included root: %s" % (extractor.included_root,)) |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1072 | logger.debug("tail path: %s" % (tail_path,)) |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1073 | if os.path.isdir(action.target): |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1074 | logger.debug("action target: %s" % (action.target,)) |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1075 | path_args.insert(1, action.target) |
b0290eeb3b7a
Recurse better when the contents were just one file.
Brett Smith <brett@brettcsmith.org>
parents:
70
diff
changeset
|
1076 | directory = os.path.join(*path_args) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
1077 | self.archives.setdefault(directory, []).append(basename) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
1078 | |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1079 | def check_file(self, filename): |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1080 | try: |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1081 | result = os.stat(filename) |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1082 | except OSError, error: |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1083 | return error.strerror |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1084 | if stat.S_ISDIR(result.st_mode): |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1085 | return "cannot extract a directory" |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1086 | |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1087 | def show_stderr(self, logger_func, stderr): |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1088 | if stderr: |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1089 | logger_func("Error output from the extraction process:\n" + |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1090 | stderr.rstrip('\n')) |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1091 | |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1092 | def try_extractors(self, filename, builder): |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1093 | errors = [] |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1094 | for extractor in builder: |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1095 | error = self.action.run(filename, extractor) |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1096 | if error: |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1097 | errors.append((extractor.file_type, extractor.encoding, error, |
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1098 | extractor.get_stderr())) |
77
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
1099 | if extractor.target is not None: |
3a1f49be7667
Clean the target directory if an extraction attempt failed.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
76
diff
changeset
|
1100 | self.clean_destination(extractor.target) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1101 | else: |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1102 | self.show_stderr(logger.warn, extractor.get_stderr()) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1103 | self.recurse(filename, extractor, self.action) |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1104 | return |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1105 | logger.error("could not handle %s" % (filename,)) |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1106 | if not errors: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1107 | logger.error("not a known archive type") |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1108 | return True |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1109 | for file_type, encoding, error, stderr in errors: |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1110 | message = ["treating as", file_type, "failed:", error] |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1111 | if encoding: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1112 | message.insert(1, "%s-encoded" % (encoding,)) |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1113 | logger.error(' '.join(message)) |
78
978307ec7d11
Don't show errors from failed extractors unless they all fail.
Brett Smith <brettcsmith@brettcsmith.org>
parents:
77
diff
changeset
|
1114 | self.show_stderr(logger.error, stderr) |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1115 | return True |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1116 | |
19 | 1117 | def run(self): |
1118 | if self.options.show_list: | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
1119 | action = ListAction |
19 | 1120 | else: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
1121 | action = ExtractionAction |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1122 | self.action = action(self.options, self.archives.values()[0]) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1123 | while self.archives: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1124 | self.current_directory, self.filenames = self.archives.popitem() |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1125 | os.chdir(self.current_directory) |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1126 | for filename in self.filenames: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
1127 | builder = ExtractorBuilder(filename, self.options) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1128 | error = (self.check_file(filename) or |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1129 | self.try_extractors(filename, builder.get_extractor())) |
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1130 | if error: |
45
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1131 | if error != True: |
37d555407334
[svn] At work I was getting an unhelpful "No such file or directory" error when I
brett
parents:
43
diff
changeset
|
1132 | logger.error("%s: %s" % (filename, error)) |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1133 | self.failures.append(filename) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1134 | else: |
39
027fcd7ae002
[svn] Improve the error reporting to be more user-friendly, at least in many of
brett
parents:
36
diff
changeset
|
1135 | self.successes.append(filename) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
1136 | self.options.one_entry_policy.permanent_policy = EXTRACT_WRAP |
5 | 1137 | if self.failures: |
1138 | return 1 | |
1139 | return 0 | |
1140 | ||
1 | 1141 | |
1142 | if __name__ == '__main__': | |
5 | 1143 | app = ExtractorApplication(sys.argv[1:]) |
1144 | sys.exit(app.run()) |