v0.2.1
This commit is contained in:
parent
efba39dbe0
commit
46071b62cf
@ -1,5 +1,10 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
- **2025-04-27 - Commit v0.2.1**
|
||||||
|
|
||||||
|
- **Geändert:**
|
||||||
|
- [x] `scanner.py`: Vollständige Google-Style-Docstrings und saubere Kommentare hinzugefügt (keine Funktionsänderung).
|
||||||
|
|
||||||
- **2025-04-27 - Commit v0.2.0**
|
- **2025-04-27 - Commit v0.2.0**
|
||||||
|
|
||||||
- **Hinzugefügt:**
|
- **Hinzugefügt:**
|
||||||
|
64
scanner.py
64
scanner.py
@ -3,7 +3,28 @@ import argparse
|
|||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
||||||
class TreeScannerConfig:
|
class TreeScannerConfig:
|
||||||
def __init__(self, root_path: str = ".", folder_icon: str = "\U0001F4C1", file_icon: str = "\U0001F4C4", max_files_per_dir: int = 2, max_depth: Optional[int] = None, align_comments: bool = True, language: str = "de"):
|
"""Konfigurationsklasse für den TreeScanner.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
root_path (str): Pfad des Stammverzeichnisses.
|
||||||
|
folder_icon (str): Icon für Ordner.
|
||||||
|
file_icon (str): Icon für Dateien und Platzhalter.
|
||||||
|
max_files_per_dir (int): Maximale Anzahl Dateien pro Verzeichnis.
|
||||||
|
max_depth (Optional[int]): Maximale Rekursionstiefe.
|
||||||
|
align_comments (bool): Kommentare am Zeilenende ausrichten.
|
||||||
|
language (str): Sprache der Programmausgabe (de oder en).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
root_path: str = ".",
|
||||||
|
folder_icon: str = "\U0001F4C1",
|
||||||
|
file_icon: str = "\U0001F4C4",
|
||||||
|
max_files_per_dir: int = 2,
|
||||||
|
max_depth: Optional[int] = None,
|
||||||
|
align_comments: bool = True,
|
||||||
|
language: str = "de"
|
||||||
|
):
|
||||||
self.root_path = root_path
|
self.root_path = root_path
|
||||||
self.folder_icon = folder_icon
|
self.folder_icon = folder_icon
|
||||||
self.file_icon = file_icon
|
self.file_icon = file_icon
|
||||||
@ -13,7 +34,14 @@ class TreeScannerConfig:
|
|||||||
self.language = language
|
self.language = language
|
||||||
|
|
||||||
class TreeScanner:
|
class TreeScanner:
|
||||||
|
"""Klasse zum Scannen von Verzeichnissen und Erzeugen einer ASCII-Baumstruktur."""
|
||||||
|
|
||||||
def __init__(self, config: TreeScannerConfig):
|
def __init__(self, config: TreeScannerConfig):
|
||||||
|
"""Initialisiert den TreeScanner.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (TreeScannerConfig): Konfiguration für den Scanner.
|
||||||
|
"""
|
||||||
self.config = config
|
self.config = config
|
||||||
self.folder_count = 0
|
self.folder_count = 0
|
||||||
self.file_count = 0
|
self.file_count = 0
|
||||||
@ -27,13 +55,25 @@ class TreeScanner:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def scan_directory(self, path: str, depth: int = 0, prefix: str = "") -> List[str]:
|
def scan_directory(self, path: str, depth: int = 0, prefix: str = "") -> List[str]:
|
||||||
|
"""Scannt ein Verzeichnis und gibt eine Liste von ASCII-Zeilen zurück.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): Pfad des zu scannenden Verzeichnisses.
|
||||||
|
depth (int): Aktuelle Rekursionstiefe.
|
||||||
|
prefix (str): Präfix für Einrückung und Connectoren.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Zeilen der Baumstruktur.
|
||||||
|
"""
|
||||||
lines: List[str] = []
|
lines: List[str] = []
|
||||||
try:
|
try:
|
||||||
entries = sorted(os.listdir(path))
|
entries = sorted(os.listdir(path))
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
return [f"{prefix}└── [Zugriff verweigert] {path}"]
|
return [f"{prefix}└── [Zugriff verweigert] {path}"]
|
||||||
|
|
||||||
folders = [e for e in entries if os.path.isdir(os.path.join(path, e))]
|
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))]
|
files = [e for e in entries if os.path.isfile(os.path.join(path, e))]
|
||||||
|
|
||||||
for idx, folder in enumerate(folders):
|
for idx, folder in enumerate(folders):
|
||||||
self.folder_count += 1
|
self.folder_count += 1
|
||||||
folder_path = os.path.join(path, folder)
|
folder_path = os.path.join(path, folder)
|
||||||
@ -42,19 +82,30 @@ class TreeScanner:
|
|||||||
if self.config.max_depth is None or depth < self.config.max_depth:
|
if self.config.max_depth is None or depth < self.config.max_depth:
|
||||||
extension = "│ " if idx < len(folders) - 1 or files else " "
|
extension = "│ " if idx < len(folders) - 1 or files else " "
|
||||||
lines.extend(self.scan_directory(folder_path, depth + 1, prefix + extension))
|
lines.extend(self.scan_directory(folder_path, depth + 1, prefix + extension))
|
||||||
|
|
||||||
visible_files = files[: self.config.max_files_per_dir]
|
visible_files = files[: self.config.max_files_per_dir]
|
||||||
remaining = len(files) - len(visible_files)
|
remaining = len(files) - len(visible_files)
|
||||||
combined = visible_files.copy()
|
combined = visible_files.copy()
|
||||||
if remaining > 0:
|
if remaining > 0:
|
||||||
combined.append(f"<und {remaining} weitere Dateien>")
|
combined.append(f"<und {remaining} weitere Dateien>")
|
||||||
|
|
||||||
for idx, name in enumerate(combined):
|
for idx, name in enumerate(combined):
|
||||||
if not name.startswith("<und "):
|
if not name.startswith("<und "):
|
||||||
self.file_count += 1
|
self.file_count += 1
|
||||||
connector = "├── " if idx < len(combined) - 1 else "└── "
|
connector = "├── " if idx < len(combined) - 1 else "└── "
|
||||||
lines.append(f"{prefix}{connector}{self.config.file_icon} {name}")
|
lines.append(f"{prefix}{connector}{self.config.file_icon} {name}")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def align_lines_with_comments(self, lines: List[str]) -> List[str]:
|
def align_lines_with_comments(self, lines: List[str]) -> List[str]:
|
||||||
|
"""Richtet alle Zeilen so aus, dass Kommentare am gleichen Spaltenindex stehen.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lines (List[str]): Liste der Baumstruktur-Zeilen ohne Kommentare.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Zeilen mit ausgerichteten Kommentar-Platzhaltern (#).
|
||||||
|
"""
|
||||||
max_length = max(len(line.rstrip()) for line in lines)
|
max_length = max(len(line.rstrip()) for line in lines)
|
||||||
aligned: List[str] = []
|
aligned: List[str] = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
@ -64,6 +115,11 @@ class TreeScanner:
|
|||||||
return aligned
|
return aligned
|
||||||
|
|
||||||
def generate_tree(self) -> str:
|
def generate_tree(self) -> str:
|
||||||
|
"""Generiert den vollständigen Verzeichnisbaum als String.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Mehrzeiliger String mit Ordner-Icon, Ordner- und Dateienstruktur.
|
||||||
|
"""
|
||||||
root_name = os.path.basename(os.path.abspath(self.config.root_path)) or self.config.root_path
|
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 = [f"{self.config.folder_icon} {root_name}/"]
|
||||||
lines += self.scan_directory(self.config.root_path)
|
lines += self.scan_directory(self.config.root_path)
|
||||||
@ -72,10 +128,16 @@ class TreeScanner:
|
|||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
def print_summary(self, output_file: str) -> None:
|
def print_summary(self, output_file: str) -> None:
|
||||||
|
"""Gibt eine Zusammenfassung des Scanlaufs aus.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
output_file (str): Name der geschriebenen Ausgabedatei.
|
||||||
|
"""
|
||||||
message_template = self.messages.get(self.config.language, self.messages["de"])
|
message_template = self.messages.get(self.config.language, self.messages["de"])
|
||||||
print(message_template["summary"].format(folders=self.folder_count, files=self.file_count, file=output_file))
|
print(message_template["summary"].format(folders=self.folder_count, files=self.file_count, file=output_file))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""Standalone-Ausführung mit CLI-Parameter-Unterstützung."""
|
||||||
parser = argparse.ArgumentParser(description="Generiert eine ASCII-Baumstruktur eines Verzeichnisses.")
|
parser = argparse.ArgumentParser(description="Generiert eine ASCII-Baumstruktur eines Verzeichnisses.")
|
||||||
parser.add_argument("root_path", nargs="?", default=".", help="Pfad des Stammverzeichnisses (default: aktuelles Verzeichnis).")
|
parser.add_argument("root_path", nargs="?", default=".", help="Pfad des Stammverzeichnisses (default: aktuelles Verzeichnis).")
|
||||||
parser.add_argument("-n", "--max-files-per-dir", type=int, default=2, help="Maximale Anzahl Dateien pro Verzeichnis (default: 2).")
|
parser.add_argument("-n", "--max-files-per-dir", type=int, default=2, help="Maximale Anzahl Dateien pro Verzeichnis (default: 2).")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user