v0.3.0
This commit is contained in:
commit
6c8dc35cc0
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,4 +1,16 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG - treeScannerASCII
|
||||||
|
|
||||||
|
- **2025-04-30 Commit v0.3.0**
|
||||||
|
|
||||||
|
- **Geändert:**
|
||||||
|
- [x] Fortschrittsanzeige beim Scan: Ausgabe alle 5 Sekunden via Timer (TreeScanner.scan_directory)
|
||||||
|
- [x] Fehlerbehandlung bei ungültigem root_path verbessert (CLI)
|
||||||
|
- [x] Unterstützung für Ignorierliste von Verzeichnissen (`--ignore`, `-x`), rekursiv wirksam
|
||||||
|
|
||||||
|
- **Hinzugefügt:**
|
||||||
|
- [x] Unterstützung für Paket-Ausführung via `python -m treeScannerASCII`
|
||||||
|
- Leeres `__init__.py` beibehalten
|
||||||
|
- `__main__.py` mit Fallback-Import (`relative` + `direct`) implementiert
|
||||||
|
|
||||||
- **2025-04-27 - Commit v0.2.1**
|
- **2025-04-27 - Commit v0.2.1**
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ python scanner.py [root_path] [-n N] [-d DEPTH] [--no-align-comments] [-l {de,en
|
|||||||
| `-d`, `--max-depth` | Maximale Tiefe der Rekursion; unbegrenzt, wenn nicht gesetzt. |
|
| `-d`, `--max-depth` | Maximale Tiefe der Rekursion; unbegrenzt, wenn nicht gesetzt. |
|
||||||
| `--no-align-comments` | Deaktiviert die Ausrichtung der Kommentar-Platzhalter am Zeilenende. |
|
| `--no-align-comments` | Deaktiviert die Ausrichtung der Kommentar-Platzhalter am Zeilenende. |
|
||||||
| `-l`, `--language` | Sprache der Abschlussmeldung (`de` für Deutsch, `en` für Englisch; Default: `de`). |
|
| `-l`, `--language` | Sprache der Abschlussmeldung (`de` für Deutsch, `en` für Englisch; Default: `de`). |
|
||||||
|
| `-x`, `--ignore` | Ignoriert angegebene Verzeichnisse rekursiv (z. B. `.git`, `__pycache__`). Mehrfach möglich. |
|
||||||
|
| `-o`, `--output` | Zielpfad der Ausgabedatei (z. B. `tree.txt` oder `logs/struktur.txt`) |
|
||||||
| `-h`, `--help` | Zeigt diese Hilfe an und beendet das Programm. |
|
| `-h`, `--help` | Zeigt diese Hilfe an und beendet das Programm. |
|
||||||
|
|
||||||
**Ausgabe:**
|
**Ausgabe:**
|
||||||
@ -70,6 +72,8 @@ print(output)
|
|||||||
| `max_depth: Optional[int]` | Ganzzahl oder None | Maximale Rekursionstiefe; `None` = unbegrenzt |
|
| `max_depth: Optional[int]` | Ganzzahl oder None | Maximale Rekursionstiefe; `None` = unbegrenzt |
|
||||||
| `align_comments: bool` | Bool | Kommentare am Zeilenende ausrichten (Default: `True`) |
|
| `align_comments: bool` | Bool | Kommentare am Zeilenende ausrichten (Default: `True`) |
|
||||||
| `language: str` | String | Sprache der Zusammenfassung (`de` oder `en`) (Default: `de`) |
|
| `language: str` | String | Sprache der Zusammenfassung (`de` oder `en`) (Default: `de`) |
|
||||||
|
| `output_file: str` | String | Dateiname und Pfad der Ausgabe-Datei (Default: `tree.txt`) |
|
||||||
|
| `ignored_dirs: List[str]` | Liste von Strings | Verzeichnisse, die rekursiv ignoriert werden sollen (z. B. `.git`) |
|
||||||
|
|
||||||
## 📄 Beispielausgabe (tree.txt)
|
## 📄 Beispielausgabe (tree.txt)
|
||||||
|
|
||||||
@ -94,13 +98,14 @@ print(output)
|
|||||||
- Mehrsprachige Abschlussmeldung (Deutsch, Englisch)
|
- Mehrsprachige Abschlussmeldung (Deutsch, Englisch)
|
||||||
- Ausgabe als Textdatei (`tree.txt`)
|
- Ausgabe als Textdatei (`tree.txt`)
|
||||||
- Saubere Google-Style Docstrings für IDE-Kompatibilität
|
- Saubere Google-Style Docstrings für IDE-Kompatibilität
|
||||||
|
- Fortschrittsanzeige bei großen Scans (alle 5 Sekunden automatische Statusmeldung)
|
||||||
|
- Ignorieren beliebiger Verzeichnisse rekursiv via `--ignore`
|
||||||
|
- Konfigurierbarer Ausgabe-Dateiname/-Pfad via `--output`
|
||||||
- Modularer Aufbau für spätere Erweiterungen
|
- Modularer Aufbau für spätere Erweiterungen
|
||||||
|
|
||||||
## 🛡️ Geplante Erweiterungen
|
## 🛡️ Geplante Erweiterungen
|
||||||
|
|
||||||
- Bessere Fehlerbehandlung bei ungültigem Pfad (anstatt Absturz)
|
|
||||||
- Farbliche Ausgabe der Baumstruktur in der Konsole (optional)
|
- Farbliche Ausgabe der Baumstruktur in der Konsole (optional)
|
||||||
- Konfigurierbare Ausgabe-Datei über CLI
|
|
||||||
- Vorbereitung für Unicode-optimierte Konsolen
|
- Vorbereitung für Unicode-optimierte Konsolen
|
||||||
|
|
||||||
## 📄 Lizenz
|
## 📄 Lizenz
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
# __init__.py
|
||||||
|
# (leer) Kennzeichnet das Verzeichnis als Python-Paket
|
12
__main__.py
12
__main__.py
@ -0,0 +1,12 @@
|
|||||||
|
# __main__.py
|
||||||
|
# (leer) Optional: erlaubt spätere Ausführung mit `python -m treescannerASCII`
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Für Paket-Ausführung mit `python -m treeScannerASCII`
|
||||||
|
from .scanner import main
|
||||||
|
except ImportError:
|
||||||
|
# Für direkte Ausführung mit `python scanner.py`
|
||||||
|
from scanner import main
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -1,5 +1,5 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "treescanner"
|
name = "treeScannerASCII"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Ein Verzeichnisscanner als CLI-Tool und Python-Modul"
|
description = "Ein Verzeichnisscanner als CLI-Tool und Python-Modul"
|
||||||
authors = [
|
authors = [
|
||||||
@ -8,7 +8,7 @@ authors = [
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.7"
|
requires-python = ">=3.7"
|
||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
keywords = ["filesystem", "tree", "scanner", "cli", "modul"]
|
keywords = ["filesystem", "tree", "scanner", "cli", "modul", "markdown"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools"]
|
requires = ["setuptools"]
|
||||||
|
48
scanner.py
48
scanner.py
@ -1,5 +1,7 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
import time
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
||||||
class TreeScannerConfig:
|
class TreeScannerConfig:
|
||||||
@ -13,6 +15,8 @@ class TreeScannerConfig:
|
|||||||
max_depth (Optional[int]): Maximale Rekursionstiefe.
|
max_depth (Optional[int]): Maximale Rekursionstiefe.
|
||||||
align_comments (bool): Kommentare am Zeilenende ausrichten.
|
align_comments (bool): Kommentare am Zeilenende ausrichten.
|
||||||
language (str): Sprache der Programmausgabe (de oder en).
|
language (str): Sprache der Programmausgabe (de oder en).
|
||||||
|
output_file (str): Pfad und Name der Ausgabedatei.
|
||||||
|
ignored_dirs (Optional[List[str]]): Liste von Verzeichnissen, die ignoriert werden sollen.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -20,10 +24,12 @@ class TreeScannerConfig:
|
|||||||
root_path: str = ".",
|
root_path: str = ".",
|
||||||
folder_icon: str = "\U0001F4C1",
|
folder_icon: str = "\U0001F4C1",
|
||||||
file_icon: str = "\U0001F4C4",
|
file_icon: str = "\U0001F4C4",
|
||||||
max_files_per_dir: int = 2,
|
max_files_per_dir: int = 100,
|
||||||
max_depth: Optional[int] = None,
|
max_depth: Optional[int] = None,
|
||||||
align_comments: bool = True,
|
align_comments: bool = True,
|
||||||
language: str = "de"
|
language: str = "de",
|
||||||
|
output_file: str = "tree.txt",
|
||||||
|
ignored_dirs: Optional[List[str]] = None
|
||||||
):
|
):
|
||||||
self.root_path = root_path
|
self.root_path = root_path
|
||||||
self.folder_icon = folder_icon
|
self.folder_icon = folder_icon
|
||||||
@ -32,6 +38,8 @@ class TreeScannerConfig:
|
|||||||
self.max_depth = max_depth
|
self.max_depth = max_depth
|
||||||
self.align_comments = align_comments
|
self.align_comments = align_comments
|
||||||
self.language = language
|
self.language = language
|
||||||
|
self.output_file = output_file
|
||||||
|
self.ignored_dirs = ignored_dirs or []
|
||||||
|
|
||||||
class TreeScanner:
|
class TreeScanner:
|
||||||
"""Klasse zum Scannen von Verzeichnissen und Erzeugen einer ASCII-Baumstruktur."""
|
"""Klasse zum Scannen von Verzeichnissen und Erzeugen einer ASCII-Baumstruktur."""
|
||||||
@ -42,6 +50,7 @@ class TreeScanner:
|
|||||||
Args:
|
Args:
|
||||||
config (TreeScannerConfig): Konfiguration für den Scanner.
|
config (TreeScannerConfig): Konfiguration für den Scanner.
|
||||||
"""
|
"""
|
||||||
|
self.last_output = time.time()
|
||||||
self.config = config
|
self.config = config
|
||||||
self.folder_count = 0
|
self.folder_count = 0
|
||||||
self.file_count = 0
|
self.file_count = 0
|
||||||
@ -71,7 +80,7 @@ class TreeScanner:
|
|||||||
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)) and e not in self.config.ignored_dirs]
|
||||||
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):
|
||||||
@ -92,6 +101,10 @@ class TreeScanner:
|
|||||||
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
|
||||||
|
if time.time() - self.last_output >= 5:
|
||||||
|
print(f"[Info] {self.folder_count + self.file_count} Einträge gescannt...", flush=True)
|
||||||
|
self.last_output = time.time()
|
||||||
|
|
||||||
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}")
|
||||||
|
|
||||||
@ -144,23 +157,44 @@ def main():
|
|||||||
parser.add_argument("-d", "--max-depth", type=int, help="Maximale Rekursionstiefe; unbegrenzt, wenn nicht gesetzt.")
|
parser.add_argument("-d", "--max-depth", type=int, help="Maximale Rekursionstiefe; unbegrenzt, wenn nicht gesetzt.")
|
||||||
parser.add_argument("--no-align-comments", action="store_false", dest="align_comments", help="Deaktiviert das Ausrichten der Kommentare am Zeilenende.")
|
parser.add_argument("--no-align-comments", action="store_false", dest="align_comments", help="Deaktiviert das Ausrichten der Kommentare am Zeilenende.")
|
||||||
parser.add_argument("-l", "--language", type=str, default="de", choices=["de", "en"], help="Sprache der Programmausgabe (de oder en).")
|
parser.add_argument("-l", "--language", type=str, default="de", choices=["de", "en"], help="Sprache der Programmausgabe (de oder en).")
|
||||||
|
parser.add_argument(
|
||||||
|
"--ignore", "-x",
|
||||||
|
action="append",
|
||||||
|
help="Verzeichnisse, die ignoriert werden sollen (z. B. .git, __pycache__). Mehrfach verwendbar."
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument("-o", "--output", type=str, help="Pfad und Name der Ausgabedatei (Standard: tree.txt)")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
output_file = args.output if args.output else "tree.txt"
|
||||||
|
ignored_dirs = args.ignore if args.ignore else []
|
||||||
|
|
||||||
|
# Pfad validieren
|
||||||
|
if not os.path.isdir(args.root_path):
|
||||||
|
print(f"Fehler: Der angegebene Pfad '{args.root_path}' ist kein gültiges Verzeichnis oder anderer falscher Parameter.")
|
||||||
|
return
|
||||||
|
|
||||||
|
output_dir = os.path.dirname(output_file)
|
||||||
|
if output_dir:
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
config = TreeScannerConfig(
|
config = TreeScannerConfig(
|
||||||
root_path=args.root_path,
|
root_path=args.root_path,
|
||||||
max_files_per_dir=args.max_files_per_dir,
|
max_files_per_dir=args.max_files_per_dir,
|
||||||
max_depth=args.max_depth,
|
max_depth=args.max_depth,
|
||||||
align_comments=args.align_comments,
|
align_comments=args.align_comments,
|
||||||
language=args.language
|
language=args.language,
|
||||||
|
output_file=output_file,
|
||||||
|
ignored_dirs=ignored_dirs
|
||||||
)
|
)
|
||||||
scanner = TreeScanner(config)
|
scanner = TreeScanner(config)
|
||||||
tree_output = scanner.generate_tree()
|
tree_output = scanner.generate_tree()
|
||||||
|
|
||||||
output_file = "tree.txt"
|
with open(config.output_file, "w", encoding="utf-8") as f:
|
||||||
with open(output_file, "w", encoding="utf-8") as f:
|
|
||||||
f.write(tree_output + "\n")
|
f.write(tree_output + "\n")
|
||||||
|
|
||||||
scanner.print_summary(output_file)
|
scanner.print_summary(config.output_file)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user