From 184898b2703cbaa77e87d5d62f7227095e139484 Mon Sep 17 00:00:00 2001 From: kyleknap Date: Wed, 24 Sep 2014 13:26:57 -0700 Subject: [PATCH] Cleaned up ``print_thread`` code. --- awscli/customizations/s3/executor.py | 39 ++++++++++--------- awscli/customizations/s3/subcommands.py | 3 -- awscli/customizations/s3/utils.py | 5 ++- tests/unit/customizations/s3/test_executor.py | 16 +++++--- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/awscli/customizations/s3/executor.py b/awscli/customizations/s3/executor.py index 7eee384dab7d..fc850dffc328 100644 --- a/awscli/customizations/s3/executor.py +++ b/awscli/customizations/s3/executor.py @@ -278,13 +278,11 @@ def _process_print_task(self, print_task): if print_task.error: self.num_errors_seen += 1 print_to_stderr = True - warning = False + + final_str = '' if print_task.warning: - warning = True self.num_warnings_seen += 1 print_to_stderr = True - final_str = '' - if warning: final_str += print_str.ljust(self._progress_length, ' ') final_str += '\n' elif print_task.total_parts: @@ -312,26 +310,29 @@ def _process_print_task(self, print_task): self._file_count += 1 # If the message is an error or warning, print it to standard error. - if print_to_stderr == True and not self._quiet: + if print_to_stderr and not self._quiet: uni_print(final_str, sys.stderr) - sys.stderr.flush() final_str = '' is_done = self._total_files == self._file_count if not is_done: - prog_str = "Completed %s " % self._num_parts - num_files = self._total_files - if self._total_files != '...': - prog_str += "of %s " % self._total_parts - num_files = self._total_files - self._file_count - prog_str += "part(s) with %s file(s) remaining" % \ - num_files - length_prog = len(prog_str) - prog_str += '\r' - prog_str = prog_str.ljust(self._progress_length, ' ') - self._progress_length = length_prog - final_str += prog_str + final_str += self._make_progress_bar() if not self._quiet: uni_print(final_str) self._needs_newline = not final_str.endswith('\n') - sys.stdout.flush() + + def _make_progress_bar(self): + """Creates the progress bar string to print out.""" + + prog_str = "Completed %s " % self._num_parts + num_files = self._total_files + if self._total_files != '...': + prog_str += "of %s " % self._total_parts + num_files = self._total_files - self._file_count + prog_str += "part(s) with %s file(s) remaining" % \ + num_files + length_prog = len(prog_str) + prog_str += '\r' + prog_str = prog_str.ljust(self._progress_length, ' ') + self._progress_length = length_prog + return prog_str diff --git a/awscli/customizations/s3/subcommands.py b/awscli/customizations/s3/subcommands.py index 6ec6856294d9..bbe6dda1d8d1 100644 --- a/awscli/customizations/s3/subcommands.py +++ b/awscli/customizations/s3/subcommands.py @@ -272,7 +272,6 @@ def _display_page(self, response_data, use_basename=True): pre_string = "PRE".rjust(30, " ") print_str = pre_string + ' ' + prefix + '/\n' uni_print(print_str) - sys.stdout.flush() for content in contents: last_mod_str = self._make_last_mod_str(content['LastModified']) size_str = self._make_size_str(content['Size']) @@ -284,7 +283,6 @@ def _display_page(self, response_data, use_basename=True): print_str = last_mod_str + ' ' + size_str + ' ' + \ filename + '\n' uni_print(print_str) - sys.stdout.flush() def _list_all_buckets(self): operation = self.service.get_operation('ListBuckets') @@ -294,7 +292,6 @@ def _list_all_buckets(self): last_mod_str = self._make_last_mod_str(bucket['CreationDate']) print_str = last_mod_str + ' ' + bucket['Name'] + '\n' uni_print(print_str) - sys.stdout.flush() def _list_all_objects_recursive(self, bucket, key, page_size=None): operation = self.service.get_operation('ListObjects') diff --git a/awscli/customizations/s3/utils.py b/awscli/customizations/s3/utils.py index b7d2c7c97d94..97b17933d9a8 100644 --- a/awscli/customizations/s3/utils.py +++ b/awscli/customizations/s3/utils.py @@ -227,11 +227,11 @@ def uni_print(statement, out_file=None): """ This function is used to properly write unicode to a file, usually stdout or stdderr. It ensures that the proper encoding is used if the - statement is not a string type. The initial check is to allow if - ``out_file`` does not use an encoding. + statement is not a string type. """ if out_file is None: out_file = sys.stdout + # Check for an encoding on the file. encoding = getattr(out_file, 'encoding', None) if encoding is not None and not PY3: out_file.write(statement.encode(out_file.encoding)) @@ -243,6 +243,7 @@ def uni_print(statement, out_file=None): # try to decode as ascii. Interestingly enough # this works with a normal StringIO. out_file.write(statement.encode('utf-8')) + out_file.flush() def guess_content_type(filename): diff --git a/tests/unit/customizations/s3/test_executor.py b/tests/unit/customizations/s3/test_executor.py index cf172aaa4ce6..7c803fe693e7 100644 --- a/tests/unit/customizations/s3/test_executor.py +++ b/tests/unit/customizations/s3/test_executor.py @@ -92,18 +92,22 @@ def __call__(self): class TestPrintThread(unittest.TestCase): + def setUp(self): + self.result_queue = queue.Queue() + self.thread = PrintThread(result_queue=self.result_queue, quiet=False) + def test_print_error(self): - result_queue = queue.Queue() print_task = PrintTask(message="Fail File.", error=True) - thread = PrintThread(result_queue, False) with mock.patch('sys.stderr', new=six.StringIO()) as mock_stderr: - thread._process_print_task(print_task) + self.result_queue.put(print_task) + self.result_queue.put(ShutdownThreadRequest()) + self.thread.run() self.assertIn("Fail File.", mock_stderr.getvalue()) def test_print_warning(self): - result_queue = queue.Queue() print_task = PrintTask(message="Bad File.", warning=True) - thread = PrintThread(result_queue, False) with mock.patch('sys.stderr', new=six.StringIO()) as mock_stderr: - thread._process_print_task(print_task) + self.result_queue.put(print_task) + self.result_queue.put(ShutdownThreadRequest()) + self.thread.run() self.assertIn("Bad File.", mock_stderr.getvalue())