machineconfig 5.37__py3-none-any.whl → 5.38__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.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/script_execution.py +0 -1
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +0 -2
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +12 -12
- machineconfig/jobs/installer/installer_data.json +53 -2
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -3
- machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +3 -0
- machineconfig/scripts/python/ai/solutions/generic.py +1 -0
- machineconfig/scripts/python/croshell.py +5 -2
- machineconfig/scripts/python/devops.py +4 -21
- machineconfig/scripts/python/devops_helpers/cli_nw.py +2 -1
- machineconfig/scripts/python/devops_helpers/cli_repos.py +1 -3
- machineconfig/scripts/python/devops_helpers/cli_self.py +6 -6
- machineconfig/scripts/python/devops_helpers/cli_share_server.py +109 -0
- machineconfig/scripts/python/devops_helpers/cli_terminal.py +35 -23
- machineconfig/scripts/python/devops_helpers/devops_update_repos.py +63 -44
- machineconfig/scripts/python/devops_helpers/themes/choose_pwsh_theme.ps1 +16 -15
- machineconfig/scripts/python/devops_navigator.py +183 -80
- machineconfig/scripts/python/helpers_fire/{fire_gemini.py → agentic_frameworks/fire_gemini.py} +12 -9
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +43 -0
- machineconfig/scripts/python/helpers_fire/fire_agents_help_launch.py +4 -4
- machineconfig/scripts/python/helpers_fire/template.ps1 +29 -0
- machineconfig/scripts/python/interactive.py +3 -2
- machineconfig/scripts/python/nw/mount_nw_drive +1 -2
- machineconfig/scripts/windows/mounts/share_nfs.ps1 +0 -0
- machineconfig/settings/lf/linux/lfrc +0 -2
- machineconfig/settings/lf/windows/lfrc +0 -4
- machineconfig/settings/shells/bash/commands.sh +24 -0
- machineconfig/settings/shells/bash/init.sh +5 -0
- machineconfig/settings/shells/pwsh/commands.ps1 +33 -0
- machineconfig/settings/shells/pwsh/init.ps1 +4 -0
- machineconfig/setup_windows/machineconfig.ps1 +2 -0
- machineconfig/utils/files/dbms.py +4 -1
- machineconfig/utils/installer_utils/installer.py +12 -0
- machineconfig/utils/installer_utils/installer_abc.py +26 -9
- machineconfig/utils/installer_utils/installer_class.py +1 -1
- machineconfig/utils/io.py +0 -18
- machineconfig/utils/scheduler.py +3 -4
- {machineconfig-5.37.dist-info → machineconfig-5.38.dist-info}/METADATA +7 -4
- {machineconfig-5.37.dist-info → machineconfig-5.38.dist-info}/RECORD +59 -82
- machineconfig/jobs/windows/start_terminal.ps1 +0 -6
- machineconfig/jobs/windows/startup_file.cmd +0 -2
- machineconfig/scripts/cloud/init.sh +0 -105
- machineconfig/scripts/linux/agents +0 -2
- machineconfig/scripts/linux/cloud +0 -2
- machineconfig/scripts/linux/croshell +0 -3
- machineconfig/scripts/linux/devops +0 -2
- machineconfig/scripts/linux/fire +0 -2
- machineconfig/scripts/linux/ftpx +0 -2
- machineconfig/scripts/linux/kill_process +0 -2
- machineconfig/scripts/linux/sessions +0 -2
- machineconfig/scripts/linux/start_terminals +0 -3
- machineconfig/scripts/windows/agents.ps1 +0 -1
- machineconfig/scripts/windows/cloud.ps1 +0 -1
- machineconfig/scripts/windows/croshell.ps1 +0 -1
- machineconfig/scripts/windows/devops.ps1 +0 -1
- machineconfig/scripts/windows/fire.ps1 +0 -1
- machineconfig/scripts/windows/ftpx.ps1 +0 -1
- machineconfig/scripts/windows/gpt.ps1 +0 -1
- machineconfig/scripts/windows/grep.ps1 +0 -2
- machineconfig/scripts/windows/kill_process.ps1 +0 -1
- machineconfig/scripts/windows/nano.ps1 +0 -3
- machineconfig/scripts/windows/scheduler.ps1 +0 -1
- machineconfig/scripts/windows/sessions.ps1 +0 -1
- machineconfig/scripts/windows/snapshot.ps1 +0 -1
- machineconfig/scripts/windows/start_terminals.ps1 +0 -1
- machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
- machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
- /machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
- /machineconfig/scripts/linux/{share_smb → other/share_smb} +0 -0
- /machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
- /machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
- /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_fire/agentic_frameworks/__init__.py} +0 -0
- /machineconfig/scripts/python/helpers_fire/{fire_crush.json → agentic_frameworks/fire_crush.json} +0 -0
- /machineconfig/scripts/python/helpers_fire/{fire_crush.py → agentic_frameworks/fire_crush.py} +0 -0
- /machineconfig/scripts/python/helpers_fire/{fire_cursor_agents.py → agentic_frameworks/fire_cursor_agents.py} +0 -0
- /machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +0 -0
- /machineconfig/scripts/windows/{pomodoro.ps1 → mounts/pomodoro.ps1} +0 -0
- /machineconfig/scripts/windows/{reload_path.ps1 → mounts/reload_path.ps1} +0 -0
- /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
- /machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -0
- /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
- {machineconfig-5.37.dist-info → machineconfig-5.38.dist-info}/WHEEL +0 -0
- {machineconfig-5.37.dist-info → machineconfig-5.38.dist-info}/entry_points.txt +0 -0
- {machineconfig-5.37.dist-info → machineconfig-5.38.dist-info}/top_level.txt +0 -0
|
@@ -169,7 +169,6 @@
|
|
|
169
169
|
# if params.session_name != "":
|
|
170
170
|
# if platform.system() in ["Linux", "Darwin"]:
|
|
171
171
|
# Terminal().run(f"""zellij --session {params.session_name} action new-tab --name results """)
|
|
172
|
-
# # --layout ~/code/machineconfig/src/machineconfig/settings/zellij/layouts/d.kdl --cwd {res_folder.as_posix()}
|
|
173
172
|
# Terminal().run(f"""zellij --session {params.session_name} action write-chars "cd {res_folder.as_posix()};lf" """)
|
|
174
173
|
# elif platform.system() == "Windows":
|
|
175
174
|
# Terminal().run(f"""wt --window {params.session_name} new-tab --title results -startingDirectory {res_folder.as_posix()} lf """)
|
|
@@ -51,12 +51,10 @@ class ProcessMonitor:
|
|
|
51
51
|
return {"status": "unknown", "error": f"Tab '{tab_name}' not found in layout config", "running": False, "command": "", "tab_name": tab_name, "processes": [], "remote": self.remote_executor.remote_name}
|
|
52
52
|
|
|
53
53
|
command = tab_config["command"]
|
|
54
|
-
|
|
55
54
|
try:
|
|
56
55
|
check_script = self._create_process_check_script(command)
|
|
57
56
|
remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
|
|
58
57
|
result = self.remote_executor.run_command(remote_cmd, timeout=15)
|
|
59
|
-
|
|
60
58
|
if result.returncode == 0:
|
|
61
59
|
try:
|
|
62
60
|
matching_processes = json.loads(result.stdout.strip())
|
|
@@ -25,14 +25,14 @@ nerd_fonts: InstallerData = {
|
|
|
25
25
|
"doc": "Nerd Fonts is a project that patches developer targeted fonts with a high number of glyphs (icons)",
|
|
26
26
|
"fileNamePattern": {
|
|
27
27
|
"amd64": {
|
|
28
|
-
"windows": "
|
|
29
|
-
"linux": "
|
|
30
|
-
"macos": "
|
|
28
|
+
"windows": "CascadiaCode.zip",
|
|
29
|
+
"linux": "CascadiaCode.zip",
|
|
30
|
+
"macos": "CascadiaCode.zip",
|
|
31
31
|
},
|
|
32
32
|
"arm64": {
|
|
33
|
-
"windows": "
|
|
34
|
-
"linux": "
|
|
35
|
-
"macos": "
|
|
33
|
+
"windows": "CascadiaCode.zip",
|
|
34
|
+
"linux": "CascadiaCode.zip",
|
|
35
|
+
"macos": "CascadiaCode.zip",
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -40,10 +40,10 @@ nerd_fonts: InstallerData = {
|
|
|
40
40
|
|
|
41
41
|
# Patterns to match any installed variant (NF, Nerd Font, Mono, Propo, style weights) of Cascadia/Caskaydia
|
|
42
42
|
# We'll compile them at runtime for flexibility. Keep them simple to avoid false positives.
|
|
43
|
-
REQUIRED_FONT_PATTERNS: tuple[str, ...] = (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
43
|
+
# REQUIRED_FONT_PATTERNS: tuple[str, ...] = (
|
|
44
|
+
# r"caskaydiacove.*(nf|nerd ?font)",
|
|
45
|
+
# r"cascadiacode.*(nf|nerd ?font)"
|
|
46
|
+
# )
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
console = Console()
|
|
@@ -92,7 +92,7 @@ def _missing_required_fonts(installed_fonts: Iterable[str]) -> list[str]:
|
|
|
92
92
|
|
|
93
93
|
installed_norm = [f.lower().replace(" ", "") for f in installed_fonts]
|
|
94
94
|
missing: list[str] = []
|
|
95
|
-
for pattern in
|
|
95
|
+
for pattern in ["cascadiacode*"]:
|
|
96
96
|
regex = re.compile(pattern)
|
|
97
97
|
if not any(regex.search(f) for f in installed_norm):
|
|
98
98
|
missing.append(pattern)
|
|
@@ -136,7 +136,7 @@ def install_nerd_fonts() -> None:
|
|
|
136
136
|
file = PathExtended.tmpfile(suffix=".ps1")
|
|
137
137
|
file.parent.mkdir(parents=True, exist_ok=True)
|
|
138
138
|
|
|
139
|
-
raw_content = LIBRARY_ROOT.joinpath("
|
|
139
|
+
raw_content = LIBRARY_ROOT.joinpath("jobs/installer/pwsh_scripts/install_fonts.ps1").read_text(encoding="utf-8").replace(r".\fonts-to-be-installed", str(folder))
|
|
140
140
|
# PowerShell 5.1 can choke on certain unicode chars in some locales; keep ASCII only.
|
|
141
141
|
content = "".join(ch for ch in raw_content if ord(ch) < 128)
|
|
142
142
|
file.write_text(content, encoding="utf-8")
|
|
@@ -188,6 +188,40 @@
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
},
|
|
191
|
+
{
|
|
192
|
+
"appName": "croc",
|
|
193
|
+
"repoURL": "https://github.com/schollz/croc",
|
|
194
|
+
"doc": "🦎 Easily and securely send things from one computer to another",
|
|
195
|
+
"fileNamePattern": {
|
|
196
|
+
"amd64": {
|
|
197
|
+
"linux": "croc_{version}_Linux-64bit.tar.gz",
|
|
198
|
+
"windows": "croc_{version}_Windows-64bit.zip",
|
|
199
|
+
"macos": "croc_{version}_macOS-64bit.tar.gz"
|
|
200
|
+
},
|
|
201
|
+
"arm64": {
|
|
202
|
+
"linux": "croc_{version}_Linux-ARM64.tar.gz",
|
|
203
|
+
"windows": null,
|
|
204
|
+
"macos": "croc_{version}_macOS-ARM64.tar.gz"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"appName": "wormhole-rs",
|
|
210
|
+
"repoURL": "https://github.com/magic-wormhole/magic-wormhole.rs",
|
|
211
|
+
"doc": "🐛 Get things from one computer to another, safely (Rust implementation)",
|
|
212
|
+
"fileNamePattern": {
|
|
213
|
+
"amd64": {
|
|
214
|
+
"linux": "magic-wormhole-cli-x86_64-unknown-linux-gnu.tgz",
|
|
215
|
+
"windows": "magic-wormhole-cli-x86_64-pc-windows-gnu.tgz",
|
|
216
|
+
"macos": "magic-wormhole-cli-aarch64-apple-darwin.tgz"
|
|
217
|
+
},
|
|
218
|
+
"arm64": {
|
|
219
|
+
"linux": null,
|
|
220
|
+
"windows": null,
|
|
221
|
+
"macos": null
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
},
|
|
191
225
|
{
|
|
192
226
|
"appName": "easy-sharing",
|
|
193
227
|
"repoURL": "CMD",
|
|
@@ -1328,9 +1362,9 @@
|
|
|
1328
1362
|
}
|
|
1329
1363
|
},
|
|
1330
1364
|
{
|
|
1331
|
-
"appName": "
|
|
1365
|
+
"appName": "bw",
|
|
1332
1366
|
"repoURL": "CMD",
|
|
1333
|
-
"doc": "🔐
|
|
1367
|
+
"doc": "🔐 bitwarden is a password manager.",
|
|
1334
1368
|
"fileNamePattern": {
|
|
1335
1369
|
"amd64": {
|
|
1336
1370
|
"linux": "npm install -g @bitwarden/cli",
|
|
@@ -1752,6 +1786,23 @@
|
|
|
1752
1786
|
}
|
|
1753
1787
|
}
|
|
1754
1788
|
},
|
|
1789
|
+
{
|
|
1790
|
+
"appName": "docker",
|
|
1791
|
+
"repoURL": "CMD",
|
|
1792
|
+
"doc": "🐳 Docker is an open platform for developing, shipping, and running applications.",
|
|
1793
|
+
"fileNamePattern": {
|
|
1794
|
+
"amd64": {
|
|
1795
|
+
"linux": "docker.sh",
|
|
1796
|
+
"macos": "docker.sh",
|
|
1797
|
+
"windows": null
|
|
1798
|
+
},
|
|
1799
|
+
"arm64": {
|
|
1800
|
+
"linux": "docker.sh",
|
|
1801
|
+
"macos": "docker.sh",
|
|
1802
|
+
"windows": null
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
},
|
|
1755
1806
|
{
|
|
1756
1807
|
"appName": "lazydocker",
|
|
1757
1808
|
"repoURL": "https://github.com/jesseduffield/lazydocker",
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
# winget install Microsoft.VC++2015-2022Redist-x86
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
Set-Location C:
|
|
10
|
-
python -m pip install --global-option=build_ext --global-option="-IC:\Program Files\Graphviz\include" --global-option="-LC:\Program Files\Graphviz\lib" pygraphviz
|
|
8
|
+
uv pip install --global-option=build_ext --global-option="-IC:\Program Files\Graphviz\include" --global-option="-LC:\Program Files\Graphviz\lib" pygraphviz
|
|
11
9
|
# not including the options as above (from https://pygraphviz.github.io/documentation/stable/install.html)
|
|
12
10
|
# would result in an error like this: pygraphviz/graphviz_wrap.c(2711): fatal error C1083: Cannot open include file: 'graphviz/cgraph.h': No such file or directory
|
|
13
11
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# https://temp.sh/
|
|
2
3
|
# 📤 CLOUD FILE SHARING SCRIPT 📤
|
|
3
4
|
# This script uploads files or directories to transfer.sh for easy sharing
|
|
4
5
|
# Usage: share_cloud <file|directory> or command | share_cloud <file_name>
|
|
@@ -14,6 +15,8 @@ if [ $# -eq 0 ]; then
|
|
|
14
15
|
return 1
|
|
15
16
|
fi
|
|
16
17
|
|
|
18
|
+
# https://temp.sh/
|
|
19
|
+
|
|
17
20
|
# Process the input
|
|
18
21
|
if tty -s; then
|
|
19
22
|
# Direct file/directory upload mode
|
|
@@ -46,6 +46,7 @@ console = Console()
|
|
|
46
46
|
p = PathExtended(r'{path}').absolute()
|
|
47
47
|
try:
|
|
48
48
|
from machineconfig.utils.files.read import Read
|
|
49
|
+
from machineconfig.utils.accessories import pprint
|
|
49
50
|
dat = Read.read(p)
|
|
50
51
|
if isinstance(dat, dict):
|
|
51
52
|
panel_title = f"📄 File Data: {{p.name}}"
|
|
@@ -64,12 +65,12 @@ except Exception as e:
|
|
|
64
65
|
def main(
|
|
65
66
|
python: Annotated[bool, typer.Option("--python", "-p", help="flag to use python over IPython.")] = False,
|
|
66
67
|
fzf: Annotated[bool, typer.Option("--fzf", "-F", help="search with fuzzy finder for python scripts and run them")] = False,
|
|
67
|
-
ve: Annotated[Optional[str], typer.Option("--ve", "-v", help="virtual enviroment to use, defaults to activated ve, if existed, else ve.")] = None,
|
|
68
68
|
profile: Annotated[Optional[str], typer.Option("--profile", "-P", help="ipython profile to use, defaults to default profile.")] = None,
|
|
69
69
|
read: Annotated[str, typer.Option("--read", "-r", help="read a binary file.")] = "",
|
|
70
70
|
jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
|
|
71
71
|
streamlit_viewer: Annotated[bool, typer.Option("--stViewer", "-s", help="view in streamlit app")] = False,
|
|
72
72
|
visidata: Annotated[bool, typer.Option("--visidata", "-V", help="open data file in visidata")] = False,
|
|
73
|
+
local: Annotated[bool, typer.Option("--local", "-l", help="run in local mode, not in virtual env.")]= False,
|
|
73
74
|
) -> None:
|
|
74
75
|
# ==================================================================================
|
|
75
76
|
# flags processing
|
|
@@ -141,7 +142,9 @@ from pathlib import Path
|
|
|
141
142
|
else:
|
|
142
143
|
if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
|
|
143
144
|
else: profile = ""
|
|
144
|
-
|
|
145
|
+
if local: ve_line = "--project $HOME/code/machineconfig"
|
|
146
|
+
else: ve_line = "--with machineconfig[plot]"
|
|
147
|
+
fire_line = f"uv run --python 3.13 {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
|
|
145
148
|
|
|
146
149
|
from machineconfig.utils.code import run_shell_script
|
|
147
150
|
run_shell_script(fire_line, clean_env=False)
|
|
@@ -5,7 +5,7 @@ from typing import Optional
|
|
|
5
5
|
|
|
6
6
|
import machineconfig.scripts.python.devops_helpers.cli_repos as cli_repos
|
|
7
7
|
import machineconfig.scripts.python.devops_helpers.cli_config as cli_config
|
|
8
|
-
from machineconfig.scripts.python.devops_helpers.cli_self import
|
|
8
|
+
from machineconfig.scripts.python.devops_helpers.cli_self import cli_app as cli_app
|
|
9
9
|
import machineconfig.scripts.python.devops_helpers.cli_data as cli_data
|
|
10
10
|
import machineconfig.scripts.python.devops_helpers.cli_nw as cli_network
|
|
11
11
|
|
|
@@ -21,29 +21,12 @@ def install( which: Optional[str] = typer.Option(None, "--which", "-w", help="Co
|
|
|
21
21
|
installer_entry_point.main(which=which, group=group, interactive=interactive)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
app.add_typer(cli_repos.app, name="repos"
|
|
24
|
+
app.add_typer(cli_repos.app, name="repos")
|
|
25
25
|
app.add_typer(cli_config.config_apps, name="config")
|
|
26
26
|
app.add_typer(cli_data.app_data, name="data")
|
|
27
|
-
app.add_typer(
|
|
27
|
+
app.add_typer(cli_app, name="self")
|
|
28
28
|
app.add_typer(cli_network.nw_apps, name="network")
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# @app.command()
|
|
34
|
-
# def scheduler():
|
|
35
|
-
# """⏰ SCHEDULER"""
|
|
36
|
-
# # from machineconfig.scripts.python.scheduler import main as helper
|
|
37
|
-
# # helper()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# @app.command()
|
|
42
|
-
# def scheduler():
|
|
43
|
-
# """⏰ SCHEDULER"""
|
|
44
|
-
# # from machineconfig.scripts.python.scheduler import main as helper
|
|
45
|
-
# # helper()
|
|
46
|
-
|
|
47
|
-
|
|
48
31
|
if __name__ == "__main__":
|
|
49
|
-
|
|
32
|
+
app()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import machineconfig.scripts.python.devops_helpers.cli_terminal as cli_terminal
|
|
3
|
+
import machineconfig.scripts.python.devops_helpers.cli_share_server as cli_share_server
|
|
3
4
|
import typer
|
|
4
5
|
from typing import Optional
|
|
5
6
|
|
|
@@ -7,7 +8,7 @@ nw_apps = typer.Typer(help="🔐 Network subcommands", no_args_is_help=True)
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
nw_apps.command(name="share-terminal", help="📡 Share terminal via web browser")(cli_terminal.main)
|
|
10
|
-
|
|
11
|
+
nw_apps.command(name="share-server", help="🌐 Start local/global server to share files/folders via web browser", no_args_is_help=True)(cli_share_server.main)
|
|
11
12
|
|
|
12
13
|
@nw_apps.command()
|
|
13
14
|
def install_ssh_server():
|
|
@@ -8,7 +8,6 @@ in the event that username@github.com is not mentioned in the remote url.
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from typing import Annotated, Optional
|
|
10
10
|
import typer
|
|
11
|
-
from git import Repo, InvalidGitRepositoryError
|
|
12
11
|
from machineconfig.scripts.python.helpers_repos.secure_repo import main as secure_repo_main
|
|
13
12
|
|
|
14
13
|
|
|
@@ -26,7 +25,6 @@ CloudOption = Annotated[Optional[str], typer.Option("--cloud", "-c", help="☁
|
|
|
26
25
|
def push(directory: DirectoryArgument = None, recursive: RecursiveOption = False, no_sync: NoSyncOption = False) -> None:
|
|
27
26
|
"""🚀 Push changes across repositories."""
|
|
28
27
|
from machineconfig.scripts.python.repos_helpers.entrypoint import git_operations
|
|
29
|
-
|
|
30
28
|
git_operations(directory, pull=False, commit=False, push=True, recursive=recursive, no_sync=no_sync)
|
|
31
29
|
|
|
32
30
|
|
|
@@ -143,7 +141,7 @@ def cleanup(repo: DirectoryArgument = None, recursive: RecursiveOption = False)
|
|
|
143
141
|
repo = Path.cwd().as_posix()
|
|
144
142
|
|
|
145
143
|
arg_path = Path(repo).expanduser().absolute()
|
|
146
|
-
|
|
144
|
+
from git import Repo, InvalidGitRepositoryError
|
|
147
145
|
if not recursive:
|
|
148
146
|
# Check if the directory is a git repo
|
|
149
147
|
try:
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
|
|
2
2
|
import typer
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
cli_app = typer.Typer(help="🔄 SELF operations subcommands", no_args_is_help=True)
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
@
|
|
7
|
+
@cli_app.command()
|
|
8
8
|
def update():
|
|
9
9
|
"""🔄 UPDATE essential repos"""
|
|
10
10
|
import machineconfig.scripts.python.devops_helpers.devops_update_repos as helper
|
|
11
11
|
helper.main()
|
|
12
|
-
@
|
|
12
|
+
@cli_app.command()
|
|
13
13
|
def interactive():
|
|
14
14
|
"""🤖 INTERACTIVE configuration of machine."""
|
|
15
15
|
from machineconfig.scripts.python.interactive import main
|
|
16
16
|
main()
|
|
17
|
-
@
|
|
17
|
+
@cli_app.command()
|
|
18
18
|
def status():
|
|
19
19
|
"""📊 STATUS of machine, shell profile, apps, symlinks, dotfiles, etc."""
|
|
20
20
|
import machineconfig.scripts.python.devops_helpers.devops_status as helper
|
|
21
21
|
helper.main()
|
|
22
|
-
@
|
|
22
|
+
@cli_app.command()
|
|
23
23
|
def clone():
|
|
24
24
|
"""📋 CLONE machienconfig locally and incorporate to shell profile for faster execution and nightly updates."""
|
|
25
25
|
import platform
|
|
@@ -33,7 +33,7 @@ def clone():
|
|
|
33
33
|
create_default_shell_profile(method="reference")
|
|
34
34
|
run_shell_script(MACHINECONFIG.read_text(encoding="utf-8"))
|
|
35
35
|
|
|
36
|
-
@
|
|
36
|
+
@cli_app.command()
|
|
37
37
|
def navigate():
|
|
38
38
|
"""📚 NAVIGATE command structure with TUI"""
|
|
39
39
|
from machineconfig.scripts.python.devops_navigator import main
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Optional, Annotated
|
|
3
|
+
import typer
|
|
4
|
+
# import typer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def display_share_url(local_ip_v4: str, port: int, protocol: str = "http") -> None:
|
|
9
|
+
"""Display a flashy, unmissable share URL announcement."""
|
|
10
|
+
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
from rich.panel import Panel
|
|
13
|
+
from rich.text import Text
|
|
14
|
+
from rich.align import Align
|
|
15
|
+
console = Console()
|
|
16
|
+
|
|
17
|
+
# Create the main message with styling
|
|
18
|
+
url_text = Text(f"{protocol}://{local_ip_v4}:{port}", style="bold bright_cyan underline")
|
|
19
|
+
message = Text.assemble(
|
|
20
|
+
("🚀 ", "bright_red"),
|
|
21
|
+
("Share server is now accessible at: ", "bright_white bold"),
|
|
22
|
+
url_text,
|
|
23
|
+
(" 🚀", "bright_red")
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Create a fancy panel with borders and styling
|
|
27
|
+
panel = Panel(
|
|
28
|
+
Align.center(message),
|
|
29
|
+
title="[bold bright_green]🌐 SHARE SERVER READY 🌐[/bold bright_green]",
|
|
30
|
+
subtitle="[italic bright_yellow]⚡ Click the link above to access your shared files! ⚡[/italic bright_yellow]",
|
|
31
|
+
border_style="bright_magenta",
|
|
32
|
+
padding=(1, 2),
|
|
33
|
+
expand=False
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Print with extra spacing and attention-grabbing elements
|
|
37
|
+
console.print(panel)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def main(
|
|
41
|
+
path: Annotated[str, typer.Argument(help="Path to the file or directory to share")],
|
|
42
|
+
port: Annotated[Optional[int], typer.Option("--port", "-p", help="Port to run the share server on (default: 8080)")] = None,
|
|
43
|
+
username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for share access (default: current user)")] = None,
|
|
44
|
+
password: Annotated[Optional[str], typer.Option("--password", "-w", help="Password for share access (default: from ~/dotfiles/creds/passwords/quick_password)")] = None,
|
|
45
|
+
over_internet: Annotated[bool, typer.Option("--over-internet", "-i", help="Expose the share server over the internet using ngrok")] = False
|
|
46
|
+
) -> None:
|
|
47
|
+
from machineconfig.utils.installer_utils.installer import install_if_missing
|
|
48
|
+
install_if_missing("ezshare")
|
|
49
|
+
if over_internet: install_if_missing("ngrok")
|
|
50
|
+
|
|
51
|
+
if username is None:
|
|
52
|
+
import getpass
|
|
53
|
+
username = getpass.getuser()
|
|
54
|
+
if password is None:
|
|
55
|
+
pwd_path = Path.home().joinpath("dotfiles/creds/passwords/quick_password")
|
|
56
|
+
if pwd_path.exists():
|
|
57
|
+
password = pwd_path.read_text(encoding="utf-8").strip()
|
|
58
|
+
else:
|
|
59
|
+
raise ValueError("Password not provided and default password file does not exist.")
|
|
60
|
+
|
|
61
|
+
if port is None:
|
|
62
|
+
port = 8080 # Default port for ezshare
|
|
63
|
+
|
|
64
|
+
import socket
|
|
65
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
66
|
+
s.connect(('8.8.8.8',80))
|
|
67
|
+
local_ip_v4 = s.getsockname()[0]
|
|
68
|
+
s.close()
|
|
69
|
+
|
|
70
|
+
# Display the flashy share announcement
|
|
71
|
+
protocol = "http"
|
|
72
|
+
display_share_url(local_ip_v4, port, protocol)
|
|
73
|
+
import subprocess
|
|
74
|
+
import time
|
|
75
|
+
# Build ezshare command
|
|
76
|
+
ezshare_cmd = f"ezshare --port {port} --username {username} --password {password} {path}"
|
|
77
|
+
ezshare_process = subprocess.Popen(ezshare_cmd, shell=True)
|
|
78
|
+
processes = [ezshare_process]
|
|
79
|
+
|
|
80
|
+
if over_internet:
|
|
81
|
+
ngrok_process = subprocess.Popen(f"ngrok http {port}", shell=True)
|
|
82
|
+
processes.append(ngrok_process)
|
|
83
|
+
time.sleep(3)
|
|
84
|
+
try:
|
|
85
|
+
import requests
|
|
86
|
+
response = requests.get("http://localhost:4040/api/tunnels")
|
|
87
|
+
data = response.json()
|
|
88
|
+
public_url = data['tunnels'][0]['public_url']
|
|
89
|
+
print(f"🌐 Ngrok tunnel ready: {public_url}")
|
|
90
|
+
except Exception as e:
|
|
91
|
+
print(f"Could not retrieve ngrok URL: {e}")
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
while True:
|
|
95
|
+
print("Share server is running. Press Ctrl+C to stop.")
|
|
96
|
+
time.sleep(2)
|
|
97
|
+
except KeyboardInterrupt:
|
|
98
|
+
print("\nTerminating processes...")
|
|
99
|
+
for p in processes:
|
|
100
|
+
p.terminate()
|
|
101
|
+
p.wait()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def main_with_parser():
|
|
105
|
+
typer.run(main)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
pass
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
from pathlib import Path
|
|
4
2
|
from typing import Optional, Annotated
|
|
5
3
|
import typer
|
|
4
|
+
import subprocess
|
|
5
|
+
import time
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -49,19 +49,6 @@ def display_terminal_url(local_ip_v4: str, port: int, protocol: str = "http") ->
|
|
|
49
49
|
# console.print("🔥" * 60 + "\n", style="bright_red bold")
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def install_ttyd():
|
|
53
|
-
# uv run --python 3.13 --with machineconfig devops install ttyd
|
|
54
|
-
from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
|
|
55
|
-
exists = check_tool_exists("ttyd")
|
|
56
|
-
if exists:
|
|
57
|
-
print("✅ ttyd is already installed.")
|
|
58
|
-
return
|
|
59
|
-
print("⏳ ttyd not found. Installing...")
|
|
60
|
-
from machineconfig.utils.installer_utils.installer import main
|
|
61
|
-
main(which="ttyd")
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
52
|
def main(
|
|
66
53
|
port: Annotated[Optional[int], typer.Option("--port", "-p", help="Port to run the terminal server on (default: 7681)")] = None,
|
|
67
54
|
username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for terminal access (default: current user)")] = None,
|
|
@@ -70,9 +57,13 @@ def main(
|
|
|
70
57
|
ssl: Annotated[bool, typer.Option("--ssl", "-S", help="Enable SSL")] = False,
|
|
71
58
|
ssl_cert: Annotated[Optional[str], typer.Option("--ssl-cert", "-C", help="SSL certificate file path")] = None,
|
|
72
59
|
ssl_key: Annotated[Optional[str], typer.Option("--ssl-key", "-K", help="SSL key file path")] = None,
|
|
73
|
-
ssl_ca: Annotated[Optional[str], typer.Option("--ssl-ca", "-A", help="SSL CA file path for client certificate verification")] = None
|
|
60
|
+
ssl_ca: Annotated[Optional[str], typer.Option("--ssl-ca", "-A", help="SSL CA file path for client certificate verification")] = None,
|
|
61
|
+
over_internet: Annotated[bool, typer.Option("--over-internet", "-i", help="Expose the terminal over the internet using ngrok")] = False
|
|
74
62
|
) -> None:
|
|
75
|
-
|
|
63
|
+
from machineconfig.utils.installer_utils.installer import install_if_missing
|
|
64
|
+
install_if_missing("ttyd")
|
|
65
|
+
if over_internet: install_if_missing("ngrok")
|
|
66
|
+
|
|
76
67
|
if username is None:
|
|
77
68
|
import getpass
|
|
78
69
|
username = getpass.getuser()
|
|
@@ -128,12 +119,33 @@ def main(
|
|
|
128
119
|
start_command = "powershell"
|
|
129
120
|
else:
|
|
130
121
|
start_command = "bash"
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
122
|
+
|
|
123
|
+
ttyd_cmd = f"ttyd --writable -t enableSixel=true {ssl_args} --port {port} --credential \"{username}:{password}\" -t 'theme={{\"background\": \"black\"}}' {start_command}"
|
|
124
|
+
ttyd_process = subprocess.Popen(ttyd_cmd, shell=True)
|
|
125
|
+
processes = [ttyd_process]
|
|
126
|
+
|
|
127
|
+
if over_internet:
|
|
128
|
+
ngrok_process = subprocess.Popen(f"ngrok http {port}", shell=True)
|
|
129
|
+
processes.append(ngrok_process)
|
|
130
|
+
time.sleep(3)
|
|
131
|
+
try:
|
|
132
|
+
import requests
|
|
133
|
+
response = requests.get("http://localhost:4040/api/tunnels")
|
|
134
|
+
data = response.json()
|
|
135
|
+
public_url = data['tunnels'][0]['public_url']
|
|
136
|
+
print(f"🌐 Ngrok tunnel ready: {public_url}")
|
|
137
|
+
except Exception as e:
|
|
138
|
+
print(f"Could not retrieve ngrok URL: {e}")
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
while True:
|
|
142
|
+
print("Terminal server is running. Press Ctrl+C to stop.")
|
|
143
|
+
time.sleep(2)
|
|
144
|
+
except KeyboardInterrupt:
|
|
145
|
+
print("\nTerminating processes...")
|
|
146
|
+
for p in processes:
|
|
147
|
+
p.terminate()
|
|
148
|
+
p.wait()
|
|
137
149
|
|
|
138
150
|
|
|
139
151
|
def main_with_parser():
|