machineconfig 7.64__py3-none-any.whl → 7.83__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/sessions_managers/utils/maker.py +4 -2
- machineconfig/jobs/installer/custom/yazi.py +120 -0
- machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +26 -12
- machineconfig/jobs/installer/custom_dev/sysabc.py +26 -5
- machineconfig/jobs/installer/installer_data.json +232 -96
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/profile/create_helper.py +0 -12
- machineconfig/profile/create_links_export.py +2 -2
- machineconfig/profile/mapper.toml +2 -2
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/python/agents.py +22 -17
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
- machineconfig/scripts/python/croshell.py +22 -17
- machineconfig/scripts/python/devops.py +1 -1
- machineconfig/scripts/python/devops_navigator.py +0 -4
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
- machineconfig/scripts/python/fire_jobs.py +13 -13
- machineconfig/scripts/python/ftpx.py +36 -12
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
- machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
- machineconfig/scripts/python/helpers_cloud/cloud_mount.py +19 -17
- machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
- machineconfig/scripts/python/helpers_croshell/start_slidev.py +6 -7
- machineconfig/scripts/python/helpers_devops/cli_config.py +10 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +90 -10
- machineconfig/scripts/python/helpers_devops/cli_self.py +8 -7
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +7 -7
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +12 -11
- machineconfig/scripts/python/helpers_devops/cli_terminal.py +8 -10
- machineconfig/scripts/python/helpers_devops/cli_utils.py +2 -1
- machineconfig/scripts/python/helpers_devops/devops_status.py +7 -19
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +20 -9
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfg +2 -2
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +58 -1
- machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +5 -3
- machineconfig/scripts/python/helpers_repos/count_lines.py +40 -11
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
- machineconfig/scripts/python/helpers_utils/download.py +4 -3
- machineconfig/scripts/python/helpers_utils/path.py +87 -34
- machineconfig/scripts/python/interactive.py +1 -1
- machineconfig/scripts/python/{machineconfig.py → mcfg_entry.py} +4 -0
- machineconfig/scripts/python/msearch.py +55 -6
- machineconfig/scripts/python/nw/address.py +132 -0
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +8 -5
- machineconfig/scripts/python/terminal.py +2 -2
- machineconfig/scripts/python/utils.py +12 -11
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -2
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +282 -95
- machineconfig/settings/shells/pwsh/init.ps1 +1 -0
- machineconfig/settings/yazi/init.lua +4 -0
- machineconfig/settings/yazi/keymap_linux.toml +11 -4
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +10 -10
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -2
- machineconfig/utils/accessories.py +7 -4
- machineconfig/utils/code.py +4 -2
- machineconfig/utils/installer_utils/github_release_bulk.py +104 -62
- machineconfig/utils/installer_utils/install_from_url.py +200 -0
- machineconfig/utils/installer_utils/installer_class.py +25 -74
- machineconfig/utils/installer_utils/installer_cli.py +40 -50
- machineconfig/utils/installer_utils/installer_helper.py +100 -0
- machineconfig/utils/installer_utils/installer_runner.py +5 -8
- machineconfig/utils/links.py +2 -2
- machineconfig/utils/meta.py +2 -2
- machineconfig/utils/options.py +3 -3
- machineconfig/utils/path_extended.py +1 -1
- machineconfig/utils/path_helper.py +0 -1
- machineconfig/utils/ssh.py +143 -409
- machineconfig/utils/ssh_utils/abc.py +8 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +110 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
- machineconfig/utils/ssh_utils/utils.py +141 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/upgrade_packages.py +2 -1
- machineconfig/utils/ve.py +11 -4
- {machineconfig-7.64.dist-info → machineconfig-7.83.dist-info}/METADATA +2 -2
- {machineconfig-7.64.dist-info → machineconfig-7.83.dist-info}/RECORD +96 -89
- {machineconfig-7.64.dist-info → machineconfig-7.83.dist-info}/entry_points.txt +2 -2
- machineconfig/scripts/python/explore.py +0 -49
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfag +0 -17
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfrga +0 -21
- machineconfig/scripts/python/helpers_msearch/scripts_linux/skrg +0 -4
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfb.ps1 +0 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfrga.bat +0 -20
- machineconfig/settings/yazi/yazi.toml +0 -17
- machineconfig/setup_linux/others/cli_installation.sh +0 -137
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
- /machineconfig/scripts/{Restore-ThunderbirdProfile.ps1 → windows/mounts/Restore-ThunderbirdProfile.ps1} +0 -0
- {machineconfig-7.64.dist-info → machineconfig-7.83.dist-info}/WHEEL +0 -0
- {machineconfig-7.64.dist-info → machineconfig-7.83.dist-info}/top_level.txt +0 -0
|
@@ -34,13 +34,63 @@ def add_ssh_identity():
|
|
|
34
34
|
helper.main()
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def show_address():
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
def show_address() -> None:
|
|
38
|
+
"""📌 Show this computer addresses on network"""
|
|
39
|
+
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
40
|
+
import subprocess
|
|
41
|
+
install_if_missing("ipinfo")
|
|
42
|
+
result = subprocess.run(
|
|
43
|
+
["ipinfo", "myip", "--json"],
|
|
44
|
+
check=True,
|
|
45
|
+
capture_output=True,
|
|
46
|
+
text=True,
|
|
47
|
+
encoding="utf-8",
|
|
48
|
+
)
|
|
49
|
+
import json
|
|
50
|
+
loaded_json = json.loads(result.stdout)
|
|
51
|
+
from rich import print_json
|
|
52
|
+
print_json(data=loaded_json)
|
|
53
|
+
|
|
54
|
+
import machineconfig.scripts.python.nw.address as helper
|
|
55
|
+
from rich.table import Table
|
|
56
|
+
from rich.console import Console
|
|
57
|
+
res = helper.get_all_ipv4_addresses()
|
|
58
|
+
res.append( ("Public IP", loaded_json.get("ip", "N/A")))
|
|
59
|
+
|
|
60
|
+
# loc = loaded_json["loc"]
|
|
61
|
+
# cmd = f"""curl "https://maps.geoapify.com/v1/staticmap?style=osm-bright&width=600&height=300¢er=lonlat:{loc}&zoom=6&marker=lonlat:{loc};color:%23ff0000;size:medium&apiKey=$GEOAPIFY_API_KEY" -o map.png && chafa map.png"""
|
|
62
|
+
# from machineconfig.utils.code import run_shell_script
|
|
63
|
+
# run_shell_script(script=cmd)
|
|
64
|
+
|
|
65
|
+
table = Table(title="Network Interfaces")
|
|
66
|
+
table.add_column("Interface", style="cyan")
|
|
67
|
+
table.add_column("IP Address", style="green")
|
|
68
|
+
|
|
69
|
+
for iface, ip in res:
|
|
70
|
+
table.add_row(iface, ip)
|
|
71
|
+
|
|
72
|
+
console = Console()
|
|
73
|
+
console.print(table)
|
|
74
|
+
|
|
75
|
+
res = helper.select_lan_ipv4(prefer_vpn=False)
|
|
76
|
+
if res is not None:
|
|
77
|
+
# ip, iface = res
|
|
78
|
+
# print(f"Selected IP: {ip} on interface: {iface}")
|
|
79
|
+
print(f"LAN IPv4: {res}")
|
|
80
|
+
else:
|
|
81
|
+
print("No network interfaces found.")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def bind_wsl_port(port: Annotated[int, typer.Option(..., "--port", "-p", help="Port number to bind")]):
|
|
86
|
+
code = f"""
|
|
87
|
+
|
|
88
|
+
$wsl_ip = (wsl.exe hostname -I).Trim().Split(' ')[0]
|
|
89
|
+
netsh interface portproxy add v4tov4 listenport={port} listenaddress=0.0.0.0 connectport={port} connectaddress=$wsl_ip
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
from machineconfig.utils.code import exit_then_run_shell_script
|
|
93
|
+
exit_then_run_shell_script(code)
|
|
44
94
|
|
|
45
95
|
|
|
46
96
|
def debug_ssh():
|
|
@@ -101,10 +151,32 @@ def wifi_select(
|
|
|
101
151
|
console.print("[blue]👋 Goodbye![/blue]")
|
|
102
152
|
|
|
103
153
|
|
|
154
|
+
|
|
155
|
+
def reset_cloudflare_tunnel():
|
|
156
|
+
code = """
|
|
157
|
+
# cloudflared tunnel route dns glenn # creates CNAMES in Cloudflare dashboard
|
|
158
|
+
# sudo systemctl stop cloudflared
|
|
159
|
+
# test: cloudflared tunnel run glenn
|
|
160
|
+
home_dir=$HOME
|
|
161
|
+
cloudflared_path="$home_dir/.local/bin/cloudflared"
|
|
162
|
+
sudo $cloudflared_path service uninstall
|
|
163
|
+
sudo rm /etc/cloudflared/config.yml || true
|
|
164
|
+
sudo $cloudflared_path --config $home_dir/.cloudflared/config.yml service install
|
|
165
|
+
"""
|
|
166
|
+
print(code)
|
|
167
|
+
def add_ip_exclusion_to_warp(ip: Annotated[str, typer.Option(..., "--ip", help="IP address to exclude from WARP")]):
|
|
168
|
+
code = f"""
|
|
169
|
+
sudo warp-cli tunnel ip add {ip}
|
|
170
|
+
sudo warp-cli disconnect
|
|
171
|
+
sudo warp-cli connect
|
|
172
|
+
"""
|
|
173
|
+
print(code)
|
|
174
|
+
|
|
175
|
+
|
|
104
176
|
def get_app():
|
|
105
177
|
nw_apps = typer.Typer(help="🔐 [n] Network subcommands", no_args_is_help=True, add_help_option=False, add_completion=False)
|
|
106
|
-
nw_apps.command(name="share-terminal", help="📡 [t] Share terminal via web browser")(cli_terminal.
|
|
107
|
-
nw_apps.command(name="t", help="Share terminal via web browser", hidden=True)(cli_terminal.
|
|
178
|
+
nw_apps.command(name="share-terminal", help="📡 [t] Share terminal via web browser")(cli_terminal.share_terminal)
|
|
179
|
+
nw_apps.command(name="t", help="Share terminal via web browser", hidden=True)(cli_terminal.share_terminal)
|
|
108
180
|
|
|
109
181
|
nw_apps.command(name="share-server", help="🌐 [s] Start local/global server to share files/folders via web browser", no_args_is_help=True)(cli_share_server.web_file_explorer)
|
|
110
182
|
nw_apps.command(name="s", help="Start local/global server to share files/folders via web browser", hidden=True, no_args_is_help=True)(cli_share_server.web_file_explorer)
|
|
@@ -128,7 +200,15 @@ def get_app():
|
|
|
128
200
|
nw_apps.command(name="debug-ssh", help="🐛 [d] Debug SSH connection")(debug_ssh)
|
|
129
201
|
nw_apps.command(name="d", help="Debug SSH connection", hidden=True)(debug_ssh)
|
|
130
202
|
|
|
131
|
-
nw_apps.command(name="wifi-select", no_args_is_help=True, help="📶 WiFi connection utility.")(wifi_select)
|
|
203
|
+
nw_apps.command(name="wifi-select", no_args_is_help=True, help="📶 [w] WiFi connection utility.")(wifi_select)
|
|
132
204
|
nw_apps.command(name="w", no_args_is_help=True, hidden=True)(wifi_select)
|
|
133
205
|
|
|
206
|
+
nw_apps.command(name="bind-wsl-port", help="🔌 [b] Bind WSL port to Windows host", no_args_is_help=True)(bind_wsl_port)
|
|
207
|
+
nw_apps.command(name="b", help="Bind WSL port to Windows host", hidden=True, no_args_is_help=True)(bind_wsl_port)
|
|
208
|
+
|
|
209
|
+
nw_apps.command(name="reset-cloudflare-tunnel", help="☁️ [r] Reset Cloudflare tunnel service")(reset_cloudflare_tunnel)
|
|
210
|
+
nw_apps.command(name="r", help="Reset Cloudflare tunnel service", hidden=True)(reset_cloudflare_tunnel)
|
|
211
|
+
nw_apps.command(name="add-ip-exclusion-to-warp", help="🚫 [p] Add IP exclusion to WARP")(add_ip_exclusion_to_warp)
|
|
212
|
+
nw_apps.command(name="p", help="Add IP exclusion to WARP", hidden=True)(add_ip_exclusion_to_warp)
|
|
213
|
+
|
|
134
214
|
return nw_apps
|
|
@@ -30,7 +30,8 @@ uv tool install --upgrade machineconfig
|
|
|
30
30
|
if platform.system() == "Windows":
|
|
31
31
|
from machineconfig.utils.code import exit_then_run_shell_script, get_uv_command_executing_python_script
|
|
32
32
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
33
|
-
python_script = lambda_to_python_script(lambda: copy_both_assets(),
|
|
33
|
+
python_script = lambda_to_python_script(lambda: copy_both_assets(),
|
|
34
|
+
in_global=True, import_module=False)
|
|
34
35
|
uv_command, _py_file = get_uv_command_executing_python_script(python_script=python_script, uv_with=["machineconfig"], uv_project_dir=None)
|
|
35
36
|
exit_then_run_shell_script(shell_script + "\n" + uv_command, strict=True)
|
|
36
37
|
else:
|
|
@@ -48,13 +49,13 @@ def install(no_copy_assets: Annotated[bool, typer.Option("--no-assets-copy", "-n
|
|
|
48
49
|
from machineconfig.utils.code import run_shell_script
|
|
49
50
|
from pathlib import Path
|
|
50
51
|
if Path.home().joinpath("code/machineconfig").exists():
|
|
51
|
-
run_shell_script(f"""$HOME/.local/bin/uv tool install --upgrade --editable "{str(Path.home().joinpath("code/machineconfig"))}" """)
|
|
52
|
+
run_shell_script(f""" "$HOME/.local/bin/uv" tool install --upgrade --editable "{str(Path.home().joinpath("code/machineconfig"))}" """)
|
|
52
53
|
else:
|
|
53
54
|
import platform
|
|
54
55
|
if platform.system() == "Windows":
|
|
55
|
-
run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=7.
|
|
56
|
+
run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=7.83" """)
|
|
56
57
|
else:
|
|
57
|
-
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=7.
|
|
58
|
+
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=7.83" """)
|
|
58
59
|
from machineconfig.profile.create_shell_profile import create_default_shell_profile
|
|
59
60
|
if not no_copy_assets:
|
|
60
61
|
create_default_shell_profile() # involves copying assets too
|
|
@@ -77,10 +78,10 @@ def navigate():
|
|
|
77
78
|
import machineconfig.scripts.python as navigator
|
|
78
79
|
from pathlib import Path
|
|
79
80
|
path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
|
|
80
|
-
from machineconfig.utils.code import
|
|
81
|
+
from machineconfig.utils.code import exit_then_run_shell_script
|
|
81
82
|
if Path.home().joinpath("code/machineconfig").exists(): executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
|
|
82
|
-
else: executable = """--with "machineconfig>=7.
|
|
83
|
-
|
|
83
|
+
else: executable = """--with "machineconfig>=7.83,textual" """
|
|
84
|
+
exit_then_run_shell_script(f"""uv run {executable} {path}""")
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
def run_python(ip: Annotated[str, typer.Argument(..., help="Python command to run in the machineconfig environment")],
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
|
|
1
2
|
import typer
|
|
2
|
-
# import platform
|
|
3
|
-
# import sys
|
|
4
3
|
from typing import Annotated
|
|
5
4
|
|
|
6
5
|
|
|
@@ -103,12 +102,13 @@ def share_file_send(path: Annotated[str, typer.Argument(help="Path to the file o
|
|
|
103
102
|
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
104
103
|
install_if_missing(which="croc")
|
|
105
104
|
# Get relay server IP from environment or use default
|
|
106
|
-
import
|
|
105
|
+
import machineconfig.scripts.python.nw.address as helper
|
|
106
|
+
res = helper.select_lan_ipv4(prefer_vpn=False)
|
|
107
|
+
if res is None:
|
|
108
|
+
typer.echo("❌ Error: Could not determine local LAN IPv4 address for relay.", err=True)
|
|
109
|
+
raise typer.Exit(code=1)
|
|
110
|
+
local_ip_v4 = res
|
|
107
111
|
import platform
|
|
108
|
-
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
109
|
-
s.connect(('8.8.8.8',80))
|
|
110
|
-
local_ip_v4 = s.getsockname()[0]
|
|
111
|
-
s.close()
|
|
112
112
|
relay_port = "443"
|
|
113
113
|
is_windows = platform.system() == "Windows"
|
|
114
114
|
|
|
@@ -38,18 +38,16 @@ def web_file_explorer(
|
|
|
38
38
|
username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for share access (default: current user)")] = None,
|
|
39
39
|
password: Annotated[Optional[str], typer.Option("--password", "-w", help="Password for share access (default: from ~/dotfiles/creds/passwords/quick_password)")] = None,
|
|
40
40
|
over_internet: Annotated[bool, typer.Option("--over-internet", "-i", help="Expose the share server over the internet using ngrok")] = False,
|
|
41
|
-
backend: Annotated[str, typer.Option("--backend", "-b", help="Backend to use: filebrowser (default), miniserve, or easy-sharing")] = "
|
|
41
|
+
backend: Annotated[str, typer.Option("--backend", "-b", help="Backend to use: filebrowser (default), miniserve, qrcp, or easy-sharing")] = "miniserve",
|
|
42
42
|
) -> None:
|
|
43
43
|
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
44
|
-
|
|
45
|
-
if backend not in ["filebrowser", "miniserve", "easy-sharing"]:
|
|
46
|
-
typer.echo(f"❌ ERROR: Invalid backend '{backend}'. Must be one of: filebrowser, miniserve, easy-sharing", err=True)
|
|
44
|
+
|
|
45
|
+
if backend not in ["filebrowser", "miniserve", "qrcp", "easy-sharing"]:
|
|
46
|
+
typer.echo(f"❌ ERROR: Invalid backend '{backend}'. Must be one of: filebrowser, miniserve, qrcp, easy-sharing", err=True)
|
|
47
47
|
raise typer.Exit(code=1)
|
|
48
|
-
|
|
49
48
|
install_if_missing(which=backend)
|
|
50
49
|
if over_internet:
|
|
51
50
|
install_if_missing(which="ngrok")
|
|
52
|
-
|
|
53
51
|
if username is None:
|
|
54
52
|
import getpass
|
|
55
53
|
username = getpass.getuser()
|
|
@@ -65,11 +63,12 @@ def web_file_explorer(
|
|
|
65
63
|
if port is None:
|
|
66
64
|
port = 8080
|
|
67
65
|
|
|
68
|
-
import
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
import machineconfig.scripts.python.nw.address as helper
|
|
67
|
+
res = helper.select_lan_ipv4(prefer_vpn=False)
|
|
68
|
+
if res is None:
|
|
69
|
+
typer.echo("❌ ERROR: Could not determine local LAN IPv4 address for share server.", err=True)
|
|
70
|
+
raise typer.Exit(code=1)
|
|
71
|
+
local_ip_v4 = res
|
|
73
72
|
|
|
74
73
|
protocol = "http"
|
|
75
74
|
display_share_url(local_ip_v4, port, protocol)
|
|
@@ -90,6 +89,8 @@ filebrowser --address 0.0.0.0 --port {port} --root "{path_obj}" --database {db_p
|
|
|
90
89
|
command = f"""miniserve --port {port} --interfaces 0.0.0.0 --auth {username}:{password} --upload-files --mkdir --enable-tar --enable-tar-gz --enable-zip --qrcode "{path_obj}" """
|
|
91
90
|
elif backend == "easy-sharing":
|
|
92
91
|
command = f"""easy-sharing --port {port} --username {username} --password "{password}" "{path_obj}" """
|
|
92
|
+
elif backend == "qrcp":
|
|
93
|
+
command = f"""qrcp "{path_obj}" """
|
|
93
94
|
else:
|
|
94
95
|
typer.echo(f"❌ ERROR: Unknown backend '{backend}'", err=True)
|
|
95
96
|
raise typer.Exit(code=1)
|
|
@@ -17,13 +17,11 @@ reference:
|
|
|
17
17
|
|
|
18
18
|
def display_terminal_url(local_ip_v4: str, port: int, protocol: str = "http") -> None:
|
|
19
19
|
"""Display a flashy, unmissable terminal URL announcement."""
|
|
20
|
-
|
|
21
20
|
from rich.console import Console
|
|
22
21
|
from rich.panel import Panel
|
|
23
22
|
from rich.text import Text
|
|
24
23
|
from rich.align import Align
|
|
25
24
|
console = Console()
|
|
26
|
-
|
|
27
25
|
# Create the main message with styling
|
|
28
26
|
url_text = Text(f"{protocol}://{local_ip_v4}:{port}", style="bold bright_cyan underline")
|
|
29
27
|
message = Text.assemble(
|
|
@@ -42,14 +40,13 @@ def display_terminal_url(local_ip_v4: str, port: int, protocol: str = "http") ->
|
|
|
42
40
|
padding=(1, 2),
|
|
43
41
|
expand=False
|
|
44
42
|
)
|
|
45
|
-
|
|
46
43
|
# Print with extra spacing and attention-grabbing elements
|
|
47
44
|
# console.print("\n" + "🔥" * 60 + "\n", style="bright_red bold")
|
|
48
45
|
console.print(panel)
|
|
49
46
|
# console.print("🔥" * 60 + "\n", style="bright_red bold")
|
|
50
47
|
|
|
51
48
|
|
|
52
|
-
def
|
|
49
|
+
def share_terminal(
|
|
53
50
|
port: Annotated[Optional[int], typer.Option("--port", "-p", help="Port to run the terminal server on (default: 7681)")] = None,
|
|
54
51
|
username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for terminal access (default: current user)")] = None,
|
|
55
52
|
password: Annotated[Optional[str], typer.Option("--password", "-w", help="Password for terminal access (default: from ~/dotfiles/creds/passwords/quick_password)")] = None,
|
|
@@ -96,11 +93,12 @@ def main(
|
|
|
96
93
|
if ssl_ca and not Path(ssl_ca).exists():
|
|
97
94
|
raise FileNotFoundError(f"SSL CA file not found: {ssl_ca}")
|
|
98
95
|
|
|
99
|
-
import
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
import machineconfig.scripts.python.nw.address as helper
|
|
97
|
+
res = helper.select_lan_ipv4(prefer_vpn=False)
|
|
98
|
+
if res is None:
|
|
99
|
+
print("❌ Error: Could not determine local LAN IPv4 address for terminal.")
|
|
100
|
+
raise typer.Exit(code=1)
|
|
101
|
+
local_ip_v4 = res
|
|
104
102
|
|
|
105
103
|
# Display the flashy terminal announcement
|
|
106
104
|
protocol = "https" if ssl else "http"
|
|
@@ -149,7 +147,7 @@ def main(
|
|
|
149
147
|
|
|
150
148
|
|
|
151
149
|
def main_with_parser():
|
|
152
|
-
typer.run(
|
|
150
|
+
typer.run(share_terminal)
|
|
153
151
|
|
|
154
152
|
|
|
155
153
|
if __name__ == "__main__":
|
|
@@ -36,7 +36,8 @@ def merge_pdfs(
|
|
|
36
36
|
writer.write(output_path)
|
|
37
37
|
print(f"✅ Merged PDF saved to: {output_path}")
|
|
38
38
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
39
|
-
code = lambda_to_python_script(lambda : merge_pdfs_internal(pdfs=pdfs, output=output, compress=compress),
|
|
39
|
+
code = lambda_to_python_script(lambda : merge_pdfs_internal(pdfs=pdfs, output=output, compress=compress),
|
|
40
|
+
in_global=True, import_module=False)
|
|
40
41
|
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
41
42
|
uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pypdf"], uv_project_dir=None)
|
|
42
43
|
run_shell_script(uv_command)
|
|
@@ -17,22 +17,6 @@ from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH, LIBR
|
|
|
17
17
|
console = Console()
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def _check_system_info() -> dict[str, str]:
|
|
21
|
-
"""Gather basic system information."""
|
|
22
|
-
import socket
|
|
23
|
-
import os
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
"hostname": socket.gethostname(),
|
|
27
|
-
"system": platform.system(),
|
|
28
|
-
"release": platform.release(),
|
|
29
|
-
"version": platform.version(),
|
|
30
|
-
"machine": platform.machine(),
|
|
31
|
-
"processor": platform.processor() or "Unknown",
|
|
32
|
-
"python_version": platform.python_version(),
|
|
33
|
-
"user": os.getenv("USER") or os.getenv("USERNAME") or "Unknown",
|
|
34
|
-
}
|
|
35
|
-
|
|
36
20
|
|
|
37
21
|
def _check_shell_profile_status() -> dict[str, Any]:
|
|
38
22
|
"""Check shell profile configuration status."""
|
|
@@ -480,10 +464,14 @@ def main() -> None:
|
|
|
480
464
|
console.print("\n")
|
|
481
465
|
console.print(Panel(Text("📊 Machine Status Report", justify="center", style="bold white"), style="bold blue", padding=(1, 2)))
|
|
482
466
|
console.print("\n")
|
|
483
|
-
|
|
484
|
-
system_info = _check_system_info()
|
|
467
|
+
|
|
468
|
+
# system_info = _check_system_info()
|
|
469
|
+
# from machineconfig.scripts.python.helpers_devops.devops_system_info import _check_system_info
|
|
470
|
+
from machineconfig.scripts.python.helpers_utils.path import get_machine_specs
|
|
471
|
+
system_info = get_machine_specs()
|
|
472
|
+
from typing import cast
|
|
473
|
+
system_info = cast(dict[str, str], system_info)
|
|
485
474
|
_display_system_info(system_info)
|
|
486
|
-
|
|
487
475
|
shell_status = _check_shell_profile_status()
|
|
488
476
|
_display_shell_status(shell_status)
|
|
489
477
|
|
|
@@ -54,15 +54,13 @@ def choose_function_or_lines(choice_file: Path, kwargs_dict: dict[str, object])
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def get_command_streamlit(choice_file: Path, environment: str, repo_root: Optional[Path]) -> str:
|
|
57
|
-
import
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
finally:
|
|
65
|
-
s.close()
|
|
57
|
+
# from machineconfig.scripts.python.helpers_utils.path import get_machine_specs
|
|
58
|
+
from machineconfig.scripts.python.nw.address import select_lan_ipv4
|
|
59
|
+
res = select_lan_ipv4(prefer_vpn=False)
|
|
60
|
+
if res is None:
|
|
61
|
+
raise RuntimeError("Could not determine local LAN IPv4 address for streamlit app.")
|
|
62
|
+
local_ip_v4 = res
|
|
63
|
+
|
|
66
64
|
computer_name = platform.node()
|
|
67
65
|
port = 8501
|
|
68
66
|
toml_path: Optional[Path] = None
|
|
@@ -100,6 +98,19 @@ def get_command_streamlit(choice_file: Path, environment: str, repo_root: Option
|
|
|
100
98
|
except Exception as ex:
|
|
101
99
|
print(ex)
|
|
102
100
|
raise ex
|
|
101
|
+
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
102
|
+
install_if_missing("qrterminal")
|
|
103
|
+
script = f"""
|
|
104
|
+
qrterminal "http://{local_ip_v4}:{port}"
|
|
105
|
+
echo "http://{local_ip_v4}:{port}"
|
|
106
|
+
qrterminal "http://{computer_name}:{port}"
|
|
107
|
+
echo "http://{computer_name}:{port}"
|
|
108
|
+
"""
|
|
109
|
+
# from machineconfig.utils.code import run_shell_script
|
|
110
|
+
# run_shell_script(script)
|
|
111
|
+
from machineconfig.utils.code import print_code
|
|
112
|
+
print_code(code=script, lexer="shell", desc="Streamlit QR Codes and URLs")
|
|
113
|
+
|
|
103
114
|
message = f"🚀 Streamlit app is running @:\n1- http://{local_ip_v4}:{port}\n2- http://{computer_name}:{port}\n3- http://localhost:{port}"
|
|
104
115
|
from rich.panel import Panel
|
|
105
116
|
from rich import print as rprint
|
|
@@ -13,9 +13,9 @@ IFS=: read -ra selected < <(
|
|
|
13
13
|
--bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \
|
|
14
14
|
--bind "ctrl-f:unbind(change,ctrl-f)+change-prompt(2. fzf> )+enable-search+clear-query+rebind(ctrl-r)" \
|
|
15
15
|
--bind "ctrl-r:unbind(ctrl-r)+change-prompt(1. ripgrep> )+disable-search+reload($RG_PREFIX {q} || true)+rebind(change,ctrl-f)" \
|
|
16
|
-
--prompt '1.
|
|
16
|
+
--prompt '1. ripgrep> ' \
|
|
17
17
|
--delimiter : \
|
|
18
|
-
--header '╱ CTRL-R (
|
|
18
|
+
--header '╱ CTRL-R (ripgrep mode) ╱ CTRL-F (fzf mode) ╱' \
|
|
19
19
|
--preview 'bat --color=always {1} --highlight-line {2}' \
|
|
20
20
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
21
21
|
)
|
|
@@ -1,2 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
[CmdletBinding()]
|
|
3
|
+
param(
|
|
4
|
+
[Parameter(ValueFromRemainingArguments = $true)]
|
|
5
|
+
[string[]]$QueryTokens
|
|
6
|
+
)
|
|
1
7
|
|
|
2
|
-
|
|
8
|
+
if ($null -eq $QueryTokens) {
|
|
9
|
+
$QueryTokens = @()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$initialQuery = if ($QueryTokens.Count -gt 0) { [string]::Join(' ', $QueryTokens) } else { '' }
|
|
13
|
+
$rgPrefix = 'rg --column --line-number --no-heading --color=always --smart-case '
|
|
14
|
+
|
|
15
|
+
$escapedDefault = if ($initialQuery.Length -gt 0) {
|
|
16
|
+
$rgPrefix + '"' + $initialQuery.Replace('"', '""') + '" || type nul'
|
|
17
|
+
} else {
|
|
18
|
+
'type nul'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
$previousDefault = $env:FZF_DEFAULT_COMMAND
|
|
22
|
+
$env:FZF_DEFAULT_COMMAND = $escapedDefault
|
|
23
|
+
|
|
24
|
+
$reloadBinding = "change:reload:$rgPrefix{q} || type nul"
|
|
25
|
+
$ctrlFBinding = 'ctrl-f:unbind(change,ctrl-f)+change-prompt(2. fzf> )+enable-search+clear-query+rebind(ctrl-r)'
|
|
26
|
+
$ctrlRBinding = "ctrl-r:unbind(ctrl-r)+change-prompt(1. ripgrep> )+disable-search+reload($rgPrefix{q} || type nul)+rebind(change,ctrl-f)"
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
$selectionRaw = & fzf --ansi `
|
|
30
|
+
--color 'hl:-1:underline,hl+:-1:underline:reverse' `
|
|
31
|
+
--disabled `
|
|
32
|
+
--query $initialQuery `
|
|
33
|
+
--bind $reloadBinding `
|
|
34
|
+
--bind $ctrlFBinding `
|
|
35
|
+
--bind $ctrlRBinding `
|
|
36
|
+
--prompt '1. ripgrep> ' `
|
|
37
|
+
--delimiter ':' `
|
|
38
|
+
--header 'CTRL-R (ripgrep mode) | CTRL-F (fzf mode)' `
|
|
39
|
+
--preview 'bat --color=always {1} --highlight-line {2}' `
|
|
40
|
+
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
if ($null -ne $previousDefault) {
|
|
44
|
+
$env:FZF_DEFAULT_COMMAND = $previousDefault
|
|
45
|
+
} else {
|
|
46
|
+
Remove-Item Env:FZF_DEFAULT_COMMAND -ErrorAction SilentlyContinue
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($selectionRaw)) {
|
|
51
|
+
exit
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if ($selectionRaw -match '^(?<path>.+?):(?<line>\d+):(?<column>\d+):') {
|
|
55
|
+
$path = $Matches['path']
|
|
56
|
+
$line = [int]$Matches['line']
|
|
57
|
+
$column = [int]$Matches['column']
|
|
58
|
+
& hx ("{0}:{1}:{2}" -f $path,$line,$column)
|
|
59
|
+
}
|
|
@@ -188,15 +188,7 @@ class CommandTree(Tree[CommandInfo]):
|
|
|
188
188
|
description="Configure your shell profile",
|
|
189
189
|
command="devops config shell",
|
|
190
190
|
parent="config",
|
|
191
|
-
help_text="devops config shell <
|
|
192
|
-
))
|
|
193
|
-
|
|
194
|
-
config_node.add("🔗 path - Navigate PATH variable", data=CommandInfo(
|
|
195
|
-
name="path",
|
|
196
|
-
description="Navigate PATH variable with TUI",
|
|
197
|
-
command="devops config path",
|
|
198
|
-
parent="config",
|
|
199
|
-
help_text="devops config path"
|
|
191
|
+
help_text="devops config shell --which <default|nushell>"
|
|
200
192
|
))
|
|
201
193
|
|
|
202
194
|
config_node.add("🔗 starship-theme - Select starship theme", data=CommandInfo(
|
|
@@ -560,7 +552,23 @@ class CommandTree(Tree[CommandInfo]):
|
|
|
560
552
|
description="Choose a process to kill interactively",
|
|
561
553
|
command="utils kill-process",
|
|
562
554
|
parent="utils",
|
|
563
|
-
help_text="utils kill-process"
|
|
555
|
+
help_text="utils kill-process --interactive"
|
|
556
|
+
))
|
|
557
|
+
|
|
558
|
+
utils_node.add("📚 path - Navigate PATH variable", data=CommandInfo(
|
|
559
|
+
name="path",
|
|
560
|
+
description="Navigate PATH variable with TUI",
|
|
561
|
+
command="utils path",
|
|
562
|
+
parent="utils",
|
|
563
|
+
help_text="utils path"
|
|
564
|
+
))
|
|
565
|
+
|
|
566
|
+
utils_node.add("⬆️ upgrade-packages - Upgrade dependencies", data=CommandInfo(
|
|
567
|
+
name="upgrade-packages",
|
|
568
|
+
description="Upgrade project dependencies",
|
|
569
|
+
command="utils upgrade-packages",
|
|
570
|
+
parent="utils",
|
|
571
|
+
help_text="utils upgrade-packages"
|
|
564
572
|
))
|
|
565
573
|
|
|
566
574
|
utils_node.add("⬇️ download - Download file", data=CommandInfo(
|
|
@@ -571,18 +579,42 @@ class CommandTree(Tree[CommandInfo]):
|
|
|
571
579
|
help_text="utils download <url> --destination <path> --decompress"
|
|
572
580
|
))
|
|
573
581
|
|
|
574
|
-
utils_node.add("📄 merge-pdfs - Merge PDF files", data=CommandInfo(
|
|
575
|
-
name="merge-pdfs",
|
|
576
|
-
description="Merge two PDF files into one",
|
|
577
|
-
command="utils merge-pdfs",
|
|
578
|
-
parent="utils",
|
|
579
|
-
help_text="utils merge-pdfs <file1> <file2> --output <file>"
|
|
580
|
-
))
|
|
581
|
-
|
|
582
582
|
utils_node.add("🖥️ get-machine-specs - Get machine specifications", data=CommandInfo(
|
|
583
583
|
name="get-machine-specs",
|
|
584
584
|
description="Get machine specifications",
|
|
585
585
|
command="utils get-machine-specs",
|
|
586
586
|
parent="utils",
|
|
587
587
|
help_text="utils get-machine-specs"
|
|
588
|
+
))
|
|
589
|
+
|
|
590
|
+
utils_node.add("🚀 init-project - Initialize project", data=CommandInfo(
|
|
591
|
+
name="init-project",
|
|
592
|
+
description="Initialize a project with a uv virtual environment and install dev packages",
|
|
593
|
+
command="utils init-project",
|
|
594
|
+
parent="utils",
|
|
595
|
+
help_text="utils init-project"
|
|
596
|
+
))
|
|
597
|
+
|
|
598
|
+
utils_node.add("✏️ edit - Open file in editor", data=CommandInfo(
|
|
599
|
+
name="edit",
|
|
600
|
+
description="Open a file in the default editor",
|
|
601
|
+
command="utils edit",
|
|
602
|
+
parent="utils",
|
|
603
|
+
help_text="utils edit <file>"
|
|
604
|
+
))
|
|
605
|
+
|
|
606
|
+
utils_node.add("📄 pdf-merge - Merge PDF files", data=CommandInfo(
|
|
607
|
+
name="pdf-merge",
|
|
608
|
+
description="Merge two PDF files into one",
|
|
609
|
+
command="utils pdf-merge",
|
|
610
|
+
parent="utils",
|
|
611
|
+
help_text="utils pdf-merge <file1> <file2> --output <file>"
|
|
612
|
+
))
|
|
613
|
+
|
|
614
|
+
utils_node.add("� pdf-compress - Compress PDF file", data=CommandInfo(
|
|
615
|
+
name="pdf-compress",
|
|
616
|
+
description="Compress a PDF file",
|
|
617
|
+
command="utils pdf-compress",
|
|
618
|
+
parent="utils",
|
|
619
|
+
help_text="utils pdf-compress <file> --output <file>"
|
|
588
620
|
))
|
|
@@ -105,7 +105,7 @@ git pull originEnc master
|
|
|
105
105
|
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
106
106
|
uv_with = None
|
|
107
107
|
else:
|
|
108
|
-
uv_with = ["machineconfig>=7.
|
|
108
|
+
uv_with = ["machineconfig>=7.83"]
|
|
109
109
|
uv_project_dir = None
|
|
110
110
|
|
|
111
111
|
import tempfile
|
|
@@ -136,7 +136,8 @@ git pull originEnc master
|
|
|
136
136
|
def func2(remote_repo: str, local_repo: str, cloud: str):
|
|
137
137
|
from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
138
138
|
delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
139
|
-
program_1_py = lambda_to_python_script(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)),
|
|
139
|
+
program_1_py = lambda_to_python_script(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)),
|
|
140
|
+
in_global=True, import_module=False)
|
|
140
141
|
program1, _pyfile1 = get_uv_command_executing_python_script(python_script=program_1_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
141
142
|
# ================================================================================
|
|
142
143
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
@@ -161,7 +162,8 @@ sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
|
161
162
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
162
163
|
# program_3_py = function_to_script(func=func, call_with_kwargs={"repo_local_root": str(repo_local_root), "repo_remote_root": str(repo_remote_root)})
|
|
163
164
|
# shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable=executable)
|
|
164
|
-
program_3_py = lambda_to_python_script(lambda: func(repo_local_root=str(repo_local_root), repo_remote_root=str(repo_remote_root)),
|
|
165
|
+
program_3_py = lambda_to_python_script(lambda: func(repo_local_root=str(repo_local_root), repo_remote_root=str(repo_remote_root)),
|
|
166
|
+
in_global=True, import_module=False)
|
|
165
167
|
program3, _pyfile3 = get_uv_command_executing_python_script(python_script=program_3_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
166
168
|
# ================================================================================
|
|
167
169
|
|