machineconfig 1.5__py3-none-any.whl → 1.8__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/__init__.py +8 -5
- machineconfig/jobs/python/check_installations.py +173 -163
- machineconfig/jobs/python/checkout_version.py +117 -0
- machineconfig/jobs/python/create_bootable_media.py +14 -14
- machineconfig/jobs/python/create_zellij_template.py +59 -56
- machineconfig/jobs/python/python_cargo_build_share.py +50 -45
- machineconfig/jobs/python/python_ve_symlink.py +20 -18
- machineconfig/jobs/python/tasks.py +4 -0
- machineconfig/jobs/script_installer/azure_data_studio.py +22 -0
- machineconfig/jobs/script_installer/bypass_paywall.py +23 -0
- machineconfig/jobs/script_installer/code.py +34 -0
- machineconfig/jobs/script_installer/docker_desktop.py +41 -0
- machineconfig/jobs/script_installer/ngrok.py +29 -0
- machineconfig/jobs/{python_linux_installers → script_installer}/skim.py +21 -19
- machineconfig/jobs/script_installer/wezterm.py +34 -0
- machineconfig/profile/create.py +107 -200
- machineconfig/profile/shell.py +127 -0
- machineconfig/scripts/__init__.py +6 -6
- machineconfig/scripts/python/cloud_copy.py +93 -0
- machineconfig/scripts/python/cloud_manager.py +38 -0
- machineconfig/scripts/python/cloud_mount.py +115 -52
- machineconfig/scripts/python/cloud_repo_sync.py +154 -114
- machineconfig/scripts/python/cloud_sync.py +261 -79
- machineconfig/scripts/python/croshell.py +151 -0
- machineconfig/scripts/python/devops.py +119 -87
- machineconfig/scripts/python/devops_add_identity.py +27 -23
- machineconfig/scripts/python/devops_add_ssh_key.py +70 -55
- machineconfig/scripts/python/devops_backup_retrieve.py +52 -46
- machineconfig/scripts/python/devops_devapps_install.py +120 -91
- machineconfig/scripts/python/devops_update_repos.py +82 -68
- machineconfig/scripts/python/dotfile.py +42 -38
- machineconfig/scripts/python/fire_jobs.py +351 -98
- machineconfig/scripts/python/ftpx.py +82 -0
- machineconfig/scripts/python/mount_nfs.py +54 -3
- machineconfig/scripts/python/mount_nw_drive.py +31 -0
- machineconfig/scripts/python/mount_ssh.py +44 -20
- machineconfig/scripts/python/onetimeshare.py +60 -51
- machineconfig/scripts/python/pomodoro.py +41 -37
- machineconfig/scripts/python/repos.py +195 -128
- machineconfig/scripts/python/scheduler.py +52 -0
- machineconfig/scripts/python/snapshot.py +21 -21
- machineconfig/scripts/python/start_slidev.py +104 -0
- machineconfig/scripts/python/start_terminals.py +97 -0
- machineconfig/scripts/python/wifi_conn.py +90 -71
- machineconfig/scripts/python/{transfer_wsl_win.py → wsl_windows_transfer.py} +47 -39
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +44 -48
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +136 -130
- machineconfig/utils/installer.py +251 -0
- machineconfig/utils/procs.py +114 -64
- machineconfig/utils/scheduling.py +188 -0
- machineconfig/utils/utils.py +353 -249
- machineconfig/utils/ve.py +222 -0
- {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/METADATA +140 -110
- machineconfig-1.8.dist-info/RECORD +70 -0
- {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/WHEEL +1 -1
- machineconfig/jobs/python/python_linux_installers_all.py +0 -73
- machineconfig/jobs/python/python_ve_installer.py +0 -73
- machineconfig/jobs/python/python_windows_installers_all.py +0 -23
- machineconfig/jobs/python_generic_installers/archive/nvim.py +0 -15
- machineconfig/jobs/python_generic_installers/archive/strongbox.py +0 -32
- machineconfig/jobs/python_generic_installers/archive/vtm.py +0 -25
- machineconfig/jobs/python_generic_installers/broot.py +0 -39
- machineconfig/jobs/python_generic_installers/browsh.py +0 -25
- machineconfig/jobs/python_generic_installers/bw.py +0 -26
- machineconfig/jobs/python_generic_installers/chatgpt.py +0 -24
- machineconfig/jobs/python_generic_installers/cpufetch.py +0 -23
- machineconfig/jobs/python_generic_installers/delta.py +0 -59
- machineconfig/jobs/python_generic_installers/dev/__init__.py +0 -0
- machineconfig/jobs/python_generic_installers/dev/autogpt.py +0 -28
- machineconfig/jobs/python_generic_installers/dev/bw.py +0 -29
- machineconfig/jobs/python_generic_installers/dev/evcxr.py +0 -22
- machineconfig/jobs/python_generic_installers/dev/kondo.py +0 -21
- machineconfig/jobs/python_generic_installers/dev/lvim.py +0 -60
- machineconfig/jobs/python_generic_installers/dev/ngrok.py +0 -35
- machineconfig/jobs/python_generic_installers/dev/opencommit.py +0 -21
- machineconfig/jobs/python_generic_installers/dev/qrcp.py +0 -25
- machineconfig/jobs/python_generic_installers/dev/qrscan.py +0 -16
- machineconfig/jobs/python_generic_installers/dev/rust-analyzer.py +0 -24
- machineconfig/jobs/python_generic_installers/dev/termscp.py +0 -23
- machineconfig/jobs/python_generic_installers/dev/tldr.py +0 -25
- machineconfig/jobs/python_generic_installers/dev/tokei.py +0 -24
- machineconfig/jobs/python_generic_installers/diskonaut.py +0 -26
- machineconfig/jobs/python_generic_installers/dua.py +0 -21
- machineconfig/jobs/python_generic_installers/evcxr.py +0 -21
- machineconfig/jobs/python_generic_installers/gitui.py +0 -23
- machineconfig/jobs/python_generic_installers/gopass.py +0 -19
- machineconfig/jobs/python_generic_installers/helix.py +0 -45
- machineconfig/jobs/python_generic_installers/kondo.py +0 -20
- machineconfig/jobs/python_generic_installers/lf.py +0 -25
- machineconfig/jobs/python_generic_installers/lvim.py +0 -34
- machineconfig/jobs/python_generic_installers/mprocs.py +0 -20
- machineconfig/jobs/python_generic_installers/navi.py +0 -20
- machineconfig/jobs/python_generic_installers/ots.py +0 -26
- machineconfig/jobs/python_generic_installers/ouch.py +0 -25
- machineconfig/jobs/python_generic_installers/pomodoro.py +0 -19
- machineconfig/jobs/python_generic_installers/procs.py +0 -20
- machineconfig/jobs/python_generic_installers/qrcp.py +0 -22
- machineconfig/jobs/python_generic_installers/qrscan.py +0 -14
- machineconfig/jobs/python_generic_installers/rclone.py +0 -21
- machineconfig/jobs/python_generic_installers/rust-analyzer.py +0 -24
- machineconfig/jobs/python_generic_installers/tere.py +0 -26
- machineconfig/jobs/python_generic_installers/termscp.py +0 -23
- machineconfig/jobs/python_generic_installers/tldr.py +0 -24
- machineconfig/jobs/python_generic_installers/tokei.py +0 -21
- machineconfig/jobs/python_generic_installers/vtm.py +0 -26
- machineconfig/jobs/python_generic_installers/watchexec.py +0 -21
- machineconfig/jobs/python_linux_installers/archive/__init__.py +0 -0
- machineconfig/jobs/python_linux_installers/archive/ranger.py +0 -18
- machineconfig/jobs/python_linux_installers/bandwhich.py +0 -11
- machineconfig/jobs/python_linux_installers/bottom.py +0 -17
- machineconfig/jobs/python_linux_installers/btop.py +0 -17
- machineconfig/jobs/python_linux_installers/dev/bandwhich.py +0 -13
- machineconfig/jobs/python_linux_installers/dev/bytehound.py +0 -20
- machineconfig/jobs/python_linux_installers/dev/nnn.py +0 -21
- machineconfig/jobs/python_linux_installers/gotty.py +0 -16
- machineconfig/jobs/python_linux_installers/joshuto.py +0 -28
- machineconfig/jobs/python_linux_installers/mcfly.py +0 -12
- machineconfig/jobs/python_linux_installers/nnn.py +0 -18
- machineconfig/jobs/python_linux_installers/topgrade.py +0 -15
- machineconfig/jobs/python_linux_installers/viu.py +0 -19
- machineconfig/jobs/python_linux_installers/xplr.py +0 -22
- machineconfig/jobs/python_linux_installers/zellij.py +0 -31
- machineconfig/jobs/python_windows_installers/archive/ntop.py +0 -20
- machineconfig/jobs/python_windows_installers/bat.py +0 -16
- machineconfig/jobs/python_windows_installers/boxes.py +0 -19
- machineconfig/jobs/python_windows_installers/bypass_paywall.py +0 -18
- machineconfig/jobs/python_windows_installers/dev/bypass_paywall.py +0 -21
- machineconfig/jobs/python_windows_installers/dev/obs_background_removal_plugin.py +0 -20
- machineconfig/jobs/python_windows_installers/fd.py +0 -17
- machineconfig/jobs/python_windows_installers/fzf.py +0 -19
- machineconfig/jobs/python_windows_installers/obs_background_removal_plugin.py +0 -19
- machineconfig/jobs/python_windows_installers/rg.py +0 -15
- machineconfig/jobs/python_windows_installers/ugrep.py +0 -14
- machineconfig/jobs/python_windows_installers/zoomit.py +0 -20
- machineconfig/jobs/python_windows_installers/zoxide.py +0 -20
- machineconfig/profile/fix_shell_profiles.py +0 -8
- machineconfig/scripts/python/archive/__init__.py +0 -0
- machineconfig/scripts/python/archive/bu_gdrive_rx.py +0 -41
- machineconfig/scripts/python/archive/bu_gdrive_sx.py +0 -40
- machineconfig/scripts/python/archive/bu_onedrive_rx.py +0 -59
- machineconfig/scripts/python/archive/bu_onedrive_sx.py +0 -45
- machineconfig/scripts/python/chatgpt.py +0 -28
- machineconfig/scripts/python/choose_ohmybash_theme.py +0 -25
- machineconfig/scripts/python/choose_ohmyposh_theme.py +0 -40
- machineconfig/scripts/python/cloud_rx.py +0 -42
- machineconfig/scripts/python/cloud_sx.py +0 -40
- machineconfig/scripts/python/ftprx.py +0 -37
- machineconfig/scripts/python/ftpsx.py +0 -36
- machineconfig/scripts/python/im2text.py +0 -15
- machineconfig/scripts/python/tmate_conn.py +0 -28
- machineconfig/scripts/python/tmate_start.py +0 -31
- machineconfig/utils/to_exe.py +0 -7
- machineconfig-1.5.dist-info/RECORD +0 -147
- /machineconfig/jobs/{python_generic_installers/archive → script_installer}/__init__.py +0 -0
- {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/top_level.txt +0 -0
machineconfig/__init__.py
CHANGED
|
@@ -1,163 +1,173 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
else: raise NotImplementedError(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
1
|
+
|
|
2
|
+
"""CI
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import time
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import platform
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
# from rich.progress import track
|
|
11
|
+
from machineconfig.utils.utils import LIBRARY_ROOT, INSTALL_VERSION_ROOT
|
|
12
|
+
from machineconfig.utils.installer import get_installed_cli_apps
|
|
13
|
+
from crocodile.core import List as L, install_n_import, Struct
|
|
14
|
+
from crocodile.file_management import P
|
|
15
|
+
from crocodile.meta import Terminal
|
|
16
|
+
from tqdm import tqdm
|
|
17
|
+
from typing import Optional
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lower()}/apps_summary_report.csv")
|
|
21
|
+
CLOUD: str = "gdw" # Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
22
|
+
# my onedrive doesn't allow sharing.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def scan(path: P, pct: float = 0.0):
|
|
26
|
+
vt = install_n_import(library="vt", package="vt-py")
|
|
27
|
+
client = vt.Client(P.home().joinpath("dotfiles/creds/tokens/virustotal").read_text().split("\n")[0])
|
|
28
|
+
console = Console()
|
|
29
|
+
console.rule(f"Scanning {path}. {pct:.2f}% done")
|
|
30
|
+
if path.is_dir():
|
|
31
|
+
print(f"Skipping {path} as it is a directory.")
|
|
32
|
+
return None
|
|
33
|
+
with open(str(path), "rb") as f:
|
|
34
|
+
analysis = client.scan_file(f)
|
|
35
|
+
repeat_counter = 0
|
|
36
|
+
while True:
|
|
37
|
+
with console.status(f"waiting for scan of {path} ... "):
|
|
38
|
+
try:
|
|
39
|
+
anal = client.get_object("/analyses/{}", analysis.id)
|
|
40
|
+
if anal.status == "completed": break
|
|
41
|
+
except Exception as ex: # type: ignore
|
|
42
|
+
repeat_counter += 1
|
|
43
|
+
if repeat_counter > 2:
|
|
44
|
+
raise ValueError(f"Error in scanning {path}") from ex
|
|
45
|
+
print(f"Error in scanning, trying again.")
|
|
46
|
+
time.sleep(30)
|
|
47
|
+
df = pd.DataFrame(anal.results.values())
|
|
48
|
+
malicious = []
|
|
49
|
+
for _idx, row in df.iterrows():
|
|
50
|
+
# try:
|
|
51
|
+
# print(row.result)
|
|
52
|
+
# except Exception as ex: # type: ignore
|
|
53
|
+
# print(row)
|
|
54
|
+
if row.result is None and row.category in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]: continue
|
|
55
|
+
else:
|
|
56
|
+
Struct(row.to_dict()).print(as_config=True, title=f"Found Category {row.category}")
|
|
57
|
+
malicious.append(row)
|
|
58
|
+
positive_pct: float = round(number=len(malicious) / len(df) * 100, ndigits=1)
|
|
59
|
+
print(f"positive_ratio = {positive_pct:.1f} %")
|
|
60
|
+
return positive_pct, df
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def main() -> None:
|
|
64
|
+
apps_paths_tmp: L[P] = get_installed_cli_apps()
|
|
65
|
+
versions_files_paths: L[P] = INSTALL_VERSION_ROOT.search()
|
|
66
|
+
app_versions: list[Optional[str]] = []
|
|
67
|
+
apps_paths_raw: L[P] = L([])
|
|
68
|
+
for an_app in apps_paths_tmp:
|
|
69
|
+
version_path = versions_files_paths.filter(lambda x: x.stem == an_app.stem)
|
|
70
|
+
if len(version_path) == 1:
|
|
71
|
+
app_versions.append(version_path.list[0].read_text())
|
|
72
|
+
apps_paths_raw.append(an_app)
|
|
73
|
+
# if an_app.stem in versions_files_paths.stem:
|
|
74
|
+
# app_versions.append(versions_files_paths.filter(lambda x: x.stem == an_app.stem.replace(".exe", "")).list[0].read_text())
|
|
75
|
+
# else:
|
|
76
|
+
# print(f"🤔 Cloud not find a documented version for installation of {an_app.stem}, trying to get it from the app itself.")
|
|
77
|
+
# tmp = Terminal().run(f"{an_app.stem} --version", shell="powershell").capture().op_if_successfull_or_default(strict_err=False, strict_returcode=False)
|
|
78
|
+
# if tmp is not None: tmp = tmp.split("\n")[0]
|
|
79
|
+
# print(f"➡️ Found version `{tmp}` for {an_app.stem}.")
|
|
80
|
+
# app_versions.append(None)
|
|
81
|
+
print(f"Checking tools collected from `{INSTALL_VERSION_ROOT}`:")
|
|
82
|
+
apps_paths_raw.print()
|
|
83
|
+
positive_pct: list[Optional[float]] = []
|
|
84
|
+
detailed_results: list[dict[str, Optional[pd.DataFrame]]] = []
|
|
85
|
+
for idx, app in enumerate(apps_paths_raw):
|
|
86
|
+
try: res = scan(path=app, pct=idx / len(apps_paths_raw) * 100)
|
|
87
|
+
except ValueError as ve:
|
|
88
|
+
print(ve)
|
|
89
|
+
res = None
|
|
90
|
+
if res is None:
|
|
91
|
+
positive_pct.append(None)
|
|
92
|
+
detailed_results.append({app.stem: None})
|
|
93
|
+
else:
|
|
94
|
+
ppct, df = res
|
|
95
|
+
positive_pct.append(ppct)
|
|
96
|
+
detailed_results.append({app.stem: df})
|
|
97
|
+
|
|
98
|
+
res_df = pd.DataFrame({"app_name": apps_paths_raw.apply(lambda x: x.stem).list, "version": app_versions, "positive_pct": positive_pct,
|
|
99
|
+
"app_path": apps_paths_raw.apply(lambda x: x.collapseuser(strict=False).as_posix()).list})
|
|
100
|
+
|
|
101
|
+
app_url: list[Optional[str]] = []
|
|
102
|
+
for idx, row in tqdm(res_df.iterrows(), total=res_df.shape[0]):
|
|
103
|
+
apps_safe_url = upload(P(str(row["app_path"])).expanduser())
|
|
104
|
+
app_url.append(apps_safe_url.as_posix() if type(apps_safe_url) is P else apps_safe_url)
|
|
105
|
+
res_df["app_url"] = app_url
|
|
106
|
+
res_df.to_csv(APP_SUMMARY_PATH.with_suffix(".csv").create(parents_only=True), index=False)
|
|
107
|
+
APP_SUMMARY_PATH.with_suffix(".md").write_text(res_df.to_markdown())
|
|
108
|
+
print(f"Safety Report:")
|
|
109
|
+
print(res_df)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def upload(path: P):
|
|
113
|
+
set_time_out = install_n_import("call_function_with_timeout").SetTimeout
|
|
114
|
+
func_with_timeout = set_time_out(lambda: path.to_cloud(CLOUD, rel2home=True, share=True, os_specific=True), timeout=180)
|
|
115
|
+
is_done, _is_timeout, _erro_message, results = func_with_timeout()
|
|
116
|
+
if is_done: return results
|
|
117
|
+
else: return None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class PrecheckedCloudInstaller:
|
|
121
|
+
def __init__(self):
|
|
122
|
+
install_n_import("gdown")
|
|
123
|
+
self.df = pd.read_csv(APP_SUMMARY_PATH)
|
|
124
|
+
|
|
125
|
+
@staticmethod
|
|
126
|
+
def download_google_links(url: str):
|
|
127
|
+
# if "drive.google.com" in str(url): url = str(url).replace("open?", "uc?")
|
|
128
|
+
# else: raise NotImplementedError("Only google drive is supported for now.")
|
|
129
|
+
# return P(url).download(name=name)
|
|
130
|
+
gdrive_id = P(url).parts[-1].split("id=")[1]
|
|
131
|
+
gdown = install_n_import("gdown")
|
|
132
|
+
result = P(gdown.download(id=gdrive_id)).absolute()
|
|
133
|
+
return result
|
|
134
|
+
|
|
135
|
+
@staticmethod
|
|
136
|
+
def install_cli_apps(app_url: str):
|
|
137
|
+
try:
|
|
138
|
+
exe = PrecheckedCloudInstaller.download_google_links(app_url)
|
|
139
|
+
except Exception as ex: # type: ignore
|
|
140
|
+
print(f"Error in downloading {app_url} {ex}")
|
|
141
|
+
return None
|
|
142
|
+
if platform.system().lower() == "linux":
|
|
143
|
+
Terminal().run(f"chmod +x {exe}")
|
|
144
|
+
Terminal().run(f"mv {exe} /usr/local/bin/")
|
|
145
|
+
elif platform.system().lower() == "windows":
|
|
146
|
+
exe.move(folder=P.home().joinpath("AppData/Local/Microsoft/WindowsApps"), overwrite=True)
|
|
147
|
+
return True
|
|
148
|
+
|
|
149
|
+
def download_safe_apps(self, name: str = "AllEssentials"):
|
|
150
|
+
# if platform.system().lower() == "windows":
|
|
151
|
+
# from machineconfig.jobs.python.python_windows_installers_all import get_cli_py_installers
|
|
152
|
+
# cli_installers = get_cli_py_installers()
|
|
153
|
+
# elif platform.system().lower() == "linux":
|
|
154
|
+
# from machineconfig.jobs.python.python_linux_installers_all import get_cli_py_installers
|
|
155
|
+
# cli_installers = get_cli_py_installers()
|
|
156
|
+
# else: raise NotImplementedError(f"Platform {platform.system().lower()} is not supported yet.")
|
|
157
|
+
|
|
158
|
+
if name == "AllEssentials":
|
|
159
|
+
print(f"Downloading {self.df.shape[0]} apps ...")
|
|
160
|
+
print(self.df)
|
|
161
|
+
_res = L(self.df.app_url).apply(PrecheckedCloudInstaller.install_cli_apps, jobs=20)
|
|
162
|
+
else:
|
|
163
|
+
app_url = self.df[self.df.app_name == name].iloc[0].app_url
|
|
164
|
+
_res = PrecheckedCloudInstaller.install_cli_apps(app_url=app_url)
|
|
165
|
+
|
|
166
|
+
# print("\n" * 3)
|
|
167
|
+
# for item_flag, item_name in zip(res, self.df["app_name"]):
|
|
168
|
+
# if item_flag: print(f"✅ {item_name} is installed. 😁")
|
|
169
|
+
# else: print(f"❌ {item_name} failed to install for reasons explained in the log above, try manually.")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == '__main__':
|
|
173
|
+
pass
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
|
|
2
|
+
"""checkout_version.py
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from crocodile.file_management import P, Save, randstr
|
|
6
|
+
from crocodile.meta import Terminal
|
|
7
|
+
from machineconfig.utils.ve import get_ve_profile, get_ve_specs, get_ve_install_script
|
|
8
|
+
from machineconfig.scripts.python.repos import record_a_repo, install_repos
|
|
9
|
+
import platform
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# TODO: add data requirements for added isolation of file system.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def checkout_version(version: str, repo_root: P, exclude_editable: bool = False):
|
|
16
|
+
"""Checkout a version of the repo and install its requirements."""
|
|
17
|
+
ve_name = get_ve_profile(init_path=repo_root)
|
|
18
|
+
ve_path = P.home().joinpath("venvs", ve_name)
|
|
19
|
+
ve_specs = get_ve_specs(ve_path)
|
|
20
|
+
py_version = ve_specs['version_major_minor']
|
|
21
|
+
sys = platform.system().lower()
|
|
22
|
+
|
|
23
|
+
target_dir = repo_root.expanduser().absolute().joinpath(f"versions/{version}").as_posix()
|
|
24
|
+
if exclude_editable:
|
|
25
|
+
editable_json = get_editable_packages(ve_name=ve_name)
|
|
26
|
+
specs_path = P(target_dir).expanduser().joinpath("editable_packages.json")
|
|
27
|
+
Save.json(obj=editable_json, path=specs_path, indent=4)
|
|
28
|
+
install_editable_packages = install_repos(specs_path=str(specs_path), editable_install=True)
|
|
29
|
+
else: install_editable_packages = ""
|
|
30
|
+
|
|
31
|
+
version_root = repo_root.collapseuser().joinpath(f"versions/{version}").as_posix()
|
|
32
|
+
version_root_obj = P(version_root).expanduser().create()
|
|
33
|
+
checkout_ve = f"{repo_root.name}-{version}-prod" if not exclude_editable else ve_name
|
|
34
|
+
checkout_ve = input(f"Name of the ve to create (default: {checkout_ve}): ") or checkout_ve
|
|
35
|
+
|
|
36
|
+
ve_template = get_ve_install_script(ve_name=checkout_ve, py_version=py_version, system="Windows", delete_if_exists=False, install_crocodile_and_machineconfig=False)
|
|
37
|
+
version_root_obj.joinpath("install_ve.ps1").write_text(ve_template)
|
|
38
|
+
ve_template = get_ve_install_script(ve_name=checkout_ve, py_version=py_version, system="Linux", delete_if_exists=False, install_crocodile_and_machineconfig=False)
|
|
39
|
+
version_root_obj.joinpath("install_ve.sh").write_text(ve_template)
|
|
40
|
+
|
|
41
|
+
install_requirements = f"""
|
|
42
|
+
. $HOME/scripts/activate_ve {ve_name}
|
|
43
|
+
cd {version_root}
|
|
44
|
+
pip install -r requirements_{sys}.txt
|
|
45
|
+
{install_editable_packages}
|
|
46
|
+
"""
|
|
47
|
+
if sys == "windows":
|
|
48
|
+
version_root_obj.joinpath("install_requirements.ps1").write_text(install_requirements)
|
|
49
|
+
if not version_root_obj.joinpath("install_requirements.sh").exists(): version_root_obj.joinpath("install_requirements.sh").write_text(install_requirements)
|
|
50
|
+
elif sys == "linux":
|
|
51
|
+
version_root_obj.joinpath("install_requirements.sh").write_text(install_requirements)
|
|
52
|
+
if not version_root_obj.joinpath("install_requirements.ps1").exists(): version_root_obj.joinpath("install_requirements.ps1").write_text(install_requirements)
|
|
53
|
+
else: raise NotImplementedError(f"System {sys} not supported.")
|
|
54
|
+
|
|
55
|
+
pip_freeze_script = f"""
|
|
56
|
+
cd '{target_dir}'
|
|
57
|
+
. "$HOME/scripts/activate_ve" {ve_name}
|
|
58
|
+
python -m pip freeze {'--exclude-editable' if exclude_editable else ''} > requirements_{sys}.txt
|
|
59
|
+
"""
|
|
60
|
+
Terminal().run_script(pip_freeze_script, verbose=True, shell="default").print()
|
|
61
|
+
|
|
62
|
+
install_all_script = r"""
|
|
63
|
+
#!/usr/bin/bash
|
|
64
|
+
|
|
65
|
+
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
66
|
+
. $CUR_DIR/install_ve.sh
|
|
67
|
+
. $CUR_DIR/install_requirements.sh
|
|
68
|
+
"""
|
|
69
|
+
version_root_obj.joinpath("install.sh").write_text(install_all_script)
|
|
70
|
+
install_all_script = r"""
|
|
71
|
+
|
|
72
|
+
$CUR_DIR = Split-Path $MyInvocation.MyCommand.Path -Parent
|
|
73
|
+
. $CUR_DIR/install_ve.ps1
|
|
74
|
+
. $CUR_DIR/install_requirements.ps1
|
|
75
|
+
|
|
76
|
+
"""
|
|
77
|
+
version_root_obj.joinpath("install.ps1").write_text(install_all_script)
|
|
78
|
+
print(f"✅ Installed requirements for version {version}.")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def main():
|
|
82
|
+
from git.repo import Repo
|
|
83
|
+
from git.exc import InvalidGitRepositoryError
|
|
84
|
+
try:
|
|
85
|
+
repo = Repo(P.cwd(), search_parent_directories=True)
|
|
86
|
+
print(f"✅ Found repo at {repo.working_dir}")
|
|
87
|
+
except InvalidGitRepositoryError as err:
|
|
88
|
+
print(f"❌ No repo found at {P.cwd()} or its parents.")
|
|
89
|
+
raise err
|
|
90
|
+
version = input("Enter version name: ")
|
|
91
|
+
from rich.prompt import Confirm
|
|
92
|
+
exclude_editable = Confirm.ask("Exclude editable packages?", default=False)
|
|
93
|
+
|
|
94
|
+
repo_root = P(repo.working_dir)
|
|
95
|
+
checkout_version(version, repo_root, exclude_editable=exclude_editable)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_editable_packages(ve_name: str):
|
|
99
|
+
file = P.tmp().joinpath(f"tmp_files/editable_requirements_{randstr()}.txt")
|
|
100
|
+
editable_packages_script = f"""
|
|
101
|
+
. $HOME/scripts/activate_ve {ve_name}
|
|
102
|
+
pip list --editable > {file}
|
|
103
|
+
"""
|
|
104
|
+
Terminal().run_script(editable_packages_script, verbose=True, shell="default").print()
|
|
105
|
+
try: tmp3 = file.read_text(encoding='utf-16').splitlines()[2:]
|
|
106
|
+
except UnicodeError: tmp3 = file.read_text().splitlines()[2:]
|
|
107
|
+
|
|
108
|
+
res = []
|
|
109
|
+
for a_pkg in tmp3:
|
|
110
|
+
tmp = P(a_pkg.split(" ")[-1].rstrip())
|
|
111
|
+
tmp1 = record_a_repo(tmp, search_parent_directories=True) # pip list --editable returns path to package or repo in a way not yet understood.
|
|
112
|
+
res.append(tmp1)
|
|
113
|
+
return res
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
pass
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# one can either install rufus: https://rufus.ie/en/
|
|
6
|
-
# however, to create bootable media with multiple OSs to choose from:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if __name__ == '__main__':
|
|
14
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
# # one can either install rufus: https://rufus.ie/en/
|
|
6
|
+
# # however, to create bootable media with multiple OSs to choose from:
|
|
7
|
+
|
|
8
|
+
# P(r'https://github.com/ventoy/Ventoy/archive/refs/tags/v1.0.78.zip').download().unzip().search[0]()
|
|
9
|
+
# P(r'https://mirrors.layeronline.com/linuxmint/stable/21/linuxmint-21-cinnamon-64bit.iso').download(folder=P.home().joinpath("Downloads/os").create())
|
|
10
|
+
# P(r'https://download.manjaro.org/kde/21.3.7/manjaro-kde-21.3.7-minimal-220816-linux515.iso').download(folder=P.home().joinpath("Downloads/os").create())
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# if __name__ == '__main__':
|
|
14
|
+
# pass
|
|
@@ -1,56 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
res
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
1
|
+
|
|
2
|
+
"""ZT
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import socket
|
|
6
|
+
from machineconfig.utils.utils import choose_ssh_host, write_shell_script
|
|
7
|
+
from crocodile.file_management import P
|
|
8
|
+
|
|
9
|
+
prefix = """
|
|
10
|
+
|
|
11
|
+
layout {
|
|
12
|
+
default_tab_template {
|
|
13
|
+
pane size=1 borderless=true {
|
|
14
|
+
plugin location="zellij:compact-bar"
|
|
15
|
+
}
|
|
16
|
+
children
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
suffix = """
|
|
23
|
+
|
|
24
|
+
tab name="THISMACHINE" focus=true // the default_tab_template
|
|
25
|
+
}
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
tab = """
|
|
29
|
+
|
|
30
|
+
tab name="TABNAME" focus=false { // the default_tab_template with three vertical panes between the plugins
|
|
31
|
+
pane name="fpane" {
|
|
32
|
+
command "TABCOMMAND"
|
|
33
|
+
args "TABARGS"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def build_template(tabs: list[str]):
|
|
41
|
+
res = prefix
|
|
42
|
+
for t in tabs:
|
|
43
|
+
res += tab.replace("TABNAME", t).replace("TABCOMMAND", f"ssh").replace("TABARGS", t)
|
|
44
|
+
res += suffix.replace("THISMACHINE", socket.gethostname())
|
|
45
|
+
file = P.tmp().joinpath(f"tmp_files/templates/zellij_template.kdl").create(parents_only=True).write_text(res)
|
|
46
|
+
res = f"zellij --layout {file}"
|
|
47
|
+
return res
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def launch_from_ssh_config():
|
|
51
|
+
hosts = choose_ssh_host(multi=True)
|
|
52
|
+
assert isinstance(hosts, list)
|
|
53
|
+
res = build_template(hosts)
|
|
54
|
+
write_shell_script(res, execute=False, desc="zellij launch script")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
launch_from_ssh_config()
|