Wed, 25 Mar 2009 22:54:13 -0400
Reword one entry prompt; wrap prompt choices; better term size detection.
NEWS | file | annotate | diff | comparison | revisions | |
scripts/dtrx | file | annotate | diff | comparison | revisions | |
tests/tests.yml | file | annotate | diff | comparison | revisions |
--- a/NEWS Wed Mar 25 21:34:55 2009 -0400 +++ b/NEWS Wed Mar 25 22:54:13 2009 -0400 @@ -1,6 +1,20 @@ Changes in dtrx =============== +Version 6.5 +----------- + +Bug fixes +~~~~~~~~~ + + * When extracting an archive that contained a file with a mismatched + filename, the prompt would offer you a chance to "rename the directory" + instead of "rename the file." This wording has been fixed, along with + some other wording adjustments in the prompts generally. + + * Perform more reliable detection of the terminal size, and wrap more + prompts accordingly. + Version 6.4 -----------
--- a/scripts/dtrx Wed Mar 25 21:34:55 2009 -0400 +++ b/scripts/dtrx Wed Mar 25 22:54:13 2009 -0400 @@ -21,6 +21,7 @@ # Python 2.3 string methods: 'rfind', 'rindex', 'rjust', 'rstrip' import errno +import fcntl import logging import mimetypes import optparse @@ -29,9 +30,11 @@ import shutil import signal import stat +import struct import subprocess import sys import tempfile +import termios import textwrap import traceback @@ -661,11 +664,16 @@ class BasePolicy(object): try: - width = int(os.environ['COLUMNS']) - except (KeyError, ValueError): + size = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, + struct.pack("HHHH", 0, 0, 0, 0)) + width = struct.unpack("HHHH", size)[1] + except IOError: width = 80 - wrapper = textwrap.TextWrapper(width=width - 1) - + q_wrapper = textwrap.TextWrapper(width=width - 1, break_long_words=False) + choice_wrapper = textwrap.TextWrapper(width=width - 1, initial_indent=' * ', + subsequent_indent=' ', + break_long_words=False) + def __init__(self, options): self.current_policy = None if options.batch: @@ -673,15 +681,10 @@ else: self.permanent_policy = None - def wrap(self, question, filename): - # Note: This function assumes the filename is the first thing in the - # question text, and that's the only place it appears. - if len(self.wrapper.wrap(filename + ' a')) > 1: - return [filename] + self.wrapper.wrap(question[3:]) - return self.wrapper.wrap(question % (filename,)) - def ask_question(self, question): - question = question + self.choices + question = question + ["You can:"] + for choice in self.choices: + question.extend(self.choice_wrapper.wrap(choice)) while True: print "\n".join(question) try: @@ -700,10 +703,9 @@ class OneEntryPolicy(BasePolicy): answers = {'h': EXTRACT_HERE, 'i': EXTRACT_WRAP, 'r': EXTRACT_RENAME, '': EXTRACT_WRAP} - choices = ["You can:", - " * extract it Inside another directory", - " * extract it and Rename the directory", - " * extract it Here"] + choice_template = ["extract the %s _I_nside a new directory named %s", + "extract the %s and _R_ename it %s", + "extract the %s _H_ere"] prompt = "What do you want to do? (I/r/h) " def __init__(self, options): @@ -724,11 +726,14 @@ raise ValueError("bad value %s for default policy" % (default,)) def prep(self, archive_filename, extractor): - question = self.wrap(("%%s contains one %s, but its name " + - "doesn't match.") % - (extractor.content_type,), archive_filename) + question = self.q_wrapper.wrap( + "%s contains one %s, but its name doesn't match." % + (archive_filename, extractor.content_type)) question.append(" Expected: " + extractor.basename()) question.append(" Actual: " + extractor.content_name) + choice_vars = (extractor.content_type, extractor.basename()) + self.choices = [text % choice_vars[:text.count('%s')] + for text in self.choice_template] self.current_policy = (self.permanent_policy or self.ask_question(question)) @@ -739,12 +744,11 @@ class RecursionPolicy(BasePolicy): answers = {'o': RECURSE_ONCE, 'a': RECURSE_ALWAYS, 'n': RECURSE_NOT_NOW, 'v': RECURSE_NEVER, 'l': RECURSE_LIST, '': RECURSE_NOT_NOW} - choices = ["You can:", - " * Always extract included archives", - " * extract included archives this Once", - " * choose Not to extract included archives", - " * neVer extract included archives", - " * List included archives"] + choices = ["_A_lways extract included archives during this session", + "extract included archives this _O_nce", + "choose _N_ot to extract included archives this once", + "ne_V_er extract included archives during this session", + "_L_ist included archives"] prompt = "What do you want to do? (a/o/N/v/l) " def __init__(self, options): @@ -759,10 +763,9 @@ if (self.permanent_policy is not None) or (archive_count == 0): self.current_policy = self.permanent_policy or RECURSE_NOT_NOW return - question = self.wrap(("%%s contains %s other archive file(s), " + - "out of %s file(s) total.") % - (archive_count, extractor.file_count), - current_filename) + question = self.q_wrapper.wrap( + "%s contains %s other archive file(s), out of %s file(s) total." % + (current_filename, archive_count, extractor.file_count)) if target == '.': target = '' included_root = extractor.included_root
--- a/tests/tests.yml Wed Mar 25 21:34:55 2009 -0400 +++ b/tests/tests.yml Wed Mar 25 22:54:13 2009 -0400 @@ -339,6 +339,12 @@ cd test-onefile tar -zxf ../$1 +- name: prompt wording with one file + options: "" + filenames: test-onefile.tar.gz + input: i + grep: file _I_nside + - name: one file extracted with rename, with Expected text options: "" filenames: test-onefile.tar.gz @@ -358,7 +364,7 @@ - name: bomb with preceding dot in the table filenames: test-dot-first-bomb.tar.gz options: "" - antigrep: one entry + antigrep: one baseline: | mkdir test-dot-first-bomb cd test-dot-first-bomb