machineconfig 6.82__py3-none-any.whl → 8.51__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/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +29 -15
- machineconfig/cluster/sessions_managers/wt_local.py +17 -222
- machineconfig/cluster/sessions_managers/wt_local_manager.py +56 -194
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
- 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_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +4 -2
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
- machineconfig/jobs/installer/checks/check_installations.py +133 -0
- machineconfig/jobs/installer/checks/install_utils.py +132 -0
- machineconfig/jobs/installer/checks/report_utils.py +39 -0
- machineconfig/jobs/installer/checks/vt_utils.py +89 -0
- machineconfig/jobs/installer/installer_data.json +1500 -310
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
- machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
- machineconfig/jobs/installer/package_groups.py +62 -91
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +2 -3
- 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 +14 -9
- machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/python_scripts/hx.py +214 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +32 -26
- machineconfig/jobs/installer/python_scripts/sysabc.py +145 -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 +139 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- 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 +428 -0
- machineconfig/logger.py +1 -2
- machineconfig/profile/create_helper.py +56 -18
- machineconfig/profile/create_links.py +79 -21
- machineconfig/profile/create_links_export.py +87 -36
- machineconfig/profile/create_shell_profile.py +92 -127
- machineconfig/profile/mapper_data.toml +45 -0
- machineconfig/profile/mapper_dotfiles.toml +249 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +85 -165
- machineconfig/scripts/python/ai/initai.py +4 -2
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- 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.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
- machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
- machineconfig/scripts/python/ai/solutions/cline/cline.py +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 +6 -6
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +33 -0
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
- machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +13 -5
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +10 -162
- machineconfig/scripts/python/devops.py +73 -36
- machineconfig/scripts/python/devops_navigator.py +16 -6
- machineconfig/scripts/python/fire_jobs.py +8 -222
- machineconfig/scripts/python/ftpx.py +7 -200
- machineconfig/scripts/python/graph/cli_graph.json +8743 -0
- machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
- machineconfig/scripts/python/helpers/helper_env/env_manager_tui.py +204 -0
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_launch.py +38 -16
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_helper_types.py +11 -14
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/helpers/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/templates/template.sh +34 -0
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +32 -25
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +29 -22
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +9 -8
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +3 -3
- machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +12 -12
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +67 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_nw.py +201 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_self.py +197 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_share_file.py +151 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_share_server.py +125 -0
- machineconfig/scripts/python/{helpers_devops/cli_terminal.py → helpers/helpers_devops/cli_share_terminal.py} +26 -22
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +17 -23
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +78 -71
- machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +4 -4
- machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers/helpers_fire_command/file_wrangler.py} +57 -20
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
- machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +26 -16
- machineconfig/scripts/python/helpers/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/{linux → python/helpers/helpers_msearch/scripts_linux}/fzfg +6 -5
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
- machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
- machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/helpers/helpers_network/address.py +174 -0
- machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nfs.py +2 -2
- machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_ssh.py +3 -3
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
- machineconfig/scripts/python/{nw → helpers/helpers_network}/wifi_conn.py +1 -53
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -1
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +159 -48
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +4 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -12
- machineconfig/scripts/python/helpers/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{helpers_repos/count_lines.py → helpers/helpers_repos/repo_analyzer_2.py} +156 -191
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/helpers_search/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/helpers_search/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_search/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +20 -14
- machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
- machineconfig/scripts/python/helpers/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers/helpers_utils/pdf.py +96 -0
- machineconfig/scripts/python/helpers/helpers_utils/python.py +210 -0
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +143 -0
- machineconfig/scripts/python/msearch.py +26 -0
- machineconfig/scripts/python/sessions.py +69 -135
- machineconfig/scripts/python/terminal.py +58 -0
- machineconfig/scripts/python/utils.py +115 -38
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- 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 +3 -2
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +14 -16
- machineconfig/settings/linters/.ruff.toml +2 -1
- machineconfig/settings/marimo/marimo.toml +1 -1
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +47 -12
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +25 -33
- machineconfig/settings/shells/nushell/env.nu +21 -8
- machineconfig/settings/shells/nushell/init.nu +138 -0
- machineconfig/settings/shells/pwsh/init.ps1 +111 -17
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +6 -1
- machineconfig/settings/shells/wt/settings.json +27 -18
- machineconfig/settings/shells/zsh/init.sh +42 -23
- 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/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/wt/__init__.py +0 -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 +94 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/settings/zellij/layouts/st.kdl +40 -9
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/__init__.py +2 -2
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -12
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +34 -0
- machineconfig/setup_mac/__init__.py +1 -4
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_windows/__init__.py +2 -5
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +28 -12
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +31 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/type_hinting/sql/__init__.py +1 -0
- machineconfig/type_hinting/sql/base.py +216 -0
- machineconfig/type_hinting/sql/core_schema.py +64 -0
- machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
- machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
- machineconfig/type_hinting/typedict/__init__.py +1 -0
- machineconfig/type_hinting/typedict/ast_utils.py +130 -0
- machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
- machineconfig/type_hinting/typedict/generators.py +231 -0
- machineconfig/type_hinting/typedict/polars_schema.py +24 -0
- machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
- machineconfig/utils/accessories.py +31 -4
- machineconfig/utils/code.py +163 -51
- machineconfig/utils/files/ascii_art.py +11 -15
- machineconfig/utils/files/headers.py +6 -7
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +95 -138
- machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +53 -102
- machineconfig/utils/installer_utils/installer_cli.py +161 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +42 -91
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +20 -65
- machineconfig/utils/io.py +94 -9
- machineconfig/utils/links.py +56 -38
- machineconfig/utils/meta.py +38 -21
- machineconfig/utils/options.py +81 -23
- machineconfig/utils/options_utils/__init__.py +0 -0
- machineconfig/utils/options_utils/options_tv_linux.py +211 -0
- machineconfig/utils/options_utils/options_tv_windows.py +88 -0
- machineconfig/utils/options_utils/tv_options.py +37 -0
- machineconfig/utils/path_extended.py +52 -102
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +1 -1
- machineconfig/utils/scheduler.py +26 -53
- machineconfig/utils/scheduling.py +0 -2
- 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 +6 -1
- machineconfig/utils/ssh.py +216 -419
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +116 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
- machineconfig/utils/ssh_utils/utils.py +158 -0
- machineconfig/utils/ssh_utils/wsl.py +147 -0
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/terminal.py +1 -0
- machineconfig/utils/upgrade_packages.py +107 -35
- machineconfig/utils/ve.py +12 -4
- machineconfig-8.51.dist-info/METADATA +140 -0
- machineconfig-8.51.dist-info/RECORD +543 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +4 -1
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/jobs/installer/custom/hx.py +0 -140
- 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/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -256
- 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/mcfgs +0 -38
- machineconfig/scripts/linux/other/share_smb +0 -1
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -120
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -77
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_nw.py +0 -73
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -181
- machineconfig/scripts/python/helpers_devops/cli_self.py +0 -122
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +0 -104
- machineconfig/scripts/python/helpers_devops/cli_utils.py +0 -221
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
- machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
- machineconfig/scripts/python/helpers_fire/template.sh +0 -15
- machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
- machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -588
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -76
- machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
- machineconfig/scripts/python/mcfg.py +0 -48
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- machineconfig/scripts/python/nw/devops_add_identity.py +0 -82
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +0 -134
- machineconfig/scripts/python/nw/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/nw/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/mcfgs.ps1 +0 -17
- 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 -4
- 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_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/apps.ps1 +0 -62
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/utils/installer_utils/installer.py +0 -225
- machineconfig/utils/tst.py +0 -20
- machineconfig-6.82.dist-info/METADATA +0 -82
- machineconfig-6.82.dist-info/RECORD +0 -441
- machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- machineconfig/{scripts/python/helpers_cloud → jobs/installer/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/{helpers_croshell → ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- machineconfig/scripts/python/{helpers_devops → graph}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_devops/themes → helpers}/__init__.py +0 -0
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents/templates}/template.ps1 +0 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_cloud}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{nw → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command/fire_jobs_streamlit_helper.py → helpers/helpers_fire_command/f.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers/helpers_fire_command/fire_jobs_streamlit_helper.py} +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers/helpers_network/__init__.py} +0 -0
- /machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{nw → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.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
|
|
|
@@ -174,7 +103,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
174
103
|
slf = self.expanduser().resolve()
|
|
175
104
|
if content:
|
|
176
105
|
assert self.is_dir(), NotADirectoryError(f"💥 When `content` flag is set to True, path must be a directory. It is not: `{repr(self)}`")
|
|
177
|
-
[x.move(folder=path.parent, content=False, overwrite=overwrite) for x in self.
|
|
106
|
+
[x.move(folder=path.parent, content=False, overwrite=overwrite) for x in self.glob("*")]
|
|
178
107
|
return path # contents live within this directory.
|
|
179
108
|
if overwrite:
|
|
180
109
|
tmp_path = slf.rename(path.parent.absolute() / randstr())
|
|
@@ -225,7 +154,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
225
154
|
# ======================================= File Editing / Reading ===================================
|
|
226
155
|
def download(self, folder: OPLike = None, name: Optional[str] = None, allow_redirects: bool = True, timeout: Optional[int] = None, params: Any = None) -> "PathExtended":
|
|
227
156
|
import requests
|
|
228
|
-
|
|
229
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').
|
|
230
158
|
assert response.status_code == 200, f"Download failed with status code {response.status_code}\n{response.text}"
|
|
231
159
|
if name is not None:
|
|
@@ -246,7 +174,8 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
246
174
|
appended_name = f"""{name}_{len(self.parent.search(f"*{self.name.split('.')[0]}*"))}"""
|
|
247
175
|
return self.append(name=appended_name, index=False, verbose=verbose, suffix=suffix, **kwargs)
|
|
248
176
|
full_name = name or ("_" + str(timestamp()))
|
|
249
|
-
|
|
177
|
+
whatever = ("bruh" + self)
|
|
178
|
+
full_suffix = suffix or "".join(whatever.suffixes)
|
|
250
179
|
subpath = self.name.split(".")[0] + full_name + full_suffix
|
|
251
180
|
dest = self.parent.joinpath(subpath)
|
|
252
181
|
res = PathExtended(dest)
|
|
@@ -366,7 +295,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
366
295
|
target = "BROKEN LINK " + str(self) # avoid infinite recursions for broken links.
|
|
367
296
|
return "🔗 Symlink '" + str(self) + "' ==> " + (str(target) if target == self else str(target))
|
|
368
297
|
elif self.is_absolute():
|
|
369
|
-
return self._type() + " '" + str(self.clickable()) + "'" + (" | " + datetime.fromtimestamp(self.stat().st_ctime).isoformat()[:-7].replace("T", " ") if self.exists() else "") + (f" | {self.
|
|
298
|
+
return self._type() + " '" + str(self.clickable()) + "'" + (" | " + datetime.fromtimestamp(self.stat().st_ctime).isoformat()[:-7].replace("T", " ") if self.exists() else "") + (f" | {round(self.stat().st_size / (1024**2), 1)} Mb" if self.is_file() else "")
|
|
370
299
|
elif "http" in str(self):
|
|
371
300
|
return "🕸️ URL " + str(self.as_url_str())
|
|
372
301
|
else:
|
|
@@ -548,14 +477,10 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
548
477
|
verbose: bool = True,
|
|
549
478
|
content: bool = False,
|
|
550
479
|
orig: bool = False,
|
|
551
|
-
pwd: Optional[str] = None,
|
|
552
480
|
mode: FILE_MODE = "w",
|
|
553
481
|
**kwargs: Any,
|
|
554
482
|
) -> "PathExtended":
|
|
555
483
|
path_resolved, slf = self._resolve_path(folder, name, path, self.name).expanduser().resolve(), self.expanduser().resolve()
|
|
556
|
-
# if use_7z: # benefits over regular zip and encrypt: can handle very large files with low memory footprint
|
|
557
|
-
# path_resolved = path_resolved + '.7z' if not path_resolved.suffix == '.7z' else path_resolved
|
|
558
|
-
# with install_n_import("py7zr").SevenZipFile(file=path_resolved, mode=mode, password=pwd) as archive: archive.writeall(path=str(slf), arcname=None)
|
|
559
484
|
arcname_obj = PathExtended(arcname or slf.name)
|
|
560
485
|
if arcname_obj.name != slf.name:
|
|
561
486
|
arcname_obj /= slf.name # arcname has to start from somewhere and end with filename
|
|
@@ -568,7 +493,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
568
493
|
path_resolved = PathExtended(op_zip)
|
|
569
494
|
else:
|
|
570
495
|
import shutil
|
|
571
|
-
|
|
572
496
|
if content:
|
|
573
497
|
root_dir, base_dir = slf, "."
|
|
574
498
|
else:
|
|
@@ -576,7 +500,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
576
500
|
base_name = str(path_resolved)[:-4] if str(path_resolved).endswith(".zip") else str(path_resolved)
|
|
577
501
|
op_zip = shutil.make_archive(base_name=base_name, format="zip", root_dir=str(root_dir), base_dir=str(base_dir), verbose=False, **kwargs)
|
|
578
502
|
path_resolved = PathExtended(op_zip)
|
|
579
|
-
msg = f"ZIPPED {repr(slf)} ==>
|
|
503
|
+
msg = f"ZIPPED {repr(slf)} ==> {repr(path_resolved)}"
|
|
580
504
|
res_out = PathExtended(path_resolved)
|
|
581
505
|
ret = self if orig else res_out
|
|
582
506
|
delayed_msg = ""
|
|
@@ -613,7 +537,9 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
613
537
|
assert merge is False, "I have not implemented this yet"
|
|
614
538
|
assert path is None, "I have not implemented this yet"
|
|
615
539
|
if tmp:
|
|
616
|
-
|
|
540
|
+
tmp_root = PathExtended("~/tmp_results").expanduser()
|
|
541
|
+
tmp_root.mkdir(parents=True, exist_ok=True)
|
|
542
|
+
return self.unzip(folder=tmp_root.joinpath("tmp_unzips").joinpath(randstr()), content=True).joinpath(self.stem)
|
|
617
543
|
slf = zipfile__ = self.expanduser().resolve()
|
|
618
544
|
if any(ztype in str(slf.parent) for ztype in (".zip", ".7z")): # path include a zip archive in the middle.
|
|
619
545
|
tmp__ = [item for item in (".zip", ".7z", "") if item in str(slf)]
|
|
@@ -628,15 +554,6 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
628
554
|
folder = folder if not content else folder.parent
|
|
629
555
|
if slf.suffix == ".7z":
|
|
630
556
|
raise NotImplementedError("I have not implemented this yet")
|
|
631
|
-
# if overwrite: P(folder).delete(sure=True)
|
|
632
|
-
# result = folder
|
|
633
|
-
# import py7zr
|
|
634
|
-
# with py7zr.SevenZipFile(file=slf, mode='r', password=pwd) as archive:
|
|
635
|
-
# if pattern is not None:
|
|
636
|
-
# import re
|
|
637
|
-
# pat = re.compile(pattern)
|
|
638
|
-
# archive.extract(path=folder, targets=[f for f in archive.getnames() if pat.match(f)])
|
|
639
|
-
# else: archive.extractall(path=folder)
|
|
640
557
|
else:
|
|
641
558
|
if overwrite:
|
|
642
559
|
if not content:
|
|
@@ -771,21 +688,54 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
771
688
|
return ret
|
|
772
689
|
|
|
773
690
|
def decompress(self, folder: OPLike = None, name: Optional[str] = None, path: OPLike = None, inplace: bool = False, orig: bool = False, verbose: bool = True) -> "PathExtended":
|
|
774
|
-
if ".tar.gz"
|
|
691
|
+
if str(self).endswith(".tar.gz") or str(self).endswith(".tgz"):
|
|
775
692
|
# res = self.ungz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
776
693
|
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
|
|
777
|
-
elif
|
|
694
|
+
elif str(self).endswith(".tar"):
|
|
695
|
+
res = self.untar(folder=folder, name=name, path=path, inplace=inplace, orig=orig, verbose=verbose)
|
|
696
|
+
elif str(self).endswith(".gz"):
|
|
778
697
|
res = self.ungz(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
779
|
-
elif ".tar.bz"
|
|
698
|
+
elif str(self).endswith(".tar.bz") or str(self).endswith(".tbz") or str(self).endswith(".tar.bz2"):
|
|
780
699
|
res = self.unbz(name=f"tmp_{randstr()}.tar", inplace=inplace)
|
|
781
700
|
return res.untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
782
|
-
elif ".tar.xz"
|
|
701
|
+
elif str(self).endswith(".tar.xz"):
|
|
783
702
|
# res = self.unxz_untar(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
784
703
|
res = self.unxz(inplace=inplace).untar(folder=folder, name=name, path=path, inplace=True, orig=orig, verbose=verbose)
|
|
785
|
-
elif ".zip"
|
|
704
|
+
elif str(self).endswith(".zip"):
|
|
786
705
|
res = self.unzip(folder=folder, path=path, name=name, inplace=inplace, verbose=verbose, orig=orig)
|
|
706
|
+
elif str(self).endswith(".7z"):
|
|
707
|
+
def unzip_7z(archive_path: str, dest_dir: Optional[str] = None) -> Path:
|
|
708
|
+
"""
|
|
709
|
+
Uncompresses a .7z archive to a directory and returns the Path to the extraction directory.
|
|
710
|
+
|
|
711
|
+
:param archive_path: path to the .7z archive file
|
|
712
|
+
:param dest_dir: optional path to directory to extract into; if None a temporary dir will be created
|
|
713
|
+
:return: pathlib.Path pointing to the destination directory where contents were extracted
|
|
714
|
+
:raises: FileNotFoundError if archive does not exist; py7zr.Bad7zFile or other error if extraction fails
|
|
715
|
+
"""
|
|
716
|
+
import py7zr # type: ignore
|
|
717
|
+
import tempfile
|
|
718
|
+
from pathlib import Path
|
|
719
|
+
archive_path_obj = Path(archive_path)
|
|
720
|
+
if not archive_path_obj.is_file():
|
|
721
|
+
raise FileNotFoundError(f"Archive file not found: {archive_path_obj!r}")
|
|
722
|
+
if dest_dir is None:
|
|
723
|
+
# create a temporary directory
|
|
724
|
+
dest = Path(tempfile.mkdtemp(prefix=f"unzip7z_{archive_path_obj.stem}_"))
|
|
725
|
+
else:
|
|
726
|
+
dest = Path(dest_dir)
|
|
727
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
728
|
+
# Perform extraction
|
|
729
|
+
with py7zr.SevenZipFile(str(archive_path_obj), mode='r') as archive:
|
|
730
|
+
archive.extractall(path=str(dest))
|
|
731
|
+
# Return the extraction directory path
|
|
732
|
+
return dest
|
|
733
|
+
from machineconfig.utils.code import run_lambda_function
|
|
734
|
+
destination_dir = str(self.expanduser().resolve()).replace(".7z", "")
|
|
735
|
+
run_lambda_function(lambda: unzip_7z(archive_path=str(self), dest_dir=destination_dir), uv_project_dir=None, uv_with=["py7zr"])
|
|
736
|
+
res = PathExtended(destination_dir)
|
|
787
737
|
else:
|
|
788
|
-
|
|
738
|
+
raise ValueError(f"Cannot decompress file with unknown extension: {self}")
|
|
789
739
|
return res
|
|
790
740
|
|
|
791
741
|
def encrypt(
|
|
@@ -861,7 +811,7 @@ class PathExtended(type(Path()), Path): # type: ignore # pylint: disable=E0241
|
|
|
861
811
|
path = self
|
|
862
812
|
else:
|
|
863
813
|
try:
|
|
864
|
-
path = self.
|
|
814
|
+
path = PathExtended(self.expanduser().absolute().relative_to(Path.home()))
|
|
865
815
|
except ValueError as ve:
|
|
866
816
|
if strict:
|
|
867
817
|
raise ve
|
|
@@ -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
|
machineconfig/utils/procs.py
CHANGED
|
@@ -129,7 +129,7 @@ class ProcessManager:
|
|
|
129
129
|
all_lines = formatted_data.split("\n")
|
|
130
130
|
header_and_separator = all_lines[:2] # First two lines: header and separator
|
|
131
131
|
options = all_lines[2:] # Skip header and separator, only process lines
|
|
132
|
-
res = choose_from_options(options=all_lines, msg="📋 Select processes to manage:",
|
|
132
|
+
res = choose_from_options(options=all_lines, msg="📋 Select processes to manage:", tv=True, multi=True)
|
|
133
133
|
# Filter out header and separator if they were selected
|
|
134
134
|
selected_lines = [line for line in res if line not in header_and_separator]
|
|
135
135
|
indices = [options.index(val) for val in selected_lines]
|
machineconfig/utils/scheduler.py
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import Callable, Optional, Union, Any, Protocol, List, TypeVar
|
|
4
|
-
import logging
|
|
4
|
+
# import logging
|
|
5
5
|
import time
|
|
6
6
|
from datetime import datetime, timezone, timedelta
|
|
7
7
|
from machineconfig.utils.io import from_pickle
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class LoggerTemplate(Protocol):
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def
|
|
11
|
+
def trace(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
12
|
+
pass # 5
|
|
13
|
+
def success(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
14
|
+
pass # 25
|
|
15
|
+
def debug(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
14
16
|
pass # 10
|
|
15
|
-
|
|
16
|
-
def info(self, msg: str) -> None:
|
|
17
|
+
def info(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
17
18
|
pass # 20
|
|
18
|
-
|
|
19
|
-
def warning(self, msg: str) -> None:
|
|
19
|
+
def warning(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
20
20
|
pass # 30
|
|
21
|
-
|
|
22
|
-
def error(self, msg: str) -> None:
|
|
21
|
+
def error(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
23
22
|
pass # 40
|
|
24
|
-
|
|
25
|
-
def critical(self, msg: str) -> None:
|
|
26
|
-
pass # 50
|
|
27
|
-
|
|
28
|
-
def fatal(self, msg: str) -> None:
|
|
23
|
+
def critical(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
29
24
|
pass # 50
|
|
30
25
|
|
|
31
26
|
|
|
@@ -139,7 +134,7 @@ class Scheduler:
|
|
|
139
134
|
def default_exception_handler(self, ex: Union[Exception, KeyboardInterrupt], during: str, sched: "Scheduler") -> None: # user decides on handling and continue, terminate, save checkpoint, etc. # Use signal library.
|
|
140
135
|
print(sched)
|
|
141
136
|
self.record_session_end(reason=f"during {during}, " + str(ex))
|
|
142
|
-
self.logger.
|
|
137
|
+
self.logger.critical(str(ex))
|
|
143
138
|
raise ex
|
|
144
139
|
|
|
145
140
|
|
|
@@ -164,28 +159,23 @@ class CacheMemory[T]():
|
|
|
164
159
|
if fresh or not hasattr(self, "cache"):
|
|
165
160
|
why = "There was an explicit fresh order." if fresh else "Previous cache never existed."
|
|
166
161
|
t0 = time.time()
|
|
167
|
-
self.logger.warning(f"""
|
|
168
|
-
🆕 ════════════════════ NEW {self.name} CACHE ════════════════════
|
|
169
|
-
ℹ️ Reason: {why}""")
|
|
162
|
+
self.logger.warning(f"""🆕 NEW CACHE 🔄 {self.name} CACHE ℹ️ Reason: {why}""")
|
|
170
163
|
self.cache = self.source_func()
|
|
171
164
|
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
172
165
|
self.time_produced = datetime.now()
|
|
173
166
|
else:
|
|
174
167
|
age = datetime.now() - self.time_produced
|
|
175
168
|
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)):
|
|
176
|
-
|
|
177
|
-
🔄
|
|
178
|
-
|
|
179
|
-
|
|
169
|
+
if not fresh:
|
|
170
|
+
self.logger.warning(f"""🔄 CACHE STALE 📦 {self.name} cache: Populating fresh cache from source func. """ + f"""⏱️ Age = {age} > Expiry {self.expire} """ )
|
|
171
|
+
else:
|
|
172
|
+
self.logger.warning(f"""⚠️ Fresh flag raised, age = {age} > {tolerance_seconds} seconds of tolerance. Updating {self.name} cache from source func.""")
|
|
180
173
|
t0 = time.time()
|
|
181
174
|
self.cache = self.source_func()
|
|
182
175
|
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
183
176
|
self.time_produced = datetime.now()
|
|
184
177
|
else:
|
|
185
|
-
self.logger.warning(f"""
|
|
186
|
-
✅ ════════════════════ USING CACHE ════════════════════
|
|
187
|
-
📦 {self.name} cache: Using cached values
|
|
188
|
-
⏱️ Lag = {age}""")
|
|
178
|
+
self.logger.warning(f"""✅ USING CACHE 📦 {self.name} cache: Using cached values ⏱️ Lag = {age} < {self.expire} < {tolerance_seconds} seconds.""")
|
|
189
179
|
return self.cache
|
|
190
180
|
|
|
191
181
|
@staticmethod
|
|
@@ -215,28 +205,21 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
|
|
|
215
205
|
if self.path.exists(): # prefer to read from disk over source func as a default source of cache.
|
|
216
206
|
age = datetime.now() - datetime.fromtimestamp(self.path.stat().st_mtime)
|
|
217
207
|
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
|
|
218
|
-
|
|
219
|
-
🔄
|
|
220
|
-
|
|
221
|
-
|
|
208
|
+
if not fresh:
|
|
209
|
+
self.logger.warning(f"""🔄 CACHE STALE 📦 {self.name} cache: Populating fresh cache from source func. """ + f"""⏱️ Age = {age} > Expiry {self.expire} """ )
|
|
210
|
+
else:
|
|
211
|
+
self.logger.warning(f"""⚠️ Fresh flag raised, age = {age} > {tolerance_seconds} seconds of tolerance. Updating {self.name} cache from source func.""")
|
|
222
212
|
t0 = time.time()
|
|
223
213
|
self.cache = self.source_func() # fresh data.
|
|
224
214
|
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
225
215
|
self.time_produced = datetime.now()
|
|
226
216
|
self.save(self.cache, self.path)
|
|
227
217
|
return self.cache
|
|
228
|
-
|
|
229
|
-
msg1 = f"""
|
|
230
|
-
📦 ════════════════════ CACHE OPERATION ════════════════════
|
|
231
|
-
🔄 {self.name} cache: Reading cached values from `{self.path}`
|
|
232
|
-
⏱️ Lag = {age}"""
|
|
218
|
+
msg1 = f"""📦 CACHE OPERATION 🔄 {self.name} cache: Reading cached values from `{self.path}` ⏱️ Lag = {age}"""
|
|
233
219
|
try:
|
|
234
220
|
self.cache = self.reader(self.path)
|
|
235
221
|
except Exception as ex:
|
|
236
|
-
msg2 = f"""
|
|
237
|
-
❌ ════════════════════ CACHE ERROR ════════════════════
|
|
238
|
-
⚠️ {self.name} cache: Cache file is corrupted
|
|
239
|
-
🔍 Error: {ex}"""
|
|
222
|
+
msg2 = f"""❌ CACHE ERROR ⚠️ {self.name} cache: Cache file is corrupted 🔍 Error: {ex}"""
|
|
240
223
|
self.logger.warning(msg1 + msg2)
|
|
241
224
|
t0 = time.time()
|
|
242
225
|
self.cache = self.source_func()
|
|
@@ -245,11 +228,7 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
|
|
|
245
228
|
self.save(self.cache, self.path)
|
|
246
229
|
return self.cache
|
|
247
230
|
else: # disk cache does not exist, populate from source func.
|
|
248
|
-
|
|
249
|
-
self.logger.warning(f"""
|
|
250
|
-
🆕 ════════════════════ NEW CACHE ════════════════════
|
|
251
|
-
🔄 {self.name} cache: Populating fresh cache from source func
|
|
252
|
-
ℹ️ Reason: {why}""")
|
|
231
|
+
self.logger.warning(f"""🆕 NEW CACHE 🔄 {self.name} cache: Populating fresh cache from source func ℹ️ Reason: Previous cache never existed.""")
|
|
253
232
|
t0 = time.time()
|
|
254
233
|
self.cache = self.source_func() # fresh data.
|
|
255
234
|
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
@@ -258,20 +237,14 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
|
|
|
258
237
|
else: # memory cache exists
|
|
259
238
|
age = datetime.now() - self.time_produced
|
|
260
239
|
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
|
|
261
|
-
self.logger.warning(f"""
|
|
262
|
-
🔄 ════════════════════ CACHE UPDATE ════════════════════
|
|
263
|
-
⚠️ {self.name} cache: Updating cache from source func
|
|
264
|
-
⏱️ Age = {age} > {self.expire}""")
|
|
240
|
+
self.logger.warning(f"""🔄 CACHE UPDATE ⚠️ {self.name} cache: Updating cache from source func. ⏱️ Age = {age} > {self.expire}""")
|
|
265
241
|
t0 = time.time()
|
|
266
242
|
self.cache = self.source_func()
|
|
267
243
|
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
268
244
|
self.time_produced = datetime.now()
|
|
269
245
|
self.save(self.cache, self.path)
|
|
270
246
|
else:
|
|
271
|
-
self.logger.warning(f"""
|
|
272
|
-
✅ ════════════════════ USING CACHE ════════════════════
|
|
273
|
-
📦 {self.name} cache: Using cached values
|
|
274
|
-
⏱️ Lag = {age}""")
|
|
247
|
+
self.logger.warning(f"""✅ USING CACHE 📦 {self.name} cache: Using cached values ⏱️ Lag = {age} < {self.expire} < {tolerance_seconds} seconds.""")
|
|
275
248
|
return self.cache
|
|
276
249
|
|
|
277
250
|
@staticmethod
|
|
@@ -6,7 +6,7 @@ capturing all user inputs collected during interactive execution.
|
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import TypedDict, Literal, NotRequired
|
|
9
|
-
from machineconfig.scripts.python.
|
|
9
|
+
from machineconfig.scripts.python.helpers.helpers_agents.fire_agents_help_launch import AGENTS
|
|
10
10
|
|
|
11
11
|
SEARCH_STRATEGIES = Literal["file_path", "keyword_search", "filename_pattern"]
|
|
12
12
|
|