Coverage for src/extratools_core/path.py: 0%

36 statements  

« prev     ^ index     » next       coverage.py v7.8.1, created at 2025-06-19 04:20 -0700

1from collections.abc import Iterable 

2from datetime import UTC, datetime, timedelta 

3 

4from .typing import PathLike 

5 

6 

7def clear_dir(curr_dir: PathLike) -> None: 

8 """ 

9 Based on example in https://docs.python.org/3/library/pathlib.html#pathlib.Path.walk 

10 """ 

11 

12 if not curr_dir.is_dir(): 

13 raise ValueError 

14 

15 for parent, dirs, files in curr_dir.walk(top_down=False): 

16 for filename in files: 

17 (parent / filename).unlink() 

18 for dirname in dirs: 

19 (parent / dirname).rmdir() 

20 

21 

22def rm_with_empty_parents( 

23 curr: PathLike, 

24 *, 

25 stop: PathLike | None = None, 

26) -> None: 

27 curr.unlink() 

28 

29 for parent in curr.parents: 

30 if parent == stop: 

31 return 

32 

33 if parent.is_dir() and next(iter(parent.iterdir()), None) is None: 

34 parent.rmdir() 

35 

36 

37def cleanup_dir_by_ttl( 

38 curr_dir: PathLike, 

39 ttl: timedelta | datetime, 

40 *, 

41 include_empty_parents: bool = True, 

42 return_before_delete: bool = False, 

43) -> Iterable[tuple[PathLike, datetime]]: 

44 if not curr_dir.is_dir(): 

45 raise ValueError 

46 

47 now: datetime = datetime.now(UTC) 

48 

49 for parent, _, files in curr_dir.walk(top_down=False): 

50 for filename in files: 

51 f: PathLike = (parent / filename) 

52 

53 last_modified_time: datetime = datetime.fromtimestamp(f.stat().st_mtime, UTC) 

54 if isinstance(ttl, timedelta): 

55 ttl = now - ttl 

56 

57 if last_modified_time < ttl: 

58 if return_before_delete: 

59 yield (f, last_modified_time) 

60 

61 if include_empty_parents: 

62 rm_with_empty_parents(f, stop=curr_dir) 

63 else: 

64 f.unlink() 

65 

66 if not return_before_delete: 

67 yield (f, last_modified_time)