def find(where, exclude, include): """ Find plugins by scanning the given path for PluginSpecs. It starts from the current directory if --where is not specified. This is what a setup.py method would run as a build step, i.e., discovering entry points. """ with console.status(f"Scanning path {where}"): plugins = find_plugins(where, exclude, include) tree = Tree("Entrypoints") for namespace, entry_points in plugins.items(): node = tree.add(f"[bold]{namespace}") t = Table() t.add_column("Name") t.add_column("Location") for ep in entry_points: key, value = ep.split("=") t.add_row(key, value) node.add(t) rprint(tree)
def test_render(): tree = Tree("foo") tree.add("bar", style="italic") baz_tree = tree.add("baz", guide_style="bold red", style="on blue") baz_tree.add("1") baz_tree.add("2") tree.add("egg") console = Console(width=20, force_terminal=True, color_system="standard") console.begin_capture() console.print(tree) result = console.end_capture() print(repr(result)) expected = "foo \n├── \x1b[3mbar\x1b[0m\x1b[3m \x1b[0m\n\x1b[44m├── \x1b[0m\x1b[44mbaz\x1b[0m\x1b[44m \x1b[0m\n\x1b[44m│ \x1b[0m\x1b[1;31;44m┣━━ \x1b[0m\x1b[44m1\x1b[0m\x1b[44m \x1b[0m\n\x1b[44m│ \x1b[0m\x1b[1;31;44m┗━━ \x1b[0m\x1b[44m2\x1b[0m\x1b[44m \x1b[0m\n└── egg \n" assert result == expected
def test_render_tree_hide_root_non_win32(): tree = Tree("foo", hide_root=True) tree.add("bar", style="italic") baz_tree = tree.add("baz", guide_style="bold red", style="on blue") baz_tree.add("1") baz_tree.add("2") tree.add("egg") console = Console(width=20, force_terminal=True, color_system="standard", _environ={}) console.begin_capture() console.print(tree) result = console.end_capture() print(repr(result)) expected = "\x1b[3mbar\x1b[0m\x1b[3m \x1b[0m\n\x1b[44mbaz\x1b[0m\x1b[44m \x1b[0m\n\x1b[31;44m┣━━ \x1b[0m\x1b[44m1\x1b[0m\x1b[44m \x1b[0m\n\x1b[31;44m┗━━ \x1b[0m\x1b[44m2\x1b[0m\x1b[44m \x1b[0m\negg \n" assert result == expected
def __init__( self, label: TextType, data: NodeDataType, *, name: str | None = None, padding: PaddingDimensions = (1, 1), ) -> None: self.data = data self.id = NodeID(0) self.nodes: dict[NodeID, TreeNode[NodeDataType]] = {} self._tree = Tree(label) self.root: TreeNode[NodeDataType] = TreeNode(None, self.id, self, self._tree, label, data) self._tree.label = self.root self.nodes[NodeID(self.id)] = self.root super().__init__(name=name) self.padding = padding
def tree(self) -> "Tree": """Get a tree renderable to show layout structure.""" from rich.styled import Styled from rich.table import Table from rich.tree import Tree def summary(layout) -> Table: icon = layout.splitter.get_tree_icon() table = Table.grid(padding=(0, 1, 0, 0)) text: RenderableType = ( Pretty(layout) if layout.visible else Styled(Pretty(layout), "dim") ) table.add_row(icon, text) _summary = table return _summary layout = self tree = Tree( summary(layout), guide_style=f"layout.tree.{layout.splitter.name}", highlight=True, ) def recurse(tree: "Tree", layout: "Layout") -> None: for child in layout._children: recurse( tree.add( summary(child), guide_style=f"layout.tree.{child.splitter.name}", ), child, ) recurse(tree, self) return tree
def main(args): g = Gadgetizer(args.files, args.bad_chars, args.output, args.arch, args.color) tree = Tree( f'[bright_green][+][/bright_green] Categorized gadgets :: {" ".join(sys.argv)}' ) g.add_gadgets_to_tree(tree) print(tree) with open(f"{g.output}.clean", "w") as f: print(tree, file=f) print( f"[bright_green][+][/bright_green] Collection of all gadgets written to [bright_blue]{args.output}[/bright_blue]" ) g.save() if args.skip_rp: return for file in args.files: if ":" in file: file, base = file.split(":") add_missing_gadgets(g.addresses, file, args.output, bad_bytes=args.bad_chars, base_address=base) else: add_missing_gadgets(g.addresses, file, args.output, bad_bytes=args.bad_chars) clean_up_all_gadgets(args.output) print_useful_regex(args.output, args.arch)
def __search_task(self) -> None: """ Function that displays a tree with tables as child nodes with the tasks searched """ root = Tree('📒[bold blue] List of Tasks Found') query = self.sql_query() if query: # When the list is not empty table = Table() table.add_column('Tasks') table.add_column('Status') table.add_column('Category') table.add_column('Creation Date', justify='center', style='yellow') tasks_sorted = sorted(query, key=sorter) actual_task = tasks_sorted[0] actual_category = actual_task[3] child_node = root.add(f':file_folder:[#d898ed]{actual_category}') for actual_task in tasks_sorted: if actual_task[3] != actual_category: child_node.add(table) table = Table() table.add_column('Tasks') table.add_column('Status') table.add_column('Category') table.add_column('Creation Date', justify='center', style='yellow') actual_category = actual_task[3] child_node = root.add( f':file_folder: [#d898ed]{actual_category}') table.add_row(actual_task[0], status_text(actual_task[1]), actual_task[3], actual_task[2]) else: child_node.add(table) else: root.add('[red]❌ No Task Found') self.console.print(root)
def describe(self, t=None): if not t: t = Tree("") if self.configuration_key: sub_t = t.add( f"[deep_sky_blue1]configuration[/deep_sky_blue1]: " f"[orange3]{self.configuration_key}" ) if self.__doc__: t.add(f"[deep_sky_blue1]doc[/deep_sky_blue1]: {self.__doc__.strip()}") if self._item_type and self._return_type: sub_t = t.add( f"[deep_sky_blue1]signature[/deep_sky_blue1]: " f"{pretty_print_type(self._item_type)} ->" f" {pretty_print_type(self._return_type)}" ) if self._load_time: sub_t = t.add( "[deep_sky_blue1]load time[/deep_sky_blue1]: [orange3]" + humanize.naturaldelta(self._load_time, minimum_unit="seconds") ) if self._load_memory_increment is not None: sub_t = t.add( f"[deep_sky_blue1]load memory[/deep_sky_blue1]: " f"[orange3]{humanize.naturalsize(self._load_memory_increment)}" ) if self.model_dependencies.models: dep_t = t.add("[deep_sky_blue1]dependencies") for m in self.model_dependencies.models: dep_t.add("[orange3]" + escape(m)) if self.asset_path: sub_t = t.add( f"[deep_sky_blue1]asset path[/deep_sky_blue1]: " f"[orange3]{self.asset_path}" ) if self.batch_size: sub_t = t.add( f"[deep_sky_blue1]batch size[/deep_sky_blue1]: " f"[orange3]{self.batch_size}" ) if self.model_settings: sub_t = t.add("[deep_sky_blue1]model settings[/deep_sky_blue1]") describe(self.model_settings, t=sub_t) return t
def display_tree(search_date): """ Display the scrapes directory for a specific date. Calls previously defined private methods: DateTree._check_date_format() DateTree._create_directory_tree() DateTree._find_date_directory() Parameters ---------- search_date: str String denoting the date within the scrapes directory to search for Returns ------- None """ logging.info(f"Running tree command...") logging.info("") try: search_date = DateTree._check_date_format(search_date) find_dir_halo = Halo( color="white", text=f"Searching for {search_date} directory within `scrapes`." ) find_dir_halo.start() dir_exists = DateTree._find_date_directory(search_date) if dir_exists: find_dir_halo.succeed(text=f"URS was run on {search_date}.") date_dir = f"{Path(Path.cwd()).parents[0]}/scrapes/{search_date}" tree = Tree(f"[bold blue]scrapes/") dir_tree = tree.add(f"[bold blue]{search_date}") DateTree._create_directory_tree(date_dir, dir_tree) rich.print(tree) logging.info( f"Displayed directory tree for scrapes run on {search_date}." ) logging.info("") print() else: error_messsage = f"URS was not run on {search_date}." find_dir_halo.fail(Fore.RED + Style.BRIGHT + error_messsage) print() logging.critical(error_messsage) logging.critical("ABORTING URS.\n") quit() except TypeError: logging.critical("INVALID DATE FORMAT.") logging.critical("ABORTING URS.\n") Errors.e_title( "INVALID DATE FORMAT. ACCEPTED FORMATS: MM-DD-YYYY or MM/DD/YYYY." ) quit()
def list_files(self, folder: str = None, show_size: bool = False): """Create a tree displaying the files within the project.""" LOG.info(f"Listing files for project '{self.project}'") if folder: LOG.info(f"Showing files in folder '{escape(folder)}'") if folder is None: folder = "" # Make call to API try: response = requests.get( DDSEndpoint.LIST_FILES, params={"project": self.project}, json={"subpath": folder, "show_size": show_size}, headers=self.token, timeout=DDSEndpoint.TIMEOUT, ) except requests.exceptions.RequestException as err: raise exceptions.APIError( message=( f"Failed to get list of files in project '{self.project}'" + ( ": The database seems to be down." if isinstance(err, requests.exceptions.ConnectionError) else "." ) ) ) if not response.ok: raise exceptions.APIError(f"Failed to get list of files: '{response.text}'") # Get response try: resp_json = response.json() except simplejson.JSONDecodeError as err: raise exceptions.APIError(f"Could not decode JSON response: '{err}'") # Check if project empty if "num_items" in resp_json and resp_json["num_items"] == 0: raise exceptions.NoDataError(f"Project '{self.project}' is empty.") # Get files files_folders = resp_json["files_folders"] # Sort the file/folders according to names sorted_files_folders = sorted(files_folders, key=lambda f: f["name"]) # Create tree tree_title = escape(folder) or f"Files / directories in project: [green]{self.project}" tree = Tree(f"[bold magenta]{tree_title}") if not sorted_files_folders: raise exceptions.NoDataError(f"Could not find folder: '{escape(folder)}'") # Get max length of file name max_string = max([len(x["name"]) for x in sorted_files_folders]) # Get max length of size string max_size = max( [ len( dds_cli.utils.format_api_response( response=x["size"], key="Size", binary=self.binary ).split(" ", maxsplit=1)[0] ) for x in sorted_files_folders if show_size and "size" in x ], default=0, ) # Visible folders visible_folders = [] # Add items to tree for x in sorted_files_folders: # Check if string is folder is_folder = x.pop("folder") # Att 1 for folders due to trailing / tab = th.TextHandler.format_tabs( string_len=len(x["name"]) + (1 if is_folder else 0), max_string_len=max_string, ) # Add formatting if folder and set string name line = "" if is_folder: line = "[bold deep_sky_blue3]" visible_folders.append(x["name"]) line += escape(x["name"]) + ("/" if is_folder else "") # Add size to line if option specified if show_size and "size" in x: size = dds_cli.utils.format_api_response( response=x["size"], key="Size", binary=self.binary ) line += f"{tab}{size.split()[0]}" # Define space between number and size format tabs_bf_format = th.TextHandler.format_tabs( string_len=len(size), max_string_len=max_size, tab_len=2 ) line += f"{tabs_bf_format}{size.split()[1]}" tree.add(line) # Print output to stdout if len(files_folders) + 5 > dds_cli.utils.console.height: with dds_cli.utils.console.pager(): dds_cli.utils.console.print(Padding(tree, 1)) else: dds_cli.utils.console.print(Padding(tree, 1)) # Return variable return visible_folders
def test_render_single_node(): tree = Tree("foo") console = Console(color_system=None, width=20) console.begin_capture() console.print(tree) assert console.end_capture() == "foo \n"
from rich.tree import Tree from rich import print tree = Tree("Dog Data") tree.add('data1') data2 = tree.add('data2') data2.add("[red]Winner") data2.add("[green]Chihuahua") data2.add("[blue]Greyhound") print(tree)
def print_single_mission(self, mission): title = f'#{mission.id} - [bold]{mission.name}[/bold]' # if mission.mission_type is not None: # title += f' ({mission.mission_type.name})' layout = Tree(title) negative, delta = date.format_delta(datetime.now(timezone.utc), date.date_from_iso(mission.end_date)) if negative: layout.add(_(':two-thirty: [red]Closed {} ago').format(delta)) else: layout.add(_(':two-thirty: [green]{} remaining').format(delta)) layout.add(('[green]:heavy_check_mark: ' if mission.nmap else '[yellow]:hourglass_not_done:') + _(' Nmap')) layout.add(('[green]:heavy_check_mark: ' if mission.nessus else '[yellow]:hourglass_not_done:') + _(' Nessus')) if mission.path_to_codi is None: layout.add(_(f':book: [bold red]CodiMD not set')) else: layout.add(f':book: CodiMD > {mission.path_to_codi}') if mission.credentials is None: layout.add(_(f':locked_with_key: [bold red]Credentials not set')) else: layout.add(_(':locked_with_key: Credentials > {}').format(mission.credentials)) clients_node = layout.add(_(':bust_in_silhouette: [blue]Clients[/blue]'), guide_style='blue') for client in mission.clients: if isinstance(client, str): clients_node.add(_('[bold]#{}[/bold] (save to update)').format(client)) continue client_node = clients_node.add(f'[bold]{client.first_name} {client.last_name}[/bold] ({client.name})', guide_style='white') client_node.add(client.mail) client_node.add(client.phone) pentesters_node = layout.add(_(':robot: [red]Pentesters[/red]'), guide_style='red') for pentester in mission.users: if isinstance(pentester, str): pentesters_node.add(_('#{} (save to update)').format(pentester)) continue pentesters_node.add(pentester.username) hosts_node = layout.add(_(':desktop_computer: Scope')) for host in mission.hosts: if isinstance(host, str): hosts_node.add(_('#{} (save to update)').format(host)) continue host_node = hosts_node.add( ('[green]:heavy_check_mark: ' if host.checked else '[yellow]:hourglass_not_done:') + f' #{host.id} - {host.name}') for host_vuln in host.host_vulns: vuln = Vuln.get(self.api, host_vuln.vuln.id) impact = host_vuln.impact host_node.add(f'#{host_vuln.id} - {vuln.name} ({impact.name}) - {host_vuln.current_state}') steps_node = layout.add(_(':spiral_notepad: [magenta]Activity'), guide_style='magenta') for step in mission.steps: if isinstance(step, str): steps_node.add(_('#{} (save to update)').format(step)) continue __, delta = date.format_delta(datetime.now(timezone.utc), date.date_from_iso(step.created_at)) steps_node.add(_('[bold]{} ago[/bold] - #{} - {}').format(delta, step.id, step.description)) self.console.print(layout)
def getChildren(res: Resource, tree: Tree, level: int) -> None: """ Find and print the children in the tree structure. """ if maxLevel > 0 and level == maxLevel: return chs = CSE.dispatcher.directChildResources(res.ri) for ch in chs: branch = tree.add(info(ch)) getChildren(ch, branch, level + 1) if parent is not None: if (res := CSE.dispatcher.retrieveResource(parent).resource) is None: return None else: res = Utils.getCSE().resource tree = Tree(info(res)) getChildren(res, tree, 0) return tree def getResourceTreeText(self, maxLevel: int = 0) -> str: """ This function will generate a Text tree of a CSE's resource structure. """ from rich.console import Console console = Console(color_system=None) console.begin_capture() console.print(self.getResourceTreeRich()) return console.end_capture() # def info(res:Resource) -> str: # if res.ty == T.FCNT:
def _print_collected_tasks( dictionary: dict[Path, list[Task]], show_nodes: bool, editor_url_scheme: str, common_ancestor: Path, ) -> None: """Print the information on collected tasks. Parameters ---------- dictionary : Dict[Path, List["Task"]] A dictionary with path on the first level, tasks on the second, dependencies and products on the third. show_nodes : bool Indicator for whether dependencies and products should be displayed. editor_url_scheme : str The scheme to create an url. common_ancestor : Path The path common to all tasks and nodes. """ # Have a new line between the number of collected tasks and this info. console.print() tree = Tree("Collected tasks:", highlight=True) for module, tasks in dictionary.items(): reduced_module = relative_to(module, common_ancestor) url_style = create_url_style_for_path(module, editor_url_scheme) module_branch = tree.add( Text.assemble(PYTHON_ICON, "<Module ", Text(str(reduced_module), style=url_style), ">")) for task in tasks: reduced_task_name = format_task_id( task, editor_url_scheme=editor_url_scheme, relative_to=common_ancestor) task_branch = module_branch.add( Text.assemble(TASK_ICON, "<Function ", reduced_task_name, ">"), ) if show_nodes: for node in sorted(tree_just_flatten(task.depends_on), key=lambda x: x.path): reduced_node_name = relative_to(node.path, common_ancestor) url_style = create_url_style_for_path( node.path, editor_url_scheme) task_branch.add( Text.assemble( FILE_ICON, "<Dependency ", Text(str(reduced_node_name), style=url_style), ">", )) for node in sorted(tree_just_flatten(task.produces), key=lambda x: x.path): reduced_node_name = relative_to(node.path, common_ancestor) url_style = create_url_style_for_path( node.path, editor_url_scheme) task_branch.add( Text.assemble( FILE_ICON, "<Product ", Text(str(reduced_node_name), style=url_style), ">", )) console.print(tree)
from rich import box from rich.columns import Columns from rich.console import Console from rich.panel import Panel from rich.tree import Tree import subprocess import os from random import choice import datetime ########################################################################################################### console = Console(record=True, width=200) ########################################################################################################### tree = Tree( "[link=https://www.informatik.uni-leipzig.de/~akiki/]Christopher Akiki", guide_style="bold") interest_tree = tree.add("Interests") interest_tree.add("My cat") interest_tree.add("Representation Learning") interest_tree.add("Language Generation") interest_tree.add("Text Mining") interest_tree.add("Dataset Creation") past = tree.add("Past Lives") past.add("Sociocultural antropology") past.add("Network Engineering") location = tree.add("Current Location") location.add("Leipzig, Germany") ########################################################################################################### cows = os.listdir('/usr/share/cowsay/cows/') cows = [cow.split('.')[0] for cow in cows]
def PrintDirTree(self, dirpath, dirdepth): DirTree = Tree(f'目录结构:\n{os.path.basename(dirpath)}', guide_style='green') self.__ListDir(DirTree, dirpath, dirdepth) self.Console.print(DirTree)
def __init__(self): self.stack = [Tree("Calls", highlight=True)] self.seen = set()
def list_files(self, folder: str = None, show_size: bool = False): """Create a tree displaying the files within the project.""" console = Console() # Make call to API try: response = requests.get( DDSEndpoint.LIST_FILES, params={ "subpath": folder, "show_size": show_size }, headers=self.token, ) except requests.exceptions.RequestException as err: raise SystemExit from err if not response.ok: console.print(f"Failed to get list of files: {response.text}") os._exit(0) # Get response try: resp_json = response.json() except simplejson.JSONDecodeError as err: raise SystemExit from err # Check if project empty if "num_items" in resp_json and resp_json["num_items"] == 0: console.print(f"[i]Project '{self.project}' is empty.[/i]") os._exit(0) # Get files files_folders = resp_json["files_folders"] # Warn user if there will be too many rows self.warn_if_many(count=len(files_folders)) # Sort the file/folders according to names sorted_projects = sorted(files_folders, key=lambda f: f["name"]) # Create tree tree_title = folder if folder is None: tree_title = f"Files/Directories in project: {self.project}" tree = Tree(f"[bold spring_green4]{tree_title}") if sorted_projects: # Get max length of file name max_string = max([len(x["name"]) for x in sorted_projects]) # Get max length of size string sizes = [ len(x["size"][0]) for x in sorted_projects if show_size and "size" in x ] max_size = max(sizes) if sizes else 0 # Add items to tree for x in sorted_projects: # Check if string is folder is_folder = x.pop("folder") # Att 1 for folders due to trailing / tab = th.TextHandler.format_tabs( string_len=len(x["name"]) + (1 if is_folder else 0), max_string_len=max_string, ) # Add formatting if folder and set string name line = "" if is_folder: line = "[bold deep_sky_blue3]" line += x["name"] + ("/" if is_folder else "") # Add size to line if option specified if show_size and "size" in x: line += f"{tab}{x['size'][0]}" # Define space between number and size format tabs_bf_format = th.TextHandler.format_tabs( string_len=len(x["size"][0]), max_string_len=max_size, tab_len=2) line += f"{tabs_bf_format}{x['size'][1]}" tree.add(line) console.print(Padding(tree, 1)) else: console.print(Padding(f"[i]No folder called '{folder}'[/i]", 1))
from rich import box from rich.columns import Columns from rich.console import Console from rich.panel import Panel from rich.tree import Tree console = Console(record=True, width=100) tree = Tree("🤓 [link=https://www.willmcgugan.com]Will McGugan", guide_style="bold cyan") python_tree = tree.add("🐍 Python expert", guide_style="green") python_tree.add("⭐ [link=https://github.com/willmcgugan/rich]Rich") python_tree.add("⭐ [link=https://github.com/pyfilesystem/pyfilesystem2]PyFilesystem") python_tree.add("⭐ [link=https://github.com/wildfoundry/dataplicity-lomond]Lomond") full_stack_tree = tree.add("🔧 Full-stack developer") tree.add("📘 Author") about = """\ I'm a freelance software developer, living in [link=https://www.google.com/maps/place/Edinburgh/@55.9411289,-3.3454205,11z]Edinburgh[/], Scotland. Other than open source software development, my passion would be [link=https://www.willmcgugan.com/blog/photography/]wildlife photography[/]. [green]Follow me on twitter [bold link=https://twitter.com/willmcgugan]@willmcgugan[/]""" panel = Panel.fit( about, box=box.DOUBLE, border_style="blue", title="[b]Hi there", width=60 ) console.print(Columns([panel, tree])) CONSOLE_HTML_FORMAT = """\ <pre style="font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">{code}</pre> """
""" Very much inspired by the README of the author of rich: https://github.com/willmcgugan/willmcgugan """ from rich import box from rich.columns import Columns from rich.console import Console from rich.panel import Panel from rich.tree import Tree console = Console(record=True, width=150) tree = Tree("😄 [link=https://www.maartengrootendorst.com]Maarten Grootendorst", guide_style="bold cyan") packages_tree = tree.add("🐍 Packages") packages_tree.add("[link=https://github.com/MaartenGr/BERTopic]BERTopic") packages_tree.add("[link=https://github.com/MaartenGr/KeyBERT]KeyBERT") packages_tree.add("[link=https://github.com/MaartenGr/PolyFuzz]PolyFuzz") packages_tree.add("[link=https://github.com/MaartenGr/Concept]Concept") packages_tree.add("[link=https://github.com/MaartenGr/VLAC]VLAC") articles_tree = tree.add("📘 Popular Articles") articles_tree.add("[link=https://towardsdatascience.com/9-distance-measures-in-data-science-918109d069fa?sk=5a95055c23e46aed2db69271b559b464]9 Distance Measures") articles_tree.add("[link=https://towardsdatascience.com/keyword-extraction-with-bert-724efca412ea?sk=97a99c2669bb16f22f2f362820ba6bef]Keyword Extraction with BERT") articles_tree.add("[link=https://towardsdatascience.com/topic-modeling-with-bert-779f7db187e6?sk=0b5a470c006d1842ad4c8a3057063a99]Topic Modeling with BERT") articles_tree.add("[link=https://towardsdatascience.com/unit-testing-for-data-scientists-dc5e0cd397fb?sk=b947e67e56d7cea9f16b5d7046d48cce]Unit Testing for Data Scientists") about = """\ A psychologist turned data scientist who is passionate about using artificial intelligence to make the world a slightly better place. I enjoy working on [link=https://pypi.org/user/MaartenGr/]open source projects[/] and writing AI-related articles on [link=http://medium.com/@maartengrootendorst]Medium[/]. Follow me on [bold link=https://twitter.com/MaartenGr]Twitter[/] and [bold link=https://www.linkedin.com/in/mgrootendorst/]LinkedIn[/].
if ch.__isVirtual__: # Ignore virual resources continue # Ignore resources/resource patterns ri = ch.ri if len([ p for p in self.hideResources if TextTools.simpleMatch(p, ri) ]) > 0: continue branch = tree.add(info(ch)) getChildren(ch, branch, level+1) if parent: if not (res := CSE.dispatcher.retrieveResource(parent).resource): return None else: res = Utils.getCSE().resource if not res: return None tree = Tree(info(res), style=style, guide_style=style) getChildren(res, tree, 0) return tree def getResourceTreeText(self, maxLevel:int=0) -> str: """ This function will generate a Text tree of a CSE's resource structure. """ from rich.console import Console as RichConsole console = RichConsole(color_system=None) console.begin_capture() console.print(self.getResourceTreeRich()) return '\n'.join([item.rstrip() for item in console.end_capture().splitlines()])
def get_bar(self): bar = create_bar() tree = Tree(bar) self._table.add_row(tree) return CommonBar(tree, bar)
def describe(self, console=None) -> None: if not console: console = Console() t = Tree("[bold]Settings") console.print(describe(self.settings, t=t)) t = Tree("[bold]Configuration") console.print(describe(self.configuration, t=t)) t = Tree("[bold]Assets") if not self.assets_info: t.add("[dim][italic]No assets loaded") else: describe(self.assets_info, t=t) console.print(t) t = Tree("[bold]Models") if not self.models: t.add("[dim][italic]No models loaded") else: describe(self.models, t=t) console.print(t)
continue if path.is_dir(): style = "dim" if path.name.startswith("__") else "" branch = tree.add( f"[bold magenta]:open_file_folder: [link file://{path}]{escape(path.name)}", style=style, guide_style=style, ) walk_directory(path, branch) else: text_filename = Text(path.name, "green") text_filename.highlight_regex(r"\..*$", "bold red") text_filename.stylize(f"link file://{path}") file_size = path.stat().st_size text_filename.append(f" ({decimal(file_size)})", "blue") icon = "🐍 " if path.suffix == ".py" else "📄 " tree.add(Text(icon) + text_filename) try: directory = os.path.abspath(sys.argv[1]) except IndexError: print("[b]Usage:[/] python tree.py <DIRECTORY>") else: tree = Tree( f":open_file_folder: [link file://{directory}]{directory}", guide_style="bold bright_blue", ) walk_directory(pathlib.Path(directory), tree) print(tree)
def format_channels(self, channels): ''' Given channel data from `determine_channels`, build a rich Tree suitable for (rich) print()ing. ''' release_channels = [] dev_channels = [] for name, channel in channels.items(): if channel['kind'] == 'release': release_channels.append(channel) else: dev_channels.append(channel) tree = Tree('Channels') def colorize_state(state): if state == 'stopped': return '[red]stopped[/red]' return state def populate_node_with_instances(node, instances): if len(instances) == 0: return # Build up a table to describe the list of instances so we get a # grid/table visual layout. table = Table(box=box.SIMPLE) # build up all known tags first tag_keys = ['(start time)'] for instance in instances: for key in instance['tags'].keys(): # suppress tags we've already handled # - channel: already a grouping heuristic # - web-server/indexer: these encode the start time and # for table purposes it's preferable to fold them, but it # is misleading. if key == 'channel' or key == 'web-server' or key == 'indexer': continue if key not in tag_keys: tag_keys.append(key) tag_keys.sort() # populate the table headers table.add_column('role') table.add_column('target_groups') table.add_column('id') table.add_column('state') table.add_column('group') for key in tag_keys: table.add_column(key) # Instances as table rows for instance in instances: cells = [ instance['role'], ','.join(instance['target_groups']), instance['id'], colorize_state(instance['state']), instance['group'], ] # NB: It's possible the instance has keys the source of the keys # did not. for key in tag_keys: if key == '(start time)': if instance['role'] == 'indexer': key = 'indexer' else: key = 'web-server' value = instance['tags'].get(key, None) if value and key.endswith('repo'): value = value.replace('https://github.com/', '') cells.append(value) table.add_row(*cells) node.add(table) def populate_node_with_channels(node, chans): chans.sort(key=lambda x: x['name']) for channel in chans: node_name = f"{channel['name']}: ({', '.join(channel['pieces'])})" chan_node = node.add(node_name) populate_node_with_instances(chan_node, channel['instances']) populate_node_with_channels(tree.add("Release"), release_channels) populate_node_with_channels(tree.add("Development"), dev_channels) return tree
class TreeMixin: """tree instance is shared between subclasses""" # tree template tree = Tree("")
from rich.tree import Tree from rich import print from data_dicts import vrf tree = Tree("VRF") for vrf_name, params in vrf.items(): vrf_tree = tree.add(f"[red]{vrf_name}") for param, details in params.items(): param_tree = vrf_tree.add(f"[green]{param}") # param_tree = vrf_tree.add(f"[green]{param}", expanded=False) if type(details) == str: details = [details] for det in details: param_tree.add(det) print(tree)