Coverage for src/extratools_core/path.py: 0%
54 statements
« prev ^ index » next coverage.py v7.8.1, created at 2025-06-26 03:51 -0700
« prev ^ index » next coverage.py v7.8.1, created at 2025-06-26 03:51 -0700
1from collections.abc import Iterable
2from datetime import UTC, datetime, timedelta
3from io import StringIO
4from pathlib import Path
6from .typing import PathLike
9def clear_dir(curr_dir: PathLike) -> None:
10 """
11 Based on example in https://docs.python.org/3/library/pathlib.html#pathlib.Path.walk
12 """
14 if not curr_dir.is_dir():
15 raise ValueError
17 for parent, dirs, files in curr_dir.walk(top_down=False):
18 for filename in files:
19 (parent / filename).unlink()
20 for dirname in dirs:
21 (parent / dirname).rmdir()
24def rm_with_empty_parents(
25 curr: PathLike,
26 *,
27 stop: PathLike | None = None,
28) -> None:
29 curr.unlink()
31 for parent in curr.parents:
32 if parent == stop:
33 return
35 if parent.is_dir() and next(iter(parent.iterdir()), None) is None:
36 parent.rmdir()
39def cleanup_dir_by_ttl(
40 curr_dir: PathLike,
41 ttl: timedelta | datetime,
42 *,
43 include_empty_parents: bool = True,
44 return_before_delete: bool = False,
45) -> Iterable[tuple[PathLike, datetime]]:
46 if not curr_dir.is_dir():
47 raise ValueError
49 now: datetime = datetime.now(UTC)
51 for parent, _, files in curr_dir.walk(top_down=False):
52 for filename in files:
53 f: PathLike = (parent / filename)
55 last_modified_time: datetime = datetime.fromtimestamp(f.stat().st_mtime, UTC)
56 if isinstance(ttl, timedelta):
57 ttl = now - ttl
59 if last_modified_time < ttl:
60 if return_before_delete:
61 yield (f, last_modified_time)
63 if include_empty_parents:
64 rm_with_empty_parents(f, stop=curr_dir)
65 else:
66 f.unlink()
68 if not return_before_delete:
69 yield (f, last_modified_time)
72def read_text_by_pattern(
73 *patterns: str,
74 pwd: Path | str | None = None,
75 seperator: str | None = None,
76 add_newline: bool = True,
77) -> str:
78 sio = StringIO()
80 pwd = Path() if not pwd else Path(pwd).expanduser()
81 for pattern in patterns:
82 for path in pwd.glob(pattern):
83 if not path.is_file():
84 continue
86 file_content = path.read_text()
87 sio.write(file_content)
89 if add_newline and file_content[-1] != "\n":
90 sio.write("\n")
92 if seperator:
93 sio.write(seperator)
95 content: str = sio.getvalue()
96 sio.close()
97 return content