machineconfig 5.15__py3-none-any.whl → 7.98__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.
- machineconfig/__init__.py +0 -28
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/distribute.py +0 -1
- machineconfig/cluster/remote/file_manager.py +0 -2
- machineconfig/cluster/remote/script_execution.py +0 -1
- machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
- machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
- machineconfig/cluster/sessions_managers/wt_local.py +114 -289
- machineconfig/cluster/sessions_managers/wt_local_manager.py +70 -210
- machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +52 -198
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
- machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
- machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
- machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +25 -170
- machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +16 -12
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
- machineconfig/jobs/{python → installer}/check_installations.py +2 -3
- machineconfig/jobs/installer/custom/boxes.py +61 -0
- machineconfig/jobs/installer/custom/hx.py +76 -19
- machineconfig/jobs/installer/custom/yazi.py +119 -0
- machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
- machineconfig/jobs/installer/custom_dev/brave.py +5 -9
- machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/custom_dev/code.py +4 -1
- machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
- machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +33 -28
- machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
- machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
- machineconfig/jobs/installer/custom_dev/winget.py +10 -14
- machineconfig/jobs/installer/installer_data.json +1487 -229
- machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
- machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
- machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -6
- machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
- machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
- machineconfig/jobs/installer/package_groups.py +106 -177
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/logger.py +0 -1
- machineconfig/profile/backup.toml +49 -0
- machineconfig/profile/bash_shell_profiles.md +11 -0
- machineconfig/profile/create_helper.py +62 -0
- machineconfig/profile/create_links.py +288 -0
- machineconfig/profile/create_links_export.py +100 -0
- machineconfig/profile/create_shell_profile.py +147 -0
- machineconfig/profile/mapper.toml +263 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +123 -117
- machineconfig/scripts/python/ai/initai.py +3 -28
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/scripts/command_runner.sh +9 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
- machineconfig/scripts/python/ai/solutions/_shared.py +9 -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 +5 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
- machineconfig/scripts/python/ai/solutions/generic.py +28 -5
- machineconfig/scripts/python/ai/utils/generate_files.py +348 -0
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +37 -0
- machineconfig/scripts/python/cloud.py +29 -0
- machineconfig/scripts/python/croshell.py +137 -113
- machineconfig/scripts/python/devops.py +61 -101
- machineconfig/scripts/python/devops_navigator.py +6 -0
- machineconfig/scripts/python/env_manager/__init__.py +1 -0
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
- machineconfig/scripts/python/fire_jobs.py +110 -150
- machineconfig/scripts/python/ftpx.py +51 -24
- 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/run_py_script.py +79 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +126 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
- machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
- machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +29 -35
- machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
- machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
- machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +8 -9
- machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
- machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +214 -0
- machineconfig/scripts/python/helpers_devops/cli_repos.py +215 -0
- machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
- machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_share_terminal.py} +45 -35
- machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
- machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
- machineconfig/scripts/python/helpers_devops/devops_status.py +499 -0
- machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
- machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
- machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +3 -3
- machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
- machineconfig/scripts/python/helpers_fire_command/f.py +0 -0
- machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
- machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +121 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
- machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
- machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
- machineconfig/scripts/python/helpers_navigator/command_tree.py +620 -0
- machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
- machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
- machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
- machineconfig/scripts/python/helpers_network/__init__.py +0 -0
- machineconfig/scripts/python/helpers_network/address.py +132 -0
- machineconfig/scripts/python/{devops_add_identity.py → helpers_network/devops_add_identity.py} +0 -2
- machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +153 -0
- machineconfig/scripts/{linux → python/helpers_network}/mount_nfs +0 -1
- machineconfig/scripts/python/{mount_nfs.py → helpers_network/mount_nfs.py} +3 -3
- machineconfig/scripts/{linux → python/helpers_network}/mount_nw_drive +1 -2
- machineconfig/scripts/python/{mount_ssh.py → helpers_network/mount_ssh.py} +3 -3
- machineconfig/scripts/python/{onetimeshare.py → helpers_network/onetimeshare.py} +0 -1
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +391 -0
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +338 -0
- machineconfig/scripts/python/{wifi_conn.py → helpers_network/wifi_conn.py} +1 -53
- machineconfig/scripts/python/{wsl_windows_transfer.py → helpers_network/wsl_windows_transfer.py} +5 -4
- machineconfig/scripts/python/helpers_repos/action.py +209 -0
- machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
- machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
- machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
- machineconfig/scripts/python/helpers_repos/grource.py +340 -0
- machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/helpers_repos/sync.py +66 -0
- machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
- machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +65 -0
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/path.py +185 -0
- machineconfig/scripts/python/interactive.py +64 -84
- machineconfig/scripts/python/mcfg_entry.py +58 -0
- machineconfig/scripts/python/msearch.py +71 -0
- machineconfig/scripts/python/sessions.py +119 -45
- machineconfig/scripts/python/terminal.py +133 -0
- machineconfig/scripts/python/utils.py +64 -0
- machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +92 -0
- machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
- machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
- machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/broot/br.sh +0 -4
- machineconfig/settings/broot/conf.toml +1 -1
- machineconfig/settings/helix/config.toml +16 -0
- machineconfig/settings/helix/languages.toml +13 -4
- machineconfig/settings/helix/yazi-picker.sh +12 -0
- machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
- machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
- machineconfig/settings/lf/linux/lfrc +10 -12
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +18 -38
- machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
- machineconfig/settings/marimo/marimo.toml +80 -0
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/pistol/pistol.conf +1 -1
- machineconfig/settings/shells/bash/init.sh +82 -31
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -35
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +314 -0
- machineconfig/settings/shells/pwsh/init.ps1 +61 -43
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/wt/settings.json +32 -17
- machineconfig/settings/shells/zsh/init.sh +89 -0
- machineconfig/settings/svim/linux/init.toml +0 -4
- machineconfig/settings/svim/windows/init.toml +0 -3
- 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/yazi/init.lua +61 -0
- machineconfig/settings/yazi/keymap_linux.toml +94 -0
- machineconfig/settings/yazi/keymap_windows.toml +78 -0
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
- machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/setup_linux/__init__.py +11 -0
- machineconfig/setup_linux/apps_desktop.sh +89 -0
- machineconfig/setup_linux/apps_gui.sh +64 -0
- machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
- machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
- machineconfig/setup_linux/uv.sh +15 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +16 -0
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/__init__.py +11 -0
- machineconfig/setup_windows/others/power_options.ps1 +7 -0
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
- machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
- machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
- machineconfig/setup_windows/uv.ps1 +17 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -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 -5
- machineconfig/utils/cloud/onedrive/README.md +139 -0
- machineconfig/utils/code.py +155 -105
- machineconfig/utils/files/art/fat_croco.txt +10 -0
- machineconfig/utils/files/art/halfwit_croco.txt +9 -0
- machineconfig/utils/files/art/happy_croco.txt +22 -0
- machineconfig/utils/files/art/water_croco.txt +11 -0
- machineconfig/utils/files/ascii_art.py +1 -1
- machineconfig/utils/files/dbms.py +257 -0
- machineconfig/utils/files/headers.py +11 -14
- machineconfig/utils/files/ouch/__init__.py +0 -0
- machineconfig/utils/files/ouch/decompress.py +45 -0
- machineconfig/utils/files/read.py +10 -18
- 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 +64 -181
- 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} +66 -97
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +49 -82
- machineconfig/utils/io.py +77 -23
- machineconfig/utils/links.py +254 -162
- machineconfig/utils/meta.py +256 -0
- machineconfig/utils/notifications.py +1 -1
- machineconfig/utils/options.py +46 -18
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +48 -101
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +50 -70
- machineconfig/utils/scheduler.py +88 -124
- machineconfig/utils/scheduling.py +0 -3
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/source_of_truth.py +3 -6
- machineconfig/utils/ssh.py +263 -274
- 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 +302 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +3 -113
- machineconfig/utils/tst.py +20 -0
- machineconfig/utils/upgrade_packages.py +114 -28
- machineconfig/utils/ve.py +12 -4
- machineconfig-7.98.dist-info/METADATA +132 -0
- machineconfig-7.98.dist-info/RECORD +504 -0
- machineconfig-7.98.dist-info/entry_points.txt +13 -0
- machineconfig/cluster/sessions_managers/ffile.py +0 -4
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
- machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
- machineconfig/jobs/python/python_ve_symlink.py +0 -37
- machineconfig/jobs/python/vscode/api.py +0 -57
- machineconfig/jobs/python/vscode/sync_code.py +0 -73
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
- machineconfig/jobs/windows/start_terminal.ps1 +0 -6
- machineconfig/jobs/windows/startup_file.cmd +0 -2
- machineconfig/profile/create.py +0 -303
- machineconfig/profile/shell.py +0 -176
- machineconfig/scripts/cloud/init.sh +0 -119
- machineconfig/scripts/linux/agents +0 -2
- machineconfig/scripts/linux/choose_wezterm_theme +0 -3
- machineconfig/scripts/linux/cloud_copy +0 -2
- machineconfig/scripts/linux/cloud_mount +0 -2
- machineconfig/scripts/linux/cloud_repo_sync +0 -2
- machineconfig/scripts/linux/cloud_sync +0 -2
- machineconfig/scripts/linux/croshell +0 -3
- machineconfig/scripts/linux/devops +0 -2
- machineconfig/scripts/linux/fire +0 -2
- machineconfig/scripts/linux/ftpx +0 -2
- machineconfig/scripts/linux/fzf2g +0 -21
- machineconfig/scripts/linux/fzfag +0 -17
- machineconfig/scripts/linux/fzffg +0 -25
- machineconfig/scripts/linux/fzfrga +0 -21
- machineconfig/scripts/linux/gh_models +0 -2
- machineconfig/scripts/linux/initai +0 -2
- machineconfig/scripts/linux/kill_process +0 -2
- machineconfig/scripts/linux/scheduler +0 -2
- machineconfig/scripts/linux/sessions +0 -2
- machineconfig/scripts/linux/share_smb +0 -1
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/start_slidev +0 -2
- machineconfig/scripts/linux/start_terminals +0 -3
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/wifi_conn +0 -2
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/generate_files.py +0 -83
- machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
- machineconfig/scripts/python/cloud_repo_sync.py +0 -190
- machineconfig/scripts/python/count_lines_frontend.py +0 -16
- machineconfig/scripts/python/devops_add_ssh_key.py +0 -120
- machineconfig/scripts/python/dotfile.py +0 -78
- machineconfig/scripts/python/fire_agents_help_launch.py +0 -120
- machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
- machineconfig/scripts/python/fire_jobs_route_helper.py +0 -65
- machineconfig/scripts/python/get_zellij_cmd.py +0 -15
- machineconfig/scripts/python/gh_models.py +0 -104
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
- machineconfig/scripts/python/repos.py +0 -132
- machineconfig/scripts/python/repos_helper_action.py +0 -378
- machineconfig/scripts/python/snapshot.py +0 -25
- machineconfig/scripts/python/start_terminals.py +0 -121
- machineconfig/scripts/python/t4.py +0 -17
- machineconfig/scripts/windows/agents.ps1 +0 -1
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
- machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
- machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
- machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
- machineconfig/scripts/windows/croshell.ps1 +0 -1
- machineconfig/scripts/windows/devops.ps1 +0 -1
- machineconfig/scripts/windows/dotfile.ps1 +0 -1
- machineconfig/scripts/windows/fire.ps1 +0 -1
- machineconfig/scripts/windows/ftpx.ps1 +0 -1
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/gpt.ps1 +0 -1
- machineconfig/scripts/windows/grep.ps1 +0 -2
- machineconfig/scripts/windows/initai.ps1 +0 -1
- machineconfig/scripts/windows/kill_process.ps1 +0 -1
- machineconfig/scripts/windows/nano.ps1 +0 -3
- machineconfig/scripts/windows/pomodoro.ps1 +0 -1
- machineconfig/scripts/windows/reload_path.ps1 +0 -3
- machineconfig/scripts/windows/scheduler.ps1 +0 -1
- machineconfig/scripts/windows/sessions.ps1 +0 -1
- machineconfig/scripts/windows/snapshot.ps1 +0 -1
- machineconfig/scripts/windows/start_slidev.ps1 +0 -1
- machineconfig/scripts/windows/start_terminals.ps1 +0 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
- machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
- machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
- 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 -4
- machineconfig/setup_linux/nix/cli_installation.sh +0 -157
- machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
- machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
- machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
- machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
- machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
- machineconfig/utils/ai/generate_file_checklist.py +0 -68
- machineconfig/utils/installer_utils/installer.py +0 -189
- machineconfig-5.15.dist-info/METADATA +0 -188
- machineconfig-5.15.dist-info/RECORD +0 -415
- machineconfig-5.15.dist-info/entry_points.txt +0 -18
- machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
- machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
- machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
- machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
- machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers → helpers_agents}/__init__.py +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_agents/agentic_frameworks/__init__.py} +0 -0
- machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
- machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_cloud/__init__.py} +0 -0
- machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_croshell/__init__.py} +0 -0
- /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
- /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
- /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
- /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
- /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/__init__.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_devops/themes/__init__.py} +0 -0
- /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
- /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_drive +0 -0
- /machineconfig/scripts/python/{mount_nw_drive.py → helpers_network/mount_nw_drive.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_smb +0 -0
- /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
- /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
- /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
- /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from machineconfig.utils.accessories import randstr
|
|
2
|
+
from machineconfig.utils.io import decrypt, encrypt
|
|
2
3
|
|
|
3
4
|
from datetime import datetime
|
|
4
5
|
import time
|
|
@@ -10,10 +11,13 @@ from platform import system
|
|
|
10
11
|
from typing import Any, Optional, Union, Callable, TypeAlias, Literal
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
|
|
13
15
|
OPLike: TypeAlias = Union[str, "PathExtended", Path, None]
|
|
14
16
|
PLike: TypeAlias = Union[str, "PathExtended", Path]
|
|
15
17
|
FILE_MODE: TypeAlias = Literal["r", "w", "x", "a"]
|
|
16
18
|
SHUTIL_FORMATS: TypeAlias = Literal["zip", "tar", "gztar", "bztar", "xztar"]
|
|
19
|
+
DECOMPRESS_SUPPORTED_FORMATS = [".tar.gz", ".tgz", ".tar", ".gz", ".tar.bz", ".tbz", ".tar.xz", ".zip", ".7z",
|
|
20
|
+
".tar.bz2", ".tbz2", ".xz"]
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
def _is_user_admin() -> bool:
|
|
@@ -54,81 +58,6 @@ def _run_shell_command(
|
|
|
54
58
|
)
|
|
55
59
|
|
|
56
60
|
|
|
57
|
-
def pwd2key(password: str, salt: Optional[bytes] = None, iterations: int = 10) -> bytes: # Derive a secret key from a given password and salt"""
|
|
58
|
-
import base64
|
|
59
|
-
|
|
60
|
-
if salt is None:
|
|
61
|
-
import hashlib
|
|
62
|
-
|
|
63
|
-
m = hashlib.sha256()
|
|
64
|
-
m.update(password.encode(encoding="utf-8"))
|
|
65
|
-
return base64.urlsafe_b64encode(s=m.digest()) # make url-safe bytes required by Ferent.
|
|
66
|
-
from cryptography.hazmat.primitives import hashes
|
|
67
|
-
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
68
|
-
|
|
69
|
-
return base64.urlsafe_b64encode(PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=iterations, backend=None).derive(password.encode()))
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def encrypt(msg: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True, iteration: Optional[int] = None, gen_key: bool = False) -> bytes:
|
|
73
|
-
import base64
|
|
74
|
-
from cryptography.fernet import Fernet
|
|
75
|
-
|
|
76
|
-
salt, iteration = None, None
|
|
77
|
-
if pwd is not None: # generate it from password
|
|
78
|
-
assert (key is None) and (type(pwd) is str), "❌ You can either pass key or pwd, or none of them, but not both."
|
|
79
|
-
import secrets
|
|
80
|
-
|
|
81
|
-
iteration = iteration or secrets.randbelow(exclusive_upper_bound=1_000_000)
|
|
82
|
-
salt = secrets.token_bytes(nbytes=16) if salted else None
|
|
83
|
-
key_resolved = pwd2key(password=pwd, salt=salt, iterations=iteration)
|
|
84
|
-
elif key is None:
|
|
85
|
-
if gen_key:
|
|
86
|
-
key_resolved = Fernet.generate_key()
|
|
87
|
-
Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").write_bytes(key_resolved)
|
|
88
|
-
else:
|
|
89
|
-
try:
|
|
90
|
-
key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes()
|
|
91
|
-
print(f"⚠️ Using key from: {Path.home().joinpath('dotfiles/creds/data/encrypted_files_key.bytes')}")
|
|
92
|
-
except FileNotFoundError as err:
|
|
93
|
-
print("\n" * 3, "~" * 50, """Consider Loading up your dotfiles or pass `gen_key=True` to make and save one.""", "~" * 50, "\n" * 3)
|
|
94
|
-
raise FileNotFoundError(err) from err
|
|
95
|
-
elif isinstance(key, (str, PathExtended, Path)):
|
|
96
|
-
key_resolved = Path(key).read_bytes() # a path to a key file was passed, read it:
|
|
97
|
-
elif type(key) is bytes:
|
|
98
|
-
key_resolved = key # key passed explicitly
|
|
99
|
-
else:
|
|
100
|
-
raise TypeError("❌ Key must be either a path, bytes object or None.")
|
|
101
|
-
code = Fernet(key=key_resolved).encrypt(msg)
|
|
102
|
-
if pwd is not None and salt is not None and iteration is not None:
|
|
103
|
-
return base64.urlsafe_b64encode(b"%b%b%b" % (salt, iteration.to_bytes(4, "big"), base64.urlsafe_b64decode(code)))
|
|
104
|
-
return code
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def decrypt(token: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True) -> bytes:
|
|
108
|
-
import base64
|
|
109
|
-
|
|
110
|
-
if pwd is not None:
|
|
111
|
-
assert key is None, "❌ You can either pass key or pwd, or none of them, but not both."
|
|
112
|
-
if salted:
|
|
113
|
-
decoded = base64.urlsafe_b64decode(token)
|
|
114
|
-
salt, iterations, token = decoded[:16], decoded[16:20], base64.urlsafe_b64encode(decoded[20:])
|
|
115
|
-
key_resolved = pwd2key(password=pwd, salt=salt, iterations=int.from_bytes(bytes=iterations, byteorder="big"))
|
|
116
|
-
else:
|
|
117
|
-
key_resolved = pwd2key(password=pwd) # trailing `;` prevents IPython from caching the result.
|
|
118
|
-
elif type(key) is bytes:
|
|
119
|
-
assert pwd is None, "❌ You can either pass key or pwd, or none of them, but not both."
|
|
120
|
-
key_resolved = key # passsed explicitly
|
|
121
|
-
elif key is None:
|
|
122
|
-
key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes() # read from file
|
|
123
|
-
elif isinstance(key, (str, Path)):
|
|
124
|
-
key_resolved = Path(key).read_bytes() # passed a path to a file containing kwy
|
|
125
|
-
else:
|
|
126
|
-
raise TypeError(f"❌ Key must be either str, P, Path, bytes or None. Recieved: {type(key)}")
|
|
127
|
-
from cryptography.fernet import Fernet
|
|
128
|
-
|
|
129
|
-
return Fernet(key=key_resolved).decrypt(token)
|
|
130
|
-
|
|
131
|
-
|
|
132
61
|
def validate_name(astring: str, replace: str = "_") -> str:
|
|
133
62
|
import re
|
|
134
63
|
|
|
@@ -167,7 +96,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
167
96
|
print(f"🗑️ ❌ DELETED {repr(self)}.")
|
|
168
97
|
return self
|
|
169
98
|
|
|
170
|
-
def move(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, rel2it: bool = False, overwrite: bool = False, verbose: bool = True, parents: bool = True, content: bool = False) -> "PathExtended":
|
|
99
|
+
def move(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, rel2it: bool = False, overwrite: bool = False, verbose: bool = True, parents: bool = True, content: bool = False) -> "PathExtended": # type: ignore
|
|
171
100
|
path = self._resolve_path(folder=folder, name=name, path=path, default_name=self.absolute().name, rel2it=rel2it)
|
|
172
101
|
if parents:
|
|
173
102
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -193,9 +122,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
193
122
|
print(f"🚚 MOVED {repr(self)} ==> {repr(path)}`")
|
|
194
123
|
return path
|
|
195
124
|
|
|
196
|
-
def copy(
|
|
197
|
-
self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, content: bool = False, verbose: bool = True, append: Optional[str] = None, overwrite: bool = False, orig: bool = False
|
|
198
|
-
) -> "PathExtended": # tested %100 # TODO: replace `content` flag with ability to interpret "*" in resolve method.
|
|
125
|
+
def copy(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, content: bool = False, verbose: bool = True, append: Optional[str] = None, overwrite: bool = False, orig: bool = False) -> "PathExtended": # type: ignore
|
|
199
126
|
dest = self._resolve_path(folder=folder, name=name, path=path, default_name=self.name, rel2it=False)
|
|
200
127
|
dest = dest.expanduser().resolve()
|
|
201
128
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -227,7 +154,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
227
154
|
# ======================================= File Editing / Reading ===================================
|
|
228
155
|
def download(self, folder: OPLike = None, name: Optional[str] = None, allow_redirects: bool = True, timeout: Optional[int] = None, params: Any = None) -> "PathExtended":
|
|
229
156
|
import requests
|
|
230
|
-
|
|
231
157
|
response = requests.get(self.as_url_str(), allow_redirects=allow_redirects, timeout=timeout, params=params) # Alternative: from urllib import request; request.urlopen(url).read().decode('utf-8').
|
|
232
158
|
assert response.status_code == 200, f"Download failed with status code {response.status_code}\n{response.text}"
|
|
233
159
|
if name is not None:
|
|
@@ -555,9 +481,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
555
481
|
**kwargs: Any,
|
|
556
482
|
) -> "PathExtended":
|
|
557
483
|
path_resolved, slf = self._resolve_path(folder, name, path, self.name).expanduser().resolve(), self.expanduser().resolve()
|
|
558
|
-
# if use_7z: # benefits over regular zip and encrypt: can handle very large files with low memory footprint
|
|
559
|
-
# path_resolved = path_resolved + '.7z' if not path_resolved.suffix == '.7z' else path_resolved
|
|
560
|
-
# with install_n_import("py7zr").SevenZipFile(file=path_resolved, mode=mode, password=pwd) as archive: archive.writeall(path=str(slf), arcname=None)
|
|
561
484
|
arcname_obj = PathExtended(arcname or slf.name)
|
|
562
485
|
if arcname_obj.name != slf.name:
|
|
563
486
|
arcname_obj /= slf.name # arcname has to start from somewhere and end with filename
|
|
@@ -630,15 +553,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
630
553
|
folder = folder if not content else folder.parent
|
|
631
554
|
if slf.suffix == ".7z":
|
|
632
555
|
raise NotImplementedError("I have not implemented this yet")
|
|
633
|
-
# if overwrite: P(folder).delete(sure=True)
|
|
634
|
-
# result = folder
|
|
635
|
-
# import py7zr
|
|
636
|
-
# with py7zr.SevenZipFile(file=slf, mode='r', password=pwd) as archive:
|
|
637
|
-
# if pattern is not None:
|
|
638
|
-
# import re
|
|
639
|
-
# pat = re.compile(pattern)
|
|
640
|
-
# archive.extract(path=folder, targets=[f for f in archive.getnames() if pat.match(f)])
|
|
641
|
-
# else: archive.extractall(path=folder)
|
|
642
556
|
else:
|
|
643
557
|
if overwrite:
|
|
644
558
|
if not content:
|
|
@@ -773,21 +687,54 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
773
687
|
return ret
|
|
774
688
|
|
|
775
689
|
def decompress(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, inplace: bool = False, orig: bool = False, verbose: bool = True) -> "PathExtended":
|
|
776
|
-
if ".tar.gz"
|
|
690
|
+
if str(self).endswith(".tar.gz") or str(self).endswith(".tgz"):
|
|
777
691
|
# res = self.ungz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
778
692
|
return self.ungz(name=f"tmp_{randstr()}.tar", inplace=inplace).untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose) # this works for .tgz suffix as well as .tar.gz
|
|
779
|
-
elif
|
|
693
|
+
elif str(self).endswith(".tar"):
|
|
694
|
+
res = self.untar(folder=folder, name=name, path=path, inplace=inplace, orig=orig, verbose=verbose)
|
|
695
|
+
elif str(self).endswith(".gz"):
|
|
780
696
|
res = self.ungz(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
781
|
-
elif ".tar.bz"
|
|
697
|
+
elif str(self).endswith(".tar.bz") or str(self).endswith(".tbz") or str(self).endswith(".tar.bz2"):
|
|
782
698
|
res = self.unbz(name=f"tmp_{randstr()}.tar", inplace=inplace)
|
|
783
699
|
return res.untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
784
|
-
elif ".tar.xz"
|
|
700
|
+
elif str(self).endswith(".tar.xz"):
|
|
785
701
|
# res = self.unxz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
786
702
|
res = self.unxz(inplace=inplace).untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
787
|
-
elif ".zip"
|
|
703
|
+
elif str(self).endswith(".zip"):
|
|
788
704
|
res = self.unzip(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
705
|
+
elif str(self).endswith(".7z"):
|
|
706
|
+
def unzip_7z(archive_path: str, dest_dir: Optional[str] = None) -> Path:
|
|
707
|
+
"""
|
|
708
|
+
Uncompresses a .7z archive to a directory and returns the Path to the extraction directory.
|
|
709
|
+
|
|
710
|
+
:param archive_path: path to the .7z archive file
|
|
711
|
+
:param dest_dir: optional path to directory to extract into; if None a temporary dir will be created
|
|
712
|
+
:return: pathlib.Path pointing to the destination directory where contents were extracted
|
|
713
|
+
:raises: FileNotFoundError if archive does not exist; py7zr.Bad7zFile or other error if extraction fails
|
|
714
|
+
"""
|
|
715
|
+
import py7zr # type: ignore
|
|
716
|
+
import tempfile
|
|
717
|
+
from pathlib import Path
|
|
718
|
+
archive_path_obj = Path(archive_path)
|
|
719
|
+
if not archive_path_obj.is_file():
|
|
720
|
+
raise FileNotFoundError(f"Archive file not found: {archive_path_obj!r}")
|
|
721
|
+
if dest_dir is None:
|
|
722
|
+
# create a temporary directory
|
|
723
|
+
dest = Path(tempfile.mkdtemp(prefix=f"unzip7z_{archive_path_obj.stem}_"))
|
|
724
|
+
else:
|
|
725
|
+
dest = Path(dest_dir)
|
|
726
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
727
|
+
# Perform extraction
|
|
728
|
+
with py7zr.SevenZipFile(str(archive_path_obj), mode='r') as archive:
|
|
729
|
+
archive.extractall(path=str(dest))
|
|
730
|
+
# Return the extraction directory path
|
|
731
|
+
return dest
|
|
732
|
+
from machineconfig.utils.code import run_lambda_function
|
|
733
|
+
destination_dir = str(self.expanduser().resolve()).replace(".7z", "")
|
|
734
|
+
run_lambda_function(lambda: unzip_7z(archive_path=str(self), dest_dir=destination_dir), uv_project_dir=None, uv_with=["py7zr"])
|
|
735
|
+
res = PathExtended(destination_dir)
|
|
789
736
|
else:
|
|
790
|
-
|
|
737
|
+
raise ValueError(f"Cannot decompress file with unknown extension: {self}")
|
|
791
738
|
return res
|
|
792
739
|
|
|
793
740
|
def encrypt(
|
|
@@ -863,7 +810,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
863
810
|
path = self
|
|
864
811
|
else:
|
|
865
812
|
try:
|
|
866
|
-
path = self.
|
|
813
|
+
path = PathExtended(self.expanduser().absolute().relative_to(Path.home()))
|
|
867
814
|
except ValueError as ve:
|
|
868
815
|
if strict:
|
|
869
816
|
raise ve
|
|
@@ -911,9 +858,10 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
911
858
|
rp = localpath.get_remote_path(root=root, os_specific=os_specific, rel2home=rel2home, strict=strict) # if rel2home else (P(root) / localpath if root is not None else localpath)
|
|
912
859
|
else:
|
|
913
860
|
rp = PathExtended(remotepath)
|
|
914
|
-
|
|
915
861
|
from rclone_python import rclone
|
|
862
|
+
print(f"⬆️ UPLOADING {repr(localpath)} TO {cloud}:{rp.as_posix()}`") if verbose else None
|
|
916
863
|
rclone.copyto(in_path=localpath.as_posix(), out_path=f"{cloud}:{rp.as_posix()}", )
|
|
864
|
+
|
|
917
865
|
_ = [item.delete(sure=True) for item in to_del]
|
|
918
866
|
if verbose:
|
|
919
867
|
print(f"{'⬆️' * 5} UPLOAD COMPLETED.")
|
|
@@ -924,7 +872,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
924
872
|
command = f"rclone link '{cloud}:{rp.as_posix()}'"
|
|
925
873
|
completed = _run_shell_command(command, shell_to_use)
|
|
926
874
|
from machineconfig.utils.terminal import Response
|
|
927
|
-
|
|
928
875
|
res = Response.from_completed_process(completed).capture()
|
|
929
876
|
tmp = res.op2path(strict_err=False, strict_returncode=False)
|
|
930
877
|
if tmp is None:
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
from machineconfig.utils.path_extended import PathExtended
|
|
2
|
-
from machineconfig.utils.options import choose_from_options
|
|
3
1
|
from machineconfig.utils.source_of_truth import EXCLUDE_DIRS
|
|
4
2
|
from rich.console import Console
|
|
5
3
|
from rich.panel import Panel
|
|
6
4
|
import platform
|
|
7
5
|
import subprocess
|
|
8
6
|
from pathlib import Path
|
|
9
|
-
|
|
7
|
+
from typing import Optional
|
|
10
8
|
|
|
11
9
|
console = Console()
|
|
12
10
|
|
|
13
11
|
|
|
14
|
-
def sanitize_path(a_path: str) ->
|
|
15
|
-
path =
|
|
12
|
+
def sanitize_path(a_path: str) -> Path:
|
|
13
|
+
path = Path(a_path)
|
|
16
14
|
if Path.cwd() == Path.home() and not path.exists():
|
|
17
15
|
result = input("Current working directory is home, and passed path is not full path, are you sure you want to continue, [y]/n? ") or "y"
|
|
18
16
|
if result == "y":
|
|
@@ -23,13 +21,13 @@ def sanitize_path(a_path: str) -> PathExtended:
|
|
|
23
21
|
if platform.system() == "Windows": # path copied from Linux/Mac to Windows
|
|
24
22
|
# For Linux: /home/username, for Mac: /Users/username
|
|
25
23
|
skip_parts = 3 if path.as_posix().startswith("/home") else 3 # Both have 3 parts to skip
|
|
26
|
-
path =
|
|
24
|
+
path = Path.home().joinpath(*path.parts[skip_parts:])
|
|
27
25
|
assert path.exists(), f"File not found: {path}"
|
|
28
26
|
source_os = "Linux" if path.as_posix().startswith("/home") else "macOS"
|
|
29
27
|
console.print(Panel(f"🔗 PATH MAPPING | {source_os} → Windows: `{a_path}` ➡️ `{path}`", title="Path Mapping", expand=False))
|
|
30
|
-
elif platform.system() in ["Linux", "Darwin"] and
|
|
28
|
+
elif platform.system() in ["Linux", "Darwin"] and Path.home().as_posix() not in path.as_posix(): # copied between Unix-like systems with different username
|
|
31
29
|
skip_parts = 3 # Both /home/username and /Users/username have 3 parts to skip
|
|
32
|
-
path =
|
|
30
|
+
path = Path.home().joinpath(*path.parts[skip_parts:])
|
|
33
31
|
assert path.exists(), f"File not found: {path}"
|
|
34
32
|
current_os = "Linux" if platform.system() == "Linux" else "macOS"
|
|
35
33
|
source_os = "Linux" if path.as_posix().startswith("/home") else "macOS"
|
|
@@ -37,12 +35,12 @@ def sanitize_path(a_path: str) -> PathExtended:
|
|
|
37
35
|
elif path.as_posix().startswith("C:"):
|
|
38
36
|
if platform.system() in ["Linux", "Darwin"]: # path copied from Windows to Linux/Mac
|
|
39
37
|
xx = str(a_path).replace("\\\\", "/")
|
|
40
|
-
path =
|
|
38
|
+
path = Path.home().joinpath(*Path(xx).parts[3:]) # exclude C:\\Users\\username
|
|
41
39
|
assert path.exists(), f"File not found: {path}"
|
|
42
40
|
target_os = "Linux" if platform.system() == "Linux" else "macOS"
|
|
43
41
|
console.print(Panel(f"🔗 PATH MAPPING | Windows → {target_os}: `{a_path}` ➡️ `{path}`", title="Path Mapping", expand=False))
|
|
44
|
-
elif platform.system() == "Windows" and
|
|
45
|
-
path =
|
|
42
|
+
elif platform.system() == "Windows" and Path.home().as_posix() not in path.as_posix(): # copied from Windows to Windows with different username
|
|
43
|
+
path = Path.home().joinpath(*path.parts[2:])
|
|
46
44
|
assert path.exists(), f"File not found: {path}"
|
|
47
45
|
console.print(Panel(f"🔗 PATH MAPPING | Windows → Windows: `{a_path}` ➡️ `{path}`", title="Path Mapping", expand=False))
|
|
48
46
|
return path.expanduser().absolute()
|
|
@@ -67,49 +65,58 @@ def find_scripts(root: Path, name_substring: str, suffixes: set[str]) -> tuple[l
|
|
|
67
65
|
return filename_matches, partial_path_matches
|
|
68
66
|
|
|
69
67
|
|
|
70
|
-
def match_file_name(sub_string: str, search_root:
|
|
68
|
+
def match_file_name(sub_string: str, search_root: Path, suffixes: set[str]) -> Path:
|
|
71
69
|
search_root_obj = search_root.absolute()
|
|
72
70
|
# assume subscript is filename only, not a sub_path. There is no need to fzf over the paths.
|
|
73
71
|
filename_matches, partial_path_matches = find_scripts(search_root_obj, sub_string, suffixes)
|
|
74
72
|
if len(filename_matches) == 1:
|
|
75
|
-
return
|
|
73
|
+
return Path(filename_matches[0])
|
|
76
74
|
console.print(Panel(f"Partial filename {search_root_obj} match with case-insensitivity failed. This generated #{len(filename_matches)} results.", title="Search", expand=False))
|
|
77
75
|
if len(filename_matches) < 20:
|
|
78
76
|
print("\n".join([a_potential_match.as_posix() for a_potential_match in filename_matches]))
|
|
79
77
|
if len(filename_matches) > 1:
|
|
80
|
-
print("Try to narrow down filename_matches search by case-sensitivity.")
|
|
78
|
+
print(f"Try to narrow down filename_matches search by case-sensitivity, found {len(filename_matches)} results. First @ {filename_matches[0].as_posix()}")
|
|
81
79
|
# let's see if avoiding .lower() helps narrowing down to one result
|
|
82
80
|
reduced_scripts = [a_potential_match for a_potential_match in filename_matches if sub_string in a_potential_match.name]
|
|
83
81
|
if len(reduced_scripts) == 1:
|
|
84
|
-
return
|
|
82
|
+
return Path(reduced_scripts[0])
|
|
85
83
|
elif len(reduced_scripts) > 1:
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
from machineconfig.utils.options import choose_from_options
|
|
85
|
+
choice = choose_from_options(multi=False, msg="Multiple matches found", options=reduced_scripts, tv=True)
|
|
86
|
+
return Path(choice)
|
|
88
87
|
print(f"Result: This still generated {len(reduced_scripts)} results.")
|
|
89
88
|
if len(reduced_scripts) < 10:
|
|
90
89
|
print("\n".join([a_potential_match.as_posix() for a_potential_match in reduced_scripts]))
|
|
91
90
|
|
|
92
91
|
console.print(Panel(f"Partial path match with case-insensitivity failed. This generated #{len(partial_path_matches)} results.", title="Search", expand=False))
|
|
93
92
|
if len(partial_path_matches) == 1:
|
|
94
|
-
return
|
|
93
|
+
return Path(partial_path_matches[0])
|
|
95
94
|
elif len(partial_path_matches) > 1:
|
|
96
95
|
print("Try to narrow down partial_path_matches search by case-sensitivity.")
|
|
97
96
|
reduced_scripts = [a_potential_match for a_potential_match in partial_path_matches if sub_string in a_potential_match.as_posix()]
|
|
98
97
|
if len(reduced_scripts) == 1:
|
|
99
|
-
return
|
|
100
|
-
print(f"Result: This still generated {len(reduced_scripts)} results.")
|
|
98
|
+
return Path(reduced_scripts[0])
|
|
99
|
+
print(f"Result: This still generated {len(reduced_scripts)} results.")
|
|
100
|
+
|
|
101
101
|
try:
|
|
102
|
-
|
|
102
|
+
|
|
103
|
+
if len(partial_path_matches) == 0:
|
|
104
|
+
print("No partial path matches found, trying to do fd with --no-ignore ...")
|
|
105
|
+
fzf_cmd = f"cd '{search_root_obj}'; fd --no-ignore --type file --strip-cwd-prefix | fzf --ignore-case --exact --query={sub_string}"
|
|
106
|
+
else:
|
|
107
|
+
fzf_cmd = f"cd '{search_root_obj}'; fd --type file --strip-cwd-prefix | fzf --ignore-case --exact --query={sub_string}"
|
|
103
108
|
console.print(Panel(f"🔍 Second attempt: SEARCH STRATEGY | Using fd to search for '{sub_string}' in '{search_root_obj}' ...\n{fzf_cmd}", title="Search Strategy", expand=False))
|
|
104
109
|
search_res_raw = subprocess.run(fzf_cmd, stdout=subprocess.PIPE, text=True, check=True, shell=True).stdout
|
|
105
|
-
search_res = search_res_raw.strip().split("
|
|
110
|
+
search_res = search_res_raw.strip().split("\n")
|
|
106
111
|
except subprocess.CalledProcessError as cpe:
|
|
107
112
|
console.print(Panel(f"❌ ERROR | FZF search failed with '{sub_string}' in '{search_root_obj}'.\n{cpe}", title="Error", expand=False))
|
|
108
113
|
import sys
|
|
109
|
-
|
|
110
114
|
sys.exit(f"💥 FILE NOT FOUND | Path {sub_string} does not exist @ root {search_root_obj}. No search results.")
|
|
111
115
|
if len(search_res) == 1:
|
|
112
116
|
return search_root_obj.joinpath(search_res_raw)
|
|
117
|
+
elif len(search_res) == 0:
|
|
118
|
+
msg = Panel(f"💥 FILE NOT FOUND | Path {sub_string} does not exist @ root {search_root_obj}. No search results", title="File Not Found", expand=False)
|
|
119
|
+
raise FileNotFoundError(msg)
|
|
113
120
|
|
|
114
121
|
print(f"⚠️ WARNING | Multiple search results found for `{sub_string}`:\n'{search_res}'")
|
|
115
122
|
cmd = f"cd '{search_root_obj}'; fd --type file | fzf --select-1 --query={sub_string}"
|
|
@@ -121,3 +128,49 @@ def match_file_name(sub_string: str, search_root: PathExtended, suffixes: set[st
|
|
|
121
128
|
msg = Panel(f"💥 FILE NOT FOUND | Path {sub_string} does not exist @ root {search_root_obj}. No search results", title="File Not Found", expand=False)
|
|
122
129
|
raise FileNotFoundError(msg) from cpe
|
|
123
130
|
return search_root_obj.joinpath(res)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def search_for_files_of_interest(path_obj: Path, suffixes: set[str]) -> list[Path]:
|
|
134
|
+
if path_obj.is_file():
|
|
135
|
+
return [path_obj]
|
|
136
|
+
files: list[Path] = []
|
|
137
|
+
directories_to_visit: list[Path] = [path_obj]
|
|
138
|
+
while directories_to_visit:
|
|
139
|
+
current_dir = directories_to_visit.pop()
|
|
140
|
+
for entry in current_dir.iterdir():
|
|
141
|
+
if entry.is_dir():
|
|
142
|
+
if entry.name == ".venv":
|
|
143
|
+
continue
|
|
144
|
+
directories_to_visit.append(entry)
|
|
145
|
+
continue
|
|
146
|
+
if entry.suffix not in suffixes:
|
|
147
|
+
continue
|
|
148
|
+
if entry.suffix == ".py" and entry.name == "__init__.py":
|
|
149
|
+
continue
|
|
150
|
+
files.append(entry)
|
|
151
|
+
return files
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def get_choice_file(path: str, suffixes: Optional[set[str]]):
|
|
155
|
+
path_obj = sanitize_path(path)
|
|
156
|
+
if suffixes is None:
|
|
157
|
+
import platform
|
|
158
|
+
if platform.system() == "Windows":
|
|
159
|
+
suffixes = {".py", ".ps1", ".sh"}
|
|
160
|
+
elif platform.system() in ["Linux", "Darwin"]:
|
|
161
|
+
suffixes = {".py", ".sh"}
|
|
162
|
+
else:
|
|
163
|
+
suffixes = {".py"}
|
|
164
|
+
if not path_obj.exists():
|
|
165
|
+
print(f"🔍 Searching for file matching `{path}` under `{Path.cwd()}`, but only if suffix matches {suffixes}")
|
|
166
|
+
choice_file = match_file_name(sub_string=path, search_root=Path.cwd(), suffixes=suffixes)
|
|
167
|
+
elif path_obj.is_dir():
|
|
168
|
+
print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
|
|
169
|
+
files = search_for_files_of_interest(path_obj, suffixes=suffixes)
|
|
170
|
+
print(f"🔍 Got #{len(files)} results.")
|
|
171
|
+
from machineconfig.utils.options import choose_from_options
|
|
172
|
+
choice_file = choose_from_options(multi=False, options=files, tv=True, msg="Choose one option")
|
|
173
|
+
choice_file = Path(choice_file)
|
|
174
|
+
else:
|
|
175
|
+
choice_file = path_obj
|
|
176
|
+
return choice_file
|