@codebend3r/che 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +424 -0
  3. package/bin/che.py +869 -0
  4. package/bin/commands.py +872 -0
  5. package/bin/drives/eject-all-drives.py +203 -0
  6. package/bin/drives/mount-all-drives.py +140 -0
  7. package/bin/drives/ping-nas.py +242 -0
  8. package/bin/files/compress-folders.py +188 -0
  9. package/bin/files/delete-by-ext.py +108 -0
  10. package/bin/files/delete-empty-folders.py +136 -0
  11. package/bin/files/delete-smb-files.py +105 -0
  12. package/bin/files/files-under-size.py +132 -0
  13. package/bin/files/find-largest-files.py +102 -0
  14. package/bin/files/make-alpha-dir.py +63 -0
  15. package/bin/git/all-actions.py +545 -0
  16. package/bin/git/checkout-my-branches.py +147 -0
  17. package/bin/git/clean-stale-branches.py +161 -0
  18. package/bin/git/prune-worktrees.py +143 -0
  19. package/bin/git/sync-all-branches.py +368 -0
  20. package/bin/git/update-local-branches.py +195 -0
  21. package/bin/install.py +1515 -0
  22. package/bin/shellgen.py +782 -0
  23. package/bin/system/btop-launch.py +114 -0
  24. package/bin/system/update-brew.py +146 -0
  25. package/bin/tui.py +648 -0
  26. package/bin/utils.py +836 -0
  27. package/bin/video/delete-duplicate-videos.py +313 -0
  28. package/bin/video/detect-green-magenta-videos.py +268 -0
  29. package/bin/video/find-movie-by-year.py +84 -0
  30. package/bin/video/find-video-mkv-issues.py +242 -0
  31. package/bin/video/fix-codecs.py +209 -0
  32. package/bin/video/largest-tv-shows.py +175 -0
  33. package/bin/video/remove-metadata.py +126 -0
  34. package/bin/video/rename-video-file.py +329 -0
  35. package/bin/video/scan-videos-audio-language.py +110 -0
  36. package/bin/video/show-codecs.py +111 -0
  37. package/bin/video/validate-video-files.py +114 -0
  38. package/bin/video/video-list.py +120 -0
  39. package/package.json +54 -0
  40. package/shell/che.bash +382 -0
  41. package/shell/che.fish +282 -0
  42. package/shell/che.zsh +389 -0
  43. package/shell/completions/_che +146 -0
  44. package/shell/completions/che.bash +107 -0
  45. package/shell/completions/che.fish +371 -0
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env python3
2
+ """📊 List the largest files under a path, biggest first.
3
+
4
+ Usage:
5
+ find-largest-files.py [--path=.] [--length=10] [--full-path]
6
+
7
+ Options:
8
+ --path=DIR Directory to scan (default: .)
9
+ --length=N How many files to list (default: 10)
10
+ --full-path Print the whole path instead of just the basename
11
+ --help Show help
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import heapq
17
+ import re
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
22
+
23
+ from utils import (
24
+ add_bool_flag,
25
+ build_parser,
26
+ format_bytes,
27
+ info,
28
+ iter_files,
29
+ note,
30
+ run_cli,
31
+ scan_root,
32
+ warning,
33
+ )
34
+
35
+ __version__ = "2.0.4"
36
+
37
+ _NON_NEGATIVE_INT = re.compile(r"[0-9]+")
38
+
39
+
40
+ def main(argv: list[str] | None = None) -> int:
41
+ parser = build_parser(
42
+ prog="find-largest-files",
43
+ description="📊 List the largest files under a path, biggest first.",
44
+ )
45
+ parser.add_argument("--path", default=".", metavar="DIR", help="Directory to scan (default: .)")
46
+ # Kept as a string, not `type=int`: argparse's int conversion would own the
47
+ # error and exit before the shell version's own message could be produced.
48
+ parser.add_argument(
49
+ "--length", default="10", metavar="N", help="How many files to list (default: 10)"
50
+ )
51
+ add_bool_flag(parser, "--full-path", dest="full_path", help="Print the whole path")
52
+
53
+ info(f"Running command in {Path.cwd()}")
54
+ args = parser.parse_args(argv)
55
+
56
+ if not _NON_NEGATIVE_INT.fullmatch(args.length):
57
+ warning("❌ --length must be a non-negative integer")
58
+ return 1
59
+ length = int(args.length)
60
+
61
+ if not args.path:
62
+ warning("❌ --path cannot be empty")
63
+ return 1
64
+
65
+ note(f"Searching in: {args.path}")
66
+ note(f"List length: {length}")
67
+ note(f"Show full path: {str(args.full_path).lower()}")
68
+
69
+ root = scan_root(args.path)
70
+
71
+ def sized() -> list[tuple[int, str, Path]]:
72
+ for path in iter_files(root, skip_macos_metadata=False):
73
+ try:
74
+ size = path.stat().st_size
75
+ except OSError:
76
+ continue
77
+ # The shell pipeline (find | xargs stat | sort) broke on any
78
+ # filename containing its '|' separator. Sizing in-process removes
79
+ # that failure mode entirely.
80
+ yield size, str(path), path
81
+
82
+ # `sort -nr | head -n N` ties break on the whole line DESCENDING, because
83
+ # -r reverses the last-resort comparison too. nlargest on (size, str) gives
84
+ # the same ordering, and holds only N entries rather than the whole tree -
85
+ # a million-file media root would otherwise cost about a gigabyte.
86
+ top = heapq.nlargest(length, sized(), key=lambda item: (item[0], item[1]))
87
+
88
+ for size, _, path in top:
89
+ if args.full_path:
90
+ # Rebuild from the user's own --path string so a default of "."
91
+ # still prints "./name", as `find .` did. Path() would normalise
92
+ # the "./" away and break anything piping this into xargs.
93
+ label = f"{args.path.rstrip('/')}/{path.relative_to(root)}"
94
+ else:
95
+ label = path.name
96
+ print(f"{format_bytes(size):>12} {label}", flush=True)
97
+
98
+ return 0
99
+
100
+
101
+ if __name__ == "__main__":
102
+ run_cli(main)
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env python3
2
+ """🔤 Create the alphabetical bucket folders: ``#`` and ``A`` through ``Z``.
3
+
4
+ Usage:
5
+ make-alpha-dir.py [--path=/path/to/parent] (defaults to .)
6
+
7
+ Options:
8
+ --path=DIR Parent directory to create the buckets in (default: .)
9
+ --help Show help
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import string
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
19
+
20
+ from utils import build_parser, info, run_cli, warning
21
+
22
+ BUCKETS = ("#", *string.ascii_uppercase)
23
+
24
+
25
+ def main(argv: list[str] | None = None) -> int:
26
+ parser = build_parser(
27
+ prog="make-alpha-dir",
28
+ description="🔤 Create '#' and A-Z bucket folders under a parent directory.",
29
+ )
30
+ parser.add_argument(
31
+ "--path",
32
+ default=".",
33
+ metavar="DIR",
34
+ help="Parent directory to create the buckets in (default: .)",
35
+ )
36
+
37
+ info(f"Running command in {Path.cwd()}")
38
+ args = parser.parse_args(argv)
39
+
40
+ root = Path(args.path or ".")
41
+ try:
42
+ root.mkdir(parents=True, exist_ok=True)
43
+ except OSError as exc:
44
+ warning(f"❌ Could not create {root}: {exc}")
45
+ return 1
46
+
47
+ # One `mkdir -p -- '#' {A..Z}` reported each failure and still created
48
+ # every other operand, so a parent already holding a FILE named "A" ended
49
+ # up with the remaining 26 buckets. Bailing on the first error would leave
50
+ # a half-built bucket set behind.
51
+ failures = 0
52
+ for bucket in BUCKETS:
53
+ try:
54
+ (root / bucket).mkdir(exist_ok=True)
55
+ except OSError as exc:
56
+ warning(f"mkdir: {bucket}: {exc.strerror or exc}")
57
+ failures += 1
58
+
59
+ return 1 if failures else 0
60
+
61
+
62
+ if __name__ == "__main__":
63
+ run_cli(main)