Skip to content

Commit 6c8dc35

Browse files
committed
v0.3.0
2 parents c07da82 + 365d35a commit 6c8dc35

File tree

7 files changed

+78
-13
lines changed

7 files changed

+78
-13
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
# CHANGELOG
1+
# CHANGELOG - treeScannerASCII
2+
3+
- **2025-04-30 Commit v0.3.0**
4+
5+
- **Geändert:**
6+
- [x] Fortschrittsanzeige beim Scan: Ausgabe alle 5 Sekunden via Timer (TreeScanner.scan_directory)
7+
- [x] Fehlerbehandlung bei ungültigem root_path verbessert (CLI)
8+
- [x] Unterstützung für Ignorierliste von Verzeichnissen (`--ignore`, `-x`), rekursiv wirksam
9+
10+
- **Hinzugefügt:**
11+
- [x] Unterstützung für Paket-Ausführung via `python -m treeScannerASCII`
12+
- Leeres `__init__.py` beibehalten
13+
- `__main__.py` mit Fallback-Import (`relative` + `direct`) implementiert
214

315
- **2025-04-27 - Commit v0.2.1**
416

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ python scanner.py [root_path] [-n N] [-d DEPTH] [--no-align-comments] [-l {de,en
3333
| `-d`, `--max-depth` | Maximale Tiefe der Rekursion; unbegrenzt, wenn nicht gesetzt. |
3434
| `--no-align-comments` | Deaktiviert die Ausrichtung der Kommentar-Platzhalter am Zeilenende. |
3535
| `-l`, `--language` | Sprache der Abschlussmeldung (`de` für Deutsch, `en` für Englisch; Default: `de`). |
36+
| `-x`, `--ignore` | Ignoriert angegebene Verzeichnisse rekursiv (z. B. `.git`, `__pycache__`). Mehrfach möglich. |
37+
| `-o`, `--output` | Zielpfad der Ausgabedatei (z. B. `tree.txt` oder `logs/struktur.txt`) |
3638
| `-h`, `--help` | Zeigt diese Hilfe an und beendet das Programm. |
3739

3840
**Ausgabe:**
@@ -70,6 +72,8 @@ print(output)
7072
| `max_depth: Optional[int]` | Ganzzahl oder None | Maximale Rekursionstiefe; `None` = unbegrenzt |
7173
| `align_comments: bool` | Bool | Kommentare am Zeilenende ausrichten (Default: `True`) |
7274
| `language: str` | String | Sprache der Zusammenfassung (`de` oder `en`) (Default: `de`) |
75+
| `output_file: str` | String | Dateiname und Pfad der Ausgabe-Datei (Default: `tree.txt`) |
76+
| `ignored_dirs: List[str]` | Liste von Strings | Verzeichnisse, die rekursiv ignoriert werden sollen (z. B. `.git`) |
7377

7478
## 📄 Beispielausgabe (tree.txt)
7579

@@ -94,13 +98,14 @@ print(output)
9498
- Mehrsprachige Abschlussmeldung (Deutsch, Englisch)
9599
- Ausgabe als Textdatei (`tree.txt`)
96100
- Saubere Google-Style Docstrings für IDE-Kompatibilität
101+
- Fortschrittsanzeige bei großen Scans (alle 5 Sekunden automatische Statusmeldung)
102+
- Ignorieren beliebiger Verzeichnisse rekursiv via `--ignore`
103+
- Konfigurierbarer Ausgabe-Dateiname/-Pfad via `--output`
97104
- Modularer Aufbau für spätere Erweiterungen
98105

99106
## 🛡️ Geplante Erweiterungen
100107

101-
- Bessere Fehlerbehandlung bei ungültigem Pfad (anstatt Absturz)
102108
- Farbliche Ausgabe der Baumstruktur in der Konsole (optional)
103-
- Konfigurierbare Ausgabe-Datei über CLI
104109
- Vorbereitung für Unicode-optimierte Konsolen
105110

106111
## 📄 Lizenz

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.2
1+
0.3.0

__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# __init__.py
2+
# (leer) Kennzeichnet das Verzeichnis als Python-Paket

__main__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# __main__.py
2+
# (leer) Optional: erlaubt spätere Ausführung mit `python -m treescannerASCII`
3+
4+
try:
5+
# Für Paket-Ausführung mit `python -m treeScannerASCII`
6+
from .scanner import main
7+
except ImportError:
8+
# Für direkte Ausführung mit `python scanner.py`
9+
from scanner import main
10+
11+
if __name__ == "__main__":
12+
main()

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[project]
2-
name = "treescanner"
2+
name = "treeScannerASCII"
33
version = "0.1.0"
44
description = "Ein Verzeichnisscanner als CLI-Tool und Python-Modul"
55
authors = [
@@ -8,7 +8,7 @@ authors = [
88
readme = "README.md"
99
requires-python = ">=3.7"
1010
license = { text = "MIT" }
11-
keywords = ["filesystem", "tree", "scanner", "cli", "modul"]
11+
keywords = ["filesystem", "tree", "scanner", "cli", "modul", "markdown"]
1212

1313
[build-system]
1414
requires = ["setuptools"]

scanner.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#!/usr/bin/env python3
12
import os
23
import argparse
4+
import time
35
from typing import Optional, List
46

57
class TreeScannerConfig:
@@ -13,17 +15,21 @@ class TreeScannerConfig:
1315
max_depth (Optional[int]): Maximale Rekursionstiefe.
1416
align_comments (bool): Kommentare am Zeilenende ausrichten.
1517
language (str): Sprache der Programmausgabe (de oder en).
18+
output_file (str): Pfad und Name der Ausgabedatei.
19+
ignored_dirs (Optional[List[str]]): Liste von Verzeichnissen, die ignoriert werden sollen.
1620
"""
1721

1822
def __init__(
1923
self,
2024
root_path: str = ".",
2125
folder_icon: str = "\U0001F4C1",
2226
file_icon: str = "\U0001F4C4",
23-
max_files_per_dir: int = 2,
27+
max_files_per_dir: int = 100,
2428
max_depth: Optional[int] = None,
2529
align_comments: bool = True,
26-
language: str = "de"
30+
language: str = "de",
31+
output_file: str = "tree.txt",
32+
ignored_dirs: Optional[List[str]] = None
2733
):
2834
self.root_path = root_path
2935
self.folder_icon = folder_icon
@@ -32,6 +38,8 @@ def __init__(
3238
self.max_depth = max_depth
3339
self.align_comments = align_comments
3440
self.language = language
41+
self.output_file = output_file
42+
self.ignored_dirs = ignored_dirs or []
3543

3644
class TreeScanner:
3745
"""Klasse zum Scannen von Verzeichnissen und Erzeugen einer ASCII-Baumstruktur."""
@@ -42,6 +50,7 @@ def __init__(self, config: TreeScannerConfig):
4250
Args:
4351
config (TreeScannerConfig): Konfiguration für den Scanner.
4452
"""
53+
self.last_output = time.time()
4554
self.config = config
4655
self.folder_count = 0
4756
self.file_count = 0
@@ -71,7 +80,7 @@ def scan_directory(self, path: str, depth: int = 0, prefix: str = "") -> List[st
7180
except PermissionError:
7281
return [f"{prefix}└── [Zugriff verweigert] {path}"]
7382

74-
folders = [e for e in entries if os.path.isdir(os.path.join(path, e))]
83+
folders = [e for e in entries if os.path.isdir(os.path.join(path, e)) and e not in self.config.ignored_dirs]
7584
files = [e for e in entries if os.path.isfile(os.path.join(path, e))]
7685

7786
for idx, folder in enumerate(folders):
@@ -92,6 +101,10 @@ def scan_directory(self, path: str, depth: int = 0, prefix: str = "") -> List[st
92101
for idx, name in enumerate(combined):
93102
if not name.startswith("<und "):
94103
self.file_count += 1
104+
if time.time() - self.last_output >= 5:
105+
print(f"[Info] {self.folder_count + self.file_count} Einträge gescannt...", flush=True)
106+
self.last_output = time.time()
107+
95108
connector = "├── " if idx < len(combined) - 1 else "└── "
96109
lines.append(f"{prefix}{connector}{self.config.file_icon} {name}")
97110

@@ -144,23 +157,44 @@ def main():
144157
parser.add_argument("-d", "--max-depth", type=int, help="Maximale Rekursionstiefe; unbegrenzt, wenn nicht gesetzt.")
145158
parser.add_argument("--no-align-comments", action="store_false", dest="align_comments", help="Deaktiviert das Ausrichten der Kommentare am Zeilenende.")
146159
parser.add_argument("-l", "--language", type=str, default="de", choices=["de", "en"], help="Sprache der Programmausgabe (de oder en).")
160+
parser.add_argument(
161+
"--ignore", "-x",
162+
action="append",
163+
help="Verzeichnisse, die ignoriert werden sollen (z. B. .git, __pycache__). Mehrfach verwendbar."
164+
)
165+
166+
parser.add_argument("-o", "--output", type=str, help="Pfad und Name der Ausgabedatei (Standard: tree.txt)")
167+
147168
args = parser.parse_args()
148169

170+
output_file = args.output if args.output else "tree.txt"
171+
ignored_dirs = args.ignore if args.ignore else []
172+
173+
# Pfad validieren
174+
if not os.path.isdir(args.root_path):
175+
print(f"Fehler: Der angegebene Pfad '{args.root_path}' ist kein gültiges Verzeichnis oder anderer falscher Parameter.")
176+
return
177+
178+
output_dir = os.path.dirname(output_file)
179+
if output_dir:
180+
os.makedirs(output_dir, exist_ok=True)
181+
149182
config = TreeScannerConfig(
150183
root_path=args.root_path,
151184
max_files_per_dir=args.max_files_per_dir,
152185
max_depth=args.max_depth,
153186
align_comments=args.align_comments,
154-
language=args.language
187+
language=args.language,
188+
output_file=output_file,
189+
ignored_dirs=ignored_dirs
155190
)
156191
scanner = TreeScanner(config)
157192
tree_output = scanner.generate_tree()
158193

159-
output_file = "tree.txt"
160-
with open(output_file, "w", encoding="utf-8") as f:
194+
with open(config.output_file, "w", encoding="utf-8") as f:
161195
f.write(tree_output + "\n")
162196

163-
scanner.print_summary(output_file)
197+
scanner.print_summary(config.output_file)
164198

165199
if __name__ == "__main__":
166200
main()

0 commit comments

Comments
 (0)