Skip to content

Instantly share code, notes, and snippets.

@ArthurFDLR
Last active May 19, 2024 00:10
Show Gist options
  • Save ArthurFDLR/4c497df38bfbffb64d883f47a3dd37fd to your computer and use it in GitHub Desktop.
Save ArthurFDLR/4c497df38bfbffb64d883f47a3dd37fd to your computer and use it in GitHub Desktop.
Basic [tree](https://manpages.ubuntu.com/manpages/trusty/man1/tree.1.html) alternative where `--filelimit` defines the maximum number of entry to display per folder, instead of the maximum of entry to display a folder.
#!/usr/bin/env python3
"""
File: tree.py
Author: Arthur Findelair
Date: 2024-05-18
Description: Basic [tree](https://manpages.ubuntu.com/manpages/trusty/man1/tree.1.html) alternative where `--filelimit`
defines the maximum number of entry to display per folder, instead of the maximum of entry to display a folder.
"""
from pathlib import Path
from typing import Optional
def list_files(
startpath: Path,
max_entries: Optional[int] = None,
max_depth: Optional[int] = None,
current_depth: int = 0,
prefix: str = "",
):
"""
Recursively lists files and directories in a tree-like format.
Args:
startpath (Path): The starting directory path.
max_entries (Optional[int]): The maximum number of entries to display per directory.
max_depth (Optional[int]): The maximum depth to traverse.
current_depth (int): The current depth in the directory tree.
prefix (str): The prefix for formatting the tree structure.
"""
if max_depth is not None and current_depth > max_depth:
return
entries = sorted(startpath.iterdir())
displayed_entries = entries if max_entries is None else entries[:max_entries]
entries_count = len(displayed_entries)
for i, entry in enumerate(displayed_entries):
connector = "├── " if i < entries_count - 1 else "└── "
print(prefix + connector + entry.name)
if entry.is_dir():
extension = "│ " if i < entries_count - 1 else " "
list_files(
startpath=entry,
max_entries=max_entries,
max_depth=max_depth,
current_depth=current_depth + 1,
prefix=prefix + extension,
)
if max_entries is not None and len(entries) > max_entries:
not_displayed_count = len(entries) - max_entries
print(prefix + f" ... ({not_displayed_count} more)")
def display_tree(
startpath: str,
max_entries: Optional[int] = None,
max_depth: Optional[int] = None,
show_full_path: bool = False,
):
"""
Displays a tree-like structure of a directory.
Args:
startpath (str): The starting directory path.
max_entries (Optional[int]): The maximum number of entries to display per directory.
max_depth (Optional[int]): The maximum depth to traverse.
"""
startpath = Path(startpath).resolve()
if startpath.is_dir():
print(str(startpath) if show_full_path else startpath.name + "/")
list_files(
startpath=startpath,
max_entries=max_entries,
max_depth=max_depth,
current_depth=1,
prefix="",
)
else:
print("The specified path is not a directory")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Display a tree-like structure of a directory."
)
parser.add_argument("directory", type=str, help="The directory to display.")
parser.add_argument(
"--filelimit",
type=int,
help="Do not display more than # entries per directory.",
)
parser.add_argument(
"--level",
"-L",
type=int,
help="Max display depth of the directory tree.",
)
parser.add_argument(
"--show_full_top_path",
action="store_true",
help="Show full path instead of just the directory name.",
)
args = parser.parse_args()
display_tree(
args.directory,
max_entries=args.filelimit,
max_depth=args.level,
show_full_path=args.show_full_top_path,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment