def __init__(self, output_type="list", initial_len=1, interval=0, force_single_line=False, no_warning=False, sort_key=lambda x: x[0]): self.sort_key = sort_key self.no_warning = no_warning no_warning and print("All reprint warning diabled.") global is_atty # reprint does not work in the IDLE terminal, and any other environment that can't get terminal_size if is_atty and not all(get_terminal_size()): if not no_warning: r = input( "Fail to get terminal size, we got {}, continue anyway? (y/N)" .format(get_terminal_size())) if not (r and isinstance(r, str) and r.lower()[0] in ['y', 't', '1']): sys.exit(0) is_atty = False if output_type == "list": self.warped_obj = output.SignalList(self, [''] * initial_len) elif output_type == "dict": self.warped_obj = output.SignalDict(self, {}) self.interval = interval self.force_single_line = force_single_line self._last_update = int(time.time() * 1000)
def display(title, data, color=""): """Write colored text to the console.""" color += colorama.Style.BRIGHT width, _ = get_terminal_size() six.print_(color + "{0:=^{1}}".format(' ' + title + ' ', width)) six.print_(color + json.dumps(data, indent=4)) six.print_(color + '=' * width)
def progress_bar_(currect, target, text_center='', text_end='%100', text_end_lenght=0, center_bgc='30;42', defult_bgc=''): c_width = get_terminal_size()[0] if text_end_lenght == 0: text_end_lenght = len(text_end) if text_end == '%100': text_end = '%' + str(currect * 100 / target) text_end_lenght = len('%100') c_width_croped = c_width - text_end_lenght - 2 Lpading = round((c_width_croped - len(text_center)) / 2) Rpading = round(c_width_croped - len(text_center) - Lpading) #print(Lpading,text_center,Rpading,defult_bgc,text_end,(text_end_lenght - len(text_end)),currect * c_width_croped / target) progress_b = ' ' * Lpading + text_center + ' ' * Rpading + '\033[' + defult_bgc + 'm' + '|' + text_end + ' ' * ( text_end_lenght - len(text_end)) marker_pos = round(currect * c_width_croped / target) progress_b = '\033[' + center_bgc + 'm' + progress_b[: marker_pos] + '\033[' + defult_bgc + 'm' + progress_b[ marker_pos: marker_pos + 1] + progress_b[ marker_pos + 1:] return progress_b
def __init__(self, config, stream=None, event_loop=None): stream = (stream or create_msg_channel(config["viewer_channel"], "message")) data_store = MessageAsyncDataStore(stream.on_recv) context = gviewer.DisplayerContext(data_store, self, actions=gviewer.Actions([ ("e", "export replay script", self.export_replay), ("r", "replay", self.replay), ("L", "log", self.log) ])) self.log_context = LogDisplayer(config).context event_loop = event_loop or urwid.TornadoEventLoop( ioloop.IOLoop.instance()) self.viewer = gviewer.GViewer(context, palette=self.PALETTE, other_contexts=[self.log_context], config=gviewer.Config(auto_scroll=True), event_loop=event_loop) self.formatter = TuiFormatter() self.config = config self.event_client = EventClient(config["events_channel"]) self.terminal_width, _ = get_terminal_size()
def printer(): while True: cols, rows = get_terminal_size() msg = "#" + "-" * (cols - 2) + "#\n" try: new_line = str(printq.get_nowait()) if new_line != '!@#EXIT#@!': lines.append(new_line) printq.task_done() else: printq.task_done() sys.exit() except Queue.Empty: pass for line in lines: res = line while len(res) != 0: toprint, res = split_line(res, cols) msg += '\n' + toprint subprocess.check_call('clear') sys.stdout.write(msg) sys.stdout.flush() time.sleep(0.5)
def user_message(message, max_columns=None, pause=False): """ Print a message to the user, with some extra utility over the basic print() function. :param message: the message to print :type message: str :param max_columns: optional, the maximum number of columns to print for a single line. Default is ``None``, i.e. do not wrap the message at all. Must be > 0. :type max_columns: int :param pause: optional, if ``True``, then after displaying the message, Python will pause and ask the user to press enter to continue. Default is ``False``. :type pause: bool :return: None """ terminal_cols = get_terminal_size().columns # If the user specifies a maximum number of columns greater than the current terminal width, don't do anything if max_columns is not None: if max_columns <= 0: UIErrorWrapper.raise_error(UIValueError('max_columns must be > 0')) elif max_columns > terminal_cols: max_columns = None lines = hard_wrap(message, max_columns=max_columns) print('\n'.join(lines)) if pause: # use getpass here just to avoid printing other characters to the screen, so it looks nice getpass('\nPress ENTER to continue')
def printer(): while True: cols, rows = get_terminal_size() # Get the terminal dimensions msg = '#' + '-' * (cols - 2) + '#\n' # Create the try: new_line = str(printq.get_nowait()) if new_line != '!@#EXIT#@!': # A nice way to turn the printer # thread out gracefully lines.append(new_line) printq.task_done() else: printq.task_done() sys.exit() except Queue.Empty: pass # Build the new message to show and split too long lines for line in lines: res = line # The following is to split lines which are # longer than cols. while len(res) != 0: toprint, res = split_line(res, cols) msg += '\n' + toprint # Clear the shell and print the new output subprocess.check_call('clear') # Keep the shell clean sys.stdout.write(msg) sys.stdout.flush() time.sleep(.5)
def tabulate(self, review_requests): """Print review request summary and status in a table. Args: review_requests (list of dict): A list that contains statistics about each review request. """ self.json.add('summaries', []) if len(review_requests): has_branches = False has_bookmarks = False table = tt.Texttable(get_terminal_size().columns) header = ['Status', 'Review Request'] for info in review_requests: if 'branch' in info: has_branches = True if 'bookmark' in info: has_bookmarks = True if has_branches: header.append('Branch') if has_bookmarks: header.append('Bookmark') table.header(header) for info in review_requests: row = [ info['status'], 'r/%s - %s' % (info['id'], info['summary']), ] summary = { 'status': info['status'], 'review_request': info['id'], 'summary': info['summary'], 'description': info['description'], } if has_branches: row.append(info.get('branch') or '') summary['branch'] = row[-1] if has_bookmarks: row.append(info.get('bookmark') or '') summary['bookmark'] = row[-1] table.add_row(row) self.json.append('summaries', summary) self.stdout.write(table.draw()) else: self.stdout.write('No review requests found.') self.stdout.new_line()
def show_message(text): width = get_terminal_size().columns width -= 1 text = textwrap.fill(text, width=width) print() print('-' * width) print(text) print('-' * width)
def print_multi_line(content, force_single_line, sort_key): """ 'sort_key' ???? dict ????? 'sort_key' parameter only available in 'dict' mode """ global last_output_lines global overflow_flag global is_atty if not is_atty: if isinstance(content, list): for line in content: print(line) elif isinstance(content, dict): for k, v in sorted(content.items(), key=sort_key): print("{}: {}".format(k, v)) else: raise TypeError("Excepting types: list, dict. Got: {}".format( type(content))) return columns, rows = get_terminal_size() lines = lines_of_content(content, columns) if force_single_line is False and lines > rows: overflow_flag = True elif force_single_line is True and len(content) > rows: overflow_flag = True # ??????????????? # to make sure the cursor is at the left most print("\b" * columns, end="") if isinstance(content, list): for line in content: _line = preprocess(line) print_line(_line, columns, force_single_line) elif isinstance(content, dict): for k, v in sorted(content.items(), key=sort_key): _k, _v = map(preprocess, (k, v)) print_line("{}: {}".format(_k, _v), columns, force_single_line) else: raise TypeError("Excepting types: list, dict. Got: {}".format( type(content))) # ???????????????????? # do extra blank lines to wipe the remaining of last output print(" " * columns * (last_output_lines - lines), end="") # ???????? # back to the origin pos if platform == 'win32': print(magic_char * (max(last_output_lines, lines)), end="") else: print(magic_char * (max(last_output_lines, lines) - 1), end="") sys.stdout.flush() last_output_lines = lines
def py_git_stat(): # get the current working directory cwd = os.getcwd() # status messages are friends not food print('Listing git statuses for ' + cwd) # set up Path object in cwd to start workin' p = Path(cwd) # get subdirs of the cwd subdirs = [item for item in p.iterdir() if item.is_dir()] # then, see if each subdir contains ".git" and put it in git_repos list git_repos = [] for subdir in subdirs: q = subdir / '.git' if q.exists(): git_repos.append(subdir) # now that we have only top-level git repos, let's execute git status on all of them, then store the # command output status_results = {} for git_repo in git_repos: os.chdir(str(git_repo.resolve())) result = subprocess.check_output(['git', 'status']) status_results.update({git_repo.name: result.split('\n')}) # let's print out some headers for the table. first, get width of the terminal if get_terminal_size()[0] != 0: term_width = get_terminal_size()[0] else: term_width = 80 print_row_separators(term_width) # let's get the longest repo name and make that the width of the first column in the table. longest_repo_name = (get_longest_element(status_results)) + 1 longest_repo_branch = (get_longest_element(status_results.values()[1])) + 1 print('{0: <{longest_repo_name}}|{1}'.format( 'git repository', 'repo branch', longest_repo_name=longest_repo_name)) print_row_separators(term_width) for repo_name, repo_info in status_results.iteritems(): print('{0: <{longest_repo_name}}|{1: <{longest_repo_branch}}'.format( repo_name, repo_info[0], longest_repo_name=longest_repo_name, longest_repo_branch=longest_repo_branch))
def test_os_environ_first(monkeypatch): "Check if environment variables have precedence" monkeypatch.setenv("COLUMNS", 777) monkeypatch.setenv("LINES", 888) size = get_terminal_size() assert size.columns == 777 assert size.lines == 888
def test_does_not_crash(): """Check if get_terminal_size() returns a meaningful value. There's no easy portable way to actually check the size of the terminal, so let's check if it returns something sensible instead. """ size = get_terminal_size() assert size.columns >= 0 assert size.lines >= 0
def print_fragmap(fragmap, do_color): matrix = fragmap.render_for_console(do_color) matrix = filter_consecutive_equal_columns(matrix) if len(matrix) == 0: return 0, 0 matrix_width = len(matrix[0]) hash_width = 8 padded_matrix_width = matrix_width terminal_column_size = get_terminal_size().columns if terminal_column_size == 0: # Fall back to a default value terminal_column_size = 80 max_actual_commit_width = max([len(p._header._message[0]) for p in fragmap.patches]) max_commit_width = max(0, min(max_actual_commit_width + 1, terminal_column_size/2, terminal_column_size - (hash_width + 1 + 1 + padded_matrix_width))) actual_total_width = hash_width + 1 + max_commit_width + 1 + padded_matrix_width def infill_layout(matrix, print_text_action, print_matrix_action): r = 0 for i in xrange(len(matrix)): r = i / 3 if i % 3 == 1: print_text_action(r) else: print(''.ljust(hash_width + 1 + max_commit_width), end='') print_matrix_action(i) def normal_layout(matrix, print_text_action, print_matrix_action): for r in xrange(len(matrix)): print_text_action(r) print_matrix_action(r) # Draw the text and matrix def print_line(r): cur_patch = fragmap.patches[r]._header commit_msg = cur_patch._message[0] # First row of message hash = cur_patch._hash # Pad short commit messages commit_msg = commit_msg.ljust(max_commit_width, ' ') # Truncate long commit messages commit_msg = commit_msg[0:min(max_commit_width,len(commit_msg))] # Print hash, commit, matrix row hash = hash[0:hash_width] if do_color: hash = ANSI_FG_CYAN + hash + ANSI_RESET print(hash, commit_msg, end='') def print_matrix(r): print(''.join(matrix[r]), ' ') if isinstance(fragmap, ConnectedFragmap): infill_layout(matrix, print_line, print_matrix) else: normal_layout(matrix, print_line, print_matrix) lines_printed = len(matrix) return lines_printed, actual_total_width
def cprint(text="", color=None, on_color=None, attrs=None, **kwargs): """Colorizes text (and wraps to terminal's width).""" # update progress progress(False) # assume 80 in case not running in a terminal columns, lines = get_terminal_size() if columns == 0: columns = 80 # because get_terminal_size's default fallback doesn't work in pipes # print text termcolor.cprint(textwrap.fill(text, columns, drop_whitespace=False), color=color, on_color=on_color, attrs=attrs, **kwargs)
def generate_progress_handler(file_path, action='', max_bar_length=80): """ Returns a function that prints a progress bar in the terminal. :param file_path: the name of the file being transferred :param action: uploading/downloading :param max_bar_length: maximum allowed length of the bar :return: configured ``print_progress`` function """ # We want to limit the maximum line length to 80, but allow for a smaller terminal size. We also # include the action string, and some extra chars terminal_width = get_terminal_size().columns # This takes care of the case where there is no terminal (e.g. unittest) terminal_width = terminal_width or max_bar_length bar_length = min(max_bar_length, terminal_width) - len(action) - 12 # Shorten the file name if it's too long file_name = os.path.basename(file_path) if len(file_name) > (bar_length / 4) + 3: file_name = file_name[:bar_length / 4] + '...' bar_length -= len(file_name) def print_progress(read_bytes, total_bytes): """ Print upload/download progress on a single line. Call this function in a loop to create a progress bar in the terminal. :param read_bytes: number of bytes already processed :param total_bytes: total number of bytes in the file """ filled_length = min( bar_length, int(round(bar_length * read_bytes / float(total_bytes)))) percents = min(100.00, round(100.00 * (read_bytes / float(total_bytes)), 2)) bar = '#' * filled_length + '-' * (bar_length - filled_length) # pylint: disable=blacklisted-name # The \r caret makes sure the cursor moves back to the beginning of the line sys.stdout.write('\r{0} {1} |{2}| {3}%'.format(action, file_name, bar, percents)) if read_bytes >= total_bytes: sys.stdout.write(os.linesep) return print_progress
def tabulate(self, review_requests): """Print review request summary and status in a table. Args: review_requests (list of dict): A list that contains statistics about each review request. """ if len(review_requests): has_branches = False has_bookmarks = False table = tt.Texttable(get_terminal_size().columns) header = ['Status', 'Review Request'] for info in review_requests: if 'branch' in info: has_branches = True if 'bookmark' in info: has_bookmarks = True if has_branches: header.append('Branch') if has_bookmarks: header.append('Bookmark') table.header(header) for info in review_requests: row = [ info['status'], 'r/%s - %s' % (info['id'], info['summary']), ] if has_branches: row.append(info.get('branch') or '') if has_bookmarks: row.append(info.get('bookmark') or '') table.add_row(row) print(table.draw()) else: print('No review requests found.') print()
def get_terminal_columns(): """Determine the amount of available columns in the terminal Returns ------- int Terminal width """ terminal_size = get_terminal_size() # If column size is 0 either we are not connected # to a terminal or something else went wrong. Fallback to 80. if terminal_size.columns == 0: return 80 else: return terminal_size.columns
def cprint(text="", color=None, on_color=None, attrs=None, **kwargs): """Colorizes text (and wraps to terminal's width).""" # stop spinner (if spinning) spin(False) # assume 80 in case not running in a terminal columns, _ = get_terminal_size() if columns == 0: columns = 80 # because get_terminal_size's default fallback doesn't work in pipes # only python3 supports "flush" keyword argument if sys.version_info < (3, 0) and "flush" in kwargs: del kwargs["flush"] # print text termcolor.cprint(textwrap.fill(text, columns, drop_whitespace=False), color=color, on_color=on_color, attrs=attrs, **kwargs)
def generate_progress_handler(file_path, action='', max_bar_length=80): """Returns a function that prints a progress bar in the terminal :param file_path: The name of the file being transferred :param action: Uploading/Downloading :param max_bar_length: Maximum allowed length of the bar. Default: 80 :return: The configured print_progress function """ # We want to limit the maximum line length to 80, but allow for a smaller # terminal size. We also include the action string, and some extra chars terminal_width = get_terminal_size().columns # This takes care of the case where there is no terminal (e.g. unittest) terminal_width = terminal_width or max_bar_length bar_length = min(max_bar_length, terminal_width) - len(action) - 12 # Shorten the file name if it's too long file_name = os.path.basename(file_path) if len(file_name) > (bar_length / 4) + 3: file_name = file_name[:bar_length / 4] + '...' bar_length -= len(file_name) def print_progress(read_bytes, total_bytes): """Print upload/download progress on a single line Call this function in a loop to create a progress bar in the terminal :param read_bytes: Number of bytes already processed :param total_bytes: Total number of bytes in the file """ filled_length = min(bar_length, int(round(bar_length * read_bytes / float(total_bytes)))) percents = min(100.00, round( 100.00 * (read_bytes / float(total_bytes)), 2)) bar = '#' * filled_length + '-' * (bar_length - filled_length) # The \r caret makes sure the cursor moves back to the beginning of # the line msg = '\r{0} {1} |{2}| {3}%'.format(action, file_name, bar, percents) click.echo(msg, nl=False) if read_bytes >= total_bytes: sys.stdout.write('\n') return print_progress
def shell(three=None): # Ensure that virtualenv is available. ensure_project(three=three) # Set an environment variable, so we know we're in the environment. os.environ['PIPENV_ACTIVE'] = '1' # Spawn the Python process, and interact with it. try: shell = os.environ['SHELL'] except KeyError: click.echo(crayons.red('Windows is not currently supported.')) sys.exit(1) click.echo(crayons.yellow('Spawning environment shell ({0}).'.format(crayons.red(shell)))) # Grab current terminal dimensions to replace the hardcoded default # dimensions of pexpect terminal_dimensions = get_terminal_size() c = pexpect.spawn( "{0} -c '. {1}; exec {0} -i'".format( shell, activate_virtualenv(source=False) ), dimensions=( terminal_dimensions.lines, terminal_dimensions.columns ) ) # Activate the virtualenv. c.send(activate_virtualenv() + '\n') # Handler for terminal resizing events # Must be defined here to have the shell process in its context, since we # can't pass it as an argument def sigwinch_passthrough(sig, data): terminal_dimensions = get_terminal_size() c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns) signal.signal(signal.SIGWINCH, sigwinch_passthrough) # Interact with the new shell. c.interact() c.close() sys.exit(c.exitstatus)
def __exit__(self, exc_type, exc_val, exc_tb): global is_atty self.refresh(forced=True) if is_atty: columns, _ = get_terminal_size() if self.force_single_line: print('\n' * len(self.warped_obj), end="") else: print('\n' * lines_of_content(self.warped_obj, columns), end="") global last_output_lines global overflow_flag last_output_lines = 0 if overflow_flag: if not self.no_warning: print("Detected that the lines of output has been exceeded the height of terminal windows, which \ caused the former output remained and keep adding new lines.") print("检测到输出过程中, 输出行数曾大于命令行窗口行数, 这会导致输出清除不完整, 而使输出不停增长。请注意控制输出行数。")
def cprint(text="", color=None, on_color=None, attrs=None, end="\n"): """Colorize text (and wraps to terminal's width).""" # Assume 80 in case not running in a terminal columns, _ = get_terminal_size() if columns == 0: columns = 80 # Print text, flushing output termcolor.cprint(fill(text, columns, drop_whitespace=False, replace_whitespace=False), color=color, on_color=on_color, attrs=attrs, end=end) sys.stdout.flush()
def saveErrorMessage(): """ Simpan pesan error ke directory ``error`` *brutemap* """ errMsg = "Running version: %s\n" % VERSION_STRING errMsg += "Python version: %s\n" % sys.version.split()[0] errMsg += "Operating system: %s\n" % platform.platform() errMsg += "Command line: %s\n" % re.sub( r".+?%s.py\b" % TOOL_NAME, "%s.py" % TOOL_NAME, " ".join(sys.argv)) errMsg += ("=" * get_terminal_size()[0]) + "\n" errMsg += getErrorMessage() filename = time.strftime("%d-%m-%Y_%X").replace(":", "-") + ".txt" filepath = os.path.join(DEFAULT.ERROR_DIRECTORY, filename) with open(filepath, "w") as fp: fp.write(errMsg) return filepath
def __init__(self): self.lines = [] self.wrapper = None self.stream = None self.cursor = None # Terminal size used to split lines longer than console width t = get_terminal_size() self.width = t.columns self.height = t.lines # TODO: cap self.lines at height - 2? # State from previous write used # to determine whether print modifies # a line or creates a new one self._n = True # \n self._r = False # \r self._e = False # eol
def format(self, record): ''' Formats incoming message according to look described in main doc. ''' try: msg = record.getMessage() except TypeError: msg = str(record.msg) record.asctime = self.formatTime(record, self.datefmt) record.block = (self.colored and "{{{0}}} {{/{0}}}" or " ").format( self._COLORS.get(record.levelno, "invis") ) if self.colored and record.levelno == logging.CRITICAL: record.inds, record.inde = ("{negative}", "{/negative}") else: record.inds, record.inde = ("", "") # Arbitrary number is for cases like supervisor'd # with self.colored == True self.wrapper.width = get_terminal_size().columns or 500 self.wrapper.initial_indent = self._indent self.wrapper.subsequent_indent = self._indent if record.exc_info: msg = '{}\n{}'.format( msg, ''.join(traceback.format_exception(*record.exc_info)) ) self.join_str = "\n" if record.levelno in [SEND, RECV]: self.join_str = "\n" msg = self.join_str.join(chain.from_iterable( self._wrap(m) for m in msg.replace("{", "{{").replace("}", "}}").splitlines() )) return Color("{}{}".format(self._header, msg).format( record.block, **record.__dict__ ))
def format(self, record): ''' Formats incoming message according to look described in main doc. ''' try: msg = record.getMessage() except TypeError: msg = str(record.msg) record.asctime = self.formatTime(record, self.datefmt) record.block = (self.colored and "{{{0}}} {{/{0}}}" or " ").format( self._COLORS.get(record.levelno, "invis")) if self.colored and record.levelno == logging.CRITICAL: record.inds, record.inde = ("{negative}", "{/negative}") else: record.inds, record.inde = ("", "") # Arbitrary number is for cases like supervisor'd # with self.colored == True self.wrapper.width = get_terminal_size().columns or 500 self.wrapper.initial_indent = self._indent self.wrapper.subsequent_indent = self._indent if record.exc_info: msg = '{}\n{}'.format( msg, ''.join(traceback.format_exception(*record.exc_info))) self.join_str = "\n" if record.levelno in [SEND, RECV]: self.join_str = "\n" msg = self.join_str.join( chain.from_iterable( self._wrap(m) for m in msg.replace("{", "{{").replace( "}", "}}").splitlines())) return Color("{}{}".format(self._header, msg).format(record.block, **record.__dict__))
def test_stty_match(monkeypatch): """Check if stty returns the same results ignoring env This test will fail if stdin and stdout are connected to different terminals with different sizes. Nevertheless, such situations should be pretty rare. """ try: process = subprocess.Popen(["stty", "size"], stdout=subprocess.PIPE) output, err = process.communicate() if process.poll() != 0: raise OSError size = output.decode().split() except (OSError, subprocess.CalledProcessError): pytest.skip("stty invocation failed") expected = (int(size[1]), int(size[0])) # reversed order monkeypatch.delenv("LINES", raising=False) monkeypatch.delenv("COLUMNS", raising=False) actual = get_terminal_size() assert expected == actual
def shell(three=None, python=False, shell_args=None): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) # Set an environment variable, so we know we're in the environment. os.environ['PIPENV_ACTIVE'] = '1' # Grab current terminal dimensions to replace the hardcoded default # dimensions of pexpect terminal_dimensions = get_terminal_size() c = pexpect.spawn( 'pew', ["workon", project.name], dimensions=( terminal_dimensions.lines, terminal_dimensions.columns ) ) # Send additional arguments to the subshell. if shell_args: c.sendline(' '.join(shell_args)) # Handler for terminal resizing events # Must be defined here to have the shell process in its context, since we # can't pass it as an argument def sigwinch_passthrough(sig, data): terminal_dimensions = get_terminal_size() c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns) signal.signal(signal.SIGWINCH, sigwinch_passthrough) # Interact with the new shell. c.interact() c.close() sys.exit(c.exitstatus)
def __init__(self, config, stream=None, event_loop=None): stream = ( stream or create_msg_channel(config["viewer_channel"], "message") ) data_store = MessageAsyncDataStore(stream.on_recv) context = gviewer.DisplayerContext( data_store, self, actions=gviewer.Actions([ ("e", "export replay script", self.export_replay), ("r", "replay", self.replay), ("L", "log", self.log)])) self.log_context = LogDisplayer(config).context event_loop = event_loop or urwid.TornadoEventLoop(ioloop.IOLoop.instance()) self.viewer = gviewer.GViewer( context, palette=self.PALETTE, other_contexts=[self.log_context], config=gviewer.Config(auto_scroll=True), event_loop=event_loop) self.formatter = TuiFormatter() self.config = config self.event_client = EventClient(config["events_channel"]) self.terminal_width, _ = get_terminal_size()
def main(): logger.debug("Hello.") query = arguments['QUERY'] # file_location = "~/.nbssh-cache" # filename = os.path.expanduser("%s" % file_location) # if arguments['--refresh']: # print("Refreshing from Netbox API...") # all_devices = get_all_devices(config.get('main', 'API_ADDRESS'), # config.get('main', 'API_TOKEN')) # save_devices_to_file(all_devices, filename) # sys.exit() # all_devices = read_devices_from_file(filename) # i = 1 # displayed_device_list_length = 20 # devices = [] # for device in all_devices: # if i < displayed_device_list_length: # if query in device.name: # devices.append(device) # i += 1 # if i >= displayed_device_list_length: # print("Displaying the first %s results only. You might want to try a more specific search." % displayed_device_list_length) check_for_update() term = Terminal() term_height = get_terminal_size()[1] try: config.get('main', 'NO_OF_RESULTS') try: if 1 <= int(config.get('main', 'NO_OF_RESULTS')) <= 100: displayed_device_list_length = int( config.get('main', 'NO_OF_RESULTS')) else: print( "NO_OF_RESULTS must be an positive integer between 1 and 100. Using terminal height instead." ) displayed_device_list_length = term_height - 5 except Exception as e: print( "%s\nNO_OF_RESULTS must be an positive integer between 1 and 100. Using terminal height instead." % e) displayed_device_list_length = term_height - 6 except Exception as e: displayed_device_list_length = term_height - 4 devices = get_devices_by_query(config.get('main', 'API_ADDRESS'), config.get('main', 'API_TOKEN'), query, displayed_device_list_length) if len(devices) >= displayed_device_list_length: print( "Displaying the first %s results only. You might want to try a more specific search." % displayed_device_list_length) # if there's a single result, just SSH directly without displaying the menu elif len(devices) == 1: print( term.bright_magenta("Single result. Going directly to %s..." % devices[0].name)) os.system("ssh root@%s" % devices[0].primary_ip_address) sys.exit() elif len(devices) == 0: print("No results.") sys.exit() pick_options = [] desired_length = 0 for device in devices: if len(device.name) > desired_length: desired_length = len(device.name) for device in devices: #pick_options.append("%s → %s" % (make_string_this_length(device.name, 30), device.primary_ip_address)) pick_options.append( make_string_this_length(device.name, desired_length)) jon_theme = { "List": { "selection_color": "black_on_cyan", "selection_cursor": " ", "unselected_color": "normal" }, "Question": { "mark_color": "white", "brackets_color": "bright_magenta", "default_color": "white_on_magenta", } } questions = [ inquirer.List( 'selection', message="Which device?", choices=pick_options, ), ] answers = inquirer.prompt( questions, theme=inquirer.themes.load_theme_from_dict(jon_theme)) if answers is None: exit() selection = answers['selection'] for device in devices: # selection is the column width, so removing whitespace if device.name == selection.replace(" ", ""): logger.info("SSHing into %s..." % device.primary_ip_address) os.system("ssh root@%s" % device.primary_ip_address)
def sigwinch_passthrough(sig, data): terminal_dimensions = get_terminal_size() c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns)
def shell(three=None, python=False, compat=False, shell_args=None): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) if 'PIPENV_ACTIVE' in os.environ: click.echo(crayons.yellow('Shell already activated. No action taken to avoid nested environments.')) return # Set an environment variable, so we know we're in the environment. os.environ['PIPENV_ACTIVE'] = '1' # Support shell compatibility mode. if PIPENV_SHELL_COMPAT: compat = True # Compatibility mode: if compat: try: shell = os.environ['SHELL'] except KeyError: click.echo(crayons.red('Windows is not currently supported.')) sys.exit(1) click.echo(crayons.yellow('Spawning environment shell ({0}).'.format(crayons.red(shell)))) cmd = "{0} -i'".format(shell) args = [] # Standard (properly configured shell) mode: else: cmd = 'pew' args = ["workon", project.virtualenv_name] # Grab current terminal dimensions to replace the hardcoded default # dimensions of pexpect terminal_dimensions = get_terminal_size() c = pexpect.spawn( cmd, args, dimensions=( terminal_dimensions.lines, terminal_dimensions.columns ) ) # Activate the virtualenv if in compatibility mode. if compat: c.sendline(activate_virtualenv()) # Send additional arguments to the subshell. if shell_args: c.sendline(' '.join(shell_args)) # Handler for terminal resizing events # Must be defined here to have the shell process in its context, since we # can't pass it as an argument def sigwinch_passthrough(sig, data): terminal_dimensions = get_terminal_size() c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns) signal.signal(signal.SIGWINCH, sigwinch_passthrough) # Interact with the new shell. c.interact() c.close() sys.exit(c.exitstatus)
def main(self, review_request_id, diff_revision=None): repository_info, self.tool = self.initialize_scm_tool( client_name=self.options.repository_type) server_url = self.get_server_url(repository_info, self.tool) api_client, api_root = self.get_api(server_url) self.setup_tool(self.tool, api_root=api_root) try: review_request = api_root.get_review_request( review_request_id=review_request_id, expand='submitter') except APIError: raise CommandError('The review request does not exist.') diff = None commits = None if 'repository' in review_request.links is not None: try: diffs = review_request.get_diffs() except APIError as e: raise CommandError('Error retrieving diffs: %s' % e) if diff_revision is None: diff_revision = diffs.total_results diff = diffs.get_item(diff_revision) if getattr(diff, 'commit_count', 0) > 0: try: commits = diff.get_commits() except APIError as e: raise CommandError('Error retrieving commits: %s' % e) elif diff_revision is not None: raise CommandError('This review request does not have diffs ' 'attached') print(review_request.summary) print() print('Submitter: %s' % (review_request.submitter.fullname or review_request.submitter.username)) print() print(review_request.description) print() print('URL: %s' % review_request.absolute_url) if diff: print ('Diff: %sdiff/%s/' % (review_request.absolute_url, diff_revision)) print() print('Revision: %s (of %d)' % (diff_revision, diffs.total_results)) if commits: print() print('Commits:') table = Texttable(get_terminal_size().columns) table.header(('ID', 'Summary', 'Author')) for commit in commits: summary = commit.commit_message.split('\n', 1)[0].strip() if len(summary) > 80: summary = summary[:77] + '...' table.add_row((commit.commit_id, summary, commit.author_name)) print(table.draw())
def print_fragmap(fragmap, do_color): matrix = fragmap.render_for_console(do_color) matrix = filter_consecutive_equal_columns(matrix) if len(matrix) == 0: return 0, 0 matrix_width = len(matrix[0]) hash_width = 8 padded_matrix_width = matrix_width reported_terminal_column_size = get_terminal_size().columns if reported_terminal_column_size == 0: # Fall back to a default value reported_terminal_column_size = 80 # Note: Subtracting two because ConEmu/Cmder line wraps two columns before terminal_column_size = reported_terminal_column_size - 2 max_actual_commit_width = max( [len(first_line(p.header.message)) for p in fragmap.patches]) max_commit_width = max( 0, min(max_actual_commit_width + 1, int(terminal_column_size / 2), terminal_column_size - (hash_width + 1 + 1 + padded_matrix_width))) actual_total_width = hash_width + 1 + max_commit_width + 1 + padded_matrix_width def infill_layout(matrix, print_text_action, print_matrix_action): r = 0 for i in range(len(matrix)): r = i / 3 if i % 3 == 1: print_text_action(r) else: print(''.ljust(hash_width + 1 + max_commit_width), end='') print_matrix_action(i) def normal_layout(matrix, print_text_action, print_matrix_action): for r in range(len(matrix)): print_text_action(r) print_matrix_action(r) # Draw the text and matrix def print_line(r): cur_patch = fragmap.patches[r].header commit_msg = first_line(cur_patch.message) hash = cur_patch.hex # Pad short commit messages commit_msg = commit_msg.ljust(max_commit_width, ' ') # Truncate long commit messages commit_msg = commit_msg[0:min(max_commit_width, len(commit_msg))] # Print hash, commit, matrix row hash = hash[0:hash_width] if do_color: hash = ANSI_FG_CYAN + hash + ANSI_RESET print(hash, commit_msg, end='') def print_matrix(r): print(''.join(matrix[r]), ' ') if isinstance(fragmap, ConnectedFragmap): infill_layout(matrix, print_line, print_matrix) else: normal_layout(matrix, print_line, print_matrix) lines_printed = len(matrix) return lines_printed, actual_total_width
def shell(three=None, python=False, compat=False, shell_args=None): # Ensure that virtualenv is available. ensure_project(three=three, python=python, validate=False) # Set an environment variable, so we know we're in the environment. os.environ['PIPENV_ACTIVE'] = '1' # Support shell compatibility mode. if PIPENV_SHELL_COMPAT: compat = True # Compatibility mode: if compat: try: shell = os.environ['SHELL'] except KeyError: click.echo(crayons.red('Windows is not currently supported.')) sys.exit(1) click.echo(crayons.yellow('Spawning environment shell ({0}).'.format(crayons.red(shell)))) cmd = "{0} -i'".format(shell) args = [] # Standard (properly configured shell) mode: else: cmd = 'pew' args = ["workon", project.name] # Grab current terminal dimensions to replace the hardcoded default # dimensions of pexpect terminal_dimensions = get_terminal_size() c = pexpect.spawn( cmd, args, dimensions=( terminal_dimensions.lines, terminal_dimensions.columns ) ) # Activate the virtualenv if in compatibility mode. if compat: c.sendline(activate_virtualenv()) # Send additional arguments to the subshell. if shell_args: c.sendline(' '.join(shell_args)) # Handler for terminal resizing events # Must be defined here to have the shell process in its context, since we # can't pass it as an argument def sigwinch_passthrough(sig, data): terminal_dimensions = get_terminal_size() c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns) signal.signal(signal.SIGWINCH, sigwinch_passthrough) # Interact with the new shell. c.interact() c.close() sys.exit(c.exitstatus)
def main(self, review_request_id, diff_revision=None): repository_info, self.tool = self.initialize_scm_tool( client_name=self.options.repository_type) server_url = self.get_server_url(repository_info, self.tool) api_client, api_root = self.get_api(server_url) self.setup_tool(self.tool, api_root=api_root) try: review_request = api_root.get_review_request( review_request_id=review_request_id, expand='submitter') except APIError: raise CommandError('The review request does not exist.') diff = None commits = None if 'repository' in review_request.links is not None: try: diffs = review_request.get_diffs() except APIError as e: raise CommandError('Error retrieving diffs: %s' % e) if diff_revision is None: diff_revision = diffs.total_results diff = diffs.get_item(diff_revision) if getattr(diff, 'commit_count', 0) > 0: try: commits = diff.get_commits() except APIError as e: raise CommandError('Error retrieving commits: %s' % e) elif diff_revision is not None: raise CommandError('This review request does not have diffs ' 'attached') print(review_request.summary) print() print('Submitter: %s' % (review_request.submitter.fullname or review_request.submitter.username)) print() print(review_request.description) print() print('URL: %s' % review_request.absolute_url) if diff: print('Diff: %sdiff/%s/' % (review_request.absolute_url, diff_revision)) print() print('Revision: %s (of %d)' % (diff_revision, diffs.total_results)) if commits: print() print('Commits:') table = Texttable(get_terminal_size().columns) table.header(('ID', 'Summary', 'Author')) for commit in commits: summary = commit.commit_message.split('\n', 1)[0].strip() if len(summary) > 80: summary = summary[:77] + '...' table.add_row( (commit.commit_id, summary, commit.author_name)) print(table.draw())