shellscripts 0.23.1__py3-none-any.whl

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. shell_scripts/__init__.py +5 -0
  2. shell_scripts/__main__.py +5 -0
  3. shell_scripts/commands/__init__.py +81 -0
  4. shell_scripts/commands/_dc_common.py +138 -0
  5. shell_scripts/commands/ai_install.py +453 -0
  6. shell_scripts/commands/bin_links.py +78 -0
  7. shell_scripts/commands/claude.py +56 -0
  8. shell_scripts/commands/clean.py +98 -0
  9. shell_scripts/commands/codex.py +107 -0
  10. shell_scripts/commands/copilot.py +54 -0
  11. shell_scripts/commands/dicom2jpg.py +98 -0
  12. shell_scripts/commands/dicomviewer.py +83 -0
  13. shell_scripts/commands/diff_cmd.py +50 -0
  14. shell_scripts/commands/doxygen_cmd.py +159 -0
  15. shell_scripts/commands/edit_cmd.py +50 -0
  16. shell_scripts/commands/gemini.py +54 -0
  17. shell_scripts/commands/kiro.py +54 -0
  18. shell_scripts/commands/opencode.py +54 -0
  19. shell_scripts/commands/pdf_crop.py +520 -0
  20. shell_scripts/commands/pdf_merge.py +180 -0
  21. shell_scripts/commands/pdf_split_by_format.py +243 -0
  22. shell_scripts/commands/pdf_split_by_toc.py +197 -0
  23. shell_scripts/commands/pdf_tiler_090.py +61 -0
  24. shell_scripts/commands/pdf_tiler_100.py +61 -0
  25. shell_scripts/commands/pdf_toc_clean.py +175 -0
  26. shell_scripts/commands/pi.py +61 -0
  27. shell_scripts/commands/req_cmd.py +362 -0
  28. shell_scripts/commands/tests_cmd.py +87 -0
  29. shell_scripts/commands/ubuntu_dark_theme.py +64 -0
  30. shell_scripts/commands/venv_cmd.py +82 -0
  31. shell_scripts/commands/video2h264.py +89 -0
  32. shell_scripts/commands/video2h265.py +87 -0
  33. shell_scripts/commands/view_cmd.py +50 -0
  34. shell_scripts/commands/vscode_cmd.py +42 -0
  35. shell_scripts/commands/vsinsider_cmd.py +42 -0
  36. shell_scripts/config.py +328 -0
  37. shell_scripts/core.py +324 -0
  38. shell_scripts/utils.py +455 -0
  39. shell_scripts/version_check.py +323 -0
  40. shellscripts-0.23.1.dist-info/METADATA +310 -0
  41. shellscripts-0.23.1.dist-info/RECORD +45 -0
  42. shellscripts-0.23.1.dist-info/WHEEL +5 -0
  43. shellscripts-0.23.1.dist-info/entry_points.txt +3 -0
  44. shellscripts-0.23.1.dist-info/licenses/LICENSE +674 -0
  45. shellscripts-0.23.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """@brief GNOME/Qt dark-theme configurator.
3
+
4
+ @details Conditionally executes available theme helper executables and validates
5
+ each executable immediately before invocation.
6
+ @satisfies REQ-022, REQ-055, REQ-056
7
+ """
8
+ import subprocess
9
+
10
+ from shell_scripts.utils import print_info, command_exists, print_error, require_commands
11
+
12
+ PROGRAM = "shellscripts"
13
+ DESCRIPTION = "Apply GNOME and Qt dark theme settings."
14
+
15
+
16
+ def print_help(version):
17
+ print(f"Usage: {PROGRAM} ubuntu-dark-theme ({version})")
18
+ print()
19
+ print("ubuntu-dark-theme options:")
20
+ print(" --help - Show this help message.")
21
+ print()
22
+ print("Applies Adwaita-dark GTK theme via gsettings, then launches")
23
+ print("gtk-chtheme, qt5ct, and qt6ct for further customization.")
24
+
25
+
26
+ def run(args):
27
+ """@brief Apply dark-theme settings with conditional executable checks.
28
+
29
+ @details For each available theme tool (`gsettings`, `gtk-chtheme`, `qt5ct`,
30
+ `qt6ct`), validates command executability before subprocess invocation.
31
+ @param args {list[str]} Unused command arguments.
32
+ @return {int} `0` on completion.
33
+ @satisfies REQ-022, REQ-055, REQ-056
34
+ """
35
+
36
+ print_info("Configure Adwaita-dark")
37
+
38
+ if command_exists("gsettings"):
39
+ require_commands("gsettings")
40
+ subprocess.run([
41
+ "gsettings", "set", "org.gnome.desktop.interface",
42
+ "gtk-theme", "Adwaita-dark",
43
+ ])
44
+ else:
45
+ print_error("gsettings not found.")
46
+
47
+ if command_exists("gtk-chtheme"):
48
+ require_commands("gtk-chtheme")
49
+ subprocess.run(["gtk-chtheme"])
50
+
51
+ import os
52
+ env5 = os.environ.copy()
53
+ env5["QT_QPA_PLATFORMTHEME"] = "qt5ct"
54
+ if command_exists("qt5ct"):
55
+ require_commands("qt5ct")
56
+ subprocess.run(["qt5ct"], env=env5)
57
+
58
+ env6 = os.environ.copy()
59
+ env6["QT_QPA_PLATFORMTHEME"] = "qt6ct"
60
+ if command_exists("qt6ct"):
61
+ require_commands("qt6ct")
62
+ subprocess.run(["qt6ct"], env=env6)
63
+
64
+ return 0
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python3
2
+ """@brief Virtual-environment recreation workflow with optional dependency install.
3
+
4
+ @details Ensures required Python executables are available for the active flow
5
+ before creating `.venv` and optionally running `pip install -r requirements.txt`.
6
+ @satisfies REQ-038, REQ-055, REQ-056
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import shutil
12
+ import subprocess
13
+
14
+ from shell_scripts.utils import (
15
+ require_project_root,
16
+ print_info,
17
+ print_success,
18
+ require_commands,
19
+ )
20
+
21
+ PROGRAM = "shellscripts"
22
+ DESCRIPTION = "Create or recreate Python virtual environment with requirements."
23
+
24
+
25
+ def print_help(version):
26
+ print(f"Usage: {PROGRAM} venv [options] ({version})")
27
+ print()
28
+ print("venv options:")
29
+ print(" --force - Force recreation even if .venv exists.")
30
+ print(" --help - Show this help message.")
31
+
32
+
33
+ def run(args):
34
+ """@brief Recreate virtual environment with executable pre-checks.
35
+
36
+ @details Validates `sys.executable` and flow-conditional `pip` executable
37
+ before corresponding subprocess invocations.
38
+ @param args {list[str]} Command arguments (`--force` accepted).
39
+ @return {int} `0` on successful execution.
40
+ @satisfies REQ-038, REQ-055, REQ-056
41
+ """
42
+
43
+ force = "--force" in args
44
+ require_commands(sys.executable)
45
+ project_root = require_project_root()
46
+ os.chdir(project_root)
47
+
48
+ print(f"Run on path: {project_root}")
49
+
50
+ venv_dir = project_root / ".venv"
51
+
52
+ if venv_dir.is_dir():
53
+ if force:
54
+ print_info("Removing old virtual environment...")
55
+ shutil.rmtree(venv_dir)
56
+ else:
57
+ print_info("Removing old virtual environment...")
58
+ shutil.rmtree(venv_dir)
59
+
60
+ print_info("Creating virtual environment...")
61
+ subprocess.run(
62
+ [sys.executable, "-m", "venv", str(venv_dir)],
63
+ check=True,
64
+ )
65
+ print_success("Virtual environment created.")
66
+
67
+ pip = str(venv_dir / "bin" / "pip")
68
+ req_file = project_root / "requirements.txt"
69
+
70
+ if req_file.exists():
71
+ require_commands(pip)
72
+ print_info("Installing python requirements...")
73
+ subprocess.run(
74
+ [pip, "install", "-r", str(req_file)],
75
+ stdout=subprocess.DEVNULL,
76
+ check=True,
77
+ )
78
+ print_success("Requirements installed.")
79
+ else:
80
+ print_info("No requirements.txt found, skipping pip install.")
81
+
82
+ return 0
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env python3
2
+ """@brief FFmpeg-based H.264 MP4 transcoder command.
3
+
4
+ @details Converts one input video to H.264/AAC MP4 using fixed FFmpeg
5
+ arguments required by CLI contract. Output path is generated by appending
6
+ `.mp4` to the input filename and preserving the input directory.
7
+ @satisfies REQ-057, REQ-055, REQ-056, REQ-064
8
+ """
9
+
10
+ import subprocess
11
+ from pathlib import Path
12
+
13
+ from shell_scripts.utils import print_error, require_commands
14
+
15
+ ## @var PROGRAM
16
+ # @brief CLI program identifier used in usage text.
17
+ # @satisfies DES-008
18
+ PROGRAM = "shellscripts"
19
+ ## @var DESCRIPTION
20
+ # @brief Command description exposed in global help index.
21
+ # @satisfies PRJ-002, DES-008, REQ-057
22
+ DESCRIPTION = "Convert one video to H.264 MP4 via ffmpeg."
23
+
24
+
25
+ def print_help(version):
26
+ """@brief Print command usage for `video2h264`.
27
+
28
+ @details Emits deterministic help text describing required positional input
29
+ and output naming semantics.
30
+ @param version {str} CLI version string for usage suffix.
31
+ @return {None} Writes help text to stdout.
32
+ @satisfies DES-008, REQ-057
33
+ """
34
+
35
+ print(f"Usage: {PROGRAM} video2h264 <input-video> ({version})")
36
+ print()
37
+ print("video2h264 options:")
38
+ print(" <input-video> - Input video file path (required).")
39
+ print(" --help - Show this help message.")
40
+ print()
41
+ print("Output path is generated as <input-video>.mp4 in the input directory.")
42
+
43
+
44
+ def run(args):
45
+ """@brief Execute H.264 transcode command with fixed FFmpeg parameters.
46
+
47
+ @details Validates input argument presence and file existence, then executes
48
+ `ffmpeg` using required libx264 profile, level, CRF, pixel format, and AAC
49
+ audio bitrate options through blocking subprocess invocation.
50
+ @param args {list[str]} Expected single positional input-video path.
51
+ @return {int} `1` on argument/validation failure; child return code otherwise.
52
+ @satisfies REQ-057, REQ-055, REQ-056, REQ-064
53
+ """
54
+
55
+ if len(args) != 1 or args[0].startswith("-"):
56
+ print_error("Input video file required.")
57
+ print_help("")
58
+ return 1
59
+
60
+ input_file = Path(args[0])
61
+ if not input_file.is_file():
62
+ print_error(f"File not found: {input_file}")
63
+ return 1
64
+
65
+ output_file = input_file.parent / f"{input_file.name}.mp4"
66
+ cmd = [
67
+ "ffmpeg",
68
+ "-i",
69
+ str(input_file),
70
+ "-c:v",
71
+ "libx264",
72
+ "-profile:v",
73
+ "high",
74
+ "-level",
75
+ "4.1",
76
+ "-crf",
77
+ "20",
78
+ "-pix_fmt",
79
+ "yuv420p",
80
+ "-c:a",
81
+ "aac",
82
+ "-b:a",
83
+ "192k",
84
+ str(output_file),
85
+ ]
86
+
87
+ require_commands(cmd[0])
88
+ result = subprocess.run(cmd)
89
+ return result.returncode
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """@brief FFmpeg-based H.265 MP4 transcoder command.
3
+
4
+ @details Converts one input video to H.265/AAC MP4 using fixed FFmpeg
5
+ arguments required by CLI contract. Output path is generated by appending
6
+ `.mp4` to the input filename and preserving the input directory.
7
+ @satisfies REQ-058, REQ-055, REQ-056, REQ-064
8
+ """
9
+
10
+ import subprocess
11
+ from pathlib import Path
12
+
13
+ from shell_scripts.utils import print_error, require_commands
14
+
15
+ ## @var PROGRAM
16
+ # @brief CLI program identifier used in usage text.
17
+ # @satisfies DES-008
18
+ PROGRAM = "shellscripts"
19
+ ## @var DESCRIPTION
20
+ # @brief Command description exposed in global help index.
21
+ # @satisfies PRJ-002, DES-008, REQ-058
22
+ DESCRIPTION = "Convert one video to H.265 MP4 via ffmpeg."
23
+
24
+
25
+ def print_help(version):
26
+ """@brief Print command usage for `video2h265`.
27
+
28
+ @details Emits deterministic help text describing required positional input
29
+ and output naming semantics.
30
+ @param version {str} CLI version string for usage suffix.
31
+ @return {None} Writes help text to stdout.
32
+ @satisfies DES-008, REQ-058
33
+ """
34
+
35
+ print(f"Usage: {PROGRAM} video2h265 <input-video> ({version})")
36
+ print()
37
+ print("video2h265 options:")
38
+ print(" <input-video> - Input video file path (required).")
39
+ print(" --help - Show this help message.")
40
+ print()
41
+ print("Output path is generated as <input-video>.mp4 in the input directory.")
42
+
43
+
44
+ def run(args):
45
+ """@brief Execute H.265 transcode command with fixed FFmpeg parameters.
46
+
47
+ @details Validates input argument presence and file existence, then executes
48
+ `ffmpeg` using required libx265 CRF, codec tag, pixel format, and AAC audio
49
+ bitrate options through blocking subprocess invocation.
50
+ @param args {list[str]} Expected single positional input-video path.
51
+ @return {int} `1` on argument/validation failure; child return code otherwise.
52
+ @satisfies REQ-058, REQ-055, REQ-056, REQ-064
53
+ """
54
+
55
+ if len(args) != 1 or args[0].startswith("-"):
56
+ print_error("Input video file required.")
57
+ print_help("")
58
+ return 1
59
+
60
+ input_file = Path(args[0])
61
+ if not input_file.is_file():
62
+ print_error(f"File not found: {input_file}")
63
+ return 1
64
+
65
+ output_file = input_file.parent / f"{input_file.name}.mp4"
66
+ cmd = [
67
+ "ffmpeg",
68
+ "-i",
69
+ str(input_file),
70
+ "-c:v",
71
+ "libx265",
72
+ "-crf",
73
+ "23",
74
+ "-tag:v",
75
+ "hvc1",
76
+ "-pix_fmt",
77
+ "yuv420p",
78
+ "-c:a",
79
+ "aac",
80
+ "-b:a",
81
+ "192k",
82
+ str(output_file),
83
+ ]
84
+
85
+ require_commands(cmd[0])
86
+ result = subprocess.run(cmd)
87
+ return result.returncode
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python3
2
+ """@brief MIME-based view command wrapper.
3
+
4
+ @details Exposes the `view` CLI command and delegates category-based executable
5
+ selection to shared `_dc_common.dispatch` logic.
6
+ @satisfies PRJ-003, DES-007, REQ-023, REQ-024
7
+ """
8
+
9
+ import sys
10
+
11
+ from shell_scripts.config import get_dispatch_profile
12
+ from shell_scripts.commands._dc_common import dispatch
13
+
14
+ PROGRAM = "shellscripts"
15
+ DESCRIPTION = "File viewer dispatcher by MIME type."
16
+
17
+
18
+ def print_help(version):
19
+ """@brief Render command help for `view`.
20
+
21
+ @details Prints usage, required file argument semantics, and argument
22
+ forwarding contract for the selected external viewer executable.
23
+ @param version {str} Version string appended in usage output.
24
+ @return {None} Writes help text to stdout.
25
+ @satisfies DES-008
26
+ """
27
+ print(f"Usage: {PROGRAM} view <file> [args...] ({version})")
28
+ print()
29
+ print("view options:")
30
+ print(" <file> - File to view (required).")
31
+ print(" Additional arguments are passed to the selected viewer.")
32
+ print(" --help - Show this help message.")
33
+
34
+
35
+ def run(args):
36
+ """@brief Execute MIME-routed view dispatch.
37
+
38
+ @details Validates that a file argument exists; on missing argument prints
39
+ error plus help and returns status code `2`; otherwise resolves runtime
40
+ dispatch profile and delegates by file category through shared `_dc_common`.
41
+ @param args {list[str]} CLI args where `args[0]` is file path.
42
+ @return {int} Return code `2` on missing file; otherwise delegated dispatch result.
43
+ @satisfies REQ-023, REQ-024
44
+ """
45
+ if not args:
46
+ print("Error: file argument required.", file=sys.stderr)
47
+ print_help("")
48
+ return 2
49
+ category_cmds, fallback = get_dispatch_profile("view")
50
+ return dispatch(category_cmds, fallback, args[0], args[1:])
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env python3
2
+ """@brief VS Code launcher in project context with Codex integration.
3
+
4
+ @details Resolves project root, configures `CODEX_HOME`, validates VS Code
5
+ executable availability, and performs blocking subprocess invocation.
6
+ @satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
7
+ """
8
+
9
+ import os
10
+ import subprocess
11
+
12
+ from shell_scripts.utils import require_project_root, require_commands
13
+
14
+ PROGRAM = "shellscripts"
15
+ DESCRIPTION = "Open VS Code in the project root with Codex integration."
16
+
17
+
18
+ def print_help(version):
19
+ print(f"Usage: {PROGRAM} vscode [args...] ({version})")
20
+ print()
21
+ print("vscode options:")
22
+ print(" [args...] - Arguments passed through to VS Code.")
23
+ print(" --help - Show this help message.")
24
+
25
+
26
+ def run(args):
27
+ """@brief Launch VS Code after executable validation.
28
+
29
+ @details Sets `CODEX_HOME`, validates executable availability for VS Code
30
+ binary, and executes the command with project-root working directory.
31
+ @param args {list[str]} Additional CLI args forwarded to VS Code.
32
+ @return {int} Child process return code.
33
+ @satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
34
+ """
35
+
36
+ project_root = require_project_root()
37
+ codex_home = str(project_root / ".codex")
38
+ os.environ["CODEX_HOME"] = codex_home
39
+ cmd = ["/usr/share/code/bin/code"] + args + [str(project_root)]
40
+ require_commands(cmd[0])
41
+ result = subprocess.run(cmd, cwd=project_root)
42
+ return result.returncode
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env python3
2
+ """@brief VS Code Insiders launcher in project context with Codex integration.
3
+
4
+ @details Resolves project root, configures `CODEX_HOME`, validates VS Code
5
+ Insiders executable availability, and performs blocking subprocess invocation.
6
+ @satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
7
+ """
8
+
9
+ import os
10
+ import subprocess
11
+
12
+ from shell_scripts.utils import require_project_root, require_commands
13
+
14
+ PROGRAM = "shellscripts"
15
+ DESCRIPTION = "Open VS Code Insiders in the project root with Codex integration."
16
+
17
+
18
+ def print_help(version):
19
+ print(f"Usage: {PROGRAM} vsinsider [args...] ({version})")
20
+ print()
21
+ print("vsinsider options:")
22
+ print(" [args...] - Arguments passed through to VS Code Insiders.")
23
+ print(" --help - Show this help message.")
24
+
25
+
26
+ def run(args):
27
+ """@brief Launch VS Code Insiders after executable validation.
28
+
29
+ @details Sets `CODEX_HOME`, validates executable availability for VS Code
30
+ Insiders binary, and executes the command with project-root working directory.
31
+ @param args {list[str]} Additional CLI args forwarded to VS Code Insiders.
32
+ @return {int} Child process return code.
33
+ @satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
34
+ """
35
+
36
+ project_root = require_project_root()
37
+ codex_home = str(project_root / ".codex")
38
+ os.environ["CODEX_HOME"] = codex_home
39
+ cmd = ["/usr/share/code-insiders/bin/code-insiders"] + args + [str(project_root)]
40
+ require_commands(cmd[0])
41
+ result = subprocess.run(cmd, cwd=project_root)
42
+ return result.returncode