Thu, 22 Nov 2007 22:24:04 -0500
[svn] Fix some bugs and make things a little more user-friendly now that we can
try multiple extractors per file. Add some logging as part of this. I'm
probably still not done -- heck, dtrx has never really been user-friendly
enough -- but at least now it's not ridiculous.
1 | 1 | #!/usr/bin/env python |
2 | # | |
19 | 3 | # dtrx -- Intelligently extract various archive types. |
23
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
4 | # Copyright (c) 2006, 2007 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 | |
17 | # with this program; if not, write to the Free Software Foundation, Inc., | |
18 | # 51 Franklin Street, 5th Floor, Boston, MA, 02111. | |
19 | ||
5 | 20 | import errno |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
21 | import logging |
1 | 22 | import mimetypes |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
23 | import optparse |
1 | 24 | 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
|
25 | import re |
15
28dbd52a8bb8
[svn] Add a -f/--flat option, which will extract the archive contents into the
brett
parents:
14
diff
changeset
|
26 | import stat |
1 | 27 | import subprocess |
28 | import sys | |
29 | import tempfile | |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
30 | import textwrap |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
31 | import traceback |
1 | 32 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
33 | VERSION = "5.0" |
19 | 34 | VERSION_BANNER = """dtrx version %s |
23
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
35 | Copyright (c) 2006, 2007 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
|
36 | |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
37 | 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
|
38 | 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
|
39 | 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
|
40 | option) any later version. |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
41 | |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
42 | 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
|
43 | 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
|
44 | 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
|
45 | Public License for more details.""" % (VERSION,) |
1 | 46 | |
47 | MATCHING_DIRECTORY = 1 | |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
48 | ONE_ENTRY = 2 |
1 | 49 | BOMB = 3 |
50 | EMPTY = 4 | |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
51 | ONE_ENTRY_KNOWN = 5 |
1 | 52 | |
20
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
53 | EXTRACT_HERE = 1 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
54 | EXTRACT_WRAP = 2 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
55 | EXTRACT_RENAME = 3 |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
56 | |
23
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
57 | RECURSE_ALWAYS = 1 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
58 | RECURSE_ONCE = 2 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
59 | RECURSE_NOT_NOW = 3 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
60 | RECURSE_NEVER = 4 |
039dd321a7d0
[svn] If an archive contains other archives, and the user didn't specify that
brett
parents:
22
diff
changeset
|
61 | |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
62 | mimetypes.encodings_map.setdefault('.bz2', 'bzip2') |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
63 | mimetypes.types_map.setdefault('.gem', 'x-ruby-gem') |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
64 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
65 | 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
|
66 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
67 | def run_command(command, description, stdout=None, stderr=None, stdin=None): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
68 | process = subprocess.Popen(command, stdin=stdin, stdout=stdout, |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
69 | stderr=stderr) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
70 | status = process.wait() |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
71 | for pipe in (process.stdout, process.stderr): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
72 | try: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
73 | pipe.close() |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
74 | except AttributeError: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
75 | pass |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
76 | if status != 0: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
77 | return ("%s error: '%s' returned status code %s" % |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
78 | (description, ' '.join(command), status)) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
79 | return None |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
80 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
81 | class FilenameChecker(object): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
82 | def __init__(self, original_name): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
83 | self.original_name = original_name |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
84 | |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
85 | def is_free(self, filename): |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
86 | return not os.path.exists(filename) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
87 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
88 | def check(self): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
89 | 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
|
90 | 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
|
91 | if self.is_free(filename): |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
92 | return filename |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
93 | raise ValueError("all alternatives for name %s taken" % |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
94 | (self.original_name,)) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
95 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
96 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
97 | class DirectoryChecker(FilenameChecker): |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
98 | def is_free(self, filename): |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
99 | try: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
100 | os.mkdir(filename) |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
101 | except OSError, error: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
102 | if error.errno == errno.EEXIST: |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
103 | return False |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
104 | raise |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
105 | return True |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
106 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
107 | |
1 | 108 | class ExtractorError(Exception): |
109 | pass | |
110 | ||
111 | ||
112 | class BaseExtractor(object): | |
113 | decoders = {'bzip2': 'bzcat', 'gzip': 'zcat', 'compress': 'zcat'} | |
114 | ||
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
115 | name_checker = DirectoryChecker |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
116 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
117 | 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
|
118 | 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
|
119 | 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
|
120 | self.filename = os.path.realpath(filename) |
1 | 121 | self.encoding = encoding |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
122 | self.included_archives = [] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
123 | self.target = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
124 | self.content_type = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
125 | self.content_name = None |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
126 | self.pipes = [] |
5 | 127 | try: |
128 | self.archive = open(filename, 'r') | |
129 | except (IOError, OSError), error: | |
130 | raise ExtractorError("could not open %s: %s" % | |
131 | (filename, error.strerror)) | |
1 | 132 | if encoding: |
133 | self.pipe([self.decoders[encoding]], "decoding") | |
134 | self.prepare() | |
135 | ||
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
136 | def pipe(self, command, description="extraction"): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
137 | self.pipes.append((command, description)) |
1 | 138 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
139 | def run_pipes(self, final_stdout=None): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
140 | if final_stdout is None: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
141 | # FIXME: Buffering this might be dumb. |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
142 | final_stdout = tempfile.TemporaryFile() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
143 | if not self.pipes: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
144 | return |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
145 | num_pipes = len(self.pipes) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
146 | last_pipe = num_pipes - 1 |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
147 | processes = [] |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
148 | 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
|
149 | if index == 0: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
150 | stdin = self.archive |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
151 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
152 | stdin = processes[-1].stdout |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
153 | if index == last_pipe: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
154 | stdout = final_stdout |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
155 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
156 | stdout = subprocess.PIPE |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
157 | processes.append(subprocess.Popen(command, stdin=stdin, |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
158 | stdout=stdout, |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
159 | stderr=subprocess.PIPE)) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
160 | exit_codes = [pipe.wait() for pipe in processes] |
1 | 161 | self.archive.close() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
162 | for index in range(last_pipe): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
163 | processes[index].stdout.close() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
164 | processes[index].stderr.close() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
165 | for index, status in enumerate(exit_codes): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
166 | if status != 0: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
167 | raise ExtractorError("%s error: '%s' returned status code %s" % |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
168 | (self.pipes[index][1], |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
169 | ' '.join(self.pipes[index][0]), status)) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
170 | self.archive = final_stdout |
1 | 171 | |
172 | def prepare(self): | |
173 | pass | |
174 | ||
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
175 | def check_included_archives(self, filenames): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
176 | for filename in filenames: |
32 | 177 | if (ExtractorBuilder.try_by_mimetype(filename)[0] or |
178 | ExtractorBuilder.try_by_extension(filename)[0]): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
179 | self.included_archives.append(filename) |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
180 | |
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
181 | def check_contents(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
182 | filenames = os.listdir('.') |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
183 | if not filenames: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
184 | self.content_type = EMPTY |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
185 | elif len(filenames) == 1: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
186 | if self.basename() == filenames[0]: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
187 | self.content_type = MATCHING_DIRECTORY |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
188 | else: |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
189 | self.content_type = ONE_ENTRY |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
190 | self.content_name = filenames[0] |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
191 | if os.path.isdir(filenames[0]): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
192 | self.content_name += '/' |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
193 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
194 | self.content_type = BOMB |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
195 | self.check_included_archives(filenames) |
1 | 196 | |
197 | def basename(self): | |
5 | 198 | 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
|
199 | extension = '.' + pieces[-1] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
200 | 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
|
201 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
202 | extension = '.' + pieces[-1] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
203 | 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
|
204 | 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
|
205 | mimetypes.suffix_map.has_key(extension)): |
1 | 206 | pieces.pop() |
207 | return '.'.join(pieces) | |
208 | ||
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
209 | def extract(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
210 | self.target = tempfile.mkdtemp(prefix='.dtrx-', dir='.') |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
211 | old_path = os.path.realpath(os.curdir) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
212 | 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
|
213 | try: |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
214 | 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
|
215 | 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
|
216 | self.check_contents() |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
217 | except ExtractorError: |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
218 | os.chdir(old_path) |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
219 | subprocess.call(['rm', '-rf', self.target]) |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
220 | raise |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
221 | os.chdir(old_path) |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
222 | |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
223 | def get_filenames(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
224 | self.run_pipes() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
225 | self.archive.seek(0, 0) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
226 | while True: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
227 | line = self.archive.readline() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
228 | if not line: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
229 | self.archive.close() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
230 | return |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
231 | yield line.rstrip('\n') |
1 | 232 | |
233 | ||
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
234 | class CompressionExtractor(BaseExtractor): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
235 | name_checker = FilenameChecker |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
236 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
237 | def basename(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
238 | 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
|
239 | extension = '.' + pieces[-1] |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
240 | 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
|
241 | pieces.pop() |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
242 | return '.'.join(pieces) |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
243 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
244 | def get_filenames(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
245 | yield self.basename() |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
246 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
247 | def extract(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
248 | 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
|
249 | self.content_name = self.basename() |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
250 | output_fd, self.target = tempfile.mkstemp(prefix='.dtrx-', dir='.') |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
251 | self.run_pipes(output_fd) |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
252 | os.close(output_fd) |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
253 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
254 | |
1 | 255 | class TarExtractor(BaseExtractor): |
256 | def get_filenames(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
257 | self.pipe(['tar', '-t'], "listing") |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
258 | return BaseExtractor.get_filenames(self) |
1 | 259 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
260 | def extract_archive(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
261 | self.pipe(['tar', '-x']) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
262 | self.run_pipes() |
1 | 263 | |
264 | ||
265 | class ZipExtractor(BaseExtractor): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
266 | def __init__(self, filename, encoding): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
267 | BaseExtractor.__init__(self, '/dev/null', None) |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
268 | self.filename = os.path.realpath(filename) |
1 | 269 | |
270 | def get_filenames(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
271 | self.pipe(['zipinfo', '-1', self.filename], "listing") |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
272 | return BaseExtractor.get_filenames(self) |
1 | 273 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
274 | def extract_archive(self): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
275 | self.pipe(['unzip', '-q', self.filename]) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
276 | self.run_pipes() |
1 | 277 | |
278 | ||
279 | class CpioExtractor(BaseExtractor): | |
280 | def get_filenames(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
281 | self.pipe(['cpio', '-t'], "listing") |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
282 | return BaseExtractor.get_filenames(self) |
1 | 283 | |
284 | def extract_archive(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
285 | self.pipe(['cpio', '-i', '--make-directories', |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
286 | '--no-absolute-filenames']) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
287 | self.run_pipes() |
1 | 288 | |
289 | ||
290 | class RPMExtractor(CpioExtractor): | |
291 | def prepare(self): | |
292 | self.pipe(['rpm2cpio', '-'], "rpm2cpio") | |
293 | ||
294 | def basename(self): | |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
295 | 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
|
296 | 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
|
297 | return pieces[0] |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
298 | 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
|
299 | 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
|
300 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
301 | 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
|
302 | return pieces[0] |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
303 | 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
|
304 | pieces.pop() |
1570351bf863
[svn] Fix a small bug that would crash the program if an archive was empty.
brett
parents:
1
diff
changeset
|
305 | return '.'.join(pieces) |
1 | 306 | |
307 | def check_contents(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
308 | self.check_included_archives(os.listdir('.')) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
309 | self.content_type = BOMB |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
310 | |
1 | 311 | |
312 | class DebExtractor(TarExtractor): | |
313 | def prepare(self): | |
314 | self.pipe(['ar', 'p', self.filename, 'data.tar.gz'], | |
315 | "data.tar.gz extraction") | |
316 | self.pipe(['zcat'], "data.tar.gz decompression") | |
317 | ||
318 | def basename(self): | |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
319 | 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
|
320 | 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
|
321 | return pieces[0] |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
322 | last_piece = pieces.pop() |
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
323 | 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
|
324 | return BaseExtractor.basename(self) |
9
920417b8acc9
[svn] Fix issues with basename methods. First, string's rsplit method only
brett
parents:
8
diff
changeset
|
325 | return '_'.join(pieces) |
1 | 326 | |
327 | def check_contents(self): | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
328 | self.check_included_archives(os.listdir('.')) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
329 | self.content_type = BOMB |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
330 | |
1 | 331 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
332 | class DebMetadataExtractor(DebExtractor): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
333 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
334 | 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
|
335 | "control.tar.gz extraction") |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
336 | 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
|
337 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
338 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
339 | class GemExtractor(TarExtractor): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
340 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
341 | 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
|
342 | 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
|
343 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
344 | def check_contents(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
345 | self.check_included_archives(os.listdir('.')) |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
346 | self.content_type = BOMB |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
347 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
348 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
349 | class GemMetadataExtractor(CompressionExtractor): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
350 | def prepare(self): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
351 | 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
|
352 | 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
|
353 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
354 | def basename(self): |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
355 | 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
|
356 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
357 | |
32 | 358 | class SevenExtractor(BaseExtractor): |
359 | border_re = re.compile('^[- ]+$') | |
360 | ||
361 | def __init__(self, filename, encoding): | |
362 | BaseExtractor.__init__(self, '/dev/null', None) | |
363 | self.filename = os.path.realpath(filename) | |
364 | ||
365 | def get_filenames(self): | |
366 | self.pipe(['7z', 'l', self.filename], "listing") | |
367 | self.run_pipes() | |
368 | self.archive.seek(0, 0) | |
369 | fn_index = None | |
370 | for line in self.archive: | |
371 | if self.border_re.match(line): | |
372 | if fn_index is not None: | |
373 | break | |
374 | else: | |
375 | fn_index = line.rindex(' ') + 1 | |
376 | elif fn_index is not None: | |
377 | yield line[fn_index:-1] | |
378 | self.archive.close() | |
379 | ||
380 | def extract_archive(self): | |
381 | self.pipe(['7z', 'x', self.filename]) | |
382 | self.run_pipes() | |
383 | ||
384 | ||
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
385 | class BaseHandler(object): |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
386 | def __init__(self, extractor, options): |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
387 | self.extractor = extractor |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
388 | self.options = options |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
389 | self.target = None |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
390 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
391 | def handle(self): |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
392 | command = 'find' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
393 | 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
|
394 | '-exec', 'chmod', 'u+rwx', '{}', ';']) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
395 | if status == 0: |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
396 | command = 'chmod' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
397 | status = subprocess.call(['chmod', '-R', 'u+rwX', |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
398 | self.extractor.target]) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
399 | if status != 0: |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
400 | 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
|
401 | return self.organize() |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
402 | |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
403 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
404 | # 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
|
405 | # 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
|
406 | # |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
407 | # Flat Overwrite None |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
408 | # File basename basename FilenameChecked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
409 | # Match . . tempdir + checked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
410 | # Bomb . basename DirectoryChecked |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
411 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
412 | class FlatHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
413 | 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
|
414 | 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
|
415 | (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
|
416 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
417 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
418 | def organize(self): |
17
481a2b4be471
[svn] Lots of tests for various boundary cases, and slightly better handling for
brett
parents:
16
diff
changeset
|
419 | self.target = '.' |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
420 | 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
|
421 | topdown=False): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
422 | path_parts = curdir.split(os.sep) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
423 | if path_parts[0] == '.': |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
424 | del path_parts[1] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
425 | else: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
426 | del path_parts[0] |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
427 | newdir = os.path.join(*path_parts) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
428 | if not os.path.isdir(newdir): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
429 | os.makedirs(newdir) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
430 | for filename in filenames: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
431 | os.rename(os.path.join(curdir, filename), |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
432 | os.path.join(newdir, filename)) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
433 | os.rmdir(curdir) |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
434 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
435 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
436 | class OverwriteHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
437 | 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
|
438 | 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
|
439 | (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
|
440 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
441 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
442 | def organize(self): |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
443 | self.target = self.extractor.basename() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
444 | result = run_command(['rm', '-rf', self.target], |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
445 | "removing %s to overwrite" % (self.target,)) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
446 | if result is None: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
447 | os.rename(self.extractor.target, self.target) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
448 | return result |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
449 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
450 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
451 | class MatchHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
452 | 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
|
453 | return ((contents == MATCHING_DIRECTORY) or |
22
b240777ae53e
[svn] Improve the way we check archive contents. If all the entries look like
brett
parents:
20
diff
changeset
|
454 | ((contents == ONE_ENTRY) and |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
455 | 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
|
456 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
457 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
458 | def organize(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
459 | if self.options.one_entry_policy == EXTRACT_HERE: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
460 | 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
|
461 | else: |
69c93c3e6972
[svn] If the archive contains one directory with the "wrong" name, ask the user
brett
parents:
19
diff
changeset
|
462 | destination = self.extractor.basename() |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
463 | self.target = self.extractor.name_checker(destination).check() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
464 | if os.path.isdir(self.extractor.target): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
465 | os.rename(os.path.join(self.extractor.target, |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
466 | os.listdir(self.extractor.target)[0]), |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
467 | self.target) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
468 | os.rmdir(self.extractor.target) |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
469 | else: |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
470 | os.rename(self.extractor.target, self.target) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
471 | |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
472 | |
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
473 | class EmptyHandler(object): |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
474 | def can_handle(contents, options): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
475 | return contents == EMPTY |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
476 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
477 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
478 | def __init__(self, extractor, options): pass |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
479 | def handle(self): pass |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
480 | |
14
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
481 | |
16
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
482 | class BombHandler(BaseHandler): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
483 | def can_handle(contents, options): |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
484 | return True |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
485 | can_handle = staticmethod(can_handle) |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
486 | |
28
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
487 | def organize(self): |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
488 | basename = self.extractor.basename() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
489 | self.target = self.extractor.name_checker(basename).check() |
4d88f2231d33
[svn] Change all the license notices from GPLv2 to GPLv3.
brett
parents:
27
diff
changeset
|
490 | 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
|
491 | |
29794d4d41aa
[svn] There's now an entirely new object hierarchy for handlers, because the
brett
parents:
15
diff
changeset
|
492 | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
493 | class BasePolicy(object): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
494 | def __init__(self, options): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
495 | self.current_policy = None |
26 | 496 | if options.batch: |
497 | self.permanent_policy = self.answers[''] | |
498 | else: | |
499 | self.permanent_policy = None | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
500 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
501 | def ask_question(self, question): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
502 | question = textwrap.wrap(question) + self.choices |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
503 | while True: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
504 | print "\n".join(question) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
505 | try: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
506 | answer = raw_input(self.prompt) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
507 | except EOFError: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
508 | return self.answers[''] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
509 | try: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
510 | return self.answers[answer.lower()] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
511 | except KeyError: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
512 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
513 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
514 | def __cmp__(self, other): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
515 | 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
|
516 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
517 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
518 | class OneEntryPolicy(BasePolicy): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
519 | 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
|
520 | '': EXTRACT_WRAP} |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
521 | choices = ["You can:", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
522 | " * extract it Inside another directory", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
523 | " * 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
|
524 | " * extract it Here"] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
525 | 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
|
526 | |
26 | 527 | def prep(self, archive_filename, entry_name): |
528 | question = ("%s contains one entry: %s." % | |
529 | (archive_filename, entry_name)) | |
530 | self.current_policy = (self.permanent_policy or | |
531 | self.ask_question(question)) | |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
532 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
533 | def ok_for_match(self): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
534 | 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
|
535 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
536 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
537 | class RecursionPolicy(BasePolicy): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
538 | answers = {'o': RECURSE_ONCE, 'a': RECURSE_ALWAYS, 'n': RECURSE_NOT_NOW, |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
539 | 'v': RECURSE_NEVER, '': RECURSE_NOT_NOW} |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
540 | choices = ["You can:", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
541 | " * Always extract included archives", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
542 | " * extract included archives this Once", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
543 | " * choose Not to extract included archives", |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
544 | " * neVer extract included archives"] |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
545 | prompt = "What do you want to do? (a/o/N/v) " |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
546 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
547 | def __init__(self, options): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
548 | BasePolicy.__init__(self, options) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
549 | if options.show_list: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
550 | self.permanent_policy = RECURSE_NEVER |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
551 | elif options.recursive: |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
552 | self.permanent_policy = RECURSE_ALWAYS |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
553 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
554 | def prep(self, current_filename, included_archives): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
555 | archive_count = len(included_archives) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
556 | 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
|
557 | 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
|
558 | return |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
559 | elif archive_count > 1: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
560 | question = ("%s contains %s other archive files." % |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
561 | (current_filename, archive_count)) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
562 | else: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
563 | question = ("%s contains another archive: %s." % |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
564 | (current_filename, included_archives[0])) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
565 | self.current_policy = self.ask_question(question) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
566 | 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
|
567 | 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
|
568 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
569 | def ok_to_recurse(self): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
570 | 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
|
571 | |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
572 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
573 | 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
|
574 | 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
|
575 | '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
|
576 | '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
|
577 | '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
|
578 | '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
|
579 | 'gem': (GemExtractor, GemMetadataExtractor), |
32 | 580 | 'compress': (CompressionExtractor, None), |
581 | '7z': (SevenExtractor, 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
|
582 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
583 | 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
|
584 | for mapping in (('tar', 'x-tar'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
585 | ('zip', 'x-msdos-program', 'zip'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
586 | ('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
|
587 | ('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
|
588 | ('cpio', 'x-cpio'), |
32 | 589 | ('gem', 'x-ruby-gem'), |
590 | ('7z', 'x-7z-compressed')): | |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
591 | 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
|
592 | 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
|
593 | 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
|
594 | 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
|
595 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
596 | 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
|
597 | 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
|
598 | ('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
|
599 | ('tar', 'POSIX tar archive'), |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
600 | ('zip', 'Zip archive'), |
32 | 601 | ('rpm', 'RPM'), |
602 | ('7z', '7-zip archive')): | |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
603 | 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
|
604 | 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
|
605 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
606 | 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
|
607 | 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
|
608 | ('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
|
609 | 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
|
610 | 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
|
611 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
612 | extension_map = {} |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
613 | 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
|
614 | ('tar', 'gzip', 'tar.gz', 'tgz'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
615 | ('tar', None, 'tar'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
616 | ('zip', None, 'zip', 'exe'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
617 | ('deb', None, 'deb'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
618 | ('rpm', None, 'rpm'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
619 | ('cpio', None, 'cpio'), |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
620 | ('gem', None, 'gem'), |
32 | 621 | ('compress', None, 'gz', 'bz2'), |
622 | ('7z', None, '7z')): | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
623 | for extension in mapping[2:]: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
624 | extension_map[extension] = mapping[:2] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
625 | |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
626 | def __init__(self, filename, options): |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
627 | self.filename = filename |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
628 | 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
|
629 | |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
630 | 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
|
631 | 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
|
632 | 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
|
633 | 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
|
634 | else: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
635 | 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
|
636 | 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
|
637 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
638 | def get_extractor(self): |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
639 | for func_name in ('mimetype', 'extension', 'magic'): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
640 | archive_type, encoding = \ |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
641 | getattr(self, 'try_by_' + func_name)(self.filename) |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
642 | logger.debug("%s extractor is %s, %s" % |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
643 | (func_name, archive_type, encoding)) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
644 | if archive_type 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
|
645 | yield self.build_extractor(archive_type, encoding) |
29
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
646 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
647 | def try_by_mimetype(cls, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
648 | 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
|
649 | try: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
650 | 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
|
651 | 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
|
652 | if encoding: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
653 | return 'compress', encoding |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
654 | return None, None |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
655 | 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
|
656 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
657 | def try_by_magic(cls, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
658 | 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
|
659 | 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
|
660 | 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
|
661 | if status != 0: |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
662 | return None, None |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
663 | 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
|
664 | process.stdout.close() |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
665 | if output.startswith('%s: ' % filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
666 | output = output[len(filename) + 2:] |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
667 | results = [None, None] |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
668 | for index, mapping in enumerate((cls.magic_mime_map, |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
669 | cls.magic_encoding_map)): |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
670 | for regexp, result in mapping.items(): |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
671 | if regexp.search(output): |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
672 | results[index] = result |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
673 | break |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
674 | return results |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
675 | 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
|
676 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
677 | def try_by_extension(cls, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
678 | parts = filename.rsplit('.', 2)[1:] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
679 | while parts: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
680 | try: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
681 | return cls.extension_map['.'.join(parts)] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
682 | except KeyError: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
683 | del parts[0] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
684 | return [None, None] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
685 | 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
|
686 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
687 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
688 | class BaseAction(object): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
689 | def __init__(self, options, filenames): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
690 | self.options = options |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
691 | self.filenames = filenames |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
692 | self.target = None |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
693 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
694 | def report(self, function, *args): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
695 | try: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
696 | error = function(*args) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
697 | except (ExtractorError, IOError, OSError), exception: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
698 | 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
|
699 | logger.debug(''.join(traceback.format_exception(*sys.exc_info()))) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
700 | if error: |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
701 | logger.info("%s: %s", self.current_filename, error) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
702 | return False |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
703 | return True |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
704 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
705 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
706 | class ExtractionAction(BaseAction): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
707 | handlers = [FlatHandler, OverwriteHandler, MatchHandler, EmptyHandler, |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
708 | BombHandler] |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
709 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
710 | def get_handler(self, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
711 | if extractor.content_type == ONE_ENTRY: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
712 | self.options.one_entry_policy.prep(self.current_filename, |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
713 | extractor.content_name) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
714 | for handler in self.handlers: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
715 | if handler.can_handle(extractor.content_type, self.options): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
716 | 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
|
717 | break |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
718 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
719 | def run(self, filename, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
720 | self.current_filename = filename |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
721 | success = (self.report(extractor.extract) and |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
722 | self.report(self.get_handler, extractor) and |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
723 | self.report(self.current_handler.handle)) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
724 | if success: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
725 | self.target = self.current_handler.target |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
726 | return success |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
727 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
728 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
729 | class ListAction(BaseAction): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
730 | def __init__(self, options, filenames): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
731 | BaseAction.__init__(self, options, filenames) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
732 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
733 | def get_list(self, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
734 | # 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
|
735 | # 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
|
736 | # 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
|
737 | # 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
|
738 | # 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
|
739 | self.filelist = list(extractor.get_filenames()) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
740 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
741 | def show_list(self, filename): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
742 | if len(self.filenames) != 1: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
743 | if filename != self.filenames[0]: |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
744 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
745 | print "%s:" % (filename,) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
746 | print '\n'.join(self.filelist) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
747 | |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
748 | def run(self, filename, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
749 | self.current_filename = filename |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
750 | return (self.report(self.get_list, extractor) and |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
751 | 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
|
752 | |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
753 | |
5 | 754 | class ExtractorApplication(object): |
755 | def __init__(self, arguments): | |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
756 | 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
|
757 | self.setup_logger() |
5 | 758 | self.successes = [] |
759 | self.failures = [] | |
760 | ||
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
761 | def parse_options(self, arguments): |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
762 | parser = optparse.OptionParser( |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
763 | usage="%prog [options] archive [archive2 ...]", |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
764 | description="Intelligent archive extractor", |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
765 | version=VERSION_BANNER |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
766 | ) |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
767 | 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
|
768 | action='store_true', default=False, |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
769 | 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
|
770 | parser.add_option('-q', '--quiet', dest='quiet', |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
771 | action='count', default=3, |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
772 | help='suppress warning/error messages') |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
773 | parser.add_option('-v', '--verbose', dest='verbose', |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
774 | action='count', default=0, |
0a3ef1b9f6d4
[svn] Add options to tweak the logging level to taste.
brett
parents:
12
diff
changeset
|
775 | 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
|
776 | 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
|
777 | action='store_true', default=False, |
6f9e1bb59719
[svn] Add support for just decompressing files that are compressed. So, if you
brett
parents:
13
diff
changeset
|
778 | 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
|
779 | 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
|
780 | 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
|
781 | help="don't put contents in their own directory") |
19 | 782 | parser.add_option('-l', '-t', '--list', '--table', dest='show_list', |
783 | action='store_true', default=False, | |
784 | 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
|
785 | 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
|
786 | 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
|
787 | 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
|
788 | 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
|
789 | action='store_true', default=False, |
5fad99c17221
[svn] Add support for Ruby Gems, and extracting metadata from .deb/.gem files.
brett
parents:
28
diff
changeset
|
790 | help="extract metadata from a .deb/.gem/etc.") |
6
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
791 | 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
|
792 | if not filenames: |
77043f4e6a9f
[svn] The big thing here is recursive extraction. Find archive files in the
brett
parents:
5
diff
changeset
|
793 | parser.error("you did not list any archives") |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
794 | 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
|
795 | 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
|
796 | 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
|
797 | |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
798 | def setup_logger(self): |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
799 | # WARNING is the default. |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
800 | log_level = (10 * (self.options.quiet - self.options.verbose)) |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
801 | logging.getLogger().setLevel(log_level) |
12
5d202467c589
[svn] Introduce a real logging system. Right now all this really gets us is the
brett
parents:
11
diff
changeset
|
802 | handler = logging.StreamHandler() |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
803 | handler.setLevel(log_level) |
19 | 804 | 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
|
805 | handler.setFormatter(formatter) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
806 | 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
|
807 | logger.debug("logger is set up") |
1 | 808 | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
809 | def recurse(self, filename, extractor, action): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
810 | archives = extractor.included_archives |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
811 | self.options.recursion_policy.prep(filename, archives) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
812 | if self.options.recursion_policy.ok_to_recurse(): |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
813 | for filename in archives: |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
814 | tail_path, basename = os.path.split(filename) |
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
815 | directory = os.path.join(self.current_directory, |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
816 | action.target, tail_path) |
25
ef62f2f55eb8
[svn] Move policy-handling code into a dedicated set of classes. This makes
brett
parents:
23
diff
changeset
|
817 | self.archives.setdefault(directory, []).append(basename) |
8
97388f5ff770
[svn] Make ExtractorApplication suck less. Now the strategies for handling
brett
parents:
7
diff
changeset
|
818 | |
19 | 819 | def run(self): |
820 | if self.options.show_list: | |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
821 | action = ListAction |
19 | 822 | else: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
823 | action = ExtractionAction |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
824 | 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
|
825 | 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
|
826 | 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
|
827 | 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
|
828 | for filename in self.filenames: |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
829 | builder = ExtractorBuilder(filename, self.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
|
830 | for extractor in builder.get_extractor(): |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
831 | if action.run(filename, extractor): |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
832 | self.successes.append(filename) |
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
833 | self.recurse(filename, extractor, action) |
30
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
834 | break |
1015bbd6dc5e
[svn] If we can't figure out what the file is by mimetype, try using the file
brett
parents:
29
diff
changeset
|
835 | else: |
33
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
836 | logger.error("%s: could not find a way to extract this" % |
3547e3124729
[svn] Fix some bugs and make things a little more user-friendly now that we can
brett
parents:
32
diff
changeset
|
837 | (filename,)) |
31
c3a2760d1c3a
[svn] Refactor actions (extract the archive, vs. list the contents) into their
brett
parents:
30
diff
changeset
|
838 | 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
|
839 | self.options.one_entry_policy.permanent_policy = EXTRACT_WRAP |
5 | 840 | if self.failures: |
841 | return 1 | |
842 | return 0 | |
843 | ||
1 | 844 | |
845 | if __name__ == '__main__': | |
5 | 846 | app = ExtractorApplication(sys.argv[1:]) |
847 | sys.exit(app.run()) |