197 if (ExtractorBuilder.try_by_mimetype(filename) or |
197 if (ExtractorBuilder.try_by_mimetype(filename) or |
198 ExtractorBuilder.try_by_extension(filename)): |
198 ExtractorBuilder.try_by_extension(filename)): |
199 self.included_archives.append(os.path.join(path, filename)) |
199 self.included_archives.append(os.path.join(path, filename)) |
200 |
200 |
201 def check_contents(self): |
201 def check_contents(self): |
202 filenames = os.listdir('.') |
202 self.contents = os.listdir('.') |
203 if not filenames: |
203 if not self.contents: |
204 self.content_type = EMPTY |
204 self.content_type = EMPTY |
205 elif len(filenames) == 1: |
205 elif len(self.contents) == 1: |
206 if self.basename() == filenames[0]: |
206 if self.basename() == self.contents[0]: |
207 self.content_type = MATCHING_DIRECTORY |
207 self.content_type = MATCHING_DIRECTORY |
208 else: |
208 else: |
209 self.content_type = ONE_ENTRY |
209 self.content_type = ONE_ENTRY |
210 self.content_name = filenames[0] |
210 self.content_name = self.contents[0] |
211 if os.path.isdir(filenames[0]): |
211 if os.path.isdir(self.contents[0]): |
212 self.content_name += '/' |
212 self.content_name += '/' |
213 else: |
213 else: |
214 self.content_type = BOMB |
214 self.content_type = BOMB |
215 self.check_included_archives() |
215 self.check_included_archives() |
216 |
216 |
271 yield self.basename() |
271 yield self.basename() |
272 |
272 |
273 def extract(self): |
273 def extract(self): |
274 self.content_type = ONE_ENTRY_KNOWN |
274 self.content_type = ONE_ENTRY_KNOWN |
275 self.content_name = self.basename() |
275 self.content_name = self.basename() |
|
276 self.contents = None |
|
277 self.included_root = './' |
276 try: |
278 try: |
277 output_fd, self.target = tempfile.mkstemp(prefix='.dtrx-', dir='.') |
279 output_fd, self.target = tempfile.mkstemp(prefix='.dtrx-', dir='.') |
278 except (OSError, IOError), error: |
280 except (OSError, IOError), error: |
279 raise ExtractorError("cannot extract here: %s" % (error.strerror,)) |
281 raise ExtractorError("cannot extract here: %s" % (error.strerror,)) |
280 try: |
282 try: |
813 |
815 |
814 class ExtractionAction(BaseAction): |
816 class ExtractionAction(BaseAction): |
815 handlers = [FlatHandler, OverwriteHandler, MatchHandler, EmptyHandler, |
817 handlers = [FlatHandler, OverwriteHandler, MatchHandler, EmptyHandler, |
816 BombHandler] |
818 BombHandler] |
817 |
819 |
|
820 def __init__(self, options, filenames): |
|
821 BaseAction.__init__(self, options, filenames) |
|
822 self.did_print = False |
|
823 |
818 def get_handler(self, extractor): |
824 def get_handler(self, extractor): |
819 if extractor.content_type == ONE_ENTRY: |
825 if extractor.content_type == ONE_ENTRY: |
820 self.options.one_entry_policy.prep(self.current_filename, |
826 self.options.one_entry_policy.prep(self.current_filename, |
821 extractor.content_name) |
827 extractor.content_name) |
822 for handler in self.handlers: |
828 for handler in self.handlers: |
823 if handler.can_handle(extractor.content_type, self.options): |
829 if handler.can_handle(extractor.content_type, self.options): |
824 logger.debug("using %s handler" % (handler.__name__,)) |
830 logger.debug("using %s handler" % (handler.__name__,)) |
825 self.current_handler = handler(extractor, self.options) |
831 self.current_handler = handler(extractor, self.options) |
826 break |
832 break |
827 |
833 |
|
834 def show_extraction(self, extractor): |
|
835 if self.options.log_level > logging.INFO: |
|
836 return |
|
837 elif self.did_print: |
|
838 print |
|
839 else: |
|
840 self.did_print = True |
|
841 print "%s:" % (self.current_filename,) |
|
842 if extractor.contents is None: |
|
843 print self.current_handler.target |
|
844 return |
|
845 if self.current_handler.target == '.': |
|
846 filenames = extractor.contents |
|
847 filenames.sort(reverse=True) |
|
848 else: |
|
849 filenames = [self.current_handler.target] |
|
850 pathjoin = os.path.join |
|
851 isdir = os.path.isdir |
|
852 while filenames: |
|
853 filename = filenames.pop() |
|
854 if isdir(filename): |
|
855 print "%s/" % (filename,) |
|
856 new_filenames = os.listdir(filename) |
|
857 new_filenames.sort(reverse=True) |
|
858 filenames.extend([pathjoin(filename, new_filename) |
|
859 for new_filename in new_filenames]) |
|
860 else: |
|
861 print filename |
|
862 |
828 def run(self, filename, extractor): |
863 def run(self, filename, extractor): |
829 self.current_filename = filename |
864 self.current_filename = filename |
830 error = (self.report(extractor.extract) or |
865 error = (self.report(extractor.extract) or |
831 self.report(self.get_handler, extractor) or |
866 self.report(self.get_handler, extractor) or |
832 self.report(self.current_handler.handle)) |
867 self.report(self.current_handler.handle) or |
|
868 self.report(self.show_extraction, extractor)) |
833 if not error: |
869 if not error: |
834 self.target = self.current_handler.target |
870 self.target = self.current_handler.target |
835 return error |
871 return error |
836 |
872 |
837 |
873 |
920 action='store_true', default=False, |
956 action='store_true', default=False, |
921 help="extract metadata from a .deb/.gem") |
957 help="extract metadata from a .deb/.gem") |
922 self.options, filenames = parser.parse_args(arguments) |
958 self.options, filenames = parser.parse_args(arguments) |
923 if not filenames: |
959 if not filenames: |
924 parser.error("you did not list any archives") |
960 parser.error("you did not list any archives") |
|
961 # This makes WARNING is the default. |
|
962 self.options.log_level = (10 * (self.options.quiet - |
|
963 self.options.verbose)) |
925 self.options.one_entry_policy = OneEntryPolicy(self.options) |
964 self.options.one_entry_policy = OneEntryPolicy(self.options) |
926 self.options.recursion_policy = RecursionPolicy(self.options) |
965 self.options.recursion_policy = RecursionPolicy(self.options) |
927 self.archives = {os.path.realpath(os.curdir): filenames} |
966 self.archives = {os.path.realpath(os.curdir): filenames} |
928 |
967 |
929 def setup_logger(self): |
968 def setup_logger(self): |
930 # WARNING is the default. |
969 logging.getLogger().setLevel(self.options.log_level) |
931 log_level = (10 * (self.options.quiet - self.options.verbose)) |
|
932 logging.getLogger().setLevel(log_level) |
|
933 handler = logging.StreamHandler() |
970 handler = logging.StreamHandler() |
934 handler.setLevel(log_level) |
971 handler.setLevel(self.options.log_level) |
935 formatter = logging.Formatter("dtrx: %(levelname)s: %(message)s") |
972 formatter = logging.Formatter("dtrx: %(levelname)s: %(message)s") |
936 handler.setFormatter(formatter) |
973 handler.setFormatter(formatter) |
937 logger.addHandler(handler) |
974 logger.addHandler(handler) |
938 logger.debug("logger is set up") |
975 logger.debug("logger is set up") |
939 |
976 |
983 self.action = action(self.options, self.archives.values()[0]) |
1020 self.action = action(self.options, self.archives.values()[0]) |
984 while self.archives: |
1021 while self.archives: |
985 self.current_directory, self.filenames = self.archives.popitem() |
1022 self.current_directory, self.filenames = self.archives.popitem() |
986 os.chdir(self.current_directory) |
1023 os.chdir(self.current_directory) |
987 for filename in self.filenames: |
1024 for filename in self.filenames: |
988 logger.info("handling %s" % (filename,)) |
|
989 builder = ExtractorBuilder(filename, self.options) |
1025 builder = ExtractorBuilder(filename, self.options) |
990 error = (self.check_file(filename) or |
1026 error = (self.check_file(filename) or |
991 self.try_extractors(filename, builder.get_extractor())) |
1027 self.try_extractors(filename, builder.get_extractor())) |
992 if error: |
1028 if error: |
993 if error != True: |
1029 if error != True: |
994 logger.error("%s: %s" % (filename, error)) |
1030 logger.error("%s: %s" % (filename, error)) |
995 self.failures.append(filename) |
1031 self.failures.append(filename) |
996 else: |
1032 else: |
997 logger.info("finished handling %s" % (filename,)) |
|
998 self.successes.append(filename) |
1033 self.successes.append(filename) |
999 self.options.one_entry_policy.permanent_policy = EXTRACT_WRAP |
1034 self.options.one_entry_policy.permanent_policy = EXTRACT_WRAP |
1000 if self.failures: |
1035 if self.failures: |
1001 return 1 |
1036 return 1 |
1002 return 0 |
1037 return 0 |