machineconfig 1.94__py3-none-any.whl → 1.95__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (120) hide show
  1. machineconfig/cluster/data_transfer.py +2 -1
  2. machineconfig/cluster/job_params.py +1 -1
  3. machineconfig/cluster/script_execution.py +1 -1
  4. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  5. machineconfig/jobs/linux/msc/lid.sh +2 -4
  6. machineconfig/jobs/linux/msc/network.sh +3 -6
  7. machineconfig/jobs/python/check_installations.py +6 -6
  8. machineconfig/jobs/python/checkout_version.py +4 -4
  9. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  10. machineconfig/jobs/python/python_ve_symlink.py +4 -4
  11. machineconfig/jobs/python/vscode/api.py +2 -2
  12. machineconfig/jobs/python/vscode/link_ve.py +4 -4
  13. machineconfig/jobs/python/vscode/select_interpreter.py +4 -4
  14. machineconfig/jobs/python/vscode/sync_code.py +6 -6
  15. machineconfig/jobs/python_custom_installers/archive/ngrok.py +4 -4
  16. machineconfig/jobs/python_custom_installers/dev/aider.py +4 -4
  17. machineconfig/jobs/python_custom_installers/dev/alacritty.py +4 -4
  18. machineconfig/jobs/python_custom_installers/dev/brave.py +4 -4
  19. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +4 -4
  20. machineconfig/jobs/python_custom_installers/dev/code.py +4 -4
  21. machineconfig/jobs/python_custom_installers/dev/docker.py +4 -4
  22. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
  23. machineconfig/jobs/python_custom_installers/dev/espanso.py +8 -8
  24. machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
  25. machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
  26. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +4 -4
  27. machineconfig/jobs/python_custom_installers/dev/redis.py +4 -4
  28. machineconfig/jobs/python_custom_installers/dev/warp-cli.py +4 -4
  29. machineconfig/jobs/python_custom_installers/dev/wezterm.py +4 -4
  30. machineconfig/jobs/python_custom_installers/gh.py +6 -6
  31. machineconfig/jobs/python_custom_installers/hx.py +28 -58
  32. machineconfig/jobs/python_custom_installers/scripts/linux/brave.sh +4 -8
  33. machineconfig/jobs/python_custom_installers/scripts/linux/docker.sh +5 -10
  34. machineconfig/jobs/python_custom_installers/scripts/linux/docker_start.sh +3 -6
  35. machineconfig/jobs/python_custom_installers/scripts/linux/edge.sh +3 -6
  36. machineconfig/jobs/python_custom_installers/scripts/linux/nerdfont.sh +5 -10
  37. machineconfig/jobs/python_custom_installers/scripts/linux/pgsql.sh +4 -8
  38. machineconfig/jobs/python_custom_installers/scripts/linux/redis.sh +5 -10
  39. machineconfig/jobs/python_custom_installers/scripts/linux/timescaledb.sh +6 -12
  40. machineconfig/jobs/python_custom_installers/scripts/linux/vscode.sh +9 -8
  41. machineconfig/jobs/python_custom_installers/scripts/linux/warp-cli.sh +5 -10
  42. machineconfig/jobs/python_custom_installers/scripts/linux/wezterm.sh +3 -6
  43. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  44. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  45. machineconfig/profile/shell.py +26 -47
  46. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  47. machineconfig/scripts/cloud/init.sh +9 -18
  48. machineconfig/scripts/linux/fire +5 -24
  49. machineconfig/scripts/linux/share_cloud.sh +6 -12
  50. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  51. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  52. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  53. machineconfig/scripts/python/__pycache__/cloud_repo_sync.cpython-311.pyc +0 -0
  54. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  55. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  56. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  57. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  58. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  59. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  60. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  61. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  62. machineconfig/scripts/python/archive/im2text.py +30 -30
  63. machineconfig/scripts/python/archive/tmate_conn.py +10 -13
  64. machineconfig/scripts/python/archive/tmate_start.py +12 -16
  65. machineconfig/scripts/python/choose_wezterm_theme.py +9 -18
  66. machineconfig/scripts/python/cloud_copy.py +38 -93
  67. machineconfig/scripts/python/cloud_manager.py +61 -53
  68. machineconfig/scripts/python/cloud_mount.py +23 -34
  69. machineconfig/scripts/python/cloud_repo_sync.py +20 -69
  70. machineconfig/scripts/python/cloud_sync.py +35 -45
  71. machineconfig/scripts/python/croshell.py +48 -73
  72. machineconfig/scripts/python/devops.py +50 -104
  73. machineconfig/scripts/python/devops_add_identity.py +41 -101
  74. machineconfig/scripts/python/devops_add_ssh_key.py +33 -140
  75. machineconfig/scripts/python/devops_backup_retrieve.py +23 -112
  76. machineconfig/scripts/python/devops_devapps_install.py +0 -4
  77. machineconfig/scripts/python/devops_update_repos.py +1 -1
  78. machineconfig/scripts/python/fire_jobs.py +73 -25
  79. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  80. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  81. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  82. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  83. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  84. machineconfig/scripts/python/helpers/cloud_helpers.py +37 -34
  85. machineconfig/scripts/python/helpers/helpers2.py +17 -31
  86. machineconfig/scripts/python/helpers/repo_sync_helpers.py +19 -54
  87. machineconfig/scripts/python/pomodoro.py +1 -1
  88. machineconfig/scripts/python/repos.py +49 -34
  89. machineconfig/scripts/python/wifi_conn.py +5 -3
  90. machineconfig/scripts/windows/fire.ps1 +27 -15
  91. machineconfig/settings/__pycache__/__init__.cpython-311.pyc +0 -0
  92. machineconfig/settings/shells/ipy/profiles/default/__pycache__/__init__.cpython-311.pyc +0 -0
  93. machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/__init__.cpython-311.pyc +0 -0
  94. machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/playext.cpython-311.pyc +0 -0
  95. machineconfig/setup_linux/nix/cli_installation.sh +9 -18
  96. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +3 -6
  97. machineconfig/setup_linux/web_shortcuts/all.sh +5 -10
  98. machineconfig/setup_linux/web_shortcuts/ascii_art.sh +7 -14
  99. machineconfig/setup_linux/web_shortcuts/croshell.sh +6 -12
  100. machineconfig/setup_linux/web_shortcuts/interactive.sh +34 -68
  101. machineconfig/setup_linux/web_shortcuts/ssh.sh +8 -16
  102. machineconfig/setup_linux/web_shortcuts/update_system.sh +7 -14
  103. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +16 -12
  104. machineconfig/utils/ai/browser_user_wrapper.py +60 -45
  105. machineconfig/utils/ai/generate_file_checklist.py +4 -7
  106. machineconfig/utils/ai/url2md.py +13 -5
  107. machineconfig/utils/{utils_code.py → code.py} +4 -10
  108. machineconfig/utils/installer.py +4 -10
  109. machineconfig/utils/{utils_links.py → links.py} +9 -20
  110. machineconfig/utils/{utils_options.py → options.py} +10 -20
  111. machineconfig/utils/{utils_path.py → path.py} +28 -80
  112. machineconfig/utils/procs.py +26 -30
  113. machineconfig/utils/scheduling.py +11 -11
  114. machineconfig/utils/utils.py +12 -19
  115. machineconfig/utils/ve.py +5 -21
  116. machineconfig/utils/ve_utils/ve2.py +15 -2
  117. {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/METADATA +4 -2
  118. {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/RECORD +120 -118
  119. {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/WHEEL +1 -1
  120. {machineconfig-1.94.dist-info → machineconfig-1.95.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,13 @@ from machineconfig.utils.utils import display_options, PROGRAM_PATH, write_shell
5
5
  from platform import system
6
6
  from enum import Enum
7
7
  from typing import Optional
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich import box # Import box
11
+
12
+ console = Console()
13
+
14
+ BOX_WIDTH = 150 # width for box drawing
8
15
 
9
16
 
10
17
  class Options(Enum):
@@ -25,11 +32,8 @@ class Options(Enum):
25
32
 
26
33
 
27
34
  def args_parser():
28
- print(f"""
29
- ╔{'═' * 70}╗
30
- ║ 🛠️ DevOps Tool Suite ║
31
- ╚{'═' * 70}╝
32
- """)
35
+ # Print header
36
+ console.print(Panel("🛠️ DevOps Tool Suite", title_align="left", border_style="blue", width=BOX_WIDTH))
33
37
 
34
38
  import argparse
35
39
  parser = argparse.ArgumentParser()
@@ -39,177 +43,119 @@ def args_parser():
39
43
  main(which=args.which)
40
44
 
41
45
 
46
+ def display_title(title):
47
+ console.print(Panel(title, box=box.DOUBLE_EDGE, title_align="left")) # Replace print with Panel
48
+
49
+ def display_task_title(title):
50
+ console.print(Panel(title, box=box.ROUNDED, title_align="left")) # Replace print with Panel
51
+
52
+ def display_task_status(status):
53
+ console.print(Panel(status, box=box.ROUNDED, title_align="left")) # Replace print with Panel
54
+
55
+ def display_task_result(result):
56
+ console.print(Panel(result, box=box.ROUNDED, title_align="left")) # Replace print with Panel
57
+
58
+ def display_task_error(error):
59
+ console.print(Panel(error, box=box.ROUNDED, border_style="red", title_align="left")) # Replace print with Panel
60
+
61
+ def display_task_warning(warning):
62
+ console.print(Panel(warning, box=box.ROUNDED, border_style="yellow", title_align="left")) # Replace print with Panel
63
+
64
+ def display_task_success(success):
65
+ console.print(Panel(success, box=box.ROUNDED, border_style="green", title_align="left")) # Replace print with Panel
66
+
67
+
42
68
  def main(which: Optional[str] = None):
43
69
  PROGRAM_PATH.delete(sure=True, verbose=False)
44
- print(f"""
45
- ╭{'─' * 70}╮
46
- │ 🚀 Initializing DevOps operation... │
47
- ╰{'─' * 70}╯
48
- """)
70
+ console.print(Panel("🚀 Initializing DevOps operation...", width=BOX_WIDTH, border_style="blue"))
49
71
 
50
72
  options = [op.value for op in Options]
51
73
  if which is None:
52
74
  try:
53
75
  choice_key = display_options(msg="", options=options, header="🛠️ DEVOPS", default=options[0])
54
76
  except KeyboardInterrupt:
55
- print(f"""
56
- ╔{'═' * 70}╗
57
- ║ ❌ Operation cancelled by user ║
58
- ╚{'═' * 70}╝
59
- """)
77
+ console.print(Panel("❌ Operation cancelled by user", title_align="left", border_style="red", width=BOX_WIDTH))
60
78
  return
61
79
  else: choice_key = Options[which].value
62
80
 
63
- print(f"""
64
- ╔{'═' * 70}╗
65
- ║ 🔧 SELECTED OPERATION ║
66
- ╠{'═' * 70}╣
67
- ║ {choice_key.center(68)} ║
68
- ╚{'═' * 70}╝
69
- """)
81
+ console.print(Panel(f"🔧 SELECTED OPERATION\n{choice_key}", title_align="left", border_style="green", width=BOX_WIDTH))
70
82
 
71
83
  if choice_key == Options.update.value:
72
- print(f"""
73
- ╭{'─' * 70}╮
74
- │ 🔄 Updating essential repositories... │
75
- ╰{'─' * 70}╯
76
- """)
84
+ console.print(Panel("🔄 Updating essential repositories...", width=BOX_WIDTH, border_style="blue"))
77
85
  import machineconfig.scripts.python.devops_update_repos as helper
78
86
  program = helper.main()
79
87
 
80
88
  elif choice_key == Options.ve.value:
81
- print(f"""
82
- ╭{'─' * 70}╮
83
- │ 🐍 Setting up virtual environment... │
84
- ╰{'─' * 70}╯
85
- """)
89
+ console.print(Panel("🐍 Setting up virtual environment...", width=BOX_WIDTH, border_style="blue"))
86
90
  from machineconfig.utils.ve import get_ve_install_script
87
91
  program = get_ve_install_script()
88
92
 
89
93
  elif choice_key == Options.cli_install.value:
90
- print(f"""
91
- ╭{'─' * 70}╮
92
- │ ⚙️ Installing development applications... │
93
- ╰{'─' * 70}╯
94
- """)
94
+ console.print(Panel("⚙️ Installing development applications...", width=BOX_WIDTH, border_style="blue"))
95
95
  import machineconfig.scripts.python.devops_devapps_install as helper
96
96
  program = helper.main()
97
97
 
98
98
  elif choice_key == Options.sym_new.value:
99
- print(f"""
100
- ╭{'─' * 70}╮
101
- │ 🔄 Creating new symlinks... │
102
- ╰{'─' * 70}╯
103
- """)
99
+ console.print(Panel("🔄 Creating new symlinks...", width=BOX_WIDTH, border_style="blue"))
104
100
  import machineconfig.jobs.python.python_ve_symlink as helper
105
101
  program = helper.main()
106
102
 
107
103
  elif choice_key == Options.sym_path_shell.value:
108
- print(f"""
109
- ╭{'─' * 70}╮
110
- │ 🔗 Setting up symlinks, PATH, and shell profile... │
111
- ╰{'─' * 70}╯
112
- """)
104
+ console.print(Panel("🔗 Setting up symlinks, PATH, and shell profile...", width=BOX_WIDTH, border_style="blue"))
113
105
  import machineconfig.profile.create as helper
114
106
  helper.main()
115
107
  program = "echo '✅ done with symlinks'"
116
108
 
117
109
  elif choice_key == Options.ssh_add_pubkey.value:
118
- print(f"""
119
- ╭{'─' * 70}╮
120
- │ 🔑 Adding public SSH key to this machine... │
121
- ╰{'─' * 70}╯
122
- """)
110
+ console.print(Panel("🔑 Adding public SSH key to this machine...", width=BOX_WIDTH, border_style="blue"))
123
111
  import machineconfig.scripts.python.devops_add_ssh_key as helper
124
112
  program = helper.main()
125
113
 
126
114
  elif choice_key == Options.ssh_use_pair.value:
127
- print(f"""
128
- ╔{'═' * 70}╗
129
- ║ ❌ ERROR: Not Implemented ║
130
- ║ SSH key pair connection feature is not yet implemented ║
131
- ╚{'═' * 70}╝
132
- """)
115
+ console.print(Panel("❌ ERROR: Not Implemented\nSSH key pair connection feature is not yet implemented", title_align="left", border_style="red", width=BOX_WIDTH))
133
116
  raise NotImplementedError
134
117
 
135
118
  elif choice_key == Options.ssh_add_id.value: # so that you can SSH directly withuot pointing to identity key.
136
- print(f"""
137
- ╭{'─' * 70}╮
138
- │ 🗝️ Adding SSH identity (private key) to this machine... │
139
- ╰{'─' * 70}╯
140
- """)
119
+ console.print(Panel("🗝️ Adding SSH identity (private key) to this machine...", width=BOX_WIDTH, border_style="blue"))
141
120
  import machineconfig.scripts.python.devops_add_identity as helper
142
121
  program = helper.main()
143
122
 
144
123
  elif choice_key == Options.ssh_setup.value:
145
- print(f"""
146
- ╭{'─' * 70}╮
147
- │ 📡 Setting up SSH... │
148
- ╰{'─' * 70}╯
149
- """)
124
+ console.print(Panel("📡 Setting up SSH...", width=BOX_WIDTH, border_style="blue"))
150
125
  program_windows = """Invoke-WebRequest https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/openssh_all.ps1 | Invoke-Expression # https://github.com/thisismygitrepo.keys"""
151
126
  program_linux = """curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/openssh_all.sh | sudo bash # https://github.com/thisismygitrepo.keys"""
152
127
  program = program_linux if system() == "Linux" else program_windows
153
128
 
154
129
  elif choice_key == Options.ssh_setup_wsl.value:
155
- print(f"""
156
- ╭{'─' * 70}╮
157
- │ 🐧 Setting up SSH for WSL... │
158
- ╰{'─' * 70}╯
159
- """)
130
+ console.print(Panel("🐧 Setting up SSH for WSL...", width=BOX_WIDTH, border_style="blue"))
160
131
  program = """curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/openssh_wsl.sh | sudo bash"""
161
132
 
162
133
  elif choice_key == Options.backup.value:
163
- print(f"""
164
- ╭{'─' * 70}╮
165
- │ 💾 Creating backup... │
166
- ╰{'─' * 70}╯
167
- """)
134
+ console.print(Panel("💾 Creating backup...", width=BOX_WIDTH, border_style="blue"))
168
135
  from machineconfig.scripts.python.devops_backup_retrieve import main_backup_retrieve as helper
169
136
  program = helper(direction="BACKUP")
170
137
 
171
138
  elif choice_key == Options.retreive.value:
172
- print(f"""
173
- ╭{'─' * 70}╮
174
- │ 📥 Retrieving backup... │
175
- ╰{'─' * 70}╯
176
- """)
139
+ console.print(Panel("📥 Retrieving backup...", width=BOX_WIDTH, border_style="blue"))
177
140
  from machineconfig.scripts.python.devops_backup_retrieve import main_backup_retrieve as helper
178
141
  program = helper(direction="RETRIEVE")
179
142
 
180
143
  elif choice_key == Options.scheduler.value:
181
- print(f"""
182
- ╭{'─' * 70}╮
183
- │ ⏰ Setting up scheduler... │
184
- ╰{'─' * 70}╯
185
- """)
144
+ console.print(Panel("⏰ Setting up scheduler...", width=BOX_WIDTH, border_style="blue"))
186
145
  from machineconfig.scripts.python.scheduler import main as helper
187
146
  program = helper()
188
147
 
189
148
  elif choice_key == Options.dot_files_sync.value:
190
- print(f"""
191
- ╭{'─' * 70}╮
192
- │ 🔗 Synchronizing dotfiles... │
193
- ╰{'─' * 70}╯
194
- """)
149
+ console.print(Panel("🔗 Synchronizing dotfiles...", width=BOX_WIDTH, border_style="blue"))
195
150
  from machineconfig.scripts.python.cloud_repo_sync import main as helper, P
196
151
  program = helper(cloud=None, path=str(P.home() / "dotfiles"), pwd=None, action="ask")
197
152
 
198
153
  else:
199
- print(f"""
200
- ╔{'═' * 70}╗
201
- ║ ❌ ERROR: Invalid choice ║
202
- ║ The selected operation is not implemented: {choice_key}
203
- ╚{'═' * 70}╝
204
- """)
154
+ console.print(Panel("❌ ERROR: Invalid choice", title_align="left", border_style="red", width=BOX_WIDTH))
205
155
  raise ValueError(f"Unimplemented choice: {choice_key}")
206
156
 
207
157
  if program:
208
- print(f"""
209
- ╭{'─' * 70}╮
210
- │ 📜 Preparing shell script... │
211
- ╰{'─' * 70}╯
212
- """)
158
+ console.print(Panel("📜 Preparing shell script...", width=BOX_WIDTH, border_style="blue"))
213
159
  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)
214
160
  else:
215
161
  write_shell_script_to_default_program_path(program="echo '✨ Done.'", display=False, desc="🔧 Shell script prepared by Python.", preserve_cwd=True, execute=False)
@@ -4,125 +4,65 @@
4
4
 
5
5
  # from platform import system
6
6
  from crocodile.file_management import P
7
- from machineconfig.utils.utils_options import display_options
7
+ from machineconfig.utils.options import display_options
8
+ from rich.panel import Panel
9
+ from rich.text import Text
10
+
11
+ BOX_WIDTH = 150 # width for box drawing
8
12
 
9
13
 
10
14
  def main():
11
- print(f"""
12
- ╔{'═' * 70}╗
13
- ║ 🔑 SSH IDENTITY MANAGEMENT ║
14
- ╚{'═' * 70}╝
15
- """)
16
-
17
- print(f"""
18
- ╭{'─' * 70}╮
19
- │ 🔍 Searching for existing SSH keys... │
20
- ╰{'─' * 70}╯
21
- """)
22
-
15
+ title = "🔑 SSH IDENTITY MANAGEMENT"
16
+ print(Panel(Text(title, justify="center"), expand=False))
17
+
18
+ print(Panel("🔍 Searching for existing SSH keys...", expand=False))
19
+
23
20
  private_keys = P.home().joinpath(".ssh").search("*.pub").apply(lambda x: x.with_name(x.stem)).filter(lambda x: x.exists())
24
-
21
+
25
22
  if private_keys:
26
- print(f"""
27
- ╭{'─' * 70}╮
28
- │ ✅ Found {len(private_keys)} SSH private key(s) │
29
- ╰{'─' * 70}╯
30
- """)
23
+ print(Panel(f"✅ Found {len(private_keys)} SSH private key(s)", expand=False))
31
24
  else:
32
- print(f"""
33
- ╭{'─' * 70}╮
34
- │ ⚠️ No SSH private keys found │
35
- ╰{'─' * 70}╯
36
- """)
37
-
25
+ print(Panel("⚠️ No SSH private keys found", expand=False))
26
+
38
27
  choice = display_options(msg="Path to private key to be used when ssh'ing: ", options=private_keys.apply(str).list + ["I have the path to the key file", "I want to paste the key itself"])
39
-
28
+
40
29
  if choice == "I have the path to the key file":
41
- print(f"""
42
- ╭{'─' * 70}╮
43
- │ 📄 Please enter the path to your private key file │
44
- ╰{'─' * 70}╯
45
- """)
30
+ print(Panel("📄 Please enter the path to your private key file", expand=False))
46
31
  path_to_key = P(input("📋 Input path here: ")).expanduser().absolute()
47
- print(f"""
48
- ╭{'─' * 70}╮
49
- │ 📂 Using key from custom path: {path_to_key} │
50
- ╰{'─' * 70}╯
51
- """)
52
-
32
+ print(Panel(f"📂 Using key from custom path: {path_to_key}", expand=False))
33
+
53
34
  elif choice == "I want to paste the key itself":
54
- print(f"""
55
- ╭{'─' * 70}╮
56
- │ 📋 Please provide a filename and paste the private key content │
57
- ╰{'─' * 70}╯
58
- """)
35
+ print(Panel("📋 Please provide a filename and paste the private key content", expand=False))
59
36
  key_filename = input("📝 File name (default: my_pasted_key): ") or "my_pasted_key"
60
37
  path_to_key = P.home().joinpath(f".ssh/{key_filename}").write_text(input("🔑 Paste the private key here: "))
61
- print(f"""
62
- ╭{'─' * 70}╮
63
- 💾 Key saved to: {path_to_key} │
64
- ╰{'─' * 70}╯
65
- """)
66
-
67
- elif isinstance(choice, str):
38
+ print(Panel(f"💾 Key saved to: {path_to_key}", expand=False))
39
+
40
+ elif isinstance(choice, str):
68
41
  path_to_key = P(choice)
69
- print(f"""
70
- ╭{'─' * 70}╮
71
- │ 🔑 Using selected key: {path_to_key.name} │
72
- ╰{'─' * 70}
73
- """)
74
-
75
- else:
76
- print(f"""
77
- ╔{'═' * 70}╗
78
- ║ ❌ ERROR: Invalid choice ║
79
- ║ The selected option is not supported: {choice} ║
80
- ╚{'═' * 70}╝
81
- """)
42
+ print(Panel(f"🔑 Using selected key: {path_to_key.name}", expand=False))
43
+
44
+ else:
45
+ error_message = f"❌ ERROR: Invalid choice\nThe selected option is not supported: {choice}"
46
+ print(Panel(Text(error_message, justify="center"), expand=False, border_style="red"))
82
47
  raise NotImplementedError(f"Choice {choice} not supported")
83
-
48
+
84
49
  txt = f"IdentityFile {path_to_key.collapseuser().as_posix()}" # adds this id for all connections, no host specified.
85
50
  config_path = P.home().joinpath(".ssh/config")
86
-
87
- print(f"""
88
- ╭{'─' * 70}╮
89
- 📝 Updating SSH configuration... │
90
- ╰{'─' * 70}╯
91
- """)
92
-
93
- if config_path.exists():
51
+
52
+ print(Panel("📝 Updating SSH configuration...", expand=False))
53
+
54
+ if config_path.exists():
94
55
  config_path.modify_text(txt_search=txt, txt_alt=txt, replace_line=True, notfound_append=True, prepend=True) # note that Identity line must come on top of config file otherwise it won't work, hence `prepend=True`
95
- print(f"""
96
- ╭{'─' * 70}╮
97
- │ ✏️ Updated existing SSH config file │
98
- ╰{'─' * 70}╯
99
- """)
100
- else:
56
+ print(Panel("✏️ Updated existing SSH config file", expand=False))
57
+ else:
101
58
  config_path.write_text(txt)
102
- print(f"""
103
- ╭{'─' * 70}╮
104
- 📄 Created new SSH config file
105
- ╰{'─' * 70}╯
106
- """)
107
-
108
- program = f"""echo '
109
- ╔{'═' * 70}╗
110
- ║ ✅ SSH IDENTITY CONFIGURATION COMPLETE ║
111
- ╠{'═' * 70}╣
112
- ║ Identity added to SSH config file ║
113
- ║ Consider reloading the SSH config to apply changes ║
114
- ╚{'═' * 70}╝
115
- '"""
116
-
117
- print(f"""
118
- ╔{'═' * 70}╗
119
- ║ 🎉 CONFIGURATION SUCCESSFUL ║
120
- ╠{'═' * 70}╣
121
- ║ Identity added: {path_to_key.name}
122
- ║ Config file: {config_path}
123
- ╚{'═' * 70}╝
124
- """)
125
-
59
+ print(Panel("📄 Created new SSH config file", expand=False))
60
+
61
+ program = f"""echo '{Panel(Text("✅ SSH IDENTITY CONFIGURATION COMPLETE\nIdentity added to SSH config file\nConsider reloading the SSH config to apply changes", justify="center"), expand=False, border_style="green")}' """
62
+
63
+ success_message = f"🎉 CONFIGURATION SUCCESSFUL\nIdentity added: {path_to_key.name}\nConfig file: {config_path}"
64
+ print(Panel(Text(success_message, justify="center"), expand=False, border_style="green"))
65
+
126
66
  return program
127
67
 
128
68
 
@@ -5,71 +5,38 @@
5
5
  from platform import system
6
6
  from machineconfig.utils.utils import LIBRARY_ROOT, display_options
7
7
  from crocodile.file_management import P
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich import box # Import box
11
+
12
+
13
+ console = Console()
8
14
 
9
15
 
10
16
  def get_add_ssh_key_script(path_to_key: P):
11
- print(f"""
12
- ╔{'═' * 70}╗
13
- 🔑 SSH KEY CONFIGURATION ║
14
- ╚{'═' * 70}╝
15
- """)
16
-
17
- if system() == "Linux":
17
+ console.print(Panel("🔑 SSH KEY CONFIGURATION", title="[bold blue]SSH Setup[/bold blue]"))
18
+
19
+ if system() == "Linux":
18
20
  authorized_keys = P.home().joinpath(".ssh/authorized_keys")
19
- print(f"""
20
- ╭{'─' * 70}╮
21
- │ 🐧 Linux SSH configuration │
22
- │ 📄 Authorized keys file: {authorized_keys} │
23
- ╰{'─' * 70}╯
24
- """)
25
- elif system() == "Windows":
21
+ console.print(Panel(f"🐧 Linux SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
22
+ elif system() == "Windows":
26
23
  authorized_keys = P("C:/ProgramData/ssh/administrators_authorized_keys")
27
- print(f"""
28
- ╭{'─' * 70}╮
29
- 🪟 Windows SSH configuration │
30
- │ 📄 Authorized keys file: {authorized_keys} │
31
- ╰{'─' * 70}╯
32
- """)
33
- else:
34
- print(f"""
35
- ╔{'═' * 70}╗
36
- ║ ❌ ERROR: Unsupported operating system ║
37
- ║ Only Linux and Windows are supported ║
38
- ╚{'═' * 70}╝
39
- """)
24
+ console.print(Panel(f"🪟 Windows SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
25
+ else:
26
+ console.print(Panel("❌ ERROR: Unsupported operating system\nOnly Linux and Windows are supported", title="[bold red]Error[/bold red]"))
40
27
  raise NotImplementedError
41
28
 
42
29
  if authorized_keys.exists():
43
30
  split = "\n"
44
31
  keys_text = authorized_keys.read_text().split(split)
45
32
  key_count = len([k for k in keys_text if k.strip()])
46
-
47
- print(f"""
48
- ╭{'─' * 70}╮
49
- │ 🔍 Current SSH authorization status │
50
- │ ✅ Found {key_count} authorized key(s) │
51
- ╰{'─' * 70}╯
52
- """)
53
-
33
+ console.print(Panel(f"🔍 Current SSH authorization status\n✅ Found {key_count} authorized key(s)", title="[bold blue]Status[/bold blue]"))
34
+
54
35
  if path_to_key.read_text() in authorized_keys.read_text():
55
- print(f"""
56
- ╔{'═' * 70}╗
57
- ║ ⚠️ Key already authorized ║
58
- ╠{'═' * 70}╣
59
- ║ Key: {path_to_key.name}
60
- ║ Status: Already present in authorized_keys file
61
- ║ No action required
62
- ╚{'═' * 70}╝
63
- """)
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]"))
64
37
  program = ""
65
38
  else:
66
- print(f"""
67
- ╭{'─' * 70}╮
68
- │ ➕ Adding new SSH key to authorized keys │
69
- │ 🔑 Key file: {path_to_key.name} │
70
- ╰{'─' * 70}╯
71
- """)
72
-
39
+ console.print(Panel(f"➕ Adding new SSH key to authorized keys\n🔑 Key file: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
73
40
  if system() == "Linux":
74
41
  program = f"cat {path_to_key} >> ~/.ssh/authorized_keys"
75
42
  elif system() == "Windows":
@@ -78,34 +45,18 @@ def get_add_ssh_key_script(path_to_key: P):
78
45
  place_holder = r'$sshfile = "$env:USERPROFILE\.ssh\pubkey.pub"'
79
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."
80
47
  program = program.replace(place_holder, f'$sshfile = "{path_to_key}"')
81
- print(f"""
82
- ╭{'─' * 70}╮
83
- │ 🔧 Configured PowerShell script for Windows │
84
- │ 📝 Replaced placeholder with actual key path │
85
- ╰{'─' * 70}╯
86
- """)
48
+ console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Replaced placeholder with actual key path", title="[bold blue]Configuration[/bold blue]"))
87
49
  else: raise NotImplementedError
88
50
  else:
89
- print(f"""
90
- ╭{'─' * 70}╮
91
- │ 📝 Creating new authorized_keys file │
92
- │ 🔑 Using key: {path_to_key.name} │
93
- ╰{'─' * 70}╯
94
- """)
95
-
51
+ console.print(Panel(f"📝 Creating new authorized_keys file\n🔑 Using key: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
96
52
  if system() == "Linux":
97
53
  program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
98
54
  else:
99
55
  program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
100
56
  program = P(program_path).expanduser().read_text().replace('$sshfile=""', f'$sshfile="{path_to_key}"')
101
- print(f"""
102
- ╭{'─' * 70}╮
103
- │ 🔧 Configured PowerShell script for Windows │
104
- │ 📝 Set key path in script │
105
- ╰{'─' * 70}╯
106
- """)
57
+ console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Set key path in script", title="[bold blue]Configuration[/bold blue]"))
107
58
 
108
- if system() == "Linux":
59
+ if system() == "Linux":
109
60
  program += """
110
61
 
111
62
  sudo chmod 700 ~/.ssh
@@ -113,50 +64,21 @@ sudo chmod 644 ~/.ssh/authorized_keys
113
64
  sudo chmod 644 ~/.ssh/*.pub
114
65
  sudo service ssh --full-restart
115
66
  # from superuser.com/questions/215504/permissions-on-private-key-in-ssh-folder
116
-
117
67
  """
118
- print(f"""
119
- ╭{'─' * 70}╮
120
- │ 🔒 Setting proper SSH permissions and restarting service │
121
- ╰{'─' * 70}╯
122
- """)
123
-
124
- print(f"""
125
- ╔{'═' * 70}╗
126
- ║ ✅ SSH KEY CONFIGURATION PREPARED ║
127
- ╚{'═' * 70}╝
128
- """)
129
-
130
68
  return program
131
69
 
132
70
 
133
71
  def main():
134
- print(f"""
135
- ╔{'═' * 70}╗
136
- ║ 🔐 SSH PUBLIC KEY AUTHORIZATION TOOL ║
137
- ╚{'═' * 70}╝
138
- """)
72
+ console.print(Panel("🔐 SSH PUBLIC KEY AUTHORIZATION TOOL", box=box.DOUBLE_EDGE, title_align="left"))
139
73
 
140
- print(f"""
141
- ╭{'─' * 70}╮
142
- │ 🔍 Searching for public keys... │
143
- ╰{'─' * 70}╯
144
- """)
74
+ console.print(Panel("🔍 Searching for public keys...", title="[bold blue]SSH Setup[/bold blue]", border_style="blue"))
145
75
 
146
76
  pub_keys = P.home().joinpath(".ssh").search("*.pub")
147
77
 
148
78
  if pub_keys:
149
- print(f"""
150
- ╭{'─' * 70}╮
151
- │ ✅ Found {len(pub_keys)} public key(s) │
152
- ╰{'─' * 70}╯
153
- """)
79
+ console.print(Panel(f"✅ Found {len(pub_keys)} public key(s)", title="[bold green]Status[/bold green]", border_style="green"))
154
80
  else:
155
- print(f"""
156
- ╭{'─' * 70}╮
157
- │ ⚠️ No public keys found │
158
- ╰{'─' * 70}╯
159
- """)
81
+ console.print(Panel("⚠️ No public keys found", title="[bold yellow]Warning[/bold yellow]", border_style="yellow"))
160
82
 
161
83
  all_keys_option = f"all pub keys available ({len(pub_keys)})"
162
84
  i_have_path_option = "I have the path to the key file"
@@ -166,57 +88,28 @@ def main():
166
88
  assert isinstance(res, str), f"Got {res} of type {type(res)} instead of str."
167
89
 
168
90
  if res == all_keys_option:
169
- print(f"""
170
- ╭{'─' * 70}╮
171
- │ 🔄 Processing all {len(pub_keys)} public keys... │
172
- ╰{'─' * 70}╯
173
- """)
91
+ console.print(Panel(f"🔄 Processing all {len(pub_keys)} public keys...", title="[bold blue]Processing[/bold blue]", border_style="blue"))
174
92
  program = "\n\n\n".join(pub_keys.apply(get_add_ssh_key_script))
175
93
 
176
94
  elif res == i_have_path_option:
177
- print(f"""
178
- ╭{'─' * 70}╮
179
- │ 📂 Please provide the path to your public key │
180
- ╰{'─' * 70}╯
181
- """)
95
+ console.print(Panel("📂 Please provide the path to your public key", title="[bold blue]Input Required[/bold blue]", border_style="blue"))
182
96
  key_path = P(input("📋 Path: ")).expanduser().absolute()
183
- print(f"""
184
- ╭{'─' * 70}╮
185
- │ 📄 Using key from path: {key_path} │
186
- ╰{'─' * 70}╯
187
- """)
97
+ console.print(Panel(f"📄 Using key from path: {key_path}", title="[bold blue]Info[/bold blue]", border_style="blue"))
188
98
  program = get_add_ssh_key_script(key_path)
189
99
 
190
100
  elif res == i_paste_option:
191
- print(f"""
192
- ╭{'─' * 70}╮
193
- │ 📋 Please provide a filename and paste the public key content │
194
- ╰{'─' * 70}╯
195
- """)
101
+ console.print(Panel("📋 Please provide a filename and paste the public key content", title="[bold blue]Input Required[/bold blue]", border_style="blue"))
196
102
  key_filename = input("📝 File name (default: my_pasted_key.pub): ") or "my_pasted_key.pub"
197
103
  key_path = P.home().joinpath(f".ssh/{key_filename}")
198
104
  key_path.write_text(input("🔑 Paste the public key here: "))
199
- print(f"""
200
- ╭{'─' * 70}╮
201
- │ 💾 Key saved to: {key_path} │
202
- ╰{'─' * 70}╯
203
- """)
105
+ console.print(Panel(f"💾 Key saved to: {key_path}", title="[bold green]Success[/bold green]", border_style="green"))
204
106
  program = get_add_ssh_key_script(key_path)
205
107
 
206
108
  else:
207
- print(f"""
208
- ╭{'─' * 70}╮
209
- │ 🔑 Using selected key: {P(res).name} │
210
- ╰{'─' * 70}╯
211
- """)
109
+ console.print(Panel(f"🔑 Using selected key: {P(res).name}", title="[bold blue]Info[/bold blue]", border_style="blue"))
212
110
  program = get_add_ssh_key_script(P(res))
213
111
 
214
- print(f"""
215
- ╔{'═' * 70}╗
216
- ║ 🚀 SSH KEY AUTHORIZATION READY ║
217
- ║ Run the generated script to apply changes ║
218
- ╚{'═' * 70}╝
219
- """)
112
+ console.print(Panel("🚀 SSH KEY AUTHORIZATION READY\nRun the generated script to apply changes", box=box.DOUBLE_EDGE, title_align="left"))
220
113
 
221
114
  return program
222
115