treeScannerASCII/scanner.py
2025-04-26 03:02:58 +02:00

89 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""
Verzeichnisscanner mit strukturierter Ausgabe.
Funktioniert sowohl als Standalone-Skript als auch als einbindbares Modul.
"""
import os
from typing import Optional, List
# === Konfigurationsklasse ===
class TreeScannerConfig:
def __init__(self,
root_path: str = ".",
folder_icon: str = "\U0001F4C1",
file_icon: str = "\U0001F4C4",
max_files_per_dir: int = 100,
max_depth: Optional[int] = None,
align_comments: bool = True): #
self.root_path = root_path
self.folder_icon = folder_icon
self.file_icon = file_icon
self.max_files_per_dir = max_files_per_dir
self.max_depth = max_depth
self.align_comments = align_comments
# === Hauptklasse ===
class TreeScanner:
def __init__(self, config: TreeScannerConfig):
self.config = config
def scan_directory(self, path: str, depth: int = 0, prefix: str = "") -> List[str]:
lines = []
try:
entries = sorted(os.listdir(path))
except PermissionError:
return [f"{prefix}└── [Zugriff verweigert] {path}"]
folders = [e for e in entries if os.path.isdir(os.path.join(path, e))]
files = [e for e in entries if os.path.isfile(os.path.join(path, e))]
for idx, folder in enumerate(folders):
folder_path = os.path.join(path, folder)
connector = "├── " if idx < len(folders) - 1 or files else "└── "
line = f"{prefix}{connector}{self.config.folder_icon} {folder}"
lines.append(line)
if self.config.max_depth is None or depth < self.config.max_depth:
extension = "" if idx < len(folders) - 1 or files else " "
lines.extend(self.scan_directory(folder_path, depth + 1, prefix + extension))
for idx, file in enumerate(files[:self.config.max_files_per_dir]):
connector = "├── " if idx < len(files[:self.config.max_files_per_dir]) - 1 else "└── "
line = f"{prefix}{connector}{self.config.file_icon} {file}"
lines.append(line)
if len(files) > self.config.max_files_per_dir:
remaining = len(files) - self.config.max_files_per_dir
lines.append(f"{prefix}└── <und {remaining} weitere Dateien>")
return lines
def align_lines_with_comments(self, lines: List[str]) -> List[str]:
max_length = max(len(line.rstrip()) for line in lines)
return [
line.rstrip() + (" " * (max_length - len(line.rstrip()) + 2)) + "# "
for line in lines
]
def generate_tree(self) -> str:
root_name = os.path.basename(os.path.abspath(self.config.root_path)) or self.config.root_path
lines = [f"{self.config.folder_icon} {root_name}/"]
lines += self.scan_directory(self.config.root_path)
if self.config.align_comments:
lines = self.align_lines_with_comments(lines)
return "\n".join(lines)
# === Standalone-Ausführung ===
def main():
config = TreeScannerConfig()
scanner = TreeScanner(config)
tree_output = scanner.generate_tree()
with open("tree.txt", "w", encoding="utf-8") as f:
f.write(tree_output + "\n")
if __name__ == "__main__":
main()