machineconfig 1.97__py3-none-any.whl → 2.0__py3-none-any.whl

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

Potentially problematic release.


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

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