machineconfig 7.50__py3-none-any.whl → 8.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +23 -11
- machineconfig/cluster/sessions_managers/wt_local_manager.py +22 -19
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +3 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +3 -1
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
- machineconfig/jobs/installer/installer_data.json +1185 -165
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
- machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
- machineconfig/jobs/installer/package_groups.py +52 -84
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
- machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +4 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/{custom → python_scripts}/hx.py +16 -12
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +27 -22
- machineconfig/jobs/installer/python_scripts/sysabc.py +139 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
- machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
- machineconfig/jobs/installer/python_scripts/yazi.py +121 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
- machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
- machineconfig/jobs/scripts_dynamic/a.py +25 -0
- machineconfig/logger.py +0 -1
- machineconfig/profile/create_helper.py +21 -22
- machineconfig/profile/create_links_export.py +25 -11
- machineconfig/profile/create_shell_profile.py +14 -3
- machineconfig/profile/mapper.toml +8 -6
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/wrap_mcfg +20 -21
- machineconfig/scripts/python/agents.py +74 -50
- machineconfig/scripts/python/ai/initai.py +1 -1
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/generic.py +1 -1
- machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
- machineconfig/scripts/python/cloud.py +6 -6
- machineconfig/scripts/python/croshell.py +67 -60
- machineconfig/scripts/python/devops.py +41 -21
- machineconfig/scripts/python/devops_navigator.py +0 -4
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
- machineconfig/scripts/python/fire_jobs.py +95 -67
- machineconfig/scripts/python/ftpx.py +44 -17
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +1 -1
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +9 -7
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +21 -8
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +0 -12
- machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +30 -11
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +9 -2
- machineconfig/scripts/python/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +8 -4
- machineconfig/scripts/python/helpers_agents/templates/template.sh +18 -8
- machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
- machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
- machineconfig/scripts/python/helpers_cloud/cloud_mount.py +19 -17
- machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
- machineconfig/scripts/python/helpers_croshell/crosh.py +3 -3
- machineconfig/scripts/python/helpers_croshell/start_slidev.py +6 -7
- machineconfig/scripts/python/helpers_devops/cli_config.py +19 -25
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +22 -13
- machineconfig/scripts/python/helpers_devops/cli_nw.py +113 -26
- machineconfig/scripts/python/helpers_devops/cli_repos.py +37 -11
- machineconfig/scripts/python/helpers_devops/cli_self.py +95 -42
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +9 -9
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +13 -12
- machineconfig/scripts/python/helpers_devops/{cli_terminal.py → cli_share_terminal.py} +15 -17
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +4 -4
- machineconfig/scripts/python/helpers_devops/devops_status.py +7 -19
- machineconfig/scripts/python/helpers_devops/run_script.py +180 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_wezterm_theme.py +1 -1
- machineconfig/scripts/python/helpers_fire_command/file_wrangler.py +2 -19
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_args_helper.py +1 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +25 -15
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +58 -1
- machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
- machineconfig/scripts/python/helpers_network/address.py +176 -0
- machineconfig/scripts/python/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/{nw → helpers_network}/mount_nfs.py +2 -2
- machineconfig/scripts/python/{nw → helpers_network}/mount_ssh.py +1 -1
- machineconfig/scripts/python/{nw/devops_add_identity.py → helpers_network/ssh_add_identity.py} +35 -1
- machineconfig/scripts/python/{nw/devops_add_ssh_key.py → helpers_network/ssh_add_ssh_key.py} +26 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_linux.py +7 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_windows.py +4 -4
- machineconfig/scripts/python/helpers_repos/clone.py +0 -1
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +13 -5
- machineconfig/scripts/python/helpers_repos/entrypoint.py +2 -1
- machineconfig/scripts/python/helpers_repos/record.py +2 -1
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/helpers_repos/{count_lines.py → repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +19 -13
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/pdf.py +96 -0
- machineconfig/scripts/python/helpers_utils/python.py +187 -0
- machineconfig/scripts/python/interactive.py +30 -31
- machineconfig/scripts/python/{machineconfig.py → mcfg_entry.py} +4 -5
- machineconfig/scripts/python/msearch.py +57 -6
- machineconfig/scripts/python/sessions.py +100 -31
- machineconfig/scripts/python/terminal.py +26 -17
- machineconfig/scripts/python/utils.py +17 -15
- machineconfig/scripts/windows/wrap_mcfg.ps1 +6 -3
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/shells/bash/init.sh +29 -2
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -2
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +282 -95
- machineconfig/settings/shells/pwsh/init.ps1 +1 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/zsh/init.sh +1 -8
- machineconfig/settings/television/cable_unix/alias.toml +8 -0
- machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
- machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
- machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
- machineconfig/settings/television/cable_unix/channels.toml +19 -0
- machineconfig/settings/television/cable_unix/dirs.toml +13 -0
- machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
- machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
- machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_unix/env.toml +17 -0
- machineconfig/settings/television/cable_unix/files.toml +11 -0
- machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
- machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
- machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
- machineconfig/settings/television/cable_unix/git-log.toml +12 -0
- machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
- machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
- machineconfig/settings/television/cable_unix/guix.toml +20 -0
- machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
- machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
- machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
- machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
- machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
- machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
- machineconfig/settings/television/cable_unix/procs.toml +20 -0
- machineconfig/settings/television/cable_unix/text.toml +17 -0
- machineconfig/settings/television/cable_unix/tldr.toml +18 -0
- machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
- machineconfig/settings/television/cable_windows/alias.toml +7 -0
- machineconfig/settings/television/cable_windows/dirs.toml +13 -0
- machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
- machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_windows/env.toml +17 -0
- machineconfig/settings/television/cable_windows/files.toml +14 -0
- machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
- machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
- machineconfig/settings/television/cable_windows/git-log.toml +11 -0
- machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
- machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
- machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
- machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
- machineconfig/settings/television/cable_windows/text.toml +17 -0
- machineconfig/settings/wt/__init__.py +0 -0
- machineconfig/settings/yazi/init.lua +49 -24
- machineconfig/settings/yazi/keymap_linux.toml +19 -4
- machineconfig/settings/yazi/keymap_windows.toml +0 -1
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +29 -5
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/settings/zellij/layouts/st.kdl +39 -8
- machineconfig/setup_linux/__init__.py +1 -2
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +12 -10
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +2 -3
- machineconfig/setup_windows/__init__.py +3 -5
- machineconfig/setup_windows/ssh/openssh-server.ps1 +1 -1
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +12 -10
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/utils/accessories.py +7 -4
- machineconfig/utils/code.py +69 -27
- machineconfig/utils/files/headers.py +2 -2
- machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +43 -100
- machineconfig/utils/installer_utils/installer_cli.py +175 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +36 -85
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +16 -59
- machineconfig/utils/io.py +0 -1
- machineconfig/utils/links.py +2 -2
- machineconfig/utils/meta.py +30 -16
- machineconfig/utils/options.py +42 -24
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +42 -20
- machineconfig/utils/path_helper.py +75 -22
- machineconfig/utils/procs.py +1 -1
- machineconfig/utils/scheduler.py +20 -53
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/ssh.py +159 -418
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +1 -0
- machineconfig/utils/upgrade_packages.py +6 -1
- machineconfig/utils/ve.py +12 -4
- machineconfig-8.14.dist-info/METADATA +132 -0
- {machineconfig-7.50.dist-info → machineconfig-8.14.dist-info}/RECORD +264 -215
- {machineconfig-7.50.dist-info → machineconfig-8.14.dist-info}/entry_points.txt +2 -4
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
- machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
- machineconfig/jobs/installer/powershell_scripts/openssh-server_add_key.ps1 +0 -7
- machineconfig/jobs/installer/powershell_scripts/openssh-server_copy-ssh-id.ps1 +0 -14
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
- machineconfig/scripts/python/define.py +0 -31
- machineconfig/scripts/python/explore.py +0 -49
- machineconfig/scripts/python/helpers_devops/cli_utils.py +0 -246
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfag +0 -17
- machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfrga +0 -21
- machineconfig/scripts/python/helpers_msearch/scripts_linux/skrg +0 -4
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfb.ps1 +0 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfrga.bat +0 -20
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
- machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
- machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
- machineconfig/settings/lf/windows/tst.ps1 +0 -1
- machineconfig/settings/yazi/yazi.toml +0 -17
- machineconfig/setup_linux/apps.sh +0 -66
- machineconfig/setup_linux/others/cli_installation.sh +0 -137
- machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_mac/apps.sh +0 -73
- machineconfig/setup_windows/apps.ps1 +0 -62
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/utils/installer_utils/installer.py +0 -221
- machineconfig-7.50.dist-info/METADATA +0 -92
- /machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/__init__.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
- /machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
- /machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
- /machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
- /machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
- /machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
- /machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_smb +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
- /machineconfig/{scripts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
- /machineconfig/scripts/python/{nw → ai/utils}/__init__.py +0 -0
- /machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers_network}/__init__.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/wifi_conn.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-7.50.dist-info → machineconfig-8.14.dist-info}/WHEEL +0 -0
- {machineconfig-7.50.dist-info → machineconfig-8.14.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from typing import Annotated, Optional
|
|
4
|
+
import typer
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def download(
|
|
9
|
+
url: Annotated[Optional[str], typer.Argument(..., help="The URL to download the file from.")] = None,
|
|
10
|
+
decompress: Annotated[bool, typer.Option(..., "--decompress", "-d", help="Decompress the file if it's an archive.")] = False,
|
|
11
|
+
output: Annotated[Optional[str], typer.Option("--output", "-o", help="The output file path.")] = None,
|
|
12
|
+
output_dir: Annotated[Optional[str], typer.Option("--output-dir", help="Directory to place the downloaded file in.")] = None,
|
|
13
|
+
) -> Optional["Path"]:
|
|
14
|
+
import subprocess
|
|
15
|
+
from urllib.parse import parse_qs, unquote, urlparse
|
|
16
|
+
from requests import Response
|
|
17
|
+
import requests
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
if url is None:
|
|
20
|
+
typer.echo("❌ Error: URL is required.", err=True)
|
|
21
|
+
return None
|
|
22
|
+
if output is not None and output_dir is not None:
|
|
23
|
+
typer.echo("❌ Error: --output and --output-dir cannot be used together.", err=True)
|
|
24
|
+
return None
|
|
25
|
+
typer.echo(f"📥 Downloading from: {url}")
|
|
26
|
+
|
|
27
|
+
def _sanitize_candidate_filename(name: str) -> Optional[str]:
|
|
28
|
+
candidate = Path(name).name.strip()
|
|
29
|
+
if not candidate or candidate in {".", ".."}:
|
|
30
|
+
return None
|
|
31
|
+
return candidate
|
|
32
|
+
|
|
33
|
+
def _filename_from_content_disposition(header_value: Optional[str]) -> Optional[str]:
|
|
34
|
+
if header_value is None:
|
|
35
|
+
return None
|
|
36
|
+
parts = [segment.strip() for segment in header_value.split(";")]
|
|
37
|
+
for part in parts:
|
|
38
|
+
lower = part.lower()
|
|
39
|
+
if lower.startswith("filename*="):
|
|
40
|
+
value = part.split("=", 1)[1]
|
|
41
|
+
value = value.strip().strip('"')
|
|
42
|
+
if "''" in value:
|
|
43
|
+
value = value.split("''", 1)[1]
|
|
44
|
+
decoded = unquote(value)
|
|
45
|
+
sanitized = _sanitize_candidate_filename(decoded)
|
|
46
|
+
if sanitized is not None:
|
|
47
|
+
return sanitized
|
|
48
|
+
if lower.startswith("filename="):
|
|
49
|
+
value = part.split("=", 1)[1].strip().strip('"')
|
|
50
|
+
decoded = unquote(value)
|
|
51
|
+
sanitized = _sanitize_candidate_filename(decoded)
|
|
52
|
+
if sanitized is not None:
|
|
53
|
+
return sanitized
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
def _filename_from_url(source_url: str) -> Optional[str]:
|
|
57
|
+
parsed = urlparse(source_url)
|
|
58
|
+
url_candidate = _sanitize_candidate_filename(unquote(Path(parsed.path).name))
|
|
59
|
+
if url_candidate is not None:
|
|
60
|
+
return url_candidate
|
|
61
|
+
query_params = parse_qs(parsed.query, keep_blank_values=True)
|
|
62
|
+
for key, values in query_params.items():
|
|
63
|
+
lower_key = key.lower()
|
|
64
|
+
if "name" in lower_key or "file" in lower_key:
|
|
65
|
+
for value in values:
|
|
66
|
+
sanitized = _sanitize_candidate_filename(unquote(value))
|
|
67
|
+
if sanitized is not None:
|
|
68
|
+
return sanitized
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def _resolve_download_path(request_url: str, response: Response, requested_output: Optional[str], requested_output_dir: Optional[str]) -> Path:
|
|
72
|
+
if requested_output is not None:
|
|
73
|
+
return Path(requested_output)
|
|
74
|
+
header_candidate = _filename_from_content_disposition(response.headers.get("content-disposition"))
|
|
75
|
+
if header_candidate is None:
|
|
76
|
+
header_candidate = _filename_from_url(response.url)
|
|
77
|
+
if header_candidate is None:
|
|
78
|
+
header_candidate = _filename_from_url(request_url)
|
|
79
|
+
if header_candidate is None:
|
|
80
|
+
header_candidate = "downloaded_file"
|
|
81
|
+
if requested_output_dir is not None:
|
|
82
|
+
return Path(requested_output_dir) / header_candidate
|
|
83
|
+
return Path(header_candidate)
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
with requests.get(url, allow_redirects=True, stream=True, timeout=60) as response:
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
download_path = _resolve_download_path(url, response, output, output_dir)
|
|
89
|
+
download_path.parent.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
total_size_header = response.headers.get("content-length", "0")
|
|
91
|
+
try:
|
|
92
|
+
total_size = int(total_size_header)
|
|
93
|
+
except (TypeError, ValueError):
|
|
94
|
+
total_size = 0
|
|
95
|
+
if total_size <= 0:
|
|
96
|
+
with open(download_path, "wb") as file_handle:
|
|
97
|
+
file_handle.write(response.content)
|
|
98
|
+
else:
|
|
99
|
+
downloaded = 0
|
|
100
|
+
chunk_size = 8192 * 40
|
|
101
|
+
with open(download_path, "wb") as file_handle:
|
|
102
|
+
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
103
|
+
if not chunk:
|
|
104
|
+
continue
|
|
105
|
+
file_handle.write(chunk)
|
|
106
|
+
downloaded += len(chunk)
|
|
107
|
+
progress = (downloaded / total_size) * 100
|
|
108
|
+
typer.echo(f"\r⏬ Progress: {progress:.1f}% ({downloaded}/{total_size} bytes)", nl=False)
|
|
109
|
+
typer.echo()
|
|
110
|
+
except requests.exceptions.RequestException as exception:
|
|
111
|
+
typer.echo(f"❌ Download failed: {exception}", err=True)
|
|
112
|
+
return None
|
|
113
|
+
except OSError as exception:
|
|
114
|
+
typer.echo(f"❌ File write error: {exception}", err=True)
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
typer.echo(f"✅ Downloaded to: {download_path}")
|
|
118
|
+
result_path: Path = download_path
|
|
119
|
+
if decompress:
|
|
120
|
+
typer.echo(f"📦 Decompressing: {download_path}")
|
|
121
|
+
base_name = download_path.name.split(".", maxsplit=1)[0] # ouch decompresses all (e.g. .tar.gz) in one go.
|
|
122
|
+
if base_name in {"", ".", ".."}:
|
|
123
|
+
base_name = "extracted"
|
|
124
|
+
extract_dir = download_path.parent / base_name
|
|
125
|
+
extract_dir.mkdir(parents=True, exist_ok=True)
|
|
126
|
+
try:
|
|
127
|
+
subprocess.run(
|
|
128
|
+
["ouch", "decompress", str(download_path), "--dir", str(extract_dir)],
|
|
129
|
+
check=True,
|
|
130
|
+
capture_output=True,
|
|
131
|
+
text=True,
|
|
132
|
+
)
|
|
133
|
+
typer.echo(f"✅ Decompressed to: {extract_dir}")
|
|
134
|
+
if download_path.exists():
|
|
135
|
+
download_path.unlink()
|
|
136
|
+
typer.echo(f"🗑️ Removed archive: {download_path}")
|
|
137
|
+
result_path = extract_dir
|
|
138
|
+
except subprocess.CalledProcessError as exception:
|
|
139
|
+
typer.echo(f"❌ Decompression failed: {exception.stderr}", err=True)
|
|
140
|
+
return None
|
|
141
|
+
except FileNotFoundError:
|
|
142
|
+
typer.echo("❌ Error: ouch command not found. Please install ouch.", err=True)
|
|
143
|
+
typer.echo("💡 Install with: cargo install ouch", err=True)
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
return result_path.resolve()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if __name__ == "__main__":
|
|
150
|
+
pass
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from typing import Annotated, Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def merge_pdfs(
|
|
8
|
+
pdfs: Annotated[list[str], typer.Argument(..., help="Paths to the PDF files to merge.")],
|
|
9
|
+
output: Annotated[Optional[str], typer.Option("--output", "-o", help="Output merged PDF file path.")] = None,
|
|
10
|
+
compress: Annotated[bool, typer.Option("--compress", "-c", help="Compress the output PDF.")] = False,
|
|
11
|
+
) -> None:
|
|
12
|
+
def merge_pdfs_internal(pdfs: list[str], output: str | None, compress: bool) -> None:
|
|
13
|
+
from pypdf import PdfReader, PdfWriter
|
|
14
|
+
writer = PdfWriter()
|
|
15
|
+
for pdf_path in pdfs:
|
|
16
|
+
reader = PdfReader(pdf_path)
|
|
17
|
+
for page in reader.pages:
|
|
18
|
+
writer.add_page(page)
|
|
19
|
+
output_path = output if output else "merged.pdf"
|
|
20
|
+
if compress:
|
|
21
|
+
try:
|
|
22
|
+
for p in writer.pages:
|
|
23
|
+
try:
|
|
24
|
+
# PageObject.compress_content_streams exists in pypdf
|
|
25
|
+
p.compress_content_streams()
|
|
26
|
+
except Exception:
|
|
27
|
+
# best-effort: ignore per-page compression failures
|
|
28
|
+
continue
|
|
29
|
+
except Exception:
|
|
30
|
+
pass
|
|
31
|
+
try:
|
|
32
|
+
writer.compress_identical_objects()
|
|
33
|
+
except Exception:
|
|
34
|
+
# non-fatal if this fails
|
|
35
|
+
pass
|
|
36
|
+
writer.write(output_path)
|
|
37
|
+
print(f"✅ Merged PDF saved to: {output_path}")
|
|
38
|
+
from machineconfig.utils.meta import lambda_to_python_script
|
|
39
|
+
code = lambda_to_python_script(lambda : merge_pdfs_internal(pdfs=pdfs, output=output, compress=compress),
|
|
40
|
+
in_global=True, import_module=False)
|
|
41
|
+
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
42
|
+
uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pypdf"], uv_project_dir=None)
|
|
43
|
+
run_shell_script(uv_command)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def compress_pdf(
|
|
47
|
+
pdf_input: Annotated[str, typer.Argument(..., help="Path to the input PDF file to compress.")],
|
|
48
|
+
output: Annotated[Optional[str], typer.Option("--output", "-o", help="Output compressed PDF file path.")] = None,
|
|
49
|
+
quality: Annotated[int, typer.Option("--quality", "-q", help="JPEG quality for image compression (0-100, 0=no change, 100=best).")] = 85,
|
|
50
|
+
image_dpi: Annotated[int, typer.Option("--image-dpi", "-d", help="Target DPI for image resampling. If set, images above this DPI will be downsampled.")] = 0,
|
|
51
|
+
# remove_images: Annotated[bool, typer.Option("--remove-images", "-r", help="Remove all images from the PDF.")] = False,
|
|
52
|
+
compress_streams: Annotated[bool, typer.Option("--compress-streams", "-c", help="Compress uncompressed streams.")] = True,
|
|
53
|
+
use_objstms: Annotated[bool, typer.Option("--object-streams", "-s", help="Use object streams for additional compression.")] = True,
|
|
54
|
+
) -> None:
|
|
55
|
+
def compress_pdf_internal(pdf_input: str, output: str | None, quality: int, image_dpi: int, compress_streams: bool, use_objstms: bool) -> None:
|
|
56
|
+
import pymupdf
|
|
57
|
+
from pathlib import Path
|
|
58
|
+
output_path = output if output else pdf_input.replace(".pdf", "_compressed.pdf")
|
|
59
|
+
doc = pymupdf.open(pdf_input)
|
|
60
|
+
try:
|
|
61
|
+
# if remove_images:
|
|
62
|
+
# for page in doc:
|
|
63
|
+
# page.remove_images()
|
|
64
|
+
if quality > 0 or image_dpi > 0:
|
|
65
|
+
doc.rewrite_images(
|
|
66
|
+
dpi_threshold=image_dpi if image_dpi > 0 else None,
|
|
67
|
+
dpi_target=max(72, image_dpi - 10) if image_dpi > 72 else 72,
|
|
68
|
+
quality=quality,
|
|
69
|
+
lossy=True,
|
|
70
|
+
lossless=True,
|
|
71
|
+
)
|
|
72
|
+
doc.save(
|
|
73
|
+
output_path,
|
|
74
|
+
deflate=compress_streams,
|
|
75
|
+
garbage=3,
|
|
76
|
+
use_objstms=1 if use_objstms else 0,
|
|
77
|
+
)
|
|
78
|
+
input_size = Path(pdf_input).stat().st_size
|
|
79
|
+
output_size = Path(output_path).stat().st_size
|
|
80
|
+
ratio = (1 - output_size / input_size) * 100
|
|
81
|
+
print(f"✅ Compressed PDF saved to: {output_path}")
|
|
82
|
+
print(f" Original: {input_size / 1024 / 1024:.2f} MB")
|
|
83
|
+
print(f" Compressed: {output_size / 1024 / 1024:.2f} MB")
|
|
84
|
+
print(f" Reduction: {ratio:.1f}%")
|
|
85
|
+
finally:
|
|
86
|
+
doc.close()
|
|
87
|
+
from machineconfig.utils.meta import lambda_to_python_script
|
|
88
|
+
code = lambda_to_python_script(
|
|
89
|
+
lambda: compress_pdf_internal(pdf_input=pdf_input, output=output, quality=quality, image_dpi=image_dpi, compress_streams=compress_streams, use_objstms=use_objstms),
|
|
90
|
+
in_global=True,
|
|
91
|
+
import_module=False,
|
|
92
|
+
)
|
|
93
|
+
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
94
|
+
uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pymupdf"], uv_project_dir=None)
|
|
95
|
+
run_shell_script(uv_command)
|
|
96
|
+
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
from tempfile import tempdir
|
|
2
|
+
import typer
|
|
3
|
+
from typing import Optional, Annotated, Literal, TypedDict, cast
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def tui_env(which: Annotated[Literal["PATH", "p", "ENV", "e"], typer.Argument(help="Which environment variable to display.")] = "ENV") -> None:
|
|
7
|
+
"""📚 NAVIGATE PATH variable with TUI"""
|
|
8
|
+
from machineconfig.scripts.python import env_manager as navigator
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
match which:
|
|
12
|
+
case "PATH" | "p":
|
|
13
|
+
path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
|
|
14
|
+
case "ENV" | "e":
|
|
15
|
+
path = Path(navigator.__file__).resolve().parent.joinpath("env_manager_tui.py")
|
|
16
|
+
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
17
|
+
|
|
18
|
+
uv_with = ["textual"]
|
|
19
|
+
uv_project_dir = None
|
|
20
|
+
if not Path.home().joinpath("code/machineconfig").exists():
|
|
21
|
+
uv_with.append("machineconfig>=8.14")
|
|
22
|
+
else:
|
|
23
|
+
uv_project_dir = str(Path.home().joinpath("code/machineconfig"))
|
|
24
|
+
run_shell_script(
|
|
25
|
+
get_uv_command_executing_python_script(python_script=path.read_text(encoding="utf-8"), uv_with=uv_with, uv_project_dir=uv_project_dir)[0]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def init_project(
|
|
30
|
+
name: Annotated[Optional[str], typer.Option("--name", "-n", help="Name of the project.")] = None,
|
|
31
|
+
tmp_dir: Annotated[bool, typer.Option("--tmp-dir", "-t", help="Use a temporary directory for the project initialization.")] = False,
|
|
32
|
+
python: Annotated[
|
|
33
|
+
Literal["3.11", "3.12", "3.13", "3.14"], typer.Option("--python", "-p", help="Python sub version for the uv virtual environment.")
|
|
34
|
+
] = "3.13",
|
|
35
|
+
libraries: Annotated[
|
|
36
|
+
Optional[str], typer.Option("--libraries", "-l", help="Additional packages to include in the uv virtual environment (space separated).")
|
|
37
|
+
] = None,
|
|
38
|
+
group: Annotated[
|
|
39
|
+
Optional[str], typer.Option("--group", "-g", help="group of packages names (no separation) p:plot, t:types, l:linting, i:interactive, d:data")
|
|
40
|
+
] = "ptlid",
|
|
41
|
+
) -> None:
|
|
42
|
+
if libraries is not None:
|
|
43
|
+
packages_add_line = f"uv add {libraries}"
|
|
44
|
+
else:
|
|
45
|
+
packages_add_line = ""
|
|
46
|
+
from pathlib import Path
|
|
47
|
+
|
|
48
|
+
if not tmp_dir:
|
|
49
|
+
repo_root = Path.cwd()
|
|
50
|
+
if not (repo_root / "pyproject.toml").exists():
|
|
51
|
+
typer.echo(f"❌ Error: pyproject.toml not found in {repo_root}", err=True)
|
|
52
|
+
raise typer.Exit(code=1)
|
|
53
|
+
starting_code = ""
|
|
54
|
+
else:
|
|
55
|
+
if name is not None:
|
|
56
|
+
from machineconfig.utils.accessories import randstr
|
|
57
|
+
|
|
58
|
+
repo_root = Path.home().joinpath(f"tmp_results/tmp_projects/{name}")
|
|
59
|
+
else:
|
|
60
|
+
from machineconfig.utils.accessories import randstr
|
|
61
|
+
|
|
62
|
+
repo_root = Path.home().joinpath(f"tmp_results/tmp_projects/{randstr(6)}")
|
|
63
|
+
repo_root.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
print(f"Using temporary directory for project initialization: {repo_root}")
|
|
65
|
+
starting_code = f"""
|
|
66
|
+
cd {repo_root}
|
|
67
|
+
uv init --python {python}
|
|
68
|
+
uv venv
|
|
69
|
+
"""
|
|
70
|
+
print(f"Adding group `{group}` with common data science and plotting packages...")
|
|
71
|
+
total_packages: list[str] = []
|
|
72
|
+
if group is not None:
|
|
73
|
+
if "t" in group:
|
|
74
|
+
total_packages.append(
|
|
75
|
+
"types-python-dateutil types-pyyaml types-requests types-tqdm types-mysqlclient types-paramiko types-pytz types-sqlalchemy types-toml types-urllib3"
|
|
76
|
+
)
|
|
77
|
+
if "l" in group:
|
|
78
|
+
total_packages.append("mypy pyright ruff pylint pyrefly cleanpy ipdb pudb")
|
|
79
|
+
if "i" in group:
|
|
80
|
+
total_packages.append("ipython ipykernel jupyterlab nbformat marimo")
|
|
81
|
+
if "p" in group:
|
|
82
|
+
total_packages.append("python-magic matplotlib plotly kaleido")
|
|
83
|
+
if "d" in group:
|
|
84
|
+
total_packages.append("numpy pandas polars duckdb-engine sqlalchemy psycopg2-binary pyarrow tqdm openpyxl")
|
|
85
|
+
from machineconfig.utils.ve import get_ve_activate_line
|
|
86
|
+
|
|
87
|
+
script = f"""
|
|
88
|
+
{starting_code}
|
|
89
|
+
{packages_add_line}
|
|
90
|
+
uv add --group {group} {" ".join(total_packages)}
|
|
91
|
+
{get_ve_activate_line(ve_root=str(repo_root.joinpath(".venv")))}
|
|
92
|
+
ls
|
|
93
|
+
"""
|
|
94
|
+
from machineconfig.utils.code import exit_then_run_shell_script, run_shell_script
|
|
95
|
+
# exit_then_run_shell_script(script)
|
|
96
|
+
_ = exit_then_run_shell_script
|
|
97
|
+
run_shell_script(script)
|
|
98
|
+
if tempdir:
|
|
99
|
+
from machineconfig.scripts.python.ai.initai import add_ai_configs
|
|
100
|
+
add_ai_configs(repo_root=repo_root)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def edit_file_with_hx(
|
|
104
|
+
path: Annotated[Optional[str], typer.Argument(..., help="The root directory of the project to edit, or a file path.")] = None,
|
|
105
|
+
) -> None:
|
|
106
|
+
from pathlib import Path
|
|
107
|
+
|
|
108
|
+
if path is None:
|
|
109
|
+
root_path = Path.cwd()
|
|
110
|
+
print(f"No path provided. Using current working directory: {root_path}")
|
|
111
|
+
else:
|
|
112
|
+
root_path = Path(path).expanduser().resolve()
|
|
113
|
+
print(f"Using provided path: {root_path}")
|
|
114
|
+
from machineconfig.utils.accessories import get_repo_root
|
|
115
|
+
|
|
116
|
+
repo_root = get_repo_root(root_path)
|
|
117
|
+
if repo_root is not None and repo_root.joinpath("pyproject.toml").exists():
|
|
118
|
+
code = f"""
|
|
119
|
+
cd {repo_root}
|
|
120
|
+
uv add --dev pylsp-mypy python-lsp-server[all] pyright ruff-lsp # for helix editor.
|
|
121
|
+
source ./.venv/bin/activate
|
|
122
|
+
"""
|
|
123
|
+
else:
|
|
124
|
+
code = ""
|
|
125
|
+
if root_path.is_file():
|
|
126
|
+
code += f"hx {root_path}"
|
|
127
|
+
else:
|
|
128
|
+
code += "hx"
|
|
129
|
+
from machineconfig.utils.code import exit_then_run_shell_script
|
|
130
|
+
|
|
131
|
+
exit_then_run_shell_script(code)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class MachineSpecs(TypedDict):
|
|
135
|
+
system: Literal["Windows", "Linux", "Darwin"]
|
|
136
|
+
distro: str
|
|
137
|
+
home_dir: str
|
|
138
|
+
hostname: str
|
|
139
|
+
release: str
|
|
140
|
+
version: str
|
|
141
|
+
machine: str
|
|
142
|
+
processor: str
|
|
143
|
+
python_version: str
|
|
144
|
+
user: str
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_machine_specs() -> MachineSpecs:
|
|
148
|
+
"""Write print and return the local machine specs."""
|
|
149
|
+
import platform
|
|
150
|
+
from machineconfig.utils.code import get_uv_command
|
|
151
|
+
|
|
152
|
+
uv_cmd = get_uv_command(platform=platform.system()) # type: ignore
|
|
153
|
+
command = f"""{uv_cmd} run --with distro python -c "import distro; print(distro.name(pretty=True))" """
|
|
154
|
+
import subprocess
|
|
155
|
+
from pathlib import Path
|
|
156
|
+
import socket
|
|
157
|
+
import os
|
|
158
|
+
|
|
159
|
+
distro = subprocess.run(command, shell=True, capture_output=True, text=True).stdout.strip()
|
|
160
|
+
system = platform.system()
|
|
161
|
+
if system not in {"Windows", "Linux", "Darwin"}:
|
|
162
|
+
system = "Linux"
|
|
163
|
+
specs: MachineSpecs = {
|
|
164
|
+
"system": cast(Literal["Windows", "Linux", "Darwin"], system),
|
|
165
|
+
"distro": distro,
|
|
166
|
+
"home_dir": str(Path.home()),
|
|
167
|
+
"hostname": socket.gethostname(),
|
|
168
|
+
"release": platform.release(),
|
|
169
|
+
"version": platform.version(),
|
|
170
|
+
"machine": platform.machine(),
|
|
171
|
+
"processor": platform.processor() or "Unknown",
|
|
172
|
+
"python_version": platform.python_version(),
|
|
173
|
+
"user": os.getenv("USER") or os.getenv("USERNAME") or "Unknown",
|
|
174
|
+
}
|
|
175
|
+
print(specs)
|
|
176
|
+
from machineconfig.utils.source_of_truth import CONFIG_ROOT
|
|
177
|
+
|
|
178
|
+
path = CONFIG_ROOT.joinpath("machine_specs.json")
|
|
179
|
+
CONFIG_ROOT.mkdir(parents=True, exist_ok=True)
|
|
180
|
+
import json
|
|
181
|
+
|
|
182
|
+
path.write_text(json.dumps(specs, indent=4), encoding="utf-8")
|
|
183
|
+
return specs
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
get_machine_specs()
|
|
@@ -12,16 +12,13 @@ for better user experience with checkbox selections.
|
|
|
12
12
|
# $res = ls
|
|
13
13
|
# $name = $res[0].Name
|
|
14
14
|
# mv $backup_folder $name
|
|
15
|
-
#
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
"""
|
|
19
18
|
|
|
20
19
|
import sys
|
|
21
20
|
from pathlib import Path
|
|
22
|
-
# from typing import cast
|
|
23
21
|
import platform
|
|
24
|
-
|
|
25
22
|
import questionary
|
|
26
23
|
from questionary import Choice
|
|
27
24
|
from rich.console import Console
|
|
@@ -29,12 +26,11 @@ from rich.panel import Panel
|
|
|
29
26
|
from rich.text import Text
|
|
30
27
|
from machineconfig.utils.code import run_shell_script
|
|
31
28
|
|
|
32
|
-
# _ = cast
|
|
33
29
|
console = Console()
|
|
34
30
|
|
|
35
31
|
|
|
36
32
|
def display_header() -> None:
|
|
37
|
-
from machineconfig.utils.
|
|
33
|
+
from machineconfig.utils.installer_utils.installer_runner import get_machineconfig_version
|
|
38
34
|
from rich.align import Align
|
|
39
35
|
|
|
40
36
|
# Fancy ASCII art header
|
|
@@ -74,6 +70,14 @@ def display_dotfiles_instructions() -> None:
|
|
|
74
70
|
header_text = Text("DOTFILES MIGRATION", style="bold yellow")
|
|
75
71
|
subtitle_text = Text("Configuration transfer options", style="italic yellow")
|
|
76
72
|
instructions = """
|
|
73
|
+
On remote, run:
|
|
74
|
+
rm ~/dotfiles.zip || true
|
|
75
|
+
ouch c ~/dotfiles dotfiles.zip
|
|
76
|
+
uvx wormhole-magic send ~/dotfiles.zip
|
|
77
|
+
On new machine, run:
|
|
78
|
+
cd $HOME; uvx wormhole-magic receive dotfiles.zip --accept-file
|
|
79
|
+
ouch d ~/dotfiles.zip
|
|
80
|
+
|
|
77
81
|
🖱️ [bold blue]Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE[/bold blue]
|
|
78
82
|
On original machine, run:
|
|
79
83
|
[dim]cd ~/dotfiles/creds/msc
|
|
@@ -88,54 +92,48 @@ def display_dotfiles_instructions() -> None:
|
|
|
88
92
|
|
|
89
93
|
☁️ [bold blue]Method 3: USING INTERNET SECURE SHARE[/bold blue]
|
|
90
94
|
[dim]cd ~
|
|
91
|
-
|
|
92
|
-
(requires symlinks to be created first)
|
|
95
|
+
cloud copy SHARE_URL . --config ss[/dim]
|
|
96
|
+
(requires symlinks to be created first)
|
|
97
|
+
"""
|
|
93
98
|
console.print(Panel(f"📂 {header_text}\n{subtitle_text}\n\n{instructions}", border_style="yellow", padding=(1, 2)))
|
|
94
99
|
|
|
95
100
|
|
|
96
101
|
def get_installation_choices() -> list[str]:
|
|
97
102
|
"""Get user choices for installation options."""
|
|
98
103
|
choices = [
|
|
99
|
-
Choice(value="install_machineconfig", title="🐍 Install machineconfig.", checked=False),
|
|
100
|
-
Choice(value="
|
|
101
|
-
Choice(value="
|
|
102
|
-
Choice(value="
|
|
103
|
-
Choice(value="
|
|
104
|
-
Choice(value="
|
|
105
|
-
Choice(value="
|
|
106
|
-
Choice(value="retrieve_repositories", title="📚 Retrieve Repositories", checked=False),
|
|
107
|
-
Choice(value="retrieve_data", title="💾 Retrieve Data.", checked=False),
|
|
104
|
+
Choice(value="install_machineconfig", title="🐍 Install machineconfig cli.", checked=False),
|
|
105
|
+
Choice(value="sysabc", title="📥 Install System Package Manager (Needed for other apps to be installed).", checked=False),
|
|
106
|
+
Choice(value="termabc", title="⚡ Install Terminal CLI apps essentials (group `termabc`)", checked=False),
|
|
107
|
+
Choice(value="install_shell_profile", title="🐚 Configure Shell Profile And Map Other Configs.", checked=False),
|
|
108
|
+
Choice(value="install_ssh_server", title="🔒 [ADVANCED] Configure SSH Server", checked=False),
|
|
109
|
+
Choice(value="retrieve_repositories", title="📚 [ADVANCED] Retrieve Repositories", checked=False),
|
|
110
|
+
Choice(value="retrieve_data", title="💾 [ADVANCED] Retrieve Data.", checked=False),
|
|
108
111
|
]
|
|
109
|
-
# Add Windows-specific options
|
|
110
|
-
if platform.system() == "Windows":
|
|
111
|
-
choices.append(Choice(value="install_windows_desktop", title="💻 Install Windows Desktop Apps - Install nerd fonts and set WT config.", checked=False))
|
|
112
112
|
selected = questionary.checkbox("Select the installation options you want to execute:", choices=choices, show_description=True).ask()
|
|
113
113
|
return selected or []
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
def execute_installations(selected_options: list[str]) -> None:
|
|
117
117
|
for maybe_a_group in selected_options:
|
|
118
|
-
if maybe_a_group in ("
|
|
118
|
+
if maybe_a_group in ("termabc", "sysabc"):
|
|
119
119
|
console.print(Panel("⚡ [bold bright_yellow]CLI APPLICATIONS[/bold bright_yellow]\n[italic]Command-line tools installation[/italic]", border_style="bright_yellow"))
|
|
120
120
|
console.print("🔧 Installing CLI applications", style="bold cyan")
|
|
121
121
|
try:
|
|
122
|
-
from machineconfig.utils.installer_utils.
|
|
122
|
+
from machineconfig.utils.installer_utils.installer_cli import main_installer_cli as devops_devapps_install_main
|
|
123
123
|
devops_devapps_install_main(group=True, which=maybe_a_group, interactive=False)
|
|
124
124
|
console.print("✅ CLI applications installed successfully", style="bold green")
|
|
125
125
|
except Exception as e:
|
|
126
126
|
console.print(f"❌ Error installing CLI applications: {e}", style="bold red")
|
|
127
|
-
import platform
|
|
128
127
|
if platform.system() != "Windows":
|
|
129
128
|
run_shell_script(". $HOME/.bashrc")
|
|
130
129
|
|
|
131
130
|
if "install_machineconfig" in selected_options:
|
|
132
131
|
console.print(Panel("🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Virtual environment setup[/italic]", border_style="green"))
|
|
133
132
|
from machineconfig.scripts.python.helpers_devops.cli_self import install
|
|
134
|
-
install()
|
|
133
|
+
install(copy_assets=True, dev=False)
|
|
135
134
|
|
|
136
135
|
if "install_ssh_server" in selected_options:
|
|
137
136
|
console.print(Panel("🔒 [bold red]SSH SERVER[/bold red]\n[italic]Remote access setup[/italic]", border_style="red"))
|
|
138
|
-
import platform
|
|
139
137
|
if platform.system() == "Windows":
|
|
140
138
|
powershell_script = """Write-Host "🔧 Installing and configuring SSH server..."
|
|
141
139
|
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
|
|
@@ -152,13 +150,20 @@ Set-Service -Name sshd -StartupType 'Automatic'"""
|
|
|
152
150
|
from machineconfig.profile.create_shell_profile import create_default_shell_profile
|
|
153
151
|
create_default_shell_profile()
|
|
154
152
|
console.print("✅ Shell profile configured successfully", style="bold green")
|
|
153
|
+
from machineconfig.profile.create_links_export import main_public_from_parser
|
|
154
|
+
main_public_from_parser(method="copy", on_conflict="overwrite-default-path", which="all", interactive=False)
|
|
155
|
+
if platform.system() == "Windows":
|
|
156
|
+
from machineconfig.jobs.installer.python_scripts.nerfont_windows_helper import install_nerd_fonts
|
|
157
|
+
install_nerd_fonts()
|
|
158
|
+
from machineconfig.settings.wt.set_wt_settings import main as set_wt_settings_main
|
|
159
|
+
set_wt_settings_main()
|
|
155
160
|
except Exception as e:
|
|
156
161
|
console.print(f"❌ Error configuring shell profile: {e}", style="bold red")
|
|
157
162
|
|
|
158
163
|
if "retrieve_repositories" in selected_options:
|
|
159
164
|
console.print(Panel("📚 [bold bright_magenta]REPOSITORIES[/bold bright_magenta]\n[italic]Project code retrieval[/italic]", border_style="bright_magenta"))
|
|
160
165
|
from machineconfig.scripts.python.helpers_devops import cli_repos
|
|
161
|
-
cli_repos.clone(directory=str(Path.home() / "code"), cloud=
|
|
166
|
+
cli_repos.clone(directory=str(Path.home() / "code"), cloud=None)
|
|
162
167
|
|
|
163
168
|
if "retrieve_data" in selected_options:
|
|
164
169
|
console.print(Panel("💾 [bold bright_cyan]DATA RETRIEVAL[/bold bright_cyan]\n[italic]Backup restoration[/italic]", border_style="bright_cyan"))
|
|
@@ -170,12 +175,6 @@ Set-Service -Name sshd -StartupType 'Automatic'"""
|
|
|
170
175
|
except Exception as e:
|
|
171
176
|
console.print(f"❌ Error retrieving backup data: {e}", style="bold red")
|
|
172
177
|
|
|
173
|
-
if "install_windows_desktop" in selected_options:
|
|
174
|
-
from machineconfig.jobs.installer.custom_dev.nerfont_windows_helper import install_nerd_fonts
|
|
175
|
-
install_nerd_fonts()
|
|
176
|
-
from machineconfig.setup_windows.wt_and_pwsh.set_wt_settings import main as set_wt_settings_main
|
|
177
|
-
set_wt_settings_main()
|
|
178
|
-
|
|
179
178
|
|
|
180
179
|
def main() -> None:
|
|
181
180
|
display_header()
|
|
@@ -8,7 +8,6 @@ from machineconfig.scripts.python.utils import get_app as get_utils_app
|
|
|
8
8
|
from machineconfig.scripts.python.ftpx import ftpx as ftpx_func
|
|
9
9
|
from machineconfig.scripts.python.croshell import croshell as croshell_func
|
|
10
10
|
from machineconfig.scripts.python.fire_jobs import fire as get_fire_jobs_app
|
|
11
|
-
from machineconfig.scripts.python.define import get_app as get_define_app
|
|
12
11
|
from machineconfig.scripts.python.terminal import get_app as get_terminal_app
|
|
13
12
|
|
|
14
13
|
def get_app():
|
|
@@ -42,10 +41,6 @@ def get_app():
|
|
|
42
41
|
app.add_typer(utils_app, name="utils", help="[u] Utility commands", no_args_is_help=True)
|
|
43
42
|
app.add_typer(utils_app, name="u", hidden=True) # short alias
|
|
44
43
|
|
|
45
|
-
define_app = get_define_app()
|
|
46
|
-
app.add_typer(define_app, name="define", help="[df] Define and manage configurations", no_args_is_help=True)
|
|
47
|
-
app.add_typer(define_app, name="df", hidden=True) # short alias
|
|
48
|
-
|
|
49
44
|
|
|
50
45
|
terminal_app = get_terminal_app()
|
|
51
46
|
app.add_typer(terminal_app, name="terminal", help="[t] Terminal management commands", no_args_is_help=True)
|
|
@@ -57,3 +52,7 @@ def get_app():
|
|
|
57
52
|
def main():
|
|
58
53
|
app = get_app()
|
|
59
54
|
app()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
main()
|