machineconfig 5.15__py3-none-any.whl → 7.66__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/__init__.py +0 -28
- 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 +50 -193
- machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +49 -197
- 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 +22 -169
- machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
- 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_dev/alacritty.py +4 -4
- machineconfig/jobs/installer/custom_dev/brave.py +1 -7
- 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/nerfont_windows_helper.py +9 -18
- machineconfig/jobs/installer/custom_dev/sysabc.py +119 -0
- machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
- machineconfig/jobs/installer/installer_data.json +1101 -115
- 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 +1 -0
- 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 +108 -180
- machineconfig/logger.py +0 -1
- machineconfig/profile/backup.toml +49 -0
- machineconfig/profile/bash_shell_profiles.md +11 -0
- machineconfig/profile/create_helper.py +74 -0
- machineconfig/profile/create_links.py +288 -0
- machineconfig/profile/create_links_export.py +100 -0
- machineconfig/profile/create_shell_profile.py +136 -0
- machineconfig/profile/mapper.toml +258 -0
- machineconfig/scripts/Restore-ThunderbirdProfile.ps1 +92 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
- machineconfig/scripts/linux/wrap_mcfg +47 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +92 -103
- machineconfig/scripts/python/ai/command_runner/command_runner.sh +9 -0
- machineconfig/scripts/python/ai/command_runner/prompt.txt +9 -0
- machineconfig/scripts/python/ai/generate_files.py +307 -42
- machineconfig/scripts/python/ai/initai.py +3 -28
- 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/instructions/python/dev.instructions.md +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
- machineconfig/scripts/python/ai/solutions/generic.py +27 -4
- machineconfig/scripts/python/ai/vscode_tasks.py +37 -0
- machineconfig/scripts/python/cloud.py +29 -0
- machineconfig/scripts/python/croshell.py +111 -114
- machineconfig/scripts/python/define.py +31 -0
- machineconfig/scripts/python/devops.py +44 -103
- machineconfig/scripts/python/devops_navigator.py +10 -0
- machineconfig/scripts/python/env_manager/__init__.py +1 -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/explore.py +49 -0
- machineconfig/scripts/python/fire_jobs.py +115 -152
- machineconfig/scripts/python/ftpx.py +29 -24
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +37 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +42 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/{fire_agents_help_launch.py → helpers_agents/fire_agents_help_launch.py} +34 -44
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +34 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +6 -0
- machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +24 -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} +10 -18
- 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} +2 -2
- machineconfig/scripts/python/helpers_devops/cli_config.py +95 -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 +134 -0
- machineconfig/scripts/python/helpers_devops/cli_repos.py +182 -0
- machineconfig/scripts/python/helpers_devops/cli_self.py +134 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +141 -0
- machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_terminal.py} +35 -23
- 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 +511 -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} +2 -2
- machineconfig/scripts/python/helpers_fire_command/__init__.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/{fire_jobs_route_helper.py → helpers_fire_command/fire_jobs_route_helper.py} +47 -2
- 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}/fzfag +1 -1
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +1 -1
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfrga +1 -1
- 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 +588 -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_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/{count_lines.py → helpers_repos/count_lines.py} +10 -10
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +17 -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/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 +58 -0
- machineconfig/scripts/python/helpers_utils/download.py +152 -0
- machineconfig/scripts/python/helpers_utils/path.py +108 -0
- machineconfig/scripts/python/interactive.py +64 -84
- machineconfig/scripts/python/machineconfig.py +63 -0
- machineconfig/scripts/python/msearch.py +21 -0
- machineconfig/scripts/python/nw/__init__.py +0 -0
- machineconfig/scripts/python/{devops_add_identity.py → nw/devops_add_identity.py} +0 -2
- machineconfig/scripts/python/{devops_add_ssh_key.py → nw/devops_add_ssh_key.py} +73 -43
- machineconfig/scripts/{linux → python/nw}/mount_nfs +1 -1
- machineconfig/scripts/python/{mount_nfs.py → nw/mount_nfs.py} +3 -3
- machineconfig/scripts/{linux → python/nw}/mount_nw_drive +1 -2
- machineconfig/scripts/python/{mount_ssh.py → nw/mount_ssh.py} +3 -3
- machineconfig/scripts/python/{onetimeshare.py → nw/onetimeshare.py} +0 -1
- machineconfig/scripts/python/nw/ssh_debug_linux.py +391 -0
- machineconfig/scripts/python/nw/ssh_debug_windows.py +338 -0
- machineconfig/scripts/python/{wifi_conn.py → nw/wifi_conn.py} +1 -53
- machineconfig/scripts/python/{wsl_windows_transfer.py → nw/wsl_windows_transfer.py} +5 -4
- machineconfig/scripts/python/sessions.py +64 -44
- machineconfig/scripts/python/terminal.py +127 -0
- machineconfig/scripts/python/utils.py +66 -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 +60 -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/fzf_edit.ps1 +2 -2
- 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 +55 -31
- machineconfig/settings/shells/nushell/config.nu +1 -34
- machineconfig/settings/shells/nushell/init.nu +127 -0
- machineconfig/settings/shells/pwsh/init.ps1 +60 -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/yazi/init.lua +57 -0
- machineconfig/settings/yazi/keymap_linux.toml +79 -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/yazi.toml +13 -0
- machineconfig/setup_linux/__init__.py +10 -0
- machineconfig/setup_linux/apps_desktop.sh +89 -0
- machineconfig/setup_linux/apps_gui.sh +64 -0
- machineconfig/setup_linux/{nix → others}/cli_installation.sh +9 -29
- 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_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 +8 -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 +10 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +16 -0
- machineconfig/utils/accessories.py +7 -5
- machineconfig/utils/cloud/onedrive/README.md +139 -0
- machineconfig/utils/code.py +133 -106
- 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/installer_class.py +68 -126
- machineconfig/utils/installer_utils/{installer.py → installer_cli.py} +109 -117
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +31 -81
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +44 -74
- machineconfig/utils/io.py +77 -23
- machineconfig/utils/links.py +254 -162
- machineconfig/utils/meta.py +255 -0
- machineconfig/utils/notifications.py +1 -1
- machineconfig/utils/options.py +13 -3
- machineconfig/utils/path_extended.py +46 -100
- machineconfig/utils/path_helper.py +75 -22
- machineconfig/utils/procs.py +50 -70
- machineconfig/utils/scheduler.py +94 -97
- 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 +742 -264
- machineconfig/utils/ssh_utils/utils.py +0 -0
- machineconfig/utils/terminal.py +2 -113
- machineconfig/utils/tst.py +20 -0
- machineconfig/utils/upgrade_packages.py +109 -28
- machineconfig/utils/ve.py +11 -4
- machineconfig-7.66.dist-info/METADATA +124 -0
- machineconfig-7.66.dist-info/RECORD +451 -0
- machineconfig-7.66.dist-info/entry_points.txt +15 -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/fzffg +0 -25
- 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/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/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/dotfile.py +0 -78
- machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
- 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/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/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-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/helpers_agents}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers → 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.bat → 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/{jobs/windows/msc/cli_agents.ps1 → scripts/python/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/python/{fire_jobs_streamlit_helper.py → helpers_devops/__init__.py} +0 -0
- /machineconfig/scripts/{windows/share_nfs.ps1 → 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_msearch/scripts_linux}/skrg +0 -0
- /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfb.ps1 +0 -0
- /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfg.ps1 +0 -0
- /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfrga.bat +0 -0
- /machineconfig/scripts/{linux → python/nw}/mount_drive +0 -0
- /machineconfig/scripts/python/{mount_nw_drive.py → nw/mount_nw_drive.py} +0 -0
- /machineconfig/scripts/{linux → python/nw}/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.66.dist-info}/WHEEL +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.66.dist-info}/top_level.txt +0 -0
|
@@ -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:
|
|
84
|
+
from machineconfig.utils.options import choose_from_options
|
|
86
85
|
choice = choose_from_options(multi=False, msg="Multiple matches found", options=reduced_scripts, fzf=True)
|
|
87
|
-
return
|
|
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, fzf=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
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import psutil
|
|
4
4
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
5
|
-
from zoneinfo import ZoneInfo
|
|
6
5
|
from machineconfig.utils.options import choose_from_options
|
|
7
|
-
from typing import Optional,
|
|
6
|
+
from typing import Optional, TypedDict, List, Dict
|
|
8
7
|
from rich.console import Console
|
|
9
8
|
from rich.panel import Panel
|
|
10
|
-
from datetime import datetime
|
|
9
|
+
from datetime import datetime
|
|
11
10
|
from machineconfig.utils.accessories import pprint
|
|
12
11
|
|
|
13
12
|
console = Console()
|
|
@@ -15,11 +14,29 @@ console = Console()
|
|
|
15
14
|
BOX_WIDTH = 78 # width for box drawing
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
class ProcessInfo(TypedDict):
|
|
18
|
+
"""TypedDict for process information."""
|
|
19
|
+
command: str
|
|
20
|
+
pid: int
|
|
21
|
+
name: str
|
|
22
|
+
username: str
|
|
23
|
+
cpu_percent: float
|
|
24
|
+
memory_usage_mb: float
|
|
25
|
+
status: str
|
|
26
|
+
create_time: datetime
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class FileAccessInfo(TypedDict):
|
|
30
|
+
"""TypedDict for file access information."""
|
|
31
|
+
pid: int
|
|
32
|
+
files: List[str]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_processes_accessing_file(path: str) -> List[FileAccessInfo]:
|
|
19
36
|
# header for searching processes
|
|
20
37
|
title = "🔍 SEARCHING FOR PROCESSES ACCESSING FILE"
|
|
21
38
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
22
|
-
res:
|
|
39
|
+
res: Dict[int, List[str]] = {}
|
|
23
40
|
|
|
24
41
|
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
|
|
25
42
|
progress.add_task("🔎 Scanning processes...", total=None)
|
|
@@ -34,22 +51,22 @@ def get_processes_accessing_file(path: str):
|
|
|
34
51
|
res[proc.pid] = tmp
|
|
35
52
|
|
|
36
53
|
# Convert to list of dictionaries for consistent data structure
|
|
37
|
-
result_data = [{"pid": pid, "files": files} for pid, files in res.items()]
|
|
54
|
+
result_data: List[FileAccessInfo] = [{"pid": pid, "files": files} for pid, files in res.items()]
|
|
38
55
|
console.print(Panel(f"✅ Found {len(res)} processes accessing the specified file", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
39
56
|
return result_data
|
|
40
57
|
|
|
41
58
|
|
|
42
59
|
def kill_process(name: str):
|
|
43
|
-
print(f"⚠️ Attempting to kill process: {name}...")
|
|
60
|
+
console.print(f"⚠️ Attempting to kill process: {name}...", style="yellow")
|
|
44
61
|
killed = False
|
|
45
62
|
for proc in psutil.process_iter():
|
|
46
63
|
if proc.name() == name:
|
|
47
64
|
proc.kill()
|
|
48
|
-
print(f"💀 Process {name} (PID: {proc.pid}) terminated successfully")
|
|
65
|
+
console.print(f"💀 Process {name} (PID: {proc.pid}) terminated successfully", style="green")
|
|
49
66
|
killed = True
|
|
50
67
|
if not killed:
|
|
51
|
-
print(f"❓ No process with name '{name}' was found")
|
|
52
|
-
|
|
68
|
+
console.print(f"❓ No process with name '{name}' was found", style="red")
|
|
69
|
+
console.rule(style="dim")
|
|
53
70
|
|
|
54
71
|
|
|
55
72
|
class ProcessManager:
|
|
@@ -57,15 +74,13 @@ class ProcessManager:
|
|
|
57
74
|
# header for initializing process manager
|
|
58
75
|
title = "📊 INITIALIZING PROCESS MANAGER"
|
|
59
76
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
60
|
-
process_info = []
|
|
77
|
+
process_info: List[ProcessInfo] = []
|
|
61
78
|
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
|
|
62
79
|
progress.add_task("🔍 Reading system processes...", total=None)
|
|
63
80
|
for proc in psutil.process_iter():
|
|
64
81
|
try:
|
|
65
82
|
mem_usage_mb = proc.memory_info().rss / (1024 * 1024)
|
|
66
|
-
|
|
67
|
-
create_time_utc = datetime.fromtimestamp(proc.create_time(), tz=timezone.utc)
|
|
68
|
-
create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
|
|
83
|
+
create_time = datetime.fromtimestamp(proc.create_time(), tz=None)
|
|
69
84
|
|
|
70
85
|
process_info.append(
|
|
71
86
|
{
|
|
@@ -75,7 +90,7 @@ class ProcessManager:
|
|
|
75
90
|
"cpu_percent": proc.cpu_percent(),
|
|
76
91
|
"memory_usage_mb": mem_usage_mb,
|
|
77
92
|
"status": proc.status(),
|
|
78
|
-
"create_time":
|
|
93
|
+
"create_time": create_time,
|
|
79
94
|
"command": " ".join(proc.cmdline()),
|
|
80
95
|
}
|
|
81
96
|
)
|
|
@@ -91,57 +106,51 @@ class ProcessManager:
|
|
|
91
106
|
"""Format process data as table string for display."""
|
|
92
107
|
if not self.data:
|
|
93
108
|
return ""
|
|
94
|
-
|
|
95
109
|
# Create header
|
|
96
|
-
_headers = ["PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time"
|
|
97
|
-
header_line = f"{'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20}
|
|
110
|
+
_headers = ["Command", "PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time"]
|
|
111
|
+
header_line = f"{'Command':<50} {'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20}"
|
|
98
112
|
separator = "-" * len(header_line)
|
|
99
|
-
|
|
100
113
|
lines = [header_line, separator]
|
|
101
|
-
|
|
102
114
|
for process in self.data:
|
|
103
115
|
# Format create_time as string
|
|
104
116
|
create_time_str = process["create_time"].strftime("%Y-%m-%d %H:%M:%S")
|
|
105
117
|
# Truncate command if too long
|
|
106
118
|
command = process["command"][:47] + "..." if len(process["command"]) > 50 else process["command"]
|
|
107
|
-
|
|
108
|
-
line = f"{process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20} {command:<50}"
|
|
119
|
+
line = f"{command:<50} {process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20}"
|
|
109
120
|
lines.append(line)
|
|
110
|
-
|
|
111
121
|
return "\n".join(lines)
|
|
112
122
|
|
|
113
123
|
def choose_and_kill(self):
|
|
114
124
|
# header for interactive process selection
|
|
115
125
|
title = "🎯 INTERACTIVE PROCESS SELECTION AND TERMINATION"
|
|
116
126
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
117
|
-
|
|
118
127
|
# Format data as table for display
|
|
119
128
|
formatted_data = self._format_process_table()
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
all_lines = formatted_data.split("\n")
|
|
130
|
+
header_and_separator = all_lines[:2] # First two lines: header and separator
|
|
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:", fzf=True, multi=True)
|
|
133
|
+
# Filter out header and separator if they were selected
|
|
134
|
+
selected_lines = [line for line in res if line not in header_and_separator]
|
|
135
|
+
indices = [options.index(val) for val in selected_lines]
|
|
123
136
|
selected_processes = [self.data[i] for i in indices]
|
|
124
|
-
|
|
125
137
|
print("\n📊 All Processes:")
|
|
126
138
|
print(formatted_data)
|
|
127
139
|
print("\n🎯 Selected Processes:")
|
|
128
140
|
for process in selected_processes:
|
|
129
141
|
print(f"PID: {process['pid']}, Name: {process['name']}, Memory: {process['memory_usage_mb']:.2f}MB")
|
|
130
|
-
|
|
131
142
|
for idx, process in enumerate(selected_processes):
|
|
132
|
-
pprint(process, f"📌 Process {idx}")
|
|
133
|
-
|
|
143
|
+
pprint(dict(process), f"📌 Process {idx}")
|
|
134
144
|
kill_all = input("\n⚠️ Confirm killing ALL selected processes? y/[n] ").lower() == "y"
|
|
135
145
|
if kill_all:
|
|
136
146
|
self.kill(pids=[p["pid"] for p in selected_processes])
|
|
137
147
|
return
|
|
138
|
-
|
|
139
148
|
kill_by_index = input("\n🔫 Kill by index? (enter numbers separated by spaces, e.g. '1 4') or [n] to cancel: ")
|
|
140
149
|
if kill_by_index != "" and kill_by_index != "n":
|
|
141
150
|
indices = [int(val) for val in kill_by_index.split(" ")]
|
|
142
151
|
target_processes = [selected_processes[i] for i in indices]
|
|
143
152
|
for idx2, process in enumerate(target_processes):
|
|
144
|
-
pprint(process, f"🎯 Target Process {idx2}")
|
|
153
|
+
pprint(dict(process), f"🎯 Target Process {idx2}")
|
|
145
154
|
_ = self.kill(pids=[p["pid"] for p in target_processes]) if input("\n⚠️ Confirm termination? y/[n] ").lower() == "y" else None
|
|
146
155
|
console.print(Panel("🔔 No processes were terminated.", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
147
156
|
|
|
@@ -149,12 +158,10 @@ class ProcessManager:
|
|
|
149
158
|
# header for filtering processes by name
|
|
150
159
|
title = "🔍 FILTERING AND TERMINATING PROCESSES BY NAME"
|
|
151
160
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
152
|
-
|
|
153
161
|
# Filter processes by name
|
|
154
162
|
filtered_processes = [p for p in self.data if p["name"] == name]
|
|
155
163
|
# Sort by create_time (ascending)
|
|
156
164
|
filtered_processes.sort(key=lambda x: x["create_time"])
|
|
157
|
-
|
|
158
165
|
print(f"🎯 Found {len(filtered_processes)} processes matching name: '{name}'")
|
|
159
166
|
self.kill(pids=[p["pid"] for p in filtered_processes])
|
|
160
167
|
console.print(Panel("", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
@@ -171,69 +178,42 @@ class ProcessManager:
|
|
|
171
178
|
pids = []
|
|
172
179
|
if commands is None:
|
|
173
180
|
commands = []
|
|
174
|
-
|
|
175
181
|
killed_count = 0
|
|
176
|
-
|
|
177
182
|
for name in names:
|
|
178
183
|
matching_processes = [p for p in self.data if p["name"] == name]
|
|
179
184
|
if len(matching_processes) > 0:
|
|
180
185
|
for process in matching_processes:
|
|
181
186
|
psutil.Process(process["pid"]).kill()
|
|
182
|
-
print(f"💀 Killed process {name} with PID {process['pid']}. It lived {get_age(process['create_time'])}. RIP
|
|
187
|
+
print(f"💀 Killed process {name} with PID {process['pid']}. It lived {get_age(process['create_time'])}. RIP 💐")
|
|
183
188
|
killed_count += 1
|
|
184
189
|
else:
|
|
185
190
|
print(f'❓ No process named "{name}" found')
|
|
186
|
-
|
|
187
191
|
for pid in pids:
|
|
188
192
|
try:
|
|
189
193
|
proc = psutil.Process(pid)
|
|
190
194
|
proc_name = proc.name()
|
|
191
|
-
proc_lifetime = get_age(proc.create_time())
|
|
195
|
+
proc_lifetime = get_age(datetime.fromtimestamp(proc.create_time(), tz=None))
|
|
192
196
|
proc.kill()
|
|
193
|
-
print(f'💀 Killed process with PID {pid} and name "{proc_name}". It lived {proc_lifetime}. RIP
|
|
197
|
+
print(f'💀 Killed process with PID {pid} and name "{proc_name}". It lived {proc_lifetime}. RIP 💐')
|
|
194
198
|
killed_count += 1
|
|
195
199
|
except psutil.NoSuchProcess:
|
|
196
200
|
print(f"❓ No process with PID {pid} found")
|
|
197
|
-
|
|
198
201
|
for command in commands:
|
|
199
202
|
matching_processes = [p for p in self.data if command in p["command"]]
|
|
200
203
|
if len(matching_processes) > 0:
|
|
201
204
|
for process in matching_processes:
|
|
202
205
|
psutil.Process(process["pid"]).kill()
|
|
203
|
-
print(f'💀 Killed process with "{command}" in its command & PID {process["pid"]}. It lived {get_age(process["create_time"])}. RIP
|
|
206
|
+
print(f'💀 Killed process with "{command}" in its command & PID {process["pid"]}. It lived {get_age(process["create_time"])}. RIP 💐')
|
|
204
207
|
killed_count += 1
|
|
205
208
|
else:
|
|
206
209
|
print(f'❓ No process has "{command}" in its command.')
|
|
207
|
-
|
|
208
210
|
console.print(Panel(f"✅ Termination complete: {killed_count} processes terminated", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
209
211
|
|
|
210
212
|
|
|
211
|
-
def get_age(create_time:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# Handle timestampz
|
|
216
|
-
create_time_utc = datetime.fromtimestamp(create_time, tz=timezone.utc)
|
|
217
|
-
create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
|
|
218
|
-
else:
|
|
219
|
-
# Already a datetime object
|
|
220
|
-
create_time_local = create_time
|
|
221
|
-
|
|
222
|
-
now_local = datetime.now(tz=ZoneInfo("Australia/Adelaide"))
|
|
223
|
-
age = now_local - create_time_local
|
|
224
|
-
return str(age)
|
|
225
|
-
except Exception as e:
|
|
226
|
-
try:
|
|
227
|
-
# Fallback without timezone
|
|
228
|
-
if isinstance(create_time, (int, float)):
|
|
229
|
-
create_time_dt = datetime.fromtimestamp(create_time)
|
|
230
|
-
else:
|
|
231
|
-
create_time_dt = create_time.replace(tzinfo=None) if create_time.tzinfo else create_time
|
|
232
|
-
now_dt = datetime.now()
|
|
233
|
-
age = now_dt - create_time_dt
|
|
234
|
-
return str(age)
|
|
235
|
-
except Exception as ee:
|
|
236
|
-
return f"unknown due to {ee} and {e}"
|
|
213
|
+
def get_age(create_time: datetime) -> str:
|
|
214
|
+
dtm_now = datetime.now()
|
|
215
|
+
delta = dtm_now - create_time
|
|
216
|
+
return str(delta).split(".")[0] # remove microseconds
|
|
237
217
|
|
|
238
218
|
|
|
239
219
|
def main():
|