pytree-stats 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JohannesL2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytree-stats
3
+ Version: 1.0.0
4
+ Summary: Analyze files and folders fast
5
+ Author:
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: rich
10
+ Requires-Dist: pyperclip
11
+ Dynamic: license-file
12
+
13
+ # pytree-stats
14
+ ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
15
+
16
+ <p align="center">
17
+ <img width="128" height="128" src="https://github.com/user-attachments/assets/4b45c09f-1aa2-4277-a760-94b916b9e829" />
18
+ </p>
19
+
20
+ A small Python command-line utility for generating directory tree listings. Use it to inspect folder hierarchies, share file structure snapshots, or compare directory layouts across projects.
21
+
22
+ <img alt="screenshot" src="https://github.com/user-attachments/assets/afccc1ae-e935-4f32-ae22-1fe169294009" width="400" alt="pytree-stats screenshot" />
23
+
24
+ ## What the project does
25
+
26
+ `pytree-stats` reads a filesystem path and prints a tree-style view of the directory contents. It is designed as a lightweight, easy-to-run Python script that works without complex setup.
27
+
28
+ ## Why the project is useful
29
+
30
+ - Quickly inspect folder structure from the terminal
31
+ - **AI-Friendly:** Generates structured output that is easy for LLMs to parse.
32
+ - Useful for documentation, code reviews, and project audits
33
+ - Works cross-platform with Python
34
+ - Simple, no heavy dependencies
35
+
36
+ ## Get started
37
+
38
+ ### Prerequisites
39
+
40
+ - Python 3.7+
41
+ - [Rich](https://github.com/Textualize/rich) library
42
+ - [pyperclip](https://github.com/asweigart/pyperclip) library
43
+
44
+ ### Installation
45
+
46
+ 1. Clone the repository:
47
+
48
+ ```bash
49
+ git clone https://github.com/JohannesL2/pytree-stats.git
50
+ cd pytree-stats
51
+ ```
52
+
53
+ 2. Install dependencies using the requirements file:
54
+
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ 3. Run the script
60
+
61
+ ```bash
62
+ python tree.py
63
+ ```
64
+
65
+ ## Contributing
66
+
67
+ Contributions are welcome and greatly appreciated! Here is how you can help:
68
+
69
+ 1. Look at the open issues labeled [good first issue](https://github.com/JohannesL2/pytree-stats/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
70
+ 2. Fork the repository and create a new branch for your feature or bugfix.
71
+ 3. Open a Pull Request (PR) and describe your changes.
72
+
73
+ Thanks for helping make `pytree-stats` better! 🚀
@@ -0,0 +1,61 @@
1
+ # pytree-stats
2
+ ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
3
+
4
+ <p align="center">
5
+ <img width="128" height="128" src="https://github.com/user-attachments/assets/4b45c09f-1aa2-4277-a760-94b916b9e829" />
6
+ </p>
7
+
8
+ A small Python command-line utility for generating directory tree listings. Use it to inspect folder hierarchies, share file structure snapshots, or compare directory layouts across projects.
9
+
10
+ <img alt="screenshot" src="https://github.com/user-attachments/assets/afccc1ae-e935-4f32-ae22-1fe169294009" width="400" alt="pytree-stats screenshot" />
11
+
12
+ ## What the project does
13
+
14
+ `pytree-stats` reads a filesystem path and prints a tree-style view of the directory contents. It is designed as a lightweight, easy-to-run Python script that works without complex setup.
15
+
16
+ ## Why the project is useful
17
+
18
+ - Quickly inspect folder structure from the terminal
19
+ - **AI-Friendly:** Generates structured output that is easy for LLMs to parse.
20
+ - Useful for documentation, code reviews, and project audits
21
+ - Works cross-platform with Python
22
+ - Simple, no heavy dependencies
23
+
24
+ ## Get started
25
+
26
+ ### Prerequisites
27
+
28
+ - Python 3.7+
29
+ - [Rich](https://github.com/Textualize/rich) library
30
+ - [pyperclip](https://github.com/asweigart/pyperclip) library
31
+
32
+ ### Installation
33
+
34
+ 1. Clone the repository:
35
+
36
+ ```bash
37
+ git clone https://github.com/JohannesL2/pytree-stats.git
38
+ cd pytree-stats
39
+ ```
40
+
41
+ 2. Install dependencies using the requirements file:
42
+
43
+ ```bash
44
+ pip install -r requirements.txt
45
+ ```
46
+
47
+ 3. Run the script
48
+
49
+ ```bash
50
+ python tree.py
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ Contributions are welcome and greatly appreciated! Here is how you can help:
56
+
57
+ 1. Look at the open issues labeled [good first issue](https://github.com/JohannesL2/pytree-stats/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
58
+ 2. Fork the repository and create a new branch for your feature or bugfix.
59
+ 3. Open a Pull Request (PR) and describe your changes.
60
+
61
+ Thanks for helping make `pytree-stats` better! 🚀
@@ -0,0 +1,5 @@
1
+ from .stats import calc_helper
2
+ from .cli import print_to_terminal
3
+ from .global_ import IGNORE_DIRS
4
+
5
+ __all__ = ["calc_helper", "print_to_terminal", "IGNORE_DIRS"]
@@ -0,0 +1,53 @@
1
+ from __future__ import annotations
2
+
3
+ from rich.tree import Tree
4
+ from rich.console import Console
5
+ from rich.filesize import decimal
6
+ from collections import Counter
7
+ from rich.table import Table
8
+
9
+
10
+ # Own functions
11
+ from app.core import generate_tree
12
+ from app.export import handle_markdown, handle_copy
13
+
14
+
15
+
16
+ def return_summary(file_counts: Counter) -> Table:
17
+ """Creates and returns a table with file statistics."""
18
+ tb_obj = Table(title="File statistics", title_style="bold magenta", show_header=True, header_style="bold cyan")
19
+
20
+ tb_obj.add_column("File type", style="dim")
21
+ tb_obj.add_column("Quantity", justify="right")
22
+
23
+ for ext, count in file_counts.most_common():
24
+ label = ext if ext else "No extension"
25
+ tb_obj.add_row(label, str(count))
26
+
27
+ return tb_obj
28
+
29
+ def print_to_terminal(root, total_files, file_counts, total_size, total_folders, ignore):
30
+ """handles the printing of all text in the Terminal"""
31
+ t_obj = Tree(f":open_file_folder: [bold cyan]{root.name}[/bold cyan]", guide_style="bright_black")
32
+ generate_tree(root, t_obj, ignore)
33
+
34
+ # Capture tree as string
35
+ tree_console = Console(record=True)
36
+ tree_console.print(t_obj)
37
+ tree_text_only = tree_console.export_text()
38
+ print("\n")
39
+ # Print Summary to Terminal
40
+ summary_table = return_summary(file_counts)
41
+ summary_console = Console(record=True)
42
+ summary_console.print(summary_table)
43
+ summary_console.print("\n")
44
+ summary_console.print(f"[bold cyan]Total files scanned:[/bold cyan] {total_files}")
45
+ summary_console.print(f"[bold cyan]Total folders scanned:[/bold cyan] {total_folders}")
46
+ summary_console.print(f"[bold cyan]Total size:[/bold cyan] {decimal(total_size)}")
47
+ summary_text_only = summary_console.export_text()
48
+ handle_copy(tree_text_only)
49
+ handle_markdown(summary_text_only, tree_text_only)
50
+
51
+
52
+
53
+
@@ -0,0 +1,68 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from rich.tree import Tree
5
+ from rich.filesize import decimal
6
+ from rich.markup import escape
7
+ from rich.text import Text
8
+ from rich.console import Console
9
+
10
+ console = Console(record=True)
11
+ def generate_tree(directory: Path, node: Tree, ignore_dirs: set)->None:
12
+ """Function that builds a file structure tree"""
13
+ # Sort folders first then files
14
+ paths = sorted(Path(directory).iterdir(), key=lambda p: (p.is_file(), p.name.lower()))
15
+
16
+ for path in paths:
17
+ # Ignore hidden maps like .git .gitignore
18
+ if path.name.startswith(".") or path.name in ignore_dirs:
19
+ continue
20
+
21
+ if path.is_dir():
22
+ # New branch for folders
23
+ style = "bold blue"
24
+ branch = node.add(
25
+ f"[bold blue]📂 {escape(path.name)}[/bold blue]",
26
+ guide_style="bright_blue"
27
+ )
28
+ generate_tree(path, branch, ignore_dirs)
29
+ else:
30
+ # Handle files with icons
31
+ text_filename = Text(path.name)
32
+
33
+ # File extension colors
34
+ if path.suffix == ".py":
35
+ text_filename.stylize("green")
36
+ icon = "🐍"
37
+ elif path.suffix in [".md", ".txt"]:
38
+ text_filename.stylize("yellow")
39
+ icon = "📄"
40
+ elif path.suffix in [".json", ".yaml", ".yml"]:
41
+ text_filename.stylize("magenta")
42
+ icon = "⚙️"
43
+ elif path.suffix in [".java"]:
44
+ text_filename.stylize("magenta")
45
+ icon = "☕️"
46
+ elif path.suffix in [".kt"]:
47
+ text_filename.stylize("magenta")
48
+ icon = "🟣"
49
+ elif path.suffix in [".class"]:
50
+ text_filename.stylize("magenta")
51
+ icon = "🛡️"
52
+ else:
53
+ icon = "📄"
54
+
55
+ # Add file size for convenience
56
+ try:
57
+ file_size = decimal(path.stat().st_size)
58
+ except PermissionError:
59
+ console.print(f"[yellow]WARNING:[/yellow] Skipping file (permission denied): {path}")
60
+ continue
61
+
62
+ text_filename.append(f" ({file_size})", "italic white")
63
+
64
+ # Add file size for convenience
65
+
66
+
67
+ node.add(Text(f"{icon} ") + text_filename)
68
+
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from rich.console import Console
5
+ from rich.prompt import Confirm
6
+ import pyperclip
7
+
8
+ from app.global_ import HEADING
9
+
10
+ console = Console(record=True)
11
+
12
+ def handle_copy(tree_text) -> None:
13
+ """Ask if the user want the information copy to his/her clipboard"""
14
+ print("")
15
+ if Confirm.ask("Do you want to copy the tree structure to clipboard?"):
16
+ try:
17
+
18
+ pyperclip.copy(tree_text)
19
+ console.print("[bold green] Copied to clipboard![/bold green]")
20
+ except Exception as e:
21
+ console.print(f"[bold red] Failed to copy to clipboard: {e}[/bold red]")
22
+ else:
23
+ console.print("[yellow]Skip copying to clipboard.[/yellow]")
24
+
25
+ def handle_markdown(summary_text_only:str, tree_text_only:str) ->None:
26
+ """Ask if the user wants the information delivered in a markdown file"""
27
+ print("")
28
+ if Confirm.ask("Do you want to download the tree structure as a Markdown?"):
29
+ try:
30
+ file_name = input("Name your file: ")
31
+ print("")
32
+ while not Confirm.ask(f"Are you sure you want to name the file {file_name}?"):
33
+ file_name = input("Name your file: ")
34
+ print("")
35
+ if Path(file_name).suffix.lower() != ".md":
36
+ file_name += ".md"
37
+ with open(file_name, "w", encoding="utf-8") as f:
38
+ f.write(f"{HEADING}\n")
39
+
40
+ f.write(f"```text\n{tree_text_only}\n```\n\n")
41
+
42
+ f.write(f"```text\n{summary_text_only}\n```\n")
43
+
44
+ except Exception as e:
45
+ console.print(f"[bold red] Failed to download the markdown file: {e}[/bold red]")
46
+ else:
47
+ console.print("[yellow]Skip downloading markdown file.[/yellow]")
@@ -0,0 +1,3 @@
1
+ """Just a Helper File"""
2
+ IGNORE_DIRS = {".git", "__pycache__", "node_modules", "venv", ".venv", ".DS_Store"}
3
+ HEADING = "## Project Structure"
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+ from typing import Tuple
3
+ from pathlib import Path
4
+ from collections import Counter
5
+
6
+
7
+
8
+ def collect_stats(directory: Path, ignore: set)->Tuple[int,int,list]:
9
+ """Calculates total_folders and total_size"""
10
+ all_extensions = []
11
+ total_size = 0
12
+ total_folders = 1
13
+ for path in directory.rglob("*"):
14
+ if any(part.startswith('.') or part in ignore for part in path.parts):
15
+ continue
16
+ if path.is_dir():
17
+ total_folders += 1
18
+ elif path.is_file():
19
+ all_extensions.append(path.suffix.lower())
20
+ total_size += path.stat().st_size
21
+
22
+ return total_size, total_folders, all_extensions
23
+
24
+ def calc_helper(root:Path, ignore:set)->Tuple[int,Counter,int,int]:
25
+ """Helps combining crucial values in one return"""
26
+ total_size, total_folder, all_extensions= collect_stats(root, ignore)
27
+ total_files = len(all_extensions)
28
+ file_counts = Counter(all_extensions)
29
+
30
+ return total_files, file_counts, total_size, total_folder
31
+
32
+
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pytree-stats"
7
+ version = "1.0.0"
8
+ description = "Analyze files and folders fast"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+
12
+ authors = [
13
+ { name = "" }
14
+ ]
15
+
16
+ dependencies = [
17
+ "rich",
18
+ "pyperclip"
19
+ ]
20
+
21
+ [project.scripts]
22
+ pytree-stats = "main:main"
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytree-stats
3
+ Version: 1.0.0
4
+ Summary: Analyze files and folders fast
5
+ Author:
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: rich
10
+ Requires-Dist: pyperclip
11
+ Dynamic: license-file
12
+
13
+ # pytree-stats
14
+ ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
15
+
16
+ <p align="center">
17
+ <img width="128" height="128" src="https://github.com/user-attachments/assets/4b45c09f-1aa2-4277-a760-94b916b9e829" />
18
+ </p>
19
+
20
+ A small Python command-line utility for generating directory tree listings. Use it to inspect folder hierarchies, share file structure snapshots, or compare directory layouts across projects.
21
+
22
+ <img alt="screenshot" src="https://github.com/user-attachments/assets/afccc1ae-e935-4f32-ae22-1fe169294009" width="400" alt="pytree-stats screenshot" />
23
+
24
+ ## What the project does
25
+
26
+ `pytree-stats` reads a filesystem path and prints a tree-style view of the directory contents. It is designed as a lightweight, easy-to-run Python script that works without complex setup.
27
+
28
+ ## Why the project is useful
29
+
30
+ - Quickly inspect folder structure from the terminal
31
+ - **AI-Friendly:** Generates structured output that is easy for LLMs to parse.
32
+ - Useful for documentation, code reviews, and project audits
33
+ - Works cross-platform with Python
34
+ - Simple, no heavy dependencies
35
+
36
+ ## Get started
37
+
38
+ ### Prerequisites
39
+
40
+ - Python 3.7+
41
+ - [Rich](https://github.com/Textualize/rich) library
42
+ - [pyperclip](https://github.com/asweigart/pyperclip) library
43
+
44
+ ### Installation
45
+
46
+ 1. Clone the repository:
47
+
48
+ ```bash
49
+ git clone https://github.com/JohannesL2/pytree-stats.git
50
+ cd pytree-stats
51
+ ```
52
+
53
+ 2. Install dependencies using the requirements file:
54
+
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ 3. Run the script
60
+
61
+ ```bash
62
+ python tree.py
63
+ ```
64
+
65
+ ## Contributing
66
+
67
+ Contributions are welcome and greatly appreciated! Here is how you can help:
68
+
69
+ 1. Look at the open issues labeled [good first issue](https://github.com/JohannesL2/pytree-stats/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
70
+ 2. Fork the repository and create a new branch for your feature or bugfix.
71
+ 3. Open a Pull Request (PR) and describe your changes.
72
+
73
+ Thanks for helping make `pytree-stats` better! 🚀
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ app/__init__.py
5
+ app/cli.py
6
+ app/core.py
7
+ app/export.py
8
+ app/global_.py
9
+ app/stats.py
10
+ pytree_stats.egg-info/PKG-INFO
11
+ pytree_stats.egg-info/SOURCES.txt
12
+ pytree_stats.egg-info/dependency_links.txt
13
+ pytree_stats.egg-info/entry_points.txt
14
+ pytree_stats.egg-info/requires.txt
15
+ pytree_stats.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pytree-stats = main:main
@@ -0,0 +1,2 @@
1
+ rich
2
+ pyperclip
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+