@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,114 @@
1
+ #!/usr/bin/env python3
2
+ """๐Ÿ–ฅ๏ธ Launch btop with a gruvbox theme that follows the macOS appearance.
3
+
4
+ Light mode uses ``gruvbox_light``, Dark mode ``gruvbox_dark_v2``. The chosen
5
+ theme is written into ``btop.conf`` before launch, because btop reads its
6
+ config once at start.
7
+
8
+ Usage:
9
+ btop-launch.py [btop-args...]
10
+
11
+ Any extra arguments are passed straight through to btop.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import os
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 info, require_binary, run, warning
24
+
25
+ __version__ = "1.0.1"
26
+
27
+ CONF = Path.home() / ".config" / "btop" / "btop.conf"
28
+ LIGHT_THEME = "gruvbox_light"
29
+ DARK_THEME = "gruvbox_dark_v2"
30
+
31
+ USAGE = f"""Usage:
32
+ btop-launch.py [btop-args...]
33
+
34
+ Description:
35
+ ๐Ÿ–ฅ๏ธ Set btop's color_theme to match the current macOS appearance
36
+ ({LIGHT_THEME} in Light mode, {DARK_THEME} in Dark mode), then exec btop.
37
+ Any extra arguments are passed straight through to btop.
38
+ """
39
+
40
+ # `[^\S\n]` rather than `\s`: \s matches newlines, so a config with a line
41
+ # break between "color_theme" and "=" would have two lines collapsed into one.
42
+ # perl -p works a line at a time and cannot do that.
43
+ _COLOR_THEME_RE = re.compile(r"^color_theme[^\S\n]*=.*$", re.MULTILINE)
44
+
45
+
46
+ def current_theme() -> str:
47
+ """Pick the theme matching the macOS appearance.
48
+
49
+ ``defaults read -g AppleInterfaceStyle`` prints "Dark" in Dark mode and
50
+ exits non-zero (the key is absent) in Light mode.
51
+ """
52
+ completed = run(["defaults", "read", "-g", "AppleInterfaceStyle"], check=False, capture=True)
53
+ value = (completed.stdout or "").strip() if completed.returncode == 0 else ""
54
+ return DARK_THEME if value == "Dark" else LIGHT_THEME
55
+
56
+
57
+ def apply_theme(theme: str) -> None:
58
+ """Rewrite the ``color_theme`` line in btop.conf, leaving the rest alone."""
59
+ if not CONF.is_file():
60
+ warning(f"btop config not found at {CONF}; launching with existing theme")
61
+ return
62
+
63
+ try:
64
+ # newline="" so existing CRLF (or CR) line endings survive the
65
+ # round-trip; read_text/write_text would rewrite every line ending in
66
+ # the file, where `perl -i` only ever touched the matched line.
67
+ # surrogateescape so a config carrying non-UTF-8 bytes still round-trips
68
+ # instead of raising and leaving btop unlaunchable.
69
+ with CONF.open("r", encoding="utf-8", errors="surrogateescape", newline="") as handle:
70
+ original = handle.read()
71
+ except OSError as exc:
72
+ warning(f"Could not read {CONF}: {exc}; launching with existing theme")
73
+ return
74
+
75
+ updated, count = _COLOR_THEME_RE.subn(f'color_theme = "{theme}"', original)
76
+ if count == 0:
77
+ warning(f"No color_theme line in {CONF}; launching with existing theme")
78
+ return
79
+
80
+ if updated != original:
81
+ try:
82
+ with CONF.open("w", encoding="utf-8", errors="surrogateescape", newline="") as handle:
83
+ handle.write(updated)
84
+ except OSError as exc:
85
+ warning(f"Could not write {CONF}: {exc}; launching with existing theme")
86
+ return
87
+
88
+ info(f"btop theme -> {theme}")
89
+
90
+
91
+ def main(argv: list[str] | None = None) -> int:
92
+ args = list(sys.argv[1:] if argv is None else argv)
93
+
94
+ if args and args[0] in ("-h", "--help"):
95
+ print(USAGE)
96
+ return 0
97
+
98
+ # Theme first, then the binary check: the shell version rewrote the config
99
+ # even when btop was missing, so re-ordering would silently stop the theme
100
+ # tracking the system appearance on a machine where btop is not installed.
101
+ apply_theme(current_theme())
102
+
103
+ btop = require_binary("btop", hint="Install it with `brew install btop`.")
104
+
105
+ # exec, not spawn: btop is a full-screen TUI and this process has nothing
106
+ # left to do. Replacing the image keeps signal handling and the exit code
107
+ # identical to running btop directly, exactly like `exec btop "$@"`.
108
+ # argv[0] stays the bare name, which is what btop echoes in its own usage.
109
+ os.execv(btop, ["btop", *args]) # noqa: S606 - absolute path, no shell
110
+ return 0 # unreachable; execv never returns
111
+
112
+
113
+ if __name__ == "__main__":
114
+ sys.exit(main())
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env python3
2
+ """๐Ÿบ Update Homebrew, upgrade formulae and casks, then clean up.
3
+
4
+ Usage:
5
+ update-brew.py [--dry-run] [--no-cask] [--no-cleanup] [--no-autoremove]
6
+ [--greedy] [--doctor]
7
+
8
+ Options:
9
+ --dry-run Show what would be upgraded/removed, change nothing
10
+ --no-cask Skip upgrading casks (apps)
11
+ --no-cleanup Skip 'brew cleanup' at the end
12
+ --no-autoremove Skip 'brew autoremove' (leave unused deps in place)
13
+ --greedy Pass --greedy to cask upgrade (force-update self-updating apps)
14
+ --doctor Run 'brew doctor' at the very end
15
+ --help Show help
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import sys
21
+ from pathlib import Path
22
+
23
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
24
+
25
+ from utils import (
26
+ add_bool_flag,
27
+ build_parser,
28
+ info,
29
+ log,
30
+ note,
31
+ require_binary,
32
+ run,
33
+ run_cli,
34
+ success,
35
+ warning,
36
+ )
37
+
38
+ __version__ = "1.0.0"
39
+
40
+
41
+ def brew(
42
+ argv: list[str],
43
+ *,
44
+ dry_run: bool,
45
+ dry_run_argv: list[str] | None = None,
46
+ echo: bool = False,
47
+ ) -> None:
48
+ """Run a brew subcommand, or its --dry-run form.
49
+
50
+ Homebrew's own ``--dry-run`` exits non-zero in some situations that are not
51
+ really failures, so the preview calls are non-fatal - the same ``|| true``
52
+ the shell version used. The real calls stay fatal.
53
+ """
54
+ if dry_run:
55
+ if dry_run_argv is None:
56
+ warning(f" ๐Ÿช„ Would run: {' '.join(argv)}")
57
+ return
58
+ run(dry_run_argv, check=False)
59
+ return
60
+
61
+ # Only `brew update` echoed its command in the shell version; the other
62
+ # steps called brew directly, and brew narrates itself.
63
+ if echo:
64
+ log(f" โ–ถ {' '.join(argv)}")
65
+ run(argv)
66
+
67
+
68
+ def main(argv: list[str] | None = None) -> int:
69
+ parser = build_parser(
70
+ prog="update-brew",
71
+ description="๐Ÿบ Update Homebrew, upgrade formulae and casks, then clean up.",
72
+ )
73
+ add_bool_flag(parser, "--dry-run", help="Show what would change, change nothing")
74
+ add_bool_flag(parser, "--no-cask", dest="no_cask", help="Skip upgrading casks")
75
+ add_bool_flag(parser, "--no-cleanup", dest="no_cleanup", help="Skip 'brew cleanup'")
76
+ add_bool_flag(parser, "--no-autoremove", dest="no_autoremove", help="Skip 'brew autoremove'")
77
+ add_bool_flag(parser, "--greedy", help="Pass --greedy to cask upgrade")
78
+ add_bool_flag(parser, "--doctor", help="Run 'brew doctor' at the very end")
79
+ args = parser.parse_args(argv)
80
+
81
+ require_binary("brew", hint="Install Homebrew first: https://brew.sh")
82
+
83
+ dry = args.dry_run
84
+ header_suffix = " ๐ŸŒต (dry run)" if dry else ""
85
+ note("โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•")
86
+ note(f"๐Ÿบ update-brew{header_suffix}")
87
+ note("โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•")
88
+
89
+ # 1. Refresh Homebrew itself and tap metadata
90
+ info("๐Ÿ“ก Updating Homebrew metadata...")
91
+ brew(["brew", "update"], dry_run=dry, echo=True)
92
+
93
+ # 2. Upgrade formulae
94
+ info("โฌ†๏ธ Upgrading formulae...")
95
+ brew(["brew", "upgrade"], dry_run=dry, dry_run_argv=["brew", "upgrade", "--dry-run"])
96
+
97
+ # 3. Upgrade casks (apps)
98
+ if args.no_cask:
99
+ note("โญ๏ธ Skipping cask upgrades (--no-cask)")
100
+ else:
101
+ info("๐Ÿ“ฆ Upgrading casks...")
102
+ cask_argv = ["brew", "upgrade", "--cask"]
103
+ if args.greedy:
104
+ cask_argv.append("--greedy")
105
+ brew(cask_argv, dry_run=dry, dry_run_argv=[*cask_argv, "--dry-run"])
106
+
107
+ # 4. Remove unused dependencies
108
+ if args.no_autoremove:
109
+ note("โญ๏ธ Skipping autoremove (--no-autoremove)")
110
+ else:
111
+ info("๐Ÿงน Removing unused dependencies...")
112
+ brew(
113
+ ["brew", "autoremove"],
114
+ dry_run=dry,
115
+ dry_run_argv=["brew", "autoremove", "--dry-run"],
116
+ )
117
+
118
+ # 5. Cleanup old versions + cache
119
+ if args.no_cleanup:
120
+ note("โญ๏ธ Skipping cleanup (--no-cleanup)")
121
+ else:
122
+ info("๐Ÿ—‘๏ธ Cleaning up old versions and cache...")
123
+ brew(
124
+ ["brew", "cleanup", "-s"],
125
+ dry_run=dry,
126
+ dry_run_argv=["brew", "cleanup", "--dry-run", "-s"],
127
+ )
128
+
129
+ # 6. Optional doctor pass - advisory, never fatal
130
+ if args.doctor:
131
+ info("๐Ÿฉบ Running brew doctor...")
132
+ completed = run(["brew", "doctor"], check=False)
133
+ if completed.returncode != 0:
134
+ warning("โš ๏ธ brew doctor reported issues (non-fatal)")
135
+
136
+ print()
137
+ note("โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€")
138
+ if dry:
139
+ log("๐Ÿ’ก Dry run complete. Nothing was actually changed.")
140
+ else:
141
+ success("๐ŸŽ‰ Homebrew is up to date and tidy! ๐Ÿบโœจ")
142
+ return 0
143
+
144
+
145
+ if __name__ == "__main__":
146
+ run_cli(main)