Пример #1
0
 def test_format_default(self):
     console = Console()
     output = console.format('The quick brown fox jumps over the lazy dog')
     self.assertEqual(
         repr(output),
         repr('The quick brown fox jumps over the lazy dog' + ' ' * 37)
     )
Пример #2
0
 def test_write(self):
     stream = StringIO()
     console = Console(stream)
     console.write('The quick brown fox jumps over the lazy dog')
     output = stream.getvalue()
     self.assertEqual(
         repr(output),
         repr('The quick brown fox jumps over the lazy dog')
     )
Пример #3
0
 def test_same_line(self):
     stream = StringIO()
     console = Console(stream)
     console.same_line('The quick brown fox jumps over the lazy dog')
     output = stream.getvalue()
     self.assertEqual(
         repr(output),
         repr(
             '\r'
             'The quick brown fox jumps over the lazy dog' + ' ' * 37
         )
     )
Пример #4
0
 def test_success(self):
     stream = StringIO()
     console = Console(stream)
     console.success('The quick brown fox jumps over the lazy dog')
     output = stream.getvalue()
     self.assertEqual(
         repr(output),
         repr(
             '\r\x1b[32m'
             'The quick brown fox jumps over the lazy dog'
             '\x1b[39m' + ' ' * 27 + '\n'
         )
     )
Пример #5
0
 def test_format_many_options(self):
     console = Console()
     output = console.format(
         'The quick brown fox jumps over the lazy dog',
         fg_color='RED', bg_color='YELLOW', font='BOLD', min_length=10
     )
     self.assertEqual(
         repr(output),
         repr(
             '\x1b[2m\x1b[31m\x1b[43m'
             'The quick brown fox jumps over the lazy dog'
             '\x1b[49m\x1b[39m\x1b[0m'
         )
     )
Пример #6
0
 def test_format_fg_color(self):
     console = Console()
     output = console.format(
         'The quick brown fox jumps over the lazy dog', fg_color='RED'
     )
     self.assertEqual(
         repr(output),
         repr(
             '\x1b[31m'
             'The quick brown fox jumps over the lazy dog'
             '\x1b[39m' +
             ' ' * 27
         )
     )
Пример #7
0
 def __init__(self,
              root_url=None,
              error_class=None,
              stdout=None,
              stderr=None,
              get_input=None,
              **options):
     self.root_url = root_url or '/'
     self.error_class = error_class or RuntimeError
     self.stdout = stdout or sys.stdout
     self.stderr = stderr or sys.stderr
     self.dry_run = options['dry_run']
     self.no_interactive = options['no_interactive']
     self.quiet = options['quiet']
     self.force = options['force']
     self.git_add = options['git_add']
     self.no_color = options.get('no_color')
     self.console = Console(self.stdout)
     self.get_input = get_input or default_get_input
Пример #8
0
 def test_progress_bar_console_no_eta(self):
     stream = StringIO()
     console = Console(stream)
     progress_bar = ProgressBar(console)
     for i in range(1, 51):
         progress_bar.progress(i, 50)
     output = stream.getvalue()
     self.assertEqual(
         [ln.strip() for ln in output.split('\r')],
         [
             '',
             '[#####               ]  20.00% (10 / 50) ETA: ? |',
             '[#########           ]  40.00% (20 / 50) ETA: ? /',
             '[#############       ]  60.00% (30 / 50) ETA: ? -',
             '[#################   ]  80.00% (40 / 50) ETA: ? \\',
             '[#####################] 100.00% (50 / 50) ETA: 0:00:00'
         ]
     )
Пример #9
0
class BaseSyncOperation(object):
    """Base class for website dump / load operations"""

    status_colors = {
        SyncStatus.DELETED: 'MAGENTA',
        SyncStatus.ADDED: 'GREEN',
        SyncStatus.MODIFIED: 'CYAN',
    }

    def __init__(self,
                 root_url=None,
                 error_class=None,
                 stdout=None,
                 stderr=None,
                 get_input=None,
                 **options):
        self.root_url = root_url or '/'
        self.error_class = error_class or RuntimeError
        self.stdout = stdout or sys.stdout
        self.stderr = stderr or sys.stderr
        self.dry_run = options['dry_run']
        self.no_interactive = options['no_interactive']
        self.quiet = options['quiet']
        self.force = options['force']
        self.git_add = options['git_add']
        self.no_color = options.get('no_color')
        self.console = Console(self.stdout)
        self.get_input = get_input or default_get_input

    def status_fg_color(self, status):
        """Determines fg color for status"""
        if self.no_color:
            fg_color = None
        else:
            try:
                base_status, extra_status = status
            except ValueError:
                base_status, extra_status = status, None
            if extra_status == SyncStatus.SKIPPED:
                fg_color = None
            else:
                fg_color = self.status_colors.get(base_status, None)
        return fg_color

    def log(self, message):
        """Writes informative line of text to stdout"""
        if not self.quiet:
            self.console.new_line(message)

    def log_status(self, status, item):
        """Writes informative line about status of given item (in color!)"""
        if not self.quiet:
            message = '{0} {1}'.format(status, item)
            self.console.new_line(message,
                                  fg_color=self.status_fg_color(status))

    def summary(self, summary_dict):
        """Writes summary line of text to stdout"""
        self.console.new_line('SUMMARY:')
        if summary_dict:
            for status, occurrences in summary_dict.items():
                message = '\t{0} [{1}] = {2}'.format(
                    SyncStatus.describe(status), status, occurrences)
                self.console.new_line(message,
                                      fg_color=self.status_fg_color(status))
        else:
            self.console.new_line('\tNo changes!')

    def error(self, message):
        """Stops processing by raising an exception"""
        raise self.error_class(message)

    def confirm(self, *args, **kwargs):
        """Asks user for confirmation, providing boolean output"""
        if self.no_interactive:
            choice = True
        else:
            # Delimiter:
            self.console.new_line(
                '{s} CONFIRMATION REQUIRED: {s}'.format(s='#' * 28))
            # Show diff if available:
            diff = kwargs.get('diff')
            if diff:
                self.console.new_line('{s} DIFF {s}'.format(s='-' * 37))
                for diff_line in diff.splitlines():
                    if diff_line.startswith('+'):
                        fg_color = 'GREEN'
                    elif diff_line.startswith('-'):
                        fg_color = 'RED'
                    else:
                        fg_color = None
                    self.console.new_line(diff_line, fg_color=fg_color)
                self.console.new_line('{s}'.format(s='-' * 80))
            # Show other messages:
            message = kwargs.get('message')
            messages = [message] if message else list(args)
            messages.append(
                kwargs.get('question', 'Do you want to apply this change?'))
            for message in messages:
                self.console.new_line(message)
            choice = None
            while choice is None:
                user_text = self.get_input('Y/N? ')
                if user_text in ('Y', 'y'):
                    choice = True
                elif user_text in ('N', 'n'):
                    choice = False
            # Delimiter:
            self.console.new_line('{s}'.format(s='#' * 80))
        return choice

    def run(self):
        """Performs the operation"""
        raise NotImplementedError