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.

Files changed (155) hide show
  1. machineconfig/__init__.py +8 -5
  2. machineconfig/jobs/python/check_installations.py +173 -163
  3. machineconfig/jobs/python/checkout_version.py +117 -0
  4. machineconfig/jobs/python/create_bootable_media.py +14 -14
  5. machineconfig/jobs/python/create_zellij_template.py +59 -56
  6. machineconfig/jobs/python/python_cargo_build_share.py +50 -45
  7. machineconfig/jobs/python/python_ve_symlink.py +20 -18
  8. machineconfig/jobs/python/tasks.py +4 -0
  9. machineconfig/jobs/script_installer/azure_data_studio.py +22 -0
  10. machineconfig/jobs/script_installer/bypass_paywall.py +23 -0
  11. machineconfig/jobs/script_installer/code.py +34 -0
  12. machineconfig/jobs/script_installer/docker_desktop.py +41 -0
  13. machineconfig/jobs/script_installer/ngrok.py +29 -0
  14. machineconfig/jobs/{python_linux_installers → script_installer}/skim.py +21 -19
  15. machineconfig/jobs/script_installer/wezterm.py +34 -0
  16. machineconfig/profile/create.py +107 -200
  17. machineconfig/profile/shell.py +127 -0
  18. machineconfig/scripts/__init__.py +6 -6
  19. machineconfig/scripts/python/cloud_copy.py +93 -0
  20. machineconfig/scripts/python/cloud_manager.py +38 -0
  21. machineconfig/scripts/python/cloud_mount.py +115 -52
  22. machineconfig/scripts/python/cloud_repo_sync.py +154 -114
  23. machineconfig/scripts/python/cloud_sync.py +261 -79
  24. machineconfig/scripts/python/croshell.py +151 -0
  25. machineconfig/scripts/python/devops.py +119 -87
  26. machineconfig/scripts/python/devops_add_identity.py +27 -23
  27. machineconfig/scripts/python/devops_add_ssh_key.py +70 -55
  28. machineconfig/scripts/python/devops_backup_retrieve.py +52 -46
  29. machineconfig/scripts/python/devops_devapps_install.py +120 -91
  30. machineconfig/scripts/python/devops_update_repos.py +82 -68
  31. machineconfig/scripts/python/dotfile.py +42 -38
  32. machineconfig/scripts/python/fire_jobs.py +351 -98
  33. machineconfig/scripts/python/ftpx.py +82 -0
  34. machineconfig/scripts/python/mount_nfs.py +54 -3
  35. machineconfig/scripts/python/mount_nw_drive.py +31 -0
  36. machineconfig/scripts/python/mount_ssh.py +44 -20
  37. machineconfig/scripts/python/onetimeshare.py +60 -51
  38. machineconfig/scripts/python/pomodoro.py +41 -37
  39. machineconfig/scripts/python/repos.py +195 -128
  40. machineconfig/scripts/python/scheduler.py +52 -0
  41. machineconfig/scripts/python/snapshot.py +21 -21
  42. machineconfig/scripts/python/start_slidev.py +104 -0
  43. machineconfig/scripts/python/start_terminals.py +97 -0
  44. machineconfig/scripts/python/wifi_conn.py +90 -71
  45. machineconfig/scripts/python/{transfer_wsl_win.py → wsl_windows_transfer.py} +47 -39
  46. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +44 -48
  47. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +136 -130
  48. machineconfig/utils/installer.py +251 -0
  49. machineconfig/utils/procs.py +114 -64
  50. machineconfig/utils/scheduling.py +188 -0
  51. machineconfig/utils/utils.py +353 -249
  52. machineconfig/utils/ve.py +222 -0
  53. {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/METADATA +140 -110
  54. machineconfig-1.8.dist-info/RECORD +70 -0
  55. {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/WHEEL +1 -1
  56. machineconfig/jobs/python/python_linux_installers_all.py +0 -73
  57. machineconfig/jobs/python/python_ve_installer.py +0 -73
  58. machineconfig/jobs/python/python_windows_installers_all.py +0 -23
  59. machineconfig/jobs/python_generic_installers/archive/nvim.py +0 -15
  60. machineconfig/jobs/python_generic_installers/archive/strongbox.py +0 -32
  61. machineconfig/jobs/python_generic_installers/archive/vtm.py +0 -25
  62. machineconfig/jobs/python_generic_installers/broot.py +0 -39
  63. machineconfig/jobs/python_generic_installers/browsh.py +0 -25
  64. machineconfig/jobs/python_generic_installers/bw.py +0 -26
  65. machineconfig/jobs/python_generic_installers/chatgpt.py +0 -24
  66. machineconfig/jobs/python_generic_installers/cpufetch.py +0 -23
  67. machineconfig/jobs/python_generic_installers/delta.py +0 -59
  68. machineconfig/jobs/python_generic_installers/dev/__init__.py +0 -0
  69. machineconfig/jobs/python_generic_installers/dev/autogpt.py +0 -28
  70. machineconfig/jobs/python_generic_installers/dev/bw.py +0 -29
  71. machineconfig/jobs/python_generic_installers/dev/evcxr.py +0 -22
  72. machineconfig/jobs/python_generic_installers/dev/kondo.py +0 -21
  73. machineconfig/jobs/python_generic_installers/dev/lvim.py +0 -60
  74. machineconfig/jobs/python_generic_installers/dev/ngrok.py +0 -35
  75. machineconfig/jobs/python_generic_installers/dev/opencommit.py +0 -21
  76. machineconfig/jobs/python_generic_installers/dev/qrcp.py +0 -25
  77. machineconfig/jobs/python_generic_installers/dev/qrscan.py +0 -16
  78. machineconfig/jobs/python_generic_installers/dev/rust-analyzer.py +0 -24
  79. machineconfig/jobs/python_generic_installers/dev/termscp.py +0 -23
  80. machineconfig/jobs/python_generic_installers/dev/tldr.py +0 -25
  81. machineconfig/jobs/python_generic_installers/dev/tokei.py +0 -24
  82. machineconfig/jobs/python_generic_installers/diskonaut.py +0 -26
  83. machineconfig/jobs/python_generic_installers/dua.py +0 -21
  84. machineconfig/jobs/python_generic_installers/evcxr.py +0 -21
  85. machineconfig/jobs/python_generic_installers/gitui.py +0 -23
  86. machineconfig/jobs/python_generic_installers/gopass.py +0 -19
  87. machineconfig/jobs/python_generic_installers/helix.py +0 -45
  88. machineconfig/jobs/python_generic_installers/kondo.py +0 -20
  89. machineconfig/jobs/python_generic_installers/lf.py +0 -25
  90. machineconfig/jobs/python_generic_installers/lvim.py +0 -34
  91. machineconfig/jobs/python_generic_installers/mprocs.py +0 -20
  92. machineconfig/jobs/python_generic_installers/navi.py +0 -20
  93. machineconfig/jobs/python_generic_installers/ots.py +0 -26
  94. machineconfig/jobs/python_generic_installers/ouch.py +0 -25
  95. machineconfig/jobs/python_generic_installers/pomodoro.py +0 -19
  96. machineconfig/jobs/python_generic_installers/procs.py +0 -20
  97. machineconfig/jobs/python_generic_installers/qrcp.py +0 -22
  98. machineconfig/jobs/python_generic_installers/qrscan.py +0 -14
  99. machineconfig/jobs/python_generic_installers/rclone.py +0 -21
  100. machineconfig/jobs/python_generic_installers/rust-analyzer.py +0 -24
  101. machineconfig/jobs/python_generic_installers/tere.py +0 -26
  102. machineconfig/jobs/python_generic_installers/termscp.py +0 -23
  103. machineconfig/jobs/python_generic_installers/tldr.py +0 -24
  104. machineconfig/jobs/python_generic_installers/tokei.py +0 -21
  105. machineconfig/jobs/python_generic_installers/vtm.py +0 -26
  106. machineconfig/jobs/python_generic_installers/watchexec.py +0 -21
  107. machineconfig/jobs/python_linux_installers/archive/__init__.py +0 -0
  108. machineconfig/jobs/python_linux_installers/archive/ranger.py +0 -18
  109. machineconfig/jobs/python_linux_installers/bandwhich.py +0 -11
  110. machineconfig/jobs/python_linux_installers/bottom.py +0 -17
  111. machineconfig/jobs/python_linux_installers/btop.py +0 -17
  112. machineconfig/jobs/python_linux_installers/dev/bandwhich.py +0 -13
  113. machineconfig/jobs/python_linux_installers/dev/bytehound.py +0 -20
  114. machineconfig/jobs/python_linux_installers/dev/nnn.py +0 -21
  115. machineconfig/jobs/python_linux_installers/gotty.py +0 -16
  116. machineconfig/jobs/python_linux_installers/joshuto.py +0 -28
  117. machineconfig/jobs/python_linux_installers/mcfly.py +0 -12
  118. machineconfig/jobs/python_linux_installers/nnn.py +0 -18
  119. machineconfig/jobs/python_linux_installers/topgrade.py +0 -15
  120. machineconfig/jobs/python_linux_installers/viu.py +0 -19
  121. machineconfig/jobs/python_linux_installers/xplr.py +0 -22
  122. machineconfig/jobs/python_linux_installers/zellij.py +0 -31
  123. machineconfig/jobs/python_windows_installers/archive/ntop.py +0 -20
  124. machineconfig/jobs/python_windows_installers/bat.py +0 -16
  125. machineconfig/jobs/python_windows_installers/boxes.py +0 -19
  126. machineconfig/jobs/python_windows_installers/bypass_paywall.py +0 -18
  127. machineconfig/jobs/python_windows_installers/dev/bypass_paywall.py +0 -21
  128. machineconfig/jobs/python_windows_installers/dev/obs_background_removal_plugin.py +0 -20
  129. machineconfig/jobs/python_windows_installers/fd.py +0 -17
  130. machineconfig/jobs/python_windows_installers/fzf.py +0 -19
  131. machineconfig/jobs/python_windows_installers/obs_background_removal_plugin.py +0 -19
  132. machineconfig/jobs/python_windows_installers/rg.py +0 -15
  133. machineconfig/jobs/python_windows_installers/ugrep.py +0 -14
  134. machineconfig/jobs/python_windows_installers/zoomit.py +0 -20
  135. machineconfig/jobs/python_windows_installers/zoxide.py +0 -20
  136. machineconfig/profile/fix_shell_profiles.py +0 -8
  137. machineconfig/scripts/python/archive/__init__.py +0 -0
  138. machineconfig/scripts/python/archive/bu_gdrive_rx.py +0 -41
  139. machineconfig/scripts/python/archive/bu_gdrive_sx.py +0 -40
  140. machineconfig/scripts/python/archive/bu_onedrive_rx.py +0 -59
  141. machineconfig/scripts/python/archive/bu_onedrive_sx.py +0 -45
  142. machineconfig/scripts/python/chatgpt.py +0 -28
  143. machineconfig/scripts/python/choose_ohmybash_theme.py +0 -25
  144. machineconfig/scripts/python/choose_ohmyposh_theme.py +0 -40
  145. machineconfig/scripts/python/cloud_rx.py +0 -42
  146. machineconfig/scripts/python/cloud_sx.py +0 -40
  147. machineconfig/scripts/python/ftprx.py +0 -37
  148. machineconfig/scripts/python/ftpsx.py +0 -36
  149. machineconfig/scripts/python/im2text.py +0 -15
  150. machineconfig/scripts/python/tmate_conn.py +0 -28
  151. machineconfig/scripts/python/tmate_start.py +0 -31
  152. machineconfig/utils/to_exe.py +0 -7
  153. machineconfig-1.5.dist-info/RECORD +0 -147
  154. /machineconfig/jobs/{python_generic_installers/archive → script_installer}/__init__.py +0 -0
  155. {machineconfig-1.5.dist-info → machineconfig-1.8.dist-info}/top_level.txt +0 -0
@@ -1,130 +1,136 @@
1
-
2
- import crocodile.toolbox as tb
3
- import crocodile.environment as env
4
- from uuid import uuid4
5
-
6
-
7
- """
8
- Not to be confused:
9
- * Windows Terminal & Windows Terminal Preview: The latter is the night release version of WT.
10
- * Windows PowerShell & PowerShell: The latter is community developed and is available on all platforms.
11
- * Windows Powershell comes preinstalled with the system, Powershell must be installed separately.
12
- * Lastly, powershell has a preview version as well.
13
- All settings are available on GitHub: https://aka.ms/terminal-profiles-schema
14
- """
15
-
16
-
17
- assert env.system == 'Windows', 'This script is only for Windows.'
18
-
19
-
20
- class TerminalSettings(object):
21
- def __init__(self):
22
- # Grabbing Terminal Settings file:
23
- self.path = env.LocalAppData.joinpath(r"Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json")
24
- self.path.copy(append=".orig_" + tb.randstr())
25
- self.dat = self.path.readit()
26
- self.profs = tb.L(self.dat["profiles"]["list"])
27
-
28
- def save_terminal_settings(self):
29
- self.dat["profiles"]["list"] = list(self.profs)
30
- self.dat.save_json(self.path, indent=5)
31
-
32
- # ========================= Terminal Settings =========================================
33
- def update_default_settings(self):
34
- # Changing start up settings:
35
- self.dat["startOnUserLogin"] = True
36
- self.dat["launchMode"] = "fullscreen"
37
- self.dat["theme"] = "dark"
38
- self.dat["focusFollowMouse"] = True
39
- self.dat["copyOnSelect"] = True
40
- self.dat["profiles"]["defaults"]["padding"] = "0"
41
- self.dat["profiles"]["defaults"]["useAcrylic"] = False
42
-
43
- # 1- Customizing Powershell========================================================
44
- # as opposed to Windows Powershell
45
- def customize_powershell(self, nerd_font=True):
46
- pwsh = dict(name="PowerShell",
47
- commandline="pwsh",
48
- hidden=False,
49
- opacity=87,
50
- # guid="{" + str(uuid4()) + "}", # WT doesn't accept any GUID to identify pwsh
51
- startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
52
- )
53
- if nerd_font: pwsh["font"] = dict(face="CaskaydiaCove Nerd Font") # because oh-my-posh uses glyphs from this font.
54
- for idx, item in enumerate(self.profs):
55
- if item["name"] == "PowerShell":
56
- self.profs[idx].update(pwsh)
57
- break
58
- else: print(f"Couldn't customize powershell because profile not found, try to install it first.")
59
-
60
- def make_powershell_default_profile(self):
61
- for profile in self.profs:
62
- if profile["name"] == "PowerShell":
63
- self.dat["defaultProfile"] = profile["guid"]
64
- print("Powershell is now the default profile.")
65
- break
66
- else: print("Powershell profile was not found in the list of profile and therefore was not made the deafult.")
67
-
68
- def add_croshell(self):
69
- # Adding croshell if it is not there.
70
- # py_pr = tb.copy.deepcopy(pr) # use it as a template for the new profile.
71
- import machineconfig
72
- lib_root = tb.P(machineconfig.__file__).parent.collapseuser().as_posix()
73
- croshell = dict(name="croshell",
74
- guid="{" + str(uuid4()) + "}",
75
- # commandline=f"powershell.exe -Command \"{activate} ipython -i -c 'from crocodile.toolbox import *'\"",
76
- commandline=f'powershell.exe -Command "{lib_root}/scripts/windows/croshell.ps1"',
77
- startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
78
- )
79
- # startingDirectory = None means: inheret from parent process, which will is the default, which point to /System32
80
- # Launching a new profile with ctr+shift+2 is equivalent to: wt --profile croshell -d . --new-tab
81
- for profile in self.profs:
82
- if profile["name"] == "croshell":
83
- profile.update(croshell)
84
- break
85
- else: self.profs.append(croshell)
86
-
87
- def add_ubuntu(self):
88
- # Add Ubunto if it is not there.
89
- ubuntu = dict(name="Ubuntu",
90
- commandline="wsl -d Ubuntu -- cd ~",
91
- hidden=False,
92
- guid="{" + str(uuid4()) + "}",
93
- startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
94
- )
95
- if self.profs.filter(lambda x: x["name"] == "Ubuntu").__len__() < 1: self.profs.append(ubuntu)
96
-
97
- def standardize_profiles_order(self):
98
- # Changing order of profiles:
99
- others = []
100
- pwsh = croshell = ubuntu = wpwsh = cmd = azure = None
101
- for profile in self.profs:
102
- name = profile["name"]
103
- if name == "PowerShell": pwsh = profile
104
- elif name == "croshell": croshell = profile
105
- elif name == "Ubuntu": ubuntu = profile
106
- elif name == "Windows PowerShell": wpwsh = profile
107
- elif name == "Command Prompt": cmd = profile
108
- elif name == "Azure Cloud Shell": azure = profile
109
- else: others.append(profile)
110
- self.profs = [item for item in [pwsh, croshell, ubuntu, wpwsh, cmd, azure] + others if item is not None]
111
-
112
-
113
- def main():
114
- shell = {"powershell": "pwsh.exe", "Windows Powershell": "powershell.exe"}["powershell"].split(".exe")[0]
115
- if shell == "pwsh":
116
- ts = TerminalSettings()
117
- ts.update_default_settings()
118
- ts.customize_powershell(nerd_font=True)
119
-
120
- ts.make_powershell_default_profile()
121
- ts.add_croshell()
122
- ts.add_ubuntu()
123
- ts.standardize_profiles_order()
124
- ts.dat['actions'].append({'command': 'togglePaneZoom', 'keys': 'ctrl+shift+z'})
125
- ts.save_terminal_settings()
126
- else: raise NotImplementedError
127
-
128
-
129
- if __name__ == '__main__':
130
- pass
1
+
2
+ """Set Windows Terminal Settings
3
+ """
4
+
5
+ from crocodile.core import randstr, List as L
6
+ from crocodile.file_management import P, Read, Save
7
+ import crocodile.environment as env
8
+ from machineconfig.utils.utils import LIBRARY_ROOT
9
+ from uuid import uuid4
10
+ import os
11
+ from typing import Any
12
+
13
+
14
+ """
15
+ Not to be confused:
16
+ * Windows Terminal & Windows Terminal Preview: The latter is the night release version of WT.
17
+ * Windows PowerShell & PowerShell: The latter is community developed and is available on all platforms.
18
+ * Windows Powershell comes preinstalled with the system, Powershell must be installed separately.
19
+ * Lastly, powershell has a preview version as well.
20
+ All settings are available on GitHub: https://aka.ms/terminal-profiles-schema
21
+ """
22
+
23
+
24
+ assert env.system == 'Windows', 'This script is only for Windows.'
25
+
26
+
27
+ class TerminalSettings(object):
28
+ def __init__(self):
29
+ # Grabbing Terminal Settings file:
30
+ tmp = os.getenv("LOCALAPPDATA")
31
+ if not isinstance(tmp, str):
32
+ raise ValueError("Could not find LOCALAPPDATA environment variable.")
33
+ self.path = P(tmp).joinpath(r"Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json")
34
+ self.path.copy(append=".orig_" + randstr())
35
+ self.dat: dict[str, Any] = Read.json(self.path)
36
+ self.profs = L(self.dat["profiles"]["list"])
37
+
38
+ def save_terminal_settings(self):
39
+ self.dat["profiles"]["list"] = list(self.profs)
40
+ Save.json(obj=self.dat, path=self.path, indent=5)
41
+
42
+ # ========================= Terminal Settings =========================================
43
+ def update_default_settings(self):
44
+ # Changing start up settings:
45
+ self.dat["startOnUserLogin"] = True
46
+ self.dat["launchMode"] = "fullscreen"
47
+ self.dat["theme"] = "dark"
48
+ self.dat["focusFollowMouse"] = True
49
+ self.dat["copyOnSelect"] = True
50
+ self.dat["profiles"]["defaults"]["padding"] = "0"
51
+ self.dat["profiles"]["defaults"]["useAcrylic"] = False
52
+
53
+ # 1- Customizing Powershell========================================================
54
+ # as opposed to Windows Powershell
55
+ def customize_powershell(self, nerd_font: bool = True):
56
+ pwsh: dict[str, Any] = dict(name="PowerShell",
57
+ commandline="pwsh",
58
+ hidden=False,
59
+ opacity=87,
60
+ # guid="{" + str(uuid4()) + "}", # WT doesn't accept any GUID to identify pwsh
61
+ startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
62
+ )
63
+ if nerd_font: pwsh["font"] = dict(face="CaskaydiaCove Nerd Font") # because oh-my-posh uses glyphs from this font.
64
+ for idx, item in enumerate(self.profs):
65
+ if item["name"] == "PowerShell":
66
+ self.profs.list[idx].update(pwsh)
67
+ break
68
+ else: print(f"Couldn't customize powershell because profile not found, try to install it first.")
69
+
70
+ def make_powershell_default_profile(self):
71
+ for profile in self.profs:
72
+ if profile["name"] == "PowerShell":
73
+ self.dat["defaultProfile"] = profile["guid"]
74
+ print("Powershell is now the default profile.")
75
+ break
76
+ else: print("Powershell profile was not found in the list of profile and therefore was not made the deafult.")
77
+
78
+ def add_croshell(self):
79
+ croshell = dict(name="croshell",
80
+ guid="{" + str(uuid4()) + "}",
81
+ # commandline=f"powershell.exe -Command \"{activate} ipython -i -c 'from crocodile.toolbox import *'\"",
82
+ commandline=f'powershell.exe -Command "{LIBRARY_ROOT.as_posix()}/scripts/windows/croshell.ps1"',
83
+ startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
84
+ )
85
+ # startingDirectory = None means: inheret from parent process, which will is the default, which point to /System32
86
+ # Launching a new profile with ctr+shift+2 is equivalent to: wt --profile croshell -d . --new-tab
87
+ for profile in self.profs:
88
+ if profile["name"] == "croshell":
89
+ profile.update(croshell)
90
+ break
91
+ else: self.profs.append(croshell)
92
+
93
+ def add_ubuntu(self):
94
+ # Add Ubunto if it is not there.
95
+ ubuntu = dict(name="Ubuntu",
96
+ commandline="wsl -d Ubuntu -- cd ~",
97
+ hidden=False,
98
+ guid="{" + str(uuid4()) + "}",
99
+ startingDirectory="%USERPROFILE%", # "%USERPROFILE%", # None: inherent from parent process.
100
+ )
101
+ if self.profs.filter(lambda x: x["name"] == "Ubuntu").__len__() < 1: self.profs.append(ubuntu)
102
+
103
+ def standardize_profiles_order(self):
104
+ # Changing order of profiles:
105
+ others = []
106
+ pwsh = croshell = ubuntu = wpwsh = cmd = azure = None
107
+ for profile in self.profs:
108
+ name = profile["name"]
109
+ if name == "PowerShell": pwsh = profile
110
+ elif name == "croshell": croshell = profile
111
+ elif name == "Ubuntu": ubuntu = profile
112
+ elif name == "Windows PowerShell": wpwsh = profile
113
+ elif name == "Command Prompt": cmd = profile
114
+ elif name == "Azure Cloud Shell": azure = profile
115
+ else: others.append(profile)
116
+ self.profs = L([item for item in [pwsh, croshell, ubuntu, wpwsh, cmd, azure] + others if item is not None])
117
+
118
+
119
+ def main():
120
+ shell = {"powershell": "pwsh.exe", "Windows Powershell": "powershell.exe"}["powershell"].split(".exe", maxsplit=1)[0]
121
+ if shell == "pwsh":
122
+ ts = TerminalSettings()
123
+ ts.update_default_settings()
124
+ ts.customize_powershell(nerd_font=True)
125
+
126
+ ts.make_powershell_default_profile()
127
+ ts.add_croshell()
128
+ ts.add_ubuntu()
129
+ ts.standardize_profiles_order()
130
+ ts.dat['actions'].append({'command': 'togglePaneZoom', 'keys': 'ctrl+shift+z'})
131
+ ts.save_terminal_settings()
132
+ else: raise NotImplementedError
133
+
134
+
135
+ if __name__ == '__main__':
136
+ pass
@@ -0,0 +1,251 @@
1
+
2
+ """package manager
3
+ """
4
+ from rich.console import Console
5
+
6
+ from crocodile.file_management import P, List as L, Read, Struct
7
+ from crocodile.meta import Terminal
8
+ from machineconfig.utils.utils import INSTALL_VERSION_ROOT, INSTALL_TMP_DIR, LIBRARY_ROOT, check_tool_exists
9
+
10
+ # from dataclasses import dataclass
11
+ from typing import Optional, Any
12
+ import platform
13
+ # import os
14
+
15
+
16
+ def find_move_delete_windows(downloaded_file_path: P, exe_name: Optional[str] = None, delete: bool = True, rename_to: Optional[str] = None):
17
+ if exe_name is not None and ".exe" in exe_name: exe_name = exe_name.replace(".exe", "")
18
+ if downloaded_file_path.is_file():
19
+ exe = downloaded_file_path
20
+ else:
21
+ if exe_name is None: exe = downloaded_file_path.search("*.exe", r=True).list[0]
22
+ else:
23
+ tmp = downloaded_file_path.search(f"{exe_name}.exe", r=True)
24
+ if len(tmp) == 1: exe = tmp.list[0]
25
+ else: exe = downloaded_file_path.search("*.exe", r=True).list[0]
26
+ if rename_to and exe.name != rename_to:
27
+ exe = exe.with_name(name=rename_to, inplace=True)
28
+ exe_new_location = exe.move(folder=P.get_env().WindowsApps, overwrite=True) # latest version overwrites older installation.
29
+ if delete: downloaded_file_path.delete(sure=True)
30
+ return exe_new_location
31
+
32
+
33
+ def find_move_delete_linux(downloaded: P, tool_name: str, delete: Optional[bool] = True, rename_to: Optional[str] = None):
34
+ if downloaded.is_file():
35
+ exe = downloaded
36
+ else:
37
+ res = downloaded.search(f"*{tool_name}*", folders=False, r=True)
38
+ if len(res) == 1: exe = res.list[0]
39
+ else:
40
+ exe_search_res = downloaded.search(tool_name, folders=False, r=True)
41
+ if len(exe_search_res) == 0:
42
+ print(f"No search results for `{tool_name}` in `{downloaded}`")
43
+ raise IndexError(f"No executable found in {downloaded}")
44
+ else:
45
+ exe = exe_search_res.list[0]
46
+ if rename_to and exe.name != rename_to:
47
+ exe = exe.with_name(name=rename_to, inplace=True)
48
+ print(f"MOVING file `{repr(exe)}` to '/usr/local/bin'")
49
+ exe.chmod(0o777)
50
+ # exe.move(folder=r"/usr/local/bin", overwrite=False)
51
+ Terminal().run(f"sudo mv {exe} /usr/local/bin/").print_if_unsuccessful(desc="MOVING executable to /usr/local/bin", strict_err=True, strict_returncode=True)
52
+ if delete: downloaded.delete(sure=True)
53
+ exe_new_location = P(r"/usr/local/bin").joinpath(exe.name)
54
+ return exe_new_location
55
+
56
+
57
+ class Installer:
58
+ def __init__(self, repo_url: str, name: str, doc: str, filename_template_windows_amd_64: str, filename_template_linux_amd_64: str, strip_v: bool, exe_name: str):
59
+ self.repo_url = repo_url
60
+ self.name = name
61
+ self.doc = doc
62
+ self.filename_template_windows_amd_64 = filename_template_windows_amd_64
63
+ self.filename_template_linux_amd_64 = filename_template_linux_amd_64
64
+ self.strip_v = strip_v
65
+ self.exe_name = exe_name
66
+ def __repr__(self) -> str: return f"Installer of {self.repo_url}"
67
+ def get_description(self):
68
+ # old_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
69
+ # old_version_cli = os.system(f"{self.exe_name} --version").replace("\n", "")
70
+ old_version_cli = check_tool_exists(self.exe_name)
71
+ old_version_cli_str = "✅" if old_version_cli else "❌"
72
+ # name_version = f"{self.exe_name} {old_version_cli_str}"
73
+ return f"{self.exe_name:<12} {old_version_cli_str} {self.doc}"
74
+ def to_dict(self): return self.__dict__
75
+ @staticmethod
76
+ def from_dict(d: dict[str, Any], name: str):
77
+ try: return Installer(name=name, **d)
78
+ except Exception as ex:
79
+ Struct(d).print(as_config=True)
80
+ raise ex
81
+ @staticmethod
82
+ def choose_app_and_install():
83
+ from machineconfig.utils.utils import choose_one_option
84
+ path = choose_one_option(options=LIBRARY_ROOT.joinpath("jobs").search("config.json", r=True).list)
85
+ config: dict[str, Any] = Read.json(path) # /python_generic_installers/config.json"))
86
+ # binary = choose_one_option(options=list(config.keys()), fzf=True)
87
+ for keys, dict_ in config.items():
88
+ installer = Installer.from_dict(d=dict_, name=keys)
89
+ installer.install(version=None)
90
+
91
+ def install_robust(self, version: Optional[str]):
92
+ try:
93
+ old_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
94
+ self.install(version=version)
95
+ new_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
96
+ if old_version_cli == new_version_cli: return f"📦️ 😑 {self.exe_name}, same version: {old_version_cli}"
97
+ else: return f"📦️ 🤩 {self.exe_name} updated from {old_version_cli} === to ===> {new_version_cli}"
98
+ except Exception as ex:
99
+ print(ex)
100
+ return f"📦️ Failed at {self.exe_name} with {ex}"
101
+
102
+ def install(self, version: Optional[str]):
103
+ if self.repo_url == "CUSTOM":
104
+ import machineconfig.jobs.script_installer as custom_installer
105
+ installer_path = P(custom_installer.__file__).parent.joinpath(self.exe_name + ".py")
106
+ import runpy
107
+ program = runpy.run_path(str(installer_path), run_name="__main__")['main'](version=version)
108
+ Terminal().run(program, shell="default")
109
+ version_to_be_installed = str(version)
110
+ elif "npm " in self.repo_url:
111
+ Terminal().run(self.repo_url, shell="default").print_if_unsuccessful(desc="npm install", strict_err=True, strict_returncode=True)
112
+ version_to_be_installed = "npmLatest"
113
+ elif "pip " in self.repo_url:
114
+ Terminal().run(self.repo_url, shell="default").print_if_unsuccessful(desc="pip install", strict_err=True, strict_returncode=True)
115
+ version_to_be_installed = "pipLatest"
116
+ else:
117
+ downloaded, version_to_be_installed = self.download(version=version)
118
+ if downloaded.str.endswith(".deb"):
119
+ assert platform.system() == "Linux"
120
+ Terminal().run(f"sudo apt install -y {downloaded}").print_if_unsuccessful(desc="Installing .deb", strict_err=True, strict_returncode=True)
121
+ downloaded.delete(sure=True)
122
+ else:
123
+ if platform.system() == "Windows":
124
+ exe = find_move_delete_windows(downloaded_file_path=downloaded, exe_name=self.exe_name, delete=True, rename_to=self.exe_name + ".exe")
125
+ elif platform.system() == "Linux":
126
+ exe = find_move_delete_linux(downloaded=downloaded, tool_name=self.exe_name, delete=True, rename_to=self.exe_name)
127
+ else: raise NotImplementedError(f"System {platform.system()} not implemented")
128
+ _ = exe
129
+ if exe.name.replace(".exe", "") != self.exe_name.replace(".exe", ""):
130
+ from rich import print as pprint
131
+ from rich.panel import Panel
132
+ pprint(Panel(f"Expected exe name: [red]{self.exe_name}[/red] \nAttained name: [red]{exe.name.replace('.exe', '')}[/red]", title="exe name mismatch", subtitle=self.repo_url))
133
+ new_exe_name = self.exe_name + ".exe" if platform.system() == "Windows" else self.exe_name
134
+ exe.with_name(name=new_exe_name, inplace=True, overwrite=True)
135
+ INSTALL_VERSION_ROOT.joinpath(self.exe_name).create(parents_only=True).write_text(version_to_be_installed)
136
+
137
+ def download(self, version: Optional[str]):
138
+ if "github" not in self.repo_url or ".zip" in self.repo_url or ".tar.gz" in self.repo_url:
139
+ download_link = P(self.repo_url)
140
+ version_to_be_installed = "predefined_url"
141
+ print(f"📦️ Version to be installed: {version_to_be_installed}")
142
+ elif "http" in self.filename_template_linux_amd_64 or "http" in self.filename_template_windows_amd_64:
143
+ if platform.system() == "Windows":
144
+ download_link = P(self.filename_template_windows_amd_64)
145
+ elif platform.system() == "Linux":
146
+ download_link = P(self.filename_template_linux_amd_64)
147
+ else: raise NotImplementedError(f"📦️ System {platform.system()} not implemented")
148
+ version_to_be_installed = "predefined_url"
149
+ else:
150
+ release_url, version_to_be_installed = self.get_github_release(repo_url=self.repo_url, version=version)
151
+ print(f"📦️ Version to be installed: {version_to_be_installed}")
152
+ print(f"📦️ Release URL: {release_url}")
153
+ version_to_be_installed_stripped = version_to_be_installed.replace("v", "") if self.strip_v else version_to_be_installed
154
+ if platform.system() == "Windows":
155
+ file_name = self.filename_template_windows_amd_64.format(version_to_be_installed_stripped)
156
+ elif platform.system() == "Linux":
157
+ file_name = self.filename_template_linux_amd_64.format(version_to_be_installed_stripped)
158
+ else: raise NotImplementedError(f"📦️ System {platform.system()} not implemented")
159
+ print(f"📦️ File name", file_name)
160
+ download_link = release_url.joinpath(file_name)
161
+ print("📦️ Downloading: ", download_link.as_url_str())
162
+ downloaded = download_link.download(folder=INSTALL_TMP_DIR).decompress()
163
+ return downloaded, version_to_be_installed
164
+
165
+ @staticmethod
166
+ def get_github_release(repo_url: str, version: Optional[str] = None):
167
+ print("\n\n\n")
168
+ print(f"📦️ Inspecting latest release @ {repo_url} ...")
169
+ # with console.status("Installing..."): # makes troubles on linux when prompt asks for password to move file to /usr/bin
170
+ if version is None:
171
+ import requests # https://docs.github.com/en/repositories/releasing-projects-on-github/linking-to-releases
172
+ _latest_version = requests.get(str(repo_url) + "/releases/latest", timeout=10).url.split("/")[-1] # this is to resolve the redirection that occures: https://stackoverflow.com/questions/36070821/how-to-get-redirect-url-using-python-requests
173
+ version_to_be_installed = _latest_version
174
+ # print(version_to_be_installed)
175
+ else:
176
+ version_to_be_installed = version
177
+ release_url = P(repo_url + "/releases/download/" + version_to_be_installed)
178
+ return release_url, version_to_be_installed
179
+
180
+ @staticmethod
181
+ def check_if_installed_already(exe_name: str, version: str):
182
+ version_to_be_installed = version
183
+ tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name).create(parents_only=True)
184
+ if tmp_path.exists(): existing_version = tmp_path.read_text().rstrip()
185
+ else: existing_version = None
186
+
187
+ if existing_version is not None:
188
+ if existing_version == version_to_be_installed:
189
+ print(f"📦️ ⚠️ {exe_name} already installed at version {version_to_be_installed}. See {INSTALL_VERSION_ROOT}")
190
+ return True
191
+ else:
192
+ # print(f"Latest version is {version}, logged at {tmp_path}")
193
+ print(f"📦️ ⬆️ {exe_name} installed at version {existing_version.rstrip()} --> Installing version {version_to_be_installed} ")
194
+ tmp_path.write_text(version_to_be_installed)
195
+ else:
196
+ print(f"📦️ {exe_name} has no known version. Installing version `{version_to_be_installed}` ")
197
+ tmp_path.write_text(version_to_be_installed)
198
+ return False
199
+
200
+
201
+ def get_installed_cli_apps():
202
+ if platform.system() == "Windows": apps = P.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
203
+ elif platform.system() == "Linux": apps = P(r"/usr/local/bin").search("*")
204
+ else: raise NotImplementedError("Not implemented for this OS")
205
+ apps = L([app for app in apps if app.size("kb") > 0.1 and not app.is_symlink()]) # no symlinks like paint and wsl and bash
206
+ return apps
207
+
208
+
209
+ def get_installers(system: str, dev: bool) -> list[Installer]:
210
+ if system == "Windows": import machineconfig.jobs.python_windows_installers as os_specific_installer
211
+ else: import machineconfig.jobs.python_linux_installers as os_specific_installer
212
+ import machineconfig.jobs.python_generic_installers as generic_installer
213
+ path = P(os_specific_installer.__file__).parent
214
+ gens_path = P(generic_installer.__file__).parent
215
+ if dev:
216
+ path = path.joinpath("dev")
217
+ gens_path = gens_path.joinpath("dev")
218
+ res1: dict[str, Any] = Read.json(path=path.joinpath("config.json"))
219
+ res2: dict[str, Any] = Read.json(path=gens_path.joinpath("config.json"))
220
+ res2.update(res1)
221
+ return [Installer.from_dict(d=vd, name=k) for k, vd in res2.items()]
222
+
223
+
224
+ def install_all(installers: L[Installer], safe: bool = False, jobs: int = 10, fresh: bool = False):
225
+ if fresh: INSTALL_VERSION_ROOT.delete(sure=True)
226
+ if safe:
227
+ from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
228
+ apps_dir = APP_SUMMARY_PATH.readit()
229
+ if platform.system().lower() == "windows":
230
+ apps_dir.search("*").apply(lambda app: app.move(folder=P.get_env().WindowsApps))
231
+ elif platform.system().lower() == "linux":
232
+ Terminal().run(f"sudo mv {apps_dir.as_posix()}/* /usr/local/bin/").print_if_unsuccessful(desc="MOVING executable to /usr/local/bin", strict_err=True, strict_returncode=True)
233
+ else: raise NotImplementedError(f"I don't know this system {platform.system()}")
234
+ apps_dir.delete(sure=True)
235
+ return None
236
+ installers.list[0].install(version=None)
237
+ res = installers.slice(start=1).apply(lambda x: x.install_robust(version=None), jobs=jobs) # try out the first installer alone cause it will ask for password, so the rest will inherit the sudo session.
238
+ console = Console()
239
+ print("\n")
240
+ console.rule("Same version apps")
241
+ print(f"{res.filter(lambda x: 'same version' in x).print()}")
242
+ print("\n")
243
+ console.rule("Updated apps")
244
+ print(f"{res.filter(lambda x: 'updated from' in x).print()}")
245
+ print("\n")
246
+ console.rule("Failed apps")
247
+ print(f"{res.filter(lambda x: 'Failed at' in x).print()}")
248
+
249
+ print("\n")
250
+ print("Completed Installation".center(100, "-"))
251
+ print("\n" * 2)