machineconfig 1.96__py3-none-any.whl ā 2.0__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/cloud_manager.py +22 -26
- machineconfig/cluster/data_transfer.py +2 -2
- machineconfig/cluster/distribute.py +0 -2
- machineconfig/cluster/file_manager.py +4 -4
- machineconfig/cluster/job_params.py +1 -1
- machineconfig/cluster/loader_runner.py +8 -8
- machineconfig/cluster/remote_machine.py +4 -4
- machineconfig/cluster/script_execution.py +2 -2
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
- machineconfig/cluster/sessions_managers/wt_local.py +78 -76
- machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
- machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
- machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
- machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
- machineconfig/cluster/templates/utils.py +3 -3
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
- machineconfig/jobs/python/check_installations.py +8 -9
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/vscode/link_ve.py +7 -7
- machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
- machineconfig/jobs/python/vscode/sync_code.py +5 -5
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
- machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
- machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
- 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 +3 -3
- machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
- machineconfig/jobs/python_custom_installers/docker.py +3 -3
- machineconfig/jobs/python_custom_installers/gh.py +7 -7
- machineconfig/jobs/python_custom_installers/hx.py +1 -1
- machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
- machineconfig/jobs/python_generic_installers/config.json +412 -389
- machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
- machineconfig/logger.py +50 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/profile/create.py +23 -16
- machineconfig/profile/create_hardlinks.py +8 -8
- machineconfig/profile/shell.py +41 -37
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/linux/devops +2 -2
- machineconfig/scripts/linux/fire +1 -0
- machineconfig/scripts/linux/fire_agents +0 -1
- machineconfig/scripts/linux/mcinit +27 -0
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/__init__.cpython-313.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.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
- machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
- machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
- machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
- machineconfig/scripts/python/ai/mcinit.py +103 -0
- machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
- machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
- machineconfig/scripts/python/archive/tmate_conn.py +5 -5
- machineconfig/scripts/python/archive/tmate_start.py +3 -3
- machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
- machineconfig/scripts/python/cloud_copy.py +19 -18
- machineconfig/scripts/python/cloud_mount.py +9 -7
- machineconfig/scripts/python/cloud_repo_sync.py +11 -11
- machineconfig/scripts/python/cloud_sync.py +1 -1
- machineconfig/scripts/python/croshell.py +14 -14
- machineconfig/scripts/python/devops.py +6 -6
- machineconfig/scripts/python/devops_add_identity.py +8 -6
- machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
- machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
- machineconfig/scripts/python/devops_devapps_install.py +3 -3
- machineconfig/scripts/python/devops_update_repos.py +1 -1
- machineconfig/scripts/python/dotfile.py +2 -2
- machineconfig/scripts/python/fire_agents.py +183 -41
- machineconfig/scripts/python/fire_jobs.py +17 -11
- machineconfig/scripts/python/ftpx.py +2 -2
- machineconfig/scripts/python/gh_models.py +94 -94
- 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/cloud_helpers.py +3 -3
- machineconfig/scripts/python/helpers/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers4.py +8 -6
- machineconfig/scripts/python/helpers/helpers5.py +7 -7
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
- machineconfig/scripts/python/mount_nfs.py +3 -2
- machineconfig/scripts/python/mount_nw_drive.py +4 -4
- machineconfig/scripts/python/mount_ssh.py +3 -2
- machineconfig/scripts/python/repos.py +8 -8
- machineconfig/scripts/python/scheduler.py +1 -1
- machineconfig/scripts/python/start_slidev.py +8 -7
- machineconfig/scripts/python/start_terminals.py +1 -1
- machineconfig/scripts/python/viewer.py +40 -40
- machineconfig/scripts/python/wifi_conn.py +65 -66
- machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
- machineconfig/scripts/windows/mcinit.ps1 +4 -0
- machineconfig/settings/linters/.ruff.toml +2 -2
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
- machineconfig/settings/shells/wt/settings.json +8 -8
- machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
- machineconfig/utils/ai/browser_user_wrapper.py +5 -5
- machineconfig/utils/ai/generate_file_checklist.py +11 -12
- machineconfig/utils/ai/url2md.py +1 -1
- machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
- machineconfig/utils/cloud/onedrive/transaction.py +129 -129
- machineconfig/utils/code.py +13 -6
- machineconfig/utils/installer.py +51 -53
- machineconfig/utils/installer_utils/installer_abc.py +21 -10
- machineconfig/utils/installer_utils/installer_class.py +42 -16
- machineconfig/utils/io_save.py +3 -15
- machineconfig/utils/options.py +10 -3
- machineconfig/utils/path.py +5 -0
- machineconfig/utils/path_reduced.py +201 -149
- machineconfig/utils/procs.py +23 -23
- machineconfig/utils/scheduling.py +11 -12
- machineconfig/utils/ssh.py +270 -0
- machineconfig/utils/terminal.py +180 -0
- machineconfig/utils/utils.py +1 -2
- machineconfig/utils/utils2.py +43 -0
- machineconfig/utils/utils5.py +163 -34
- machineconfig/utils/ve.py +2 -2
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/METADATA +13 -8
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/RECORD +163 -144
- machineconfig/cluster/self_ssh.py +0 -57
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/WHEEL +0 -0
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import git
|
|
4
4
|
from machineconfig.utils.path_reduced import P as PathExtended
|
|
5
|
-
from
|
|
5
|
+
from machineconfig.utils.terminal import Terminal
|
|
6
6
|
from machineconfig.utils.utils2 import randstr, read_ini
|
|
7
7
|
|
|
8
8
|
from machineconfig.scripts.python.helpers.repo_sync_helpers import fetch_dotfiles
|
|
@@ -31,14 +31,14 @@ def main(cloud: Optional[str] = None, path: Optional[str] = None, message: Optio
|
|
|
31
31
|
console.print(Panel(f"ā ERROR: No cloud profile found\nLocation: {DEFAULTS_PATH}\nPlease set one up or provide one via the --cloud flag.", title="Error", border_style="red"))
|
|
32
32
|
return ""
|
|
33
33
|
else: cloud_resolved = cloud
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# repo_root = PathExtended(args.repo).expanduser().absolute()
|
|
36
36
|
repo_local_root = PathExtended.cwd() if path is None else PathExtended(path).expanduser().absolute()
|
|
37
37
|
repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
|
|
38
38
|
repo_local_root = PathExtended(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
|
|
39
39
|
CONFIG_PATH.joinpath("remote").mkdir(parents=True, exist_ok=True)
|
|
40
40
|
repo_remote_root = CONFIG_PATH.joinpath("remote", repo_local_root.rel2home()) # .delete(sure=True)
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
try:
|
|
43
43
|
console.print(Panel("š„ DOWNLOADING REMOTE REPOSITORY", title_align="left", border_style="blue"))
|
|
44
44
|
remote_path = repo_local_root.get_remote_path(rel2home=True, os_specific=False, root="myhome") + ".zip.enc"
|
|
@@ -47,7 +47,7 @@ def main(cloud: Optional[str] = None, path: Optional[str] = None, message: Optio
|
|
|
47
47
|
console.print(Panel("š Remote repository doesn't exist\nš¤ Creating new remote and exiting...", title_align="left", border_style="green"))
|
|
48
48
|
repo_local_root.to_cloud(cloud=cloud_resolved, zip=True, encrypt=True, rel2home=True, pwd=pwd, os_specific=False)
|
|
49
49
|
return ""
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
repo_remote_obj = git.Repo(repo_remote_root)
|
|
52
52
|
if repo_remote_obj.is_dirty():
|
|
53
53
|
console.print(Panel(f"ā ļø WARNING: REMOTE REPOSITORY IS DIRTY\nLocation: {repo_remote_root}\nPlease commit or stash changes before proceeding.", title="Warning", border_style="yellow"))
|
|
@@ -129,7 +129,7 @@ git commit -am "finished merging"
|
|
|
129
129
|
# ================================================================================
|
|
130
130
|
|
|
131
131
|
console.print(Panel("š RESOLVE MERGE CONFLICT\nChoose an option to resolve the conflict:", title_align="left", border_style="blue"))
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
print(f"⢠1ļøā£ {option1:75} š {shell_file_1}")
|
|
134
134
|
print(f"⢠2ļøā£ {option2:75} š {shell_file_2}")
|
|
135
135
|
print(f"⢠3ļøā£ {option3:75} š {shell_file_3}")
|
|
@@ -139,18 +139,18 @@ git commit -am "finished merging"
|
|
|
139
139
|
match action:
|
|
140
140
|
case "ask":
|
|
141
141
|
choice = choose_one_option(options=[option1, option2, option3, option4], fzf=False)
|
|
142
|
-
if choice == option1: program_content = shell_file_1.read_text()
|
|
142
|
+
if choice == option1: program_content = shell_file_1.read_text(encoding="utf-8")
|
|
143
143
|
elif choice == option2: program_content = program_2
|
|
144
|
-
elif choice == option3: program_content = shell_file_3.read_text()
|
|
144
|
+
elif choice == option3: program_content = shell_file_3.read_text(encoding="utf-8")
|
|
145
145
|
elif choice == option4: program_content = program_4
|
|
146
146
|
else: raise NotImplementedError(f"Choice {choice} not implemented.")
|
|
147
|
-
case "pushLocalMerge": program_content = shell_file_1.read_text()
|
|
147
|
+
case "pushLocalMerge": program_content = shell_file_1.read_text(encoding="utf-8")
|
|
148
148
|
case "overwriteLocal": program_content = program_2
|
|
149
|
-
case "InspectRepos": program_content = shell_file_3.read_text()
|
|
149
|
+
case "InspectRepos": program_content = shell_file_3.read_text(encoding="utf-8")
|
|
150
150
|
case "RemoveLocalRclone": program_content = program_4
|
|
151
|
-
case _:
|
|
151
|
+
case _:
|
|
152
152
|
raise ValueError(f"Unknown action: {action}")
|
|
153
|
-
PROGRAM_PATH.write_text(program_content)
|
|
153
|
+
PROGRAM_PATH.write_text(program_content, encoding="utf-8")
|
|
154
154
|
return program_content
|
|
155
155
|
|
|
156
156
|
def args_parser():
|
|
@@ -75,7 +75,7 @@ def args_parser():
|
|
|
75
75
|
cmd_line = f"{rclone_cmd[:65]}..."
|
|
76
76
|
console.print(Panel(f"{title}\n{cmd_line}", title="[bold blue]Command[/bold blue]", expand=False))
|
|
77
77
|
|
|
78
|
-
PROGRAM_PATH.write_text(txt)
|
|
78
|
+
PROGRAM_PATH.write_text(txt, encoding="utf-8")
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
if __name__ == '__main__':
|
|
@@ -18,7 +18,7 @@ console = Console()
|
|
|
18
18
|
|
|
19
19
|
def add_print_header_pycode(path: str, title: str):
|
|
20
20
|
return f"""
|
|
21
|
-
# from machineconfig.utils.path_reduced import P as PathExtended
|
|
21
|
+
# from machineconfig.utils.path_reduced import P as PathExtended
|
|
22
22
|
from crocodile.file_management import P as PathExtended
|
|
23
23
|
pycode = PathExtended(r'{path}').read_text(encoding="utf-8")
|
|
24
24
|
pycode = pycode.split("except Exception: print(pycode)")[2]
|
|
@@ -112,7 +112,7 @@ def build_parser():
|
|
|
112
112
|
elif args.fzf:
|
|
113
113
|
text = "š Searching for Python files..."
|
|
114
114
|
console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
|
|
115
|
-
options = PathExtended.cwd().search("*.py", r=True)
|
|
115
|
+
options = [str(item) for item in PathExtended.cwd().search("*.py", r=True)]
|
|
116
116
|
file = display_options(msg="Choose a python file to run", options=options, fzf=True, multi=False, )
|
|
117
117
|
assert isinstance(file, str)
|
|
118
118
|
program = PathExtended(file).read_text(encoding='utf-8')
|
|
@@ -128,16 +128,16 @@ def build_parser():
|
|
|
128
128
|
|
|
129
129
|
elif args.read != "":
|
|
130
130
|
if args.streamlit_viewer:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
#!/bin/bash
|
|
137
|
-
. $HOME/scripts/activate_ve 've'
|
|
138
|
-
streamlit run {py_file_path}
|
|
139
|
-
"""
|
|
140
|
-
|
|
131
|
+
# text = "š STARTING STREAMLIT VIEWER"
|
|
132
|
+
# console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
|
|
133
|
+
# from machineconfig.scripts.python.viewer import run
|
|
134
|
+
# py_file_path = run(data_path=args.read, data=None, get_figure=None)
|
|
135
|
+
# final_program = f"""
|
|
136
|
+
# #!/bin/bash
|
|
137
|
+
# . $HOME/scripts/activate_ve 've'
|
|
138
|
+
# streamlit run {py_file_path}
|
|
139
|
+
# """
|
|
140
|
+
# PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
|
|
141
141
|
return None
|
|
142
142
|
file = PathExtended(str(args.read).lstrip()).expanduser().absolute()
|
|
143
143
|
program = get_read_data_pycode(str(file))
|
|
@@ -187,7 +187,7 @@ print_logo(logo="crocodile")
|
|
|
187
187
|
if interpreter == "ipython":
|
|
188
188
|
fire_line += f" {interactivity} --profile {ipython_profile} --no-banner"
|
|
189
189
|
fire_line += f" {str(pyfile)}"
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
final_program += fire_line
|
|
192
192
|
|
|
193
193
|
title = "š LAUNCHING SCRIPT"
|
|
@@ -196,7 +196,7 @@ print_logo(logo="crocodile")
|
|
|
196
196
|
launch_message = f"{title} {PROGRAM_PATH}\n{text1}\n{text2}"
|
|
197
197
|
console.print(Panel(Text(launch_message, justify="left"), expand=False, border_style="blue"))
|
|
198
198
|
|
|
199
|
-
PROGRAM_PATH.write_text(data=final_program)
|
|
199
|
+
PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
|
|
200
200
|
# (PROGRAM_PATH + ".py").write_text(str(pyfile), encoding='utf-8')
|
|
201
201
|
|
|
202
202
|
# if platform.system() == "Windows":
|
|
@@ -33,7 +33,7 @@ class Options(Enum):
|
|
|
33
33
|
def args_parser():
|
|
34
34
|
# Print header
|
|
35
35
|
console.print(Panel("š ļø DevOps Tool Suite", title_align="left", border_style="blue", width=BOX_WIDTH))
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
import argparse
|
|
38
38
|
parser = argparse.ArgumentParser()
|
|
39
39
|
new_line = "\n\n"
|
|
@@ -67,7 +67,7 @@ def display_task_success(success: str) -> None:
|
|
|
67
67
|
def main(which: Optional[str] = None):
|
|
68
68
|
PROGRAM_PATH.delete(sure=True, verbose=False)
|
|
69
69
|
console.print(Panel("š Initializing DevOps operation...", width=BOX_WIDTH, border_style="blue"))
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
options = [op.value for op in Options]
|
|
72
72
|
if which is None:
|
|
73
73
|
try:
|
|
@@ -128,7 +128,7 @@ def main(which: Optional[str] = None):
|
|
|
128
128
|
console.print(Panel("š¾ Creating backup...", width=BOX_WIDTH, border_style="blue"))
|
|
129
129
|
from machineconfig.scripts.python.devops_backup_retrieve import main_backup_retrieve as helper
|
|
130
130
|
program = helper(direction="BACKUP")
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
elif choice_key == Options.retreive.value:
|
|
133
133
|
console.print(Panel("š„ Retrieving backup...", width=BOX_WIDTH, border_style="blue"))
|
|
134
134
|
from machineconfig.scripts.python.devops_backup_retrieve import main_backup_retrieve as helper
|
|
@@ -145,14 +145,14 @@ def main(which: Optional[str] = None):
|
|
|
145
145
|
from machineconfig.scripts.python.cloud_repo_sync import main as helper, PathExtended
|
|
146
146
|
program = helper(cloud=None, path=str(PathExtended.home() / "dotfiles"), pwd=None, action="ask")
|
|
147
147
|
|
|
148
|
-
else:
|
|
148
|
+
else:
|
|
149
149
|
console.print(Panel("ā ERROR: Invalid choice", title_align="left", border_style="red", width=BOX_WIDTH))
|
|
150
150
|
raise ValueError(f"Unimplemented choice: {choice_key}")
|
|
151
|
-
|
|
151
|
+
|
|
152
152
|
if program:
|
|
153
153
|
console.print(Panel("š Preparing shell script...", width=BOX_WIDTH, border_style="blue"))
|
|
154
154
|
write_shell_script_to_default_program_path(program=program, display=True, preserve_cwd=True, desc="š§ Shell script prepared by Python.", execute=True if which is not None else False)
|
|
155
|
-
else:
|
|
155
|
+
else:
|
|
156
156
|
write_shell_script_to_default_program_path(program="echo '⨠Done.'", display=False, desc="š§ Shell script prepared by Python.", preserve_cwd=True, execute=False)
|
|
157
157
|
|
|
158
158
|
|
|
@@ -17,14 +17,14 @@ def main():
|
|
|
17
17
|
|
|
18
18
|
print(Panel("š Searching for existing SSH keys...", expand=False))
|
|
19
19
|
|
|
20
|
-
private_keys = PathExtended.home().joinpath(".ssh").search("*.pub")
|
|
21
|
-
|
|
20
|
+
private_keys = [x.with_name(x.stem) for x in PathExtended.home().joinpath(".ssh").search("*.pub")]
|
|
21
|
+
private_keys = [x for x in private_keys if x.exists()]
|
|
22
22
|
if private_keys:
|
|
23
23
|
print(Panel(f"ā
Found {len(private_keys)} SSH private key(s)", expand=False))
|
|
24
24
|
else:
|
|
25
25
|
print(Panel("ā ļø No SSH private keys found", expand=False))
|
|
26
26
|
|
|
27
|
-
choice = display_options(msg="Path to private key to be used when ssh'ing: ", options=
|
|
27
|
+
choice = display_options(msg="Path to private key to be used when ssh'ing: ", options=[str(x) for x in private_keys] + ["I have the path to the key file", "I want to paste the key itself"])
|
|
28
28
|
|
|
29
29
|
if choice == "I have the path to the key file":
|
|
30
30
|
print(Panel("š Please enter the path to your private key file", expand=False))
|
|
@@ -34,7 +34,9 @@ def main():
|
|
|
34
34
|
elif choice == "I want to paste the key itself":
|
|
35
35
|
print(Panel("š Please provide a filename and paste the private key content", expand=False))
|
|
36
36
|
key_filename = input("š File name (default: my_pasted_key): ") or "my_pasted_key"
|
|
37
|
-
path_to_key = PathExtended.home().joinpath(f".ssh/{key_filename}")
|
|
37
|
+
path_to_key = PathExtended.home().joinpath(f".ssh/{key_filename}")
|
|
38
|
+
path_to_key.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
path_to_key.write_text(input("š Paste the private key here: "), encoding="utf-8")
|
|
38
40
|
print(Panel(f"š¾ Key saved to: {path_to_key}", expand=False))
|
|
39
41
|
|
|
40
42
|
elif isinstance(choice, str):
|
|
@@ -55,7 +57,7 @@ def main():
|
|
|
55
57
|
# - If file doesn't exist, seed content with txt_search
|
|
56
58
|
# - Then run modify_text to replace/append accordingly and write back
|
|
57
59
|
if config_path.exists():
|
|
58
|
-
current = config_path.read_text()
|
|
60
|
+
current = config_path.read_text(encoding="utf-8")
|
|
59
61
|
print(Panel("āļø Updated existing SSH config file", expand=False))
|
|
60
62
|
else:
|
|
61
63
|
current = txt
|
|
@@ -68,7 +70,7 @@ def main():
|
|
|
68
70
|
notfound_append=True,
|
|
69
71
|
prepend=True,
|
|
70
72
|
)
|
|
71
|
-
config_path.write_text(new_content)
|
|
73
|
+
config_path.write_text(new_content, encoding="utf-8")
|
|
72
74
|
|
|
73
75
|
panel_complete = Panel(
|
|
74
76
|
Text(
|
|
@@ -28,11 +28,11 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
|
28
28
|
|
|
29
29
|
if authorized_keys.exists():
|
|
30
30
|
split = "\n"
|
|
31
|
-
keys_text = authorized_keys.read_text().split(split)
|
|
31
|
+
keys_text = authorized_keys.read_text(encoding="utf-8").split(split)
|
|
32
32
|
key_count = len([k for k in keys_text if k.strip()])
|
|
33
33
|
console.print(Panel(f"š Current SSH authorization status\nā
Found {key_count} authorized key(s)", title="[bold blue]Status[/bold blue]"))
|
|
34
34
|
|
|
35
|
-
if path_to_key.read_text() in authorized_keys.read_text():
|
|
35
|
+
if path_to_key.read_text(encoding="utf-8") in authorized_keys.read_text(encoding="utf-8"):
|
|
36
36
|
console.print(Panel(f"ā ļø Key already authorized\nKey: {path_to_key.name}\nStatus: Already present in authorized_keys file\nNo action required", title="[bold yellow]Warning[/bold yellow]"))
|
|
37
37
|
program = ""
|
|
38
38
|
else:
|
|
@@ -41,7 +41,7 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
|
41
41
|
program = f"cat {path_to_key} >> ~/.ssh/authorized_keys"
|
|
42
42
|
elif system() == "Windows":
|
|
43
43
|
program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
|
|
44
|
-
program = program_path.expanduser().read_text()
|
|
44
|
+
program = program_path.expanduser().read_text(encoding="utf-8")
|
|
45
45
|
place_holder = r'$sshfile = "$env:USERPROFILE\.ssh\pubkey.pub"'
|
|
46
46
|
assert place_holder in program, f"This section performs string manipulation on the script {program_path} to add the key to the authorized_keys file. The script has changed and the string {place_holder} is not found."
|
|
47
47
|
program = program.replace(place_holder, f'$sshfile = "{path_to_key}"')
|
|
@@ -53,7 +53,7 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
|
|
|
53
53
|
program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
|
|
54
54
|
else:
|
|
55
55
|
program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
|
|
56
|
-
program = PathExtended(program_path).expanduser().read_text().replace('$sshfile=""', f'$sshfile="{path_to_key}"')
|
|
56
|
+
program = PathExtended(program_path).expanduser().read_text(encoding="utf-8").replace('$sshfile=""', f'$sshfile="{path_to_key}"')
|
|
57
57
|
console.print(Panel("š§ Configured PowerShell script for Windows\nš Set key path in script", title="[bold blue]Configuration[/bold blue]"))
|
|
58
58
|
|
|
59
59
|
if system() == "Linux":
|
|
@@ -70,47 +70,47 @@ sudo service ssh --full-restart
|
|
|
70
70
|
|
|
71
71
|
def main():
|
|
72
72
|
console.print(Panel("š SSH PUBLIC KEY AUTHORIZATION TOOL", box=box.DOUBLE_EDGE, title_align="left"))
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
console.print(Panel("š Searching for public keys...", title="[bold blue]SSH Setup[/bold blue]", border_style="blue"))
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
pub_keys = PathExtended.home().joinpath(".ssh").search("*.pub")
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
if pub_keys:
|
|
79
79
|
console.print(Panel(f"ā
Found {len(pub_keys)} public key(s)", title="[bold green]Status[/bold green]", border_style="green"))
|
|
80
80
|
else:
|
|
81
81
|
console.print(Panel("ā ļø No public keys found", title="[bold yellow]Warning[/bold yellow]", border_style="yellow"))
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
all_keys_option = f"all pub keys available ({len(pub_keys)})"
|
|
84
84
|
i_have_path_option = "I have the path to the key file"
|
|
85
85
|
i_paste_option = "I want to paste the key itself"
|
|
86
|
-
|
|
87
|
-
res = display_options("Which public key to add? ", options=
|
|
86
|
+
|
|
87
|
+
res = display_options("Which public key to add? ", options=[str(x) for x in pub_keys] + [all_keys_option, i_have_path_option, i_paste_option])
|
|
88
88
|
assert isinstance(res, str), f"Got {res} of type {type(res)} instead of str."
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
if res == all_keys_option:
|
|
91
91
|
console.print(Panel(f"š Processing all {len(pub_keys)} public keys...", title="[bold blue]Processing[/bold blue]", border_style="blue"))
|
|
92
|
-
program = "\n\n\n".join(
|
|
93
|
-
|
|
92
|
+
program = "\n\n\n".join([get_add_ssh_key_script(key) for key in pub_keys])
|
|
93
|
+
|
|
94
94
|
elif res == i_have_path_option:
|
|
95
95
|
console.print(Panel("š Please provide the path to your public key", title="[bold blue]Input Required[/bold blue]", border_style="blue"))
|
|
96
96
|
key_path = PathExtended(input("š Path: ")).expanduser().absolute()
|
|
97
97
|
console.print(Panel(f"š Using key from path: {key_path}", title="[bold blue]Info[/bold blue]", border_style="blue"))
|
|
98
98
|
program = get_add_ssh_key_script(key_path)
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
elif res == i_paste_option:
|
|
101
101
|
console.print(Panel("š Please provide a filename and paste the public key content", title="[bold blue]Input Required[/bold blue]", border_style="blue"))
|
|
102
102
|
key_filename = input("š File name (default: my_pasted_key.pub): ") or "my_pasted_key.pub"
|
|
103
103
|
key_path = PathExtended.home().joinpath(f".ssh/{key_filename}")
|
|
104
|
-
key_path.write_text(input("š Paste the public key here: "))
|
|
104
|
+
key_path.write_text(input("š Paste the public key here: "), encoding="utf-8")
|
|
105
105
|
console.print(Panel(f"š¾ Key saved to: {key_path}", title="[bold green]Success[/bold green]", border_style="green"))
|
|
106
106
|
program = get_add_ssh_key_script(key_path)
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
else:
|
|
109
109
|
console.print(Panel(f"š Using selected key: {PathExtended(res).name}", title="[bold blue]Info[/bold blue]", border_style="blue"))
|
|
110
110
|
program = get_add_ssh_key_script(PathExtended(res))
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
console.print(Panel("š SSH KEY AUTHORIZATION READY\nRun the generated script to apply changes", box=box.DOUBLE_EDGE, title_align="left"))
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
return program
|
|
115
115
|
|
|
116
116
|
|
|
@@ -17,7 +17,7 @@ OPTIONS = Literal["BACKUP", "RETRIEVE"]
|
|
|
17
17
|
|
|
18
18
|
def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None):
|
|
19
19
|
console = Console()
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
try:
|
|
22
22
|
cloud: str = read_ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
23
23
|
console.print(Panel(f"ā ļø DEFAULT CLOUD CONFIGURATION\nš„ļø Using default cloud: {cloud}", title="[bold blue]Cloud Configuration[/bold blue]", border_style="blue"))
|
|
@@ -26,13 +26,13 @@ def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None):
|
|
|
26
26
|
cloud = choose_cloud_interactively()
|
|
27
27
|
|
|
28
28
|
bu_file: dict[str, Any] = read_toml(LIBRARY_ROOT.joinpath("profile/backup.toml"))
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
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"))
|
|
31
|
-
|
|
32
|
-
if system() == "Linux":
|
|
31
|
+
|
|
32
|
+
if system() == "Linux":
|
|
33
33
|
bu_file = {key: val for key, val in bu_file.items() if "windows" not in key}
|
|
34
34
|
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"))
|
|
35
|
-
elif system() == "Windows":
|
|
35
|
+
elif system() == "Windows":
|
|
36
36
|
bu_file = {key: val for key, val in bu_file.items() if "linux" not in key}
|
|
37
37
|
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"))
|
|
38
38
|
|
|
@@ -59,14 +59,14 @@ def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None):
|
|
|
59
59
|
flags += 'o' if system().lower() in item_name else ''
|
|
60
60
|
console.print(Panel(f"š¦ PROCESSING: {item_name}\nš Path: {PathExtended(item['path']).as_posix()}\nš³ļø Flags: {flags or 'None'}", title=f"[bold blue]Processing Item: {item_name}[/bold blue]", border_style="blue"))
|
|
61
61
|
if flags: flags = "-" + flags
|
|
62
|
-
if direction == "BACKUP":
|
|
62
|
+
if direction == "BACKUP":
|
|
63
63
|
program += f"""\ncloud_copy "{PathExtended(item['path']).as_posix()}" $cloud {flags}\n"""
|
|
64
|
-
elif direction == "RETRIEVE":
|
|
64
|
+
elif direction == "RETRIEVE":
|
|
65
65
|
program += f"""\ncloud_copy $cloud "{PathExtended(item['path']).as_posix()}" {flags}\n"""
|
|
66
66
|
else:
|
|
67
67
|
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"))
|
|
68
|
-
raise RuntimeError(f"Unknown direction: {direction}")
|
|
69
|
-
if item_name == "dotfiles" and system() == "Linux":
|
|
68
|
+
raise RuntimeError(f"Unknown direction: {direction}")
|
|
69
|
+
if item_name == "dotfiles" and system() == "Linux":
|
|
70
70
|
program += """\nchmod 700 ~/.ssh/*\n"""
|
|
71
71
|
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"))
|
|
72
72
|
print_code(program, lexer="shell", desc=f"{direction} script")
|
|
@@ -76,14 +76,14 @@ def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None):
|
|
|
76
76
|
|
|
77
77
|
def main(direction: OPTIONS, which: Optional[str] = None):
|
|
78
78
|
console = Console()
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
console.print(Panel(f"š {direction} OPERATION STARTED\nā±ļø {'-' * 58}", title="[bold blue]Operation Initiated[/bold blue]", border_style="blue"))
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
code = main_backup_retrieve(direction=direction, which=which)
|
|
83
83
|
from machineconfig.utils.utils import write_shell_script_to_default_program_path
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
console.print(Panel("š¾ GENERATING SHELL SCRIPT\nš Filename: backup_retrieve.sh", title="[bold blue]Shell Script Generation[/bold blue]", border_style="blue"))
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
write_shell_script_to_default_program_path(program=code, desc="backup_retrieve.sh", preserve_cwd=True, display=True, execute=False)
|
|
88
88
|
|
|
89
89
|
|
|
@@ -70,10 +70,10 @@ def get_programs_by_category(program_name: WHICH_CAT):
|
|
|
70
70
|
program = ""
|
|
71
71
|
|
|
72
72
|
case "SystemInstallers":
|
|
73
|
-
if system() == "Windows": options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text())
|
|
73
|
+
if system() == "Windows": options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text(encoding="utf-8"))
|
|
74
74
|
elif system() == "Linux":
|
|
75
|
-
options_system_1 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps_dev.sh").read_text())
|
|
76
|
-
options_system_2 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps.sh").read_text())
|
|
75
|
+
options_system_1 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps_dev.sh").read_text(encoding="utf-8"))
|
|
76
|
+
options_system_2 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps.sh").read_text(encoding="utf-8"))
|
|
77
77
|
options_system = {**options_system_1, **options_system_2}
|
|
78
78
|
else: raise NotImplementedError(f"ā System {system()} not supported")
|
|
79
79
|
program_names = choose_multiple_options(msg="", options=sorted(list(options_system.keys())), header="š CHOOSE DEV APP")
|
|
@@ -26,7 +26,7 @@ def main(verbose: bool=True) -> str:
|
|
|
26
26
|
print("""
|
|
27
27
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
28
28
|
ā ⨠Example Configuration:
|
|
29
|
-
ā
|
|
29
|
+
ā
|
|
30
30
|
ā [general]
|
|
31
31
|
ā repos = ~/code/repo1,~/code/repo2
|
|
32
32
|
ā rclone_config_name = onedrivePersonal
|
|
@@ -25,7 +25,7 @@ def main():
|
|
|
25
25
|
elif ".config" in str(orig_path): junction = orig_path.split(at=".config", sep=-1)[1]
|
|
26
26
|
else: junction = orig_path.rel2home()
|
|
27
27
|
new_path = REPO_ROOT.joinpath(junction)
|
|
28
|
-
else:
|
|
28
|
+
else:
|
|
29
29
|
dest_path = PathExtended(args.dest).expanduser().absolute()
|
|
30
30
|
dest_path.mkdir(parents=True, exist_ok=True)
|
|
31
31
|
new_path = dest_path.joinpath(orig_path.name)
|
|
@@ -35,7 +35,7 @@ def main():
|
|
|
35
35
|
print("""
|
|
36
36
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
37
37
|
ā ā
Symbolic Link Created Successfully
|
|
38
|
-
ā
|
|
38
|
+
ā
|
|
39
39
|
ā š To enshrine this mapping, add the following to mapper.toml:
|
|
40
40
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā""")
|
|
41
41
|
print(f"""
|