machineconfig 1.94__py3-none-any.whl → 1.95__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/data_transfer.py +2 -1
- machineconfig/cluster/job_params.py +1 -1
- machineconfig/cluster/script_execution.py +1 -1
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/linux/msc/lid.sh +2 -4
- machineconfig/jobs/linux/msc/network.sh +3 -6
- machineconfig/jobs/python/check_installations.py +6 -6
- machineconfig/jobs/python/checkout_version.py +4 -4
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/python_ve_symlink.py +4 -4
- machineconfig/jobs/python/vscode/api.py +2 -2
- machineconfig/jobs/python/vscode/link_ve.py +4 -4
- machineconfig/jobs/python/vscode/select_interpreter.py +4 -4
- machineconfig/jobs/python/vscode/sync_code.py +6 -6
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/aider.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/brave.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/code.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/docker.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/espanso.py +8 -8
- machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/redis.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/warp-cli.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +4 -4
- machineconfig/jobs/python_custom_installers/gh.py +6 -6
- machineconfig/jobs/python_custom_installers/hx.py +28 -58
- machineconfig/jobs/python_custom_installers/scripts/linux/brave.sh +4 -8
- machineconfig/jobs/python_custom_installers/scripts/linux/docker.sh +5 -10
- machineconfig/jobs/python_custom_installers/scripts/linux/docker_start.sh +3 -6
- machineconfig/jobs/python_custom_installers/scripts/linux/edge.sh +3 -6
- machineconfig/jobs/python_custom_installers/scripts/linux/nerdfont.sh +5 -10
- machineconfig/jobs/python_custom_installers/scripts/linux/pgsql.sh +4 -8
- machineconfig/jobs/python_custom_installers/scripts/linux/redis.sh +5 -10
- machineconfig/jobs/python_custom_installers/scripts/linux/timescaledb.sh +6 -12
- machineconfig/jobs/python_custom_installers/scripts/linux/vscode.sh +9 -8
- machineconfig/jobs/python_custom_installers/scripts/linux/warp-cli.sh +5 -10
- machineconfig/jobs/python_custom_installers/scripts/linux/wezterm.sh +3 -6
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/shell.py +26 -47
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/cloud/init.sh +9 -18
- machineconfig/scripts/linux/fire +5 -24
- machineconfig/scripts/linux/share_cloud.sh +6 -12
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_repo_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/archive/im2text.py +30 -30
- machineconfig/scripts/python/archive/tmate_conn.py +10 -13
- machineconfig/scripts/python/archive/tmate_start.py +12 -16
- machineconfig/scripts/python/choose_wezterm_theme.py +9 -18
- machineconfig/scripts/python/cloud_copy.py +38 -93
- machineconfig/scripts/python/cloud_manager.py +61 -53
- machineconfig/scripts/python/cloud_mount.py +23 -34
- machineconfig/scripts/python/cloud_repo_sync.py +20 -69
- machineconfig/scripts/python/cloud_sync.py +35 -45
- machineconfig/scripts/python/croshell.py +48 -73
- machineconfig/scripts/python/devops.py +50 -104
- machineconfig/scripts/python/devops_add_identity.py +41 -101
- machineconfig/scripts/python/devops_add_ssh_key.py +33 -140
- machineconfig/scripts/python/devops_backup_retrieve.py +23 -112
- machineconfig/scripts/python/devops_devapps_install.py +0 -4
- machineconfig/scripts/python/devops_update_repos.py +1 -1
- machineconfig/scripts/python/fire_jobs.py +73 -25
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/cloud_helpers.py +37 -34
- machineconfig/scripts/python/helpers/helpers2.py +17 -31
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +19 -54
- machineconfig/scripts/python/pomodoro.py +1 -1
- machineconfig/scripts/python/repos.py +49 -34
- machineconfig/scripts/python/wifi_conn.py +5 -3
- machineconfig/scripts/windows/fire.ps1 +27 -15
- machineconfig/settings/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/playext.cpython-311.pyc +0 -0
- machineconfig/setup_linux/nix/cli_installation.sh +9 -18
- machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +3 -6
- machineconfig/setup_linux/web_shortcuts/all.sh +5 -10
- machineconfig/setup_linux/web_shortcuts/ascii_art.sh +7 -14
- machineconfig/setup_linux/web_shortcuts/croshell.sh +6 -12
- machineconfig/setup_linux/web_shortcuts/interactive.sh +34 -68
- machineconfig/setup_linux/web_shortcuts/ssh.sh +8 -16
- machineconfig/setup_linux/web_shortcuts/update_system.sh +7 -14
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +16 -12
- machineconfig/utils/ai/browser_user_wrapper.py +60 -45
- machineconfig/utils/ai/generate_file_checklist.py +4 -7
- machineconfig/utils/ai/url2md.py +13 -5
- machineconfig/utils/{utils_code.py → code.py} +4 -10
- machineconfig/utils/installer.py +4 -10
- machineconfig/utils/{utils_links.py → links.py} +9 -20
- machineconfig/utils/{utils_options.py → options.py} +10 -20
- machineconfig/utils/{utils_path.py → path.py} +28 -80
- machineconfig/utils/procs.py +26 -30
- machineconfig/utils/scheduling.py +11 -11
- machineconfig/utils/utils.py +12 -19
- machineconfig/utils/ve.py +5 -21
- machineconfig/utils/ve_utils/ve2.py +15 -2
- {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/METADATA +4 -2
- {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/RECORD +120 -118
- {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/WHEEL +1 -1
- {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/top_level.txt +0 -0
|
@@ -7,170 +7,81 @@ from machineconfig.utils.utils import LIBRARY_ROOT, DEFAULTS_PATH, print_code, c
|
|
|
7
7
|
from machineconfig.scripts.python.helpers.helpers2 import ES
|
|
8
8
|
from platform import system
|
|
9
9
|
from typing import Any, Literal, Optional
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.panel import Panel
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
OPTIONS = Literal["BACKUP", "RETRIEVE"]
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None):
|
|
18
|
+
console = Console()
|
|
19
|
+
|
|
16
20
|
try:
|
|
17
21
|
cloud: str = Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
18
|
-
print(f"""
|
|
19
|
-
╔{'═' * 70}╗
|
|
20
|
-
║ ⚠️ DEFAULT CLOUD CONFIGURATION ║
|
|
21
|
-
╠{'═' * 70}╣
|
|
22
|
-
║ 🌥️ Using default cloud: {cloud:<52} ║
|
|
23
|
-
╚{'═' * 70}╝
|
|
24
|
-
""")
|
|
22
|
+
console.print(Panel(f"⚠️ DEFAULT CLOUD CONFIGURATION\n🌥️ Using default cloud: {cloud}", title="[bold blue]Cloud Configuration[/bold blue]", border_style="blue"))
|
|
25
23
|
except (FileNotFoundError, KeyError, IndexError):
|
|
26
|
-
print(
|
|
27
|
-
╔{'═' * 70}╗
|
|
28
|
-
║ 🔍 DEFAULT CLOUD NOT FOUND ║
|
|
29
|
-
║ 🔄 Please select a cloud configuration from the options below ║
|
|
30
|
-
╚{'═' * 70}╝
|
|
31
|
-
""")
|
|
24
|
+
console.print(Panel("🔍 DEFAULT CLOUD NOT FOUND\n🔄 Please select a cloud configuration from the options below", title="[bold red]Error: Cloud Not Found[/bold red]", border_style="red"))
|
|
32
25
|
cloud = choose_cloud_interactively()
|
|
33
26
|
|
|
34
27
|
bu_file: dict[str, Any] = Read.toml(LIBRARY_ROOT.joinpath("profile/backup.toml"))
|
|
35
28
|
|
|
36
|
-
print(f"""
|
|
37
|
-
╔{'═' * 70}╗
|
|
38
|
-
║ 🧰 LOADING BACKUP CONFIGURATION ║
|
|
39
|
-
║ 📄 File: {LIBRARY_ROOT.joinpath("profile/backup.toml")} ║
|
|
40
|
-
╚{'═' * 70}╝
|
|
41
|
-
""")
|
|
29
|
+
console.print(Panel(f"🧰 LOADING BACKUP CONFIGURATION\n📄 File: {LIBRARY_ROOT.joinpath('profile/backup.toml')}", title="[bold blue]Backup Configuration[/bold blue]", border_style="blue"))
|
|
42
30
|
|
|
43
31
|
if system() == "Linux":
|
|
44
32
|
bu_file = {key: val for key, val in bu_file.items() if "windows" not in key}
|
|
45
|
-
print(f"""
|
|
46
|
-
╔{'═' * 70}╗
|
|
47
|
-
║ 🐧 LINUX ENVIRONMENT DETECTED ║
|
|
48
|
-
║ 🔍 Filtering out Windows-specific entries ║
|
|
49
|
-
║ ✅ Found {len(bu_file)} applicable backup configuration entries ╚{'═' * 70}╝
|
|
50
|
-
""")
|
|
33
|
+
console.print(Panel(f"🐧 LINUX ENVIRONMENT DETECTED\n🔍 Filtering out Windows-specific entries\n✅ Found {len(bu_file)} applicable backup configuration entries", title="[bold blue]Linux Environment[/bold blue]", border_style="blue"))
|
|
51
34
|
elif system() == "Windows":
|
|
52
35
|
bu_file = {key: val for key, val in bu_file.items() if "linux" not in key}
|
|
53
|
-
print(f"""
|
|
54
|
-
╔{'═' * 70}╗
|
|
55
|
-
║ 🪟 WINDOWS ENVIRONMENT DETECTED ║
|
|
56
|
-
║ 🔍 Filtering out Linux-specific entries ║
|
|
57
|
-
║ ✅ Found {len(bu_file)} applicable backup configuration entries ╚{'═' * 70}╝
|
|
58
|
-
""")
|
|
36
|
+
console.print(Panel(f"🪟 WINDOWS ENVIRONMENT DETECTED\n🔍 Filtering out Linux-specific entries\n✅ Found {len(bu_file)} applicable backup configuration entries", title="[bold blue]Windows Environment[/bold blue]", border_style="blue"))
|
|
59
37
|
|
|
60
38
|
if which is None:
|
|
61
|
-
print(f"""
|
|
62
|
-
╔{'═' * 70}╗
|
|
63
|
-
║ 🔍 SELECT {direction} ITEMS ║
|
|
64
|
-
║ 📋 Choose which configuration entries to process ║
|
|
65
|
-
╚{'═' * 70}╝
|
|
66
|
-
""")
|
|
39
|
+
console.print(Panel(f"🔍 SELECT {direction} ITEMS\n📋 Choose which configuration entries to process", title="[bold blue]Select Items[/bold blue]", border_style="blue"))
|
|
67
40
|
choices = choose_multiple_options(msg=f"WHICH FILE of the following do you want to {direction}?", options=['all'] + list(bu_file.keys()))
|
|
68
41
|
else:
|
|
69
42
|
choices = which.split(",") if isinstance(which, str) else which
|
|
70
|
-
print(f"""
|
|
71
|
-
╔{'═' * 70}╗
|
|
72
|
-
║ 🔖 PRE-SELECTED ITEMS ║
|
|
73
|
-
║ 📝 Using: {', '.join(choices):<54} ║
|
|
74
|
-
╚{'═' * 70}╝
|
|
75
|
-
""")
|
|
43
|
+
console.print(Panel(f"🔖 PRE-SELECTED ITEMS\n📝 Using: {', '.join(choices)}", title="[bold blue]Pre-selected Items[/bold blue]", border_style="blue"))
|
|
76
44
|
|
|
77
45
|
if "all" in choices:
|
|
78
46
|
items = bu_file
|
|
79
|
-
print(f"""
|
|
80
|
-
╔{'═' * 70}╗
|
|
81
|
-
║ 📋 PROCESSING ALL ENTRIES ║
|
|
82
|
-
║ 🔢 Total entries to process: {len(bu_file):<39} ║
|
|
83
|
-
╚{'═' * 70}╝
|
|
84
|
-
""")
|
|
47
|
+
console.print(Panel(f"📋 PROCESSING ALL ENTRIES\n🔢 Total entries to process: {len(bu_file)}", title="[bold blue]Process All Entries[/bold blue]", border_style="blue"))
|
|
85
48
|
else:
|
|
86
49
|
items = {key: val for key, val in bu_file.items() if key in choices}
|
|
87
|
-
print(f"""
|
|
88
|
-
╔{'═' * 70}╗
|
|
89
|
-
║ 📋 PROCESSING SELECTED ENTRIES ║
|
|
90
|
-
║ 🔢 Total entries to process: {len(items):<39} ║
|
|
91
|
-
╚{'═' * 70}╝
|
|
92
|
-
""")
|
|
93
|
-
|
|
50
|
+
console.print(Panel(f"📋 PROCESSING SELECTED ENTRIES\n🔢 Total entries to process: {len(items)}", title="[bold blue]Process Selected Entries[/bold blue]", border_style="blue"))
|
|
94
51
|
program = f"""$cloud = "{cloud}:{ES}" \n """ if system() == "Windows" else f"""cloud="{cloud}:{ES}" \n """
|
|
95
|
-
|
|
96
|
-
print(f"""
|
|
97
|
-
╔{'═' * 70}╗
|
|
98
|
-
║ 🚀 GENERATING {direction} SCRIPT ║
|
|
99
|
-
╠{'═' * 70}╣
|
|
100
|
-
║ 🌥️ Cloud: {cloud:<58} ║
|
|
101
|
-
║ 🗂️ Items: {len(items):<58} ║
|
|
102
|
-
╚{'═' * 70}╝
|
|
103
|
-
""")
|
|
104
|
-
|
|
52
|
+
console.print(Panel(f"🚀 GENERATING {direction} SCRIPT\n🌥️ Cloud: {cloud}\n🗂️ Items: {len(items)}", title="[bold blue]Script Generation[/bold blue]", border_style="blue"))
|
|
105
53
|
for item_name, item in items.items():
|
|
106
54
|
flags = ''
|
|
107
55
|
flags += 'z' if item['zip'] == 'True' else ''
|
|
108
56
|
flags += 'e' if item['encrypt'] == 'True' else ''
|
|
109
57
|
flags += 'r' if item['rel2home'] == 'True' else ''
|
|
110
58
|
flags += 'o' if system().lower() in item_name else ''
|
|
111
|
-
|
|
112
|
-
print(f"""
|
|
113
|
-
╔{'─' * 70}╗
|
|
114
|
-
║ 📦 PROCESSING: {item_name:<53} ║
|
|
115
|
-
╠{'─' * 70}╣
|
|
116
|
-
║ 📂 Path: {P(item['path']).as_posix():<55} ║
|
|
117
|
-
║ 🏳️ Flags: {flags or 'None':<56} ║
|
|
118
|
-
╚{'─' * 70}╝
|
|
119
|
-
""")
|
|
120
|
-
|
|
59
|
+
console.print(Panel(f"📦 PROCESSING: {item_name}\n📂 Path: {P(item['path']).as_posix()}\n🏳️ Flags: {flags or 'None'}", title=f"[bold blue]Processing Item: {item_name}[/bold blue]", border_style="blue"))
|
|
121
60
|
if flags: flags = "-" + flags
|
|
122
61
|
if direction == "BACKUP":
|
|
123
62
|
program += f"""\ncloud_copy "{P(item['path']).as_posix()}" $cloud {flags}\n"""
|
|
124
63
|
elif direction == "RETRIEVE":
|
|
125
64
|
program += f"""\ncloud_copy $cloud "{P(item['path']).as_posix()}" {flags}\n"""
|
|
126
65
|
else:
|
|
127
|
-
print(
|
|
128
|
-
|
|
129
|
-
║ ❌ ERROR: INVALID DIRECTION ║
|
|
130
|
-
║ ⚠️ Direction must be either "BACKUP" or "RETRIEVE" ║
|
|
131
|
-
╚{'═' * 70}╝
|
|
132
|
-
""")
|
|
133
|
-
raise RuntimeError(f"Unknown direction: {direction}")
|
|
134
|
-
|
|
66
|
+
console.print(Panel("❌ ERROR: INVALID DIRECTION\n⚠️ Direction must be either \"BACKUP\" or \"RETRIEVE\"", title="[bold red]Error: Invalid Direction[/bold red]", border_style="red"))
|
|
67
|
+
raise RuntimeError(f"Unknown direction: {direction}")
|
|
135
68
|
if item_name == "dotfiles" and system() == "Linux":
|
|
136
69
|
program += """\nchmod 700 ~/.ssh/*\n"""
|
|
137
|
-
print(
|
|
138
|
-
╔{'─' * 70}╗
|
|
139
|
-
║ 🔒 SPECIAL HANDLING: SSH PERMISSIONS ║
|
|
140
|
-
║ 🛠️ Setting secure permissions for SSH files ║
|
|
141
|
-
║ 📝 Command: chmod 700 ~/.ssh/* ║
|
|
142
|
-
╚{'─' * 70}╝
|
|
143
|
-
""")
|
|
144
|
-
|
|
70
|
+
console.print(Panel("🔒 SPECIAL HANDLING: SSH PERMISSIONS\n🛠️ Setting secure permissions for SSH files\n📝 Command: chmod 700 ~/.ssh/*", title="[bold blue]Special Handling: SSH Permissions[/bold blue]", border_style="blue"))
|
|
145
71
|
print_code(program, lexer="shell", desc=f"{direction} script")
|
|
146
|
-
|
|
147
|
-
print(f"""
|
|
148
|
-
╔{'═' * 70}╗
|
|
149
|
-
║ ✅ {direction} SCRIPT GENERATION COMPLETE ║
|
|
150
|
-
║ 🚀 Ready to execute the operations ║
|
|
151
|
-
╚{'═' * 70}╝
|
|
152
|
-
""")
|
|
153
|
-
|
|
72
|
+
console.print(Panel(f"✅ {direction} SCRIPT GENERATION COMPLETE\n🚀 Ready to execute the operations", title="[bold green]Script Generation Complete[/bold green]", border_style="green"))
|
|
154
73
|
return program
|
|
155
74
|
|
|
156
75
|
|
|
157
76
|
def main(direction: OPTIONS, which: Optional[str] = None):
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
║ ⏱️ {'-' * 58} ║
|
|
162
|
-
╚{'═' * 70}╝
|
|
163
|
-
""")
|
|
77
|
+
console = Console()
|
|
78
|
+
|
|
79
|
+
console.print(Panel(f"🔄 {direction} OPERATION STARTED\n⏱️ {'-' * 58}", title="[bold blue]Operation Initiated[/bold blue]", border_style="blue"))
|
|
164
80
|
|
|
165
81
|
code = main_backup_retrieve(direction=direction, which=which)
|
|
166
82
|
from machineconfig.utils.utils import write_shell_script_to_default_program_path
|
|
167
83
|
|
|
168
|
-
print(
|
|
169
|
-
╔{'═' * 70}╗
|
|
170
|
-
║ 💾 GENERATING SHELL SCRIPT ║
|
|
171
|
-
║ 📄 Filename: backup_retrieve.sh ║
|
|
172
|
-
╚{'═' * 70}╝
|
|
173
|
-
""")
|
|
84
|
+
console.print(Panel("💾 GENERATING SHELL SCRIPT\n📄 Filename: backup_retrieve.sh", title="[bold blue]Shell Script Generation[/bold blue]", border_style="blue"))
|
|
174
85
|
|
|
175
86
|
write_shell_script_to_default_program_path(program=code, desc="backup_retrieve.sh")
|
|
176
87
|
|
|
@@ -155,10 +155,6 @@ def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
|
|
|
155
155
|
{a_chunk}
|
|
156
156
|
{'-' * 50}""")
|
|
157
157
|
raise e
|
|
158
|
-
# Struct(res).print(as_config=True)
|
|
159
|
-
# L(chunks).print(sep="-----------------------------------------------------------------------\n\n")
|
|
160
|
-
# import time
|
|
161
|
-
# time.sleep(10)
|
|
162
158
|
return res
|
|
163
159
|
|
|
164
160
|
|
|
@@ -75,7 +75,7 @@ cd "{a_repo.working_dir}"
|
|
|
75
75
|
program = "\n".join([f"""
|
|
76
76
|
echo "🔄 {("Updating " + str(a_repo.working_dir)).center(80, "═")}"
|
|
77
77
|
cd "{a_repo.working_dir}"
|
|
78
|
-
{sep.join([f'git pull {remote.name} {a_repo.active_branch.name}
|
|
78
|
+
{sep.join([f'git pull {remote.name} {a_repo.active_branch.name}' for remote in a_repo.remotes])}
|
|
79
79
|
""" for a_repo in repos_objs])
|
|
80
80
|
else: raise NotImplementedError(f"""
|
|
81
81
|
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -12,15 +12,15 @@ from machineconfig.scripts.python.helpers.helpers4 import search_for_files_of_in
|
|
|
12
12
|
from machineconfig.scripts.python.helpers.helpers4 import convert_kwargs_to_fire_kwargs_str
|
|
13
13
|
from machineconfig.scripts.python.helpers.helpers4 import parse_pyfile
|
|
14
14
|
from machineconfig.scripts.python.helpers.helpers4 import get_import_module_code
|
|
15
|
+
from machineconfig.utils.ve_utils.ve1 import get_repo_root
|
|
15
16
|
from machineconfig.utils.utils import display_options, choose_one_option, PROGRAM_PATH, match_file_name, sanitize_path
|
|
16
17
|
from machineconfig.utils.ve_utils.ve1 import get_ve_activate_line, get_ve_name_and_ipython_profile
|
|
17
|
-
from crocodile.file_management import P, Read
|
|
18
|
+
from crocodile.file_management import P, Read, Save
|
|
18
19
|
from crocodile.core import randstr
|
|
19
20
|
import platform
|
|
20
21
|
from typing import Optional
|
|
21
22
|
import argparse
|
|
22
|
-
|
|
23
|
-
from machineconfig.utils.ve_utils.ve1 import get_repo_root
|
|
23
|
+
import os
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
str2obj = {"True": True, "False": False, "None": None}
|
|
@@ -36,19 +36,28 @@ def main() -> None:
|
|
|
36
36
|
parser.add_argument("--interactive", "-i", action="store_true", help="Whether to run the job interactively using IPython")
|
|
37
37
|
parser.add_argument("--debug", "-d", action="store_true", help="debug")
|
|
38
38
|
parser.add_argument("--choose_function", "-c", action="store_true", help="debug")
|
|
39
|
-
parser.add_argument("--loop", "-l", action="store_true", help="infinite recusion (runs again after completion)")
|
|
39
|
+
parser.add_argument("--loop", "-l", action="store_true", help="infinite recusion (runs again after completion/interruption)")
|
|
40
40
|
parser.add_argument("--jupyter", "-j", action="store_true", help="open in a jupyter notebook")
|
|
41
41
|
parser.add_argument("--submit_to_cloud", "-C", action="store_true", help="submit to cloud compute")
|
|
42
42
|
parser.add_argument("--remote", "-r", action="store_true", help="launch on a remote machine")
|
|
43
43
|
parser.add_argument("--module", "-m", action="store_true", help="launch the main file")
|
|
44
44
|
parser.add_argument("--streamlit", "-S", action="store_true", help="run as streamlit app")
|
|
45
|
+
parser.add_argument("--environment", "-E", type=str, help="Choose ip, localhost, hostname or arbitrary url", default="")
|
|
45
46
|
parser.add_argument("--holdDirectory", "-D", action="store_true", help="hold current directory and avoid cd'ing to the script directory")
|
|
47
|
+
parser.add_argument("--PathExport", "-P", action="store_true", help="augment the PYTHONPATH with repo root.")
|
|
46
48
|
parser.add_argument("--git_pull", "-g", action="store_true", help="Start by pulling the git repo")
|
|
47
|
-
parser.add_argument("--optimized",
|
|
49
|
+
parser.add_argument("--optimized", "-O", action="store_true", help="Run the optimized version of the function")
|
|
48
50
|
parser.add_argument("--Nprocess", "-p", type=int, help="Number of processes to use", default=1)
|
|
49
|
-
parser.add_argument("--kw", nargs="*", default=None, help="keyword arguments to pass to the function in the form of k1 v1 k2 v2 ... (meaning k1=v1, k2=v2, etc)")
|
|
50
51
|
parser.add_argument("--zellij_tab", "-z", type=str, dest="zellij_tab", help="open in a new zellij tab")
|
|
51
|
-
|
|
52
|
+
parser.add_argument("--watch", "-w", action="store_true", help="watch the file for changes")
|
|
53
|
+
parser.add_argument("--kw", nargs="*", default=None, help="keyword arguments to pass to the function in the form of k1 v1 k2 v2 ... (meaning k1=v1, k2=v2, etc)")
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
args = parser.parse_args()
|
|
57
|
+
except Exception as ex:
|
|
58
|
+
print(f"❌ Failed to parse arguments: {ex}")
|
|
59
|
+
parser.print_help()
|
|
60
|
+
raise ex
|
|
52
61
|
|
|
53
62
|
path_obj = sanitize_path(P(args.path))
|
|
54
63
|
if not path_obj.exists():
|
|
@@ -62,7 +71,8 @@ def main() -> None:
|
|
|
62
71
|
choice_file = P(choice_file)
|
|
63
72
|
else:
|
|
64
73
|
choice_file = path_obj
|
|
65
|
-
|
|
74
|
+
repo_root = get_repo_root(str(choice_file))
|
|
75
|
+
print(f"💾 Selected file: {choice_file}. Repo root: {repo_root}")
|
|
66
76
|
|
|
67
77
|
ve_name_suggested, ipy_profile = get_ve_name_and_ipython_profile(choice_file)
|
|
68
78
|
if ipy_profile is None: ipy_profile = "default"
|
|
@@ -118,20 +128,39 @@ def main() -> None:
|
|
|
118
128
|
port = 8501
|
|
119
129
|
toml_path: Optional[P] = None
|
|
120
130
|
toml_path_maybe = choice_file.parent.joinpath(".streamlit/config.toml")
|
|
121
|
-
if toml_path_maybe.exists():
|
|
131
|
+
if toml_path_maybe.exists():
|
|
132
|
+
toml_path = toml_path_maybe
|
|
122
133
|
elif choice_file.parent.name == "pages":
|
|
123
134
|
toml_path_maybe = choice_file.parent.parent.joinpath(".streamlit/config.toml")
|
|
124
135
|
if toml_path_maybe.exists(): toml_path = toml_path_maybe
|
|
125
136
|
if toml_path is not None:
|
|
137
|
+
print(f"📄 Reading config.toml @ {toml_path}")
|
|
126
138
|
config = Read.toml(toml_path)
|
|
127
139
|
if "server" in config:
|
|
128
140
|
if "port" in config["server"]:
|
|
129
141
|
port = config["server"]["port"]
|
|
142
|
+
secrets_path = toml_path.with_name("secrets.toml")
|
|
143
|
+
if repo_root is not None:
|
|
144
|
+
secrets_template_path = P.home().joinpath(f"dotfiles/creds/streamlit/{P(repo_root).name}/{choice_file.name}/secrets.toml")
|
|
145
|
+
if args.environment != "" and not secrets_path.exists() and secrets_template_path.exists():
|
|
146
|
+
secrets_template = Read.toml(secrets_template_path)
|
|
147
|
+
if args.environment == "ip": host_url = f"http://{local_ip_v4}:{port}/oauth2callback"
|
|
148
|
+
elif args.environment == "localhost": host_url = f"http://localhost:{port}/oauth2callback"
|
|
149
|
+
elif args.environment == "hostname": host_url = f"http://{computer_name}:{port}/oauth2callback"
|
|
150
|
+
else: host_url = f"http://{args.environment}:{port}/oauth2callback"
|
|
151
|
+
try:
|
|
152
|
+
secrets_template["auth"]["redirect_uri"] = host_url
|
|
153
|
+
secrets_template["auth"]["cookie_secret"] = randstr(35)
|
|
154
|
+
secrets_template["auth"]["auth0"]["redirect_uri"] = host_url
|
|
155
|
+
Save.toml(obj=secrets_template, path=secrets_path)
|
|
156
|
+
except Exception as ex:
|
|
157
|
+
print(ex)
|
|
158
|
+
raise ex
|
|
130
159
|
message = f"🚀 Streamlit app is running @:\n1- http://{local_ip_v4}:{port}\n2- http://{computer_name}:{port}\n3- http://localhost:{port}"
|
|
131
160
|
from rich.panel import Panel
|
|
132
161
|
from rich import print as rprint
|
|
133
162
|
rprint(Panel(message))
|
|
134
|
-
exe = "streamlit run --server.address 0.0.0.0 --server.headless true"
|
|
163
|
+
exe = f"streamlit run --server.address 0.0.0.0 --server.headless true --server.port {port}"
|
|
135
164
|
# exe = f"cd '{choice_file.parent}'; " + exe
|
|
136
165
|
elif args.interactive is False: exe = "python"
|
|
137
166
|
elif args.jupyter: exe = "jupyter-lab"
|
|
@@ -145,9 +174,8 @@ def main() -> None:
|
|
|
145
174
|
raise NotImplementedError(f"File type {choice_file.suffix} not supported, in the sense that I don't know how to fire it.")
|
|
146
175
|
|
|
147
176
|
if args.module or (args.debug and args.choose_function): # because debugging tools do not support choosing functions and don't interplay with fire module. So the only way to have debugging and choose function options is to import the file as a module into a new script and run the function of interest there and debug the new script.
|
|
148
|
-
assert choice_file.suffix == ".py", f"File must be a python file to be imported as a module. Got {choice_file
|
|
177
|
+
assert choice_file.suffix == ".py", f"File must be a python file to be imported as a module. Got {choice_file}"
|
|
149
178
|
import_line = get_import_module_code(str(choice_file))
|
|
150
|
-
repo_root = get_repo_root(str(choice_file))
|
|
151
179
|
if repo_root is not None:
|
|
152
180
|
repo_root_add = f"""sys.path.append(r'{repo_root}')"""
|
|
153
181
|
else:
|
|
@@ -199,7 +227,7 @@ except ImportError as _ex:
|
|
|
199
227
|
if args.holdDirectory:
|
|
200
228
|
command = f"{exe} {choice_file}"
|
|
201
229
|
else:
|
|
202
|
-
command = f"cd {choice_file.parent}\n
|
|
230
|
+
command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {P.cwd()}"
|
|
203
231
|
|
|
204
232
|
elif args.cmd:
|
|
205
233
|
command = rf""" cd /d {choice_file.parent} & {exe} {choice_file.name} """
|
|
@@ -208,21 +236,22 @@ except ImportError as _ex:
|
|
|
208
236
|
kwargs_raw = " ".join(args.kw) if args.kw is not None else ""
|
|
209
237
|
command = f"{exe} {choice_file} {kwargs_raw}"
|
|
210
238
|
else:
|
|
211
|
-
# command = f"cd {choice_file.parent}\n
|
|
239
|
+
# command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {P.cwd()}"
|
|
212
240
|
command = f"{exe} {choice_file} "
|
|
213
241
|
# this installs in ve env, which is not execution env
|
|
214
242
|
# if "ipdb" in command: install_n_import("ipdb")
|
|
215
243
|
# if "pudb" in command: install_n_import("pudb")
|
|
216
244
|
|
|
217
245
|
if not args.cmd:
|
|
218
|
-
if "ipdb" in command: command = f"pip install ipdb\n
|
|
219
|
-
if "pudb" in command: command = f"pip install pudb\n
|
|
220
|
-
command = f"{activate_ve_line}\n
|
|
246
|
+
if "ipdb" in command: command = f"pip install ipdb\n{command}"
|
|
247
|
+
if "pudb" in command: command = f"pip install pudb\n{command}"
|
|
248
|
+
command = f"{activate_ve_line}\n{command}"
|
|
221
249
|
else:
|
|
222
250
|
# CMD equivalent
|
|
223
251
|
if "ipdb" in command: command = f"pip install ipdb & {command}"
|
|
224
252
|
if "pudb" in command: command = f"pip install pudb & {command}"
|
|
225
|
-
|
|
253
|
+
new_line = "\n"
|
|
254
|
+
command = fr"""start cmd -Argument "/k {activate_ve_line.replace(".ps1", ".bat").replace(". ", "")} & {command.replace(new_line, " & ")} " """ # this works from powershell
|
|
226
255
|
# this works from cmd # command = fr""" start cmd /k "%USERPROFILE%\venvs\{args.ve}\Scripts\activate.bat & {command} " """ # because start in cmd is different from start in powershell (in powershell it is short for Start-Process)
|
|
227
256
|
|
|
228
257
|
if args.submit_to_cloud:
|
|
@@ -235,9 +264,6 @@ python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
|
|
|
235
264
|
# try: install_n_import("clipboard").copy(command)
|
|
236
265
|
# except Exception as ex: print(f"Failed to copy command to clipboard. {ex}")
|
|
237
266
|
|
|
238
|
-
if args.loop:
|
|
239
|
-
command = command + "\n" + f". {PROGRAM_PATH}"
|
|
240
|
-
|
|
241
267
|
if args.Nprocess > 1:
|
|
242
268
|
lines = [f""" zellij action new-tab --name nProcess{randstr(2)}"""]
|
|
243
269
|
command = command.replace(". activate_ve", ". $HOME/scripts/activate_ve")
|
|
@@ -287,10 +313,32 @@ echo "Sleep 2 seconds to allow zellij to close the pane"
|
|
|
287
313
|
sleep 1
|
|
288
314
|
zellij action close-pane; sleep 2
|
|
289
315
|
"""
|
|
290
|
-
if args.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
316
|
+
if args.watch: command = "watchexec --restart --exts py,sh,ps1 " + command
|
|
317
|
+
if args.git_pull: command = f"\ngit -C {choice_file.parent} pull\n" + command
|
|
318
|
+
if args.PathExport:
|
|
319
|
+
if platform.system() == "Linux": export_line = f"""export PYTHONPATH="{repo_root}""" + """:${PYTHONPATH}" """
|
|
320
|
+
elif platform.system() == "Windows":
|
|
321
|
+
# export_line = f"""set PYTHONPATH="{repo_root}""" + """:%PYTHONPATH%" """
|
|
322
|
+
# powershell equivalent
|
|
323
|
+
export_line = f"""$env:PYTHONPATH="{repo_root}""" + """:$env:PYTHONPATH" """
|
|
324
|
+
else:
|
|
325
|
+
raise NotImplementedError(f"Platform {platform.system()} not supported.")
|
|
326
|
+
command = export_line + "\n" + command
|
|
327
|
+
|
|
328
|
+
program_path = os.environ.get("op_script", None)
|
|
329
|
+
program_path = P(program_path) if program_path is not None else PROGRAM_PATH
|
|
330
|
+
if args.loop:
|
|
331
|
+
if platform.system() == "Linux":
|
|
332
|
+
command = command + "\nsleep 0.5"
|
|
333
|
+
elif platform.system() == "Windows":
|
|
334
|
+
# command = command + "timeout 0.5\n"
|
|
335
|
+
#pwsh equivalent
|
|
336
|
+
command ="$ErrorActionPreference = 'SilentlyContinue';\n" + command + "\nStart-Sleep -Seconds 0.5"
|
|
337
|
+
else:
|
|
338
|
+
raise NotImplementedError(f"Platform {platform.system()} not supported.")
|
|
339
|
+
command = command + f"\n. {program_path}"
|
|
340
|
+
console.print(Panel(Syntax(command, lexer="shell"), title=f"🔥 fire command @ {program_path}: "), style="bold red")
|
|
341
|
+
program_path.write_text(command)
|
|
294
342
|
|
|
295
343
|
|
|
296
344
|
if __name__ == '__main__':
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
from crocodile.core import Struct
|
|
3
2
|
from crocodile.file_management import P, Read
|
|
4
3
|
from pydantic import ConfigDict
|
|
@@ -6,6 +5,12 @@ from pydantic.dataclasses import dataclass
|
|
|
6
5
|
from typing import Optional
|
|
7
6
|
import os
|
|
8
7
|
from machineconfig.utils.utils import DEFAULTS_PATH
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.panel import Panel
|
|
10
|
+
from rich import box # Import box
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
9
14
|
|
|
10
15
|
|
|
11
16
|
class ArgsDefaults:
|
|
@@ -42,32 +47,21 @@ class Args():
|
|
|
42
47
|
|
|
43
48
|
@staticmethod
|
|
44
49
|
def from_config(config_path: P):
|
|
45
|
-
# from crocodile.core import install_n_import
|
|
46
|
-
# install_n_import("pydantic")
|
|
47
|
-
# from pydantic import BaseModel, ConfigDict
|
|
48
50
|
return Args(**Read.json(config_path))
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
def find_cloud_config(path: P):
|
|
52
|
-
|
|
53
|
-
╭{'─' * 70}╮
|
|
54
|
-
│ 🔍 Searching for cloud configuration file... │
|
|
55
|
-
╰{'─' * 70}╯
|
|
56
|
-
""")
|
|
54
|
+
display_header(f"Searching for cloud configuration file @ {path}")
|
|
57
55
|
|
|
58
56
|
for _i in range(len(path.parts)):
|
|
59
57
|
if path.joinpath("cloud.json").exists():
|
|
60
58
|
res = Args.from_config(path.joinpath("cloud.json"))
|
|
61
|
-
|
|
62
|
-
╭{'─' * 70}╮
|
|
63
|
-
│ ✅ Found cloud config at: {path.joinpath('cloud.json')} │
|
|
64
|
-
╰{'─' * 70}╯
|
|
65
|
-
""")
|
|
59
|
+
display_success(f"Found cloud config at: {path.joinpath('cloud.json')}")
|
|
66
60
|
Struct(res.__dict__).print(as_config=True, title="Cloud Config")
|
|
67
61
|
return res
|
|
68
62
|
path = path.parent
|
|
69
63
|
|
|
70
|
-
|
|
64
|
+
display_error("No cloud configuration file found")
|
|
71
65
|
return None
|
|
72
66
|
|
|
73
67
|
|
|
@@ -76,30 +70,22 @@ def absolute(path: str) -> P:
|
|
|
76
70
|
if not path.startswith(".") and obj.exists(): return obj
|
|
77
71
|
try_absing = P.cwd().joinpath(path)
|
|
78
72
|
if try_absing.exists(): return try_absing
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
│ ⚠️ WARNING: │
|
|
82
|
-
│ Path {path} could not be resolved to absolute path.
|
|
83
|
-
│ Trying to resolve symlinks (this may result in unintended paths). │
|
|
84
|
-
╰{'─' * 70}╯
|
|
85
|
-
""")
|
|
73
|
+
display_warning(f"Path {path} could not be resolved to absolute path.")
|
|
74
|
+
display_warning("Trying to resolve symlinks (this may result in unintended paths).")
|
|
86
75
|
return obj.absolute()
|
|
87
76
|
|
|
88
77
|
|
|
89
78
|
|
|
90
79
|
def get_secure_share_cloud_config(interactive: bool, cloud: Optional[str]) -> Args:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
║ 🔐 Secure Share Cloud Configuration ║
|
|
94
|
-
╚{'═' * 70}╝
|
|
95
|
-
""")
|
|
80
|
+
console = Console()
|
|
81
|
+
console.print(Panel("🔐 Secure Share Cloud Configuration", expand=False))
|
|
96
82
|
|
|
97
83
|
if cloud is None:
|
|
98
84
|
if os.environ.get("CLOUD_CONFIG_NAME") is not None:
|
|
99
85
|
default_cloud = os.environ.get("CLOUD_CONFIG_NAME")
|
|
100
86
|
assert default_cloud is not None
|
|
101
87
|
cloud = default_cloud
|
|
102
|
-
print(f"☁️ Using cloud from environment: {cloud}")
|
|
88
|
+
console.print(f"☁️ Using cloud from environment: {cloud}")
|
|
103
89
|
else:
|
|
104
90
|
try:
|
|
105
91
|
default_cloud__ = Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
@@ -110,7 +96,7 @@ def get_secure_share_cloud_config(interactive: bool, cloud: Optional[str]) -> Ar
|
|
|
110
96
|
cloud = input(f"☁️ Enter cloud name (default {default_cloud__}): ") or default_cloud__
|
|
111
97
|
else:
|
|
112
98
|
cloud = default_cloud__
|
|
113
|
-
print(f"☁️ Using default cloud: {cloud}")
|
|
99
|
+
console.print(f"☁️ Using default cloud: {cloud}")
|
|
114
100
|
|
|
115
101
|
default_password_path = P.home().joinpath("dotfiles/creds/passwords/quick_password")
|
|
116
102
|
if default_password_path.exists():
|
|
@@ -125,10 +111,27 @@ def get_secure_share_cloud_config(interactive: bool, cloud: Optional[str]) -> Ar
|
|
|
125
111
|
zip=True, overwrite=True, share=True,
|
|
126
112
|
rel2home=True, root="myshare", os_specific=False,)
|
|
127
113
|
|
|
128
|
-
|
|
129
|
-
╭{'─' * 70}╮
|
|
130
|
-
│ ⚙️ Using SecureShare cloud config │
|
|
131
|
-
╰{'─' * 70}╯
|
|
132
|
-
""")
|
|
114
|
+
display_success("Using SecureShare cloud config")
|
|
133
115
|
Struct(res.__dict__).print(as_config=True, title="SecureShare Config")
|
|
134
116
|
return res
|
|
117
|
+
|
|
118
|
+
def display_header(title: str):
|
|
119
|
+
console.print(Panel(title, box=box.DOUBLE_EDGE, title_align="left")) # Replace print with Panel
|
|
120
|
+
|
|
121
|
+
def display_subheader(title: str):
|
|
122
|
+
console.print(Panel(title, box=box.ROUNDED, title_align="left")) # Replace print with Panel
|
|
123
|
+
|
|
124
|
+
def display_content(content: str):
|
|
125
|
+
console.print(Panel(content, box=box.ROUNDED, title_align="left")) # Replace print with Panel
|
|
126
|
+
|
|
127
|
+
def display_status(status: str):
|
|
128
|
+
console.print(Panel(status, box=box.ROUNDED, title_align="left")) # Replace print with Panel
|
|
129
|
+
|
|
130
|
+
def display_success(message: str):
|
|
131
|
+
console.print(Panel(message, box=box.ROUNDED, border_style="green", title_align="left")) # Replace print with Panel
|
|
132
|
+
|
|
133
|
+
def display_warning(message: str):
|
|
134
|
+
console.print(Panel(message, box=box.ROUNDED, border_style="yellow", title_align="left")) # Replace print with Panel
|
|
135
|
+
|
|
136
|
+
def display_error(message: str):
|
|
137
|
+
console.print(Panel(message, box=box.ROUNDED, border_style="red", title_align="left")) # Replace print with Panel
|