Add Auto Setup scripts
This commit is contained in:
parent
ae4a72036d
commit
e485cc9674
3 changed files with 461 additions and 1 deletions
176
scripts/auto_setup.py
Normal file
176
scripts/auto_setup.py
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
"""Wizard Kit: Auto System Setup Tool"""
|
||||
# vim: sts=2 sw=2 ts=2
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
||||
sys.path.append(os.getcwd())
|
||||
import wk # pylint: disable=wrong-import-position
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
PRESETS = {
|
||||
'Additional User': {
|
||||
'Configure System': (
|
||||
'Chrome Notifications',
|
||||
'Open Shell',
|
||||
'uBlock Origin',
|
||||
'Enable BSoD MiniDumps',
|
||||
'Enable RegBack',
|
||||
'Enable System Restore',
|
||||
'Set System Restore Size',
|
||||
'Enable Windows Updates',
|
||||
'Windows Explorer',
|
||||
),
|
||||
'System Summary': (
|
||||
'Operating System',
|
||||
'Windows Activation',
|
||||
'Secure Boot',
|
||||
'Installed RAM',
|
||||
'Storage Volumes',
|
||||
'Virus Protection',
|
||||
'Partitions 4K Aligned',
|
||||
),
|
||||
},
|
||||
'Hardware': {
|
||||
'Configure System': (
|
||||
'Enable BSoD MiniDumps',
|
||||
'Enable RegBack',
|
||||
'Enable System Restore',
|
||||
'Set System Restore Size',
|
||||
'Enable Windows Updates',
|
||||
),
|
||||
'System Information': (
|
||||
'Backup Registry',
|
||||
),
|
||||
'System Summary': (
|
||||
'Operating System',
|
||||
'Windows Activation',
|
||||
'Secure Boot',
|
||||
'Installed RAM',
|
||||
'Storage Volumes',
|
||||
'Virus Protection',
|
||||
'Partitions 4K Aligned',
|
||||
),
|
||||
'Run Programs': (
|
||||
'Device Manager',
|
||||
'HWiNFO Sensors',
|
||||
'XMPlay',
|
||||
),
|
||||
},
|
||||
'Verify': {
|
||||
'Configure System': (
|
||||
'Enable BSoD MiniDumps',
|
||||
'Enable RegBack',
|
||||
'Enable System Restore',
|
||||
'Set System Restore Size',
|
||||
'Enable Windows Updates',
|
||||
'Windows Explorer',
|
||||
),
|
||||
'System Summary': (
|
||||
'Operating System',
|
||||
'Windows Activation',
|
||||
'Secure Boot',
|
||||
'Installed RAM',
|
||||
'Storage Volumes',
|
||||
'Virus Protection',
|
||||
'Installed Office',
|
||||
'Partitions 4K Aligned',
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
# Classes
|
||||
class MenuEntry():
|
||||
# pylint: disable=too-few-public-methods
|
||||
"""Simple class to allow cleaner code below."""
|
||||
def __init__(self, name, function=None, **kwargs):
|
||||
self.name = name
|
||||
self.details = {
|
||||
'Function': function,
|
||||
'Selected': True,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
|
||||
# TODO: DELETEME
|
||||
def no_op(*args):
|
||||
"""No Op"""
|
||||
|
||||
# STATIC VARIABLES
|
||||
BASE_MENUS = {
|
||||
'Groups': {
|
||||
'Backup Settings': (
|
||||
# Add checks for existing backups and skip if detected
|
||||
MenuEntry('Backup Browsers', 'auto_backup_browser_profiles'),
|
||||
MenuEntry('Backup Power Plans', 'auto_backup_power_plans'),
|
||||
MenuEntry('Reset Power Plans', 'auto_reset_power_plans'),
|
||||
MenuEntry('Set Custom Power Plan', 'auto_set_custom_power_plan'),
|
||||
),
|
||||
'Install Software': (
|
||||
MenuEntry('Visual C++ Runtimes', no_op), # only 2012, 2013, & 2019 rest are EOL
|
||||
#MenuEntry('ESET NOD32 Antivirus', no_op),
|
||||
MenuEntry('LibreOffice', no_op),
|
||||
MenuEntry('Open Shell Skin', no_op),
|
||||
MenuEntry('uBlock Origin', no_op),
|
||||
MenuEntry('Software Bundle', no_op), # include FF x32 -> x64 convertion?
|
||||
),
|
||||
'Configure System': (
|
||||
MenuEntry('Chrome Notifications', no_op),
|
||||
#MenuEntry('O&O ShutUp 10', no_op),
|
||||
MenuEntry('Open Shell', no_op),
|
||||
MenuEntry('uBlock Origin', no_op),
|
||||
#MenuEntry('Disable Fast Startup', no_op),
|
||||
MenuEntry('Enable BSoD MiniDumps', no_op),
|
||||
#MenuEntry('Enable Hibernation', no_op),
|
||||
MenuEntry('Enable RegBack', 'auto_enable_regback'),
|
||||
MenuEntry('Enable System Restore', 'auto_system_restore_enable'),
|
||||
MenuEntry('Set System Restore Size', 'auto_system_restore_set_size'),
|
||||
MenuEntry('Create System Restore', 'auto_system_restore_create'),
|
||||
MenuEntry('Enable Windows Updates', 'auto_windows_updates_enable'),
|
||||
MenuEntry('User Account Control', no_op),
|
||||
MenuEntry('Windows Activation', no_op),
|
||||
MenuEntry('Windows Explorer', no_op),
|
||||
MenuEntry(r'Windows\Temp Fix', no_op),
|
||||
),
|
||||
'System Information': (
|
||||
MenuEntry('AIDA64 Reports', no_op),
|
||||
MenuEntry('Backup Registry', 'auto_backup_registry'),
|
||||
MenuEntry('Everything (File List)', no_op),
|
||||
),
|
||||
'System Summary': (
|
||||
MenuEntry('Operating System', no_op),
|
||||
MenuEntry('Windows Activation', no_op),
|
||||
MenuEntry('Secure Boot', no_op),
|
||||
MenuEntry('Installed RAM', no_op),
|
||||
MenuEntry('Storage Volumes', no_op),
|
||||
MenuEntry('Virus Protection', no_op),
|
||||
MenuEntry('Partitions 4K Aligned', no_op),
|
||||
),
|
||||
'Run Programs': (
|
||||
MenuEntry('Device Manager', no_op),
|
||||
MenuEntry('HWiNFO Sensors', no_op),
|
||||
#MenuEntry('Snappy Driver Installer', no_op),
|
||||
MenuEntry('Windows Updates', no_op),
|
||||
MenuEntry('Windows Activation', no_op),
|
||||
MenuEntry('XMPlay', no_op),
|
||||
),
|
||||
},
|
||||
'Actions': (
|
||||
MenuEntry('Load Preset'),
|
||||
MenuEntry('Start', Separator=True),
|
||||
MenuEntry('Quit'),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
wk.setup.win.run_auto_setup(BASE_MENUS, PRESETS)
|
||||
except KeyboardInterrupt:
|
||||
wk.std.abort()
|
||||
except SystemExit:
|
||||
raise
|
||||
except: #pylint: disable=bare-except
|
||||
wk.std.major_exception()
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
import pathlib
|
||||
import platform
|
||||
import sys
|
||||
|
||||
import requests
|
||||
|
|
@ -15,7 +16,7 @@ from wk.std import GenericError
|
|||
|
||||
|
||||
# STATIC VARIABLES
|
||||
ARCH = '64' if sys.maxsize > 2**32 else '32'
|
||||
ARCH = '64' if platform.architecture()[0] == '64bit' else '32'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
|
|||
283
scripts/wk/setup/win.py
Normal file
283
scripts/wk/setup/win.py
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
"""WizardKit: Setup - Windows"""
|
||||
# vim: sts=2 sw=2 ts=2
|
||||
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
from subprocess import CalledProcessError, DEVNULL
|
||||
|
||||
from wk.cfg.main import KIT_NAME_FULL, KIT_NAME_SHORT
|
||||
from wk.exe import (
|
||||
get_procs,
|
||||
run_program,
|
||||
popen_program,
|
||||
wait_for_procs,
|
||||
)
|
||||
from wk.io import (
|
||||
delete_folder,
|
||||
get_path_obj,
|
||||
non_clobber_path,
|
||||
rename_item,
|
||||
)
|
||||
from wk.kit.tools import (
|
||||
ARCH,
|
||||
download_tool,
|
||||
extract_tool,
|
||||
get_tool_path,
|
||||
run_tool,
|
||||
)
|
||||
from wk.log import format_log_path, update_log_path
|
||||
from wk.os.win import (
|
||||
reg_delete_value,
|
||||
reg_read_value,
|
||||
reg_set_value,
|
||||
reg_write_settings,
|
||||
disable_service,
|
||||
enable_service,
|
||||
stop_service,
|
||||
)
|
||||
from wk.repairs.win import (
|
||||
auto_backup_registry,
|
||||
auto_backup_browser_profiles,
|
||||
auto_backup_power_plans,
|
||||
auto_reset_power_plans,
|
||||
auto_set_custom_power_plan,
|
||||
auto_enable_regback,
|
||||
auto_system_restore_enable,
|
||||
auto_system_restore_set_size,
|
||||
auto_system_restore_create,
|
||||
auto_windows_updates_enable,
|
||||
)
|
||||
from wk.std import (
|
||||
GenericError,
|
||||
GenericWarning,
|
||||
Menu,
|
||||
TryAndPrint,
|
||||
abort,
|
||||
ask,
|
||||
clear_screen,
|
||||
color_string,
|
||||
pause,
|
||||
print_info,
|
||||
print_standard,
|
||||
print_warning,
|
||||
set_title,
|
||||
show_data,
|
||||
sleep,
|
||||
strip_colors,
|
||||
)
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONEMU_EXE = get_tool_path('ConEmu', 'ConEmu', check=False)
|
||||
IN_CONEMU = 'ConEmuPID' in os.environ
|
||||
MENU_PRESETS = Menu()
|
||||
PROGRAMFILES_32 = os.environ.get(
|
||||
'PROGRAMFILES(X86)', os.environ.get(
|
||||
'PROGRAMFILES', r'C:\Program Files (x86)',
|
||||
),
|
||||
)
|
||||
OS_VERSION = float(platform.win32_ver()[0])
|
||||
SYSTEMDRIVE = os.environ.get('SYSTEMDRIVE', 'C:')
|
||||
WIDTH = 50
|
||||
TRY_PRINT = TryAndPrint()
|
||||
TRY_PRINT.width = WIDTH
|
||||
TRY_PRINT.verbose = True
|
||||
for error in ('CalledProcessError', 'FileNotFoundError'):
|
||||
TRY_PRINT.add_error(error)
|
||||
|
||||
|
||||
# Auto Setup
|
||||
def build_menus(base_menus, title, presets):
|
||||
"""Build menus, returns dict."""
|
||||
menus = {}
|
||||
menus['Main'] = Menu(title=f'{title}\n{color_string("Main Menu", "GREEN")}')
|
||||
|
||||
# Main Menu
|
||||
for entry in base_menus['Actions']:
|
||||
menus['Main'].add_action(entry.name, entry.details)
|
||||
for group in base_menus['Groups']:
|
||||
menus['Main'].add_option(group, {'Selected': True})
|
||||
|
||||
# Run groups
|
||||
for group, entries in base_menus['Groups'].items():
|
||||
menus[group] = Menu(title=f'{title}\n{color_string(group, "GREEN")}')
|
||||
for entry in entries:
|
||||
menus[group].add_option(entry.name, entry.details)
|
||||
menus[group].add_action('All')
|
||||
menus[group].add_action('None')
|
||||
menus[group].add_action('Main Menu', {'Separator': True})
|
||||
menus[group].add_action('Quit')
|
||||
|
||||
# Initialize main menu display names
|
||||
menus['Main'].update()
|
||||
|
||||
# Fix Function references
|
||||
for group, menu in menus.items():
|
||||
if group not in base_menus['Groups']:
|
||||
continue
|
||||
for name in menu.options:
|
||||
_function = menu.options[name]['Function']
|
||||
if isinstance(_function, str):
|
||||
menu.options[name]['Function'] = getattr(
|
||||
sys.modules[__name__], _function,
|
||||
)
|
||||
|
||||
# Update presets Menu
|
||||
MENU_PRESETS.title = f'{title}\n{color_string("Load Preset", "GREEN")}'
|
||||
MENU_PRESETS.add_option('Default')
|
||||
for name in presets:
|
||||
MENU_PRESETS.add_option(name)
|
||||
MENU_PRESETS.add_action('Main Menu')
|
||||
MENU_PRESETS.add_action('Quit')
|
||||
MENU_PRESETS.update()
|
||||
|
||||
# Done
|
||||
return menus
|
||||
|
||||
|
||||
def load_preset(menus, presets):
|
||||
"""Load menu settings from preset."""
|
||||
selection = MENU_PRESETS.simple_select()
|
||||
|
||||
# Exit early
|
||||
if 'Main Menu' in selection:
|
||||
return
|
||||
if 'Quit' in selection:
|
||||
raise SystemExit
|
||||
|
||||
# Default case
|
||||
if 'Default' in selection:
|
||||
for menu in menus.values():
|
||||
for name in menu.options:
|
||||
menu.options[name]['Selected'] = True
|
||||
return
|
||||
|
||||
# Load preset
|
||||
preset = presets[selection[0]]
|
||||
for group, menu in menus.items():
|
||||
group_enabled = group in preset
|
||||
for name in menu.options:
|
||||
value = group_enabled and name in preset[group]
|
||||
menu.options[name]['Selected'] = value
|
||||
|
||||
|
||||
def run_auto_setup(base_menus, presets):
|
||||
"""Run Auto Setup."""
|
||||
update_log_path(dest_name='Auto Setup', timestamp=True)
|
||||
title = f'{KIT_NAME_FULL}: Auto Setup'
|
||||
clear_screen()
|
||||
set_title(title)
|
||||
print_info(title)
|
||||
print('')
|
||||
|
||||
# Generate menus
|
||||
print_standard('Initializing...')
|
||||
menus = build_menus(base_menus, title, presets)
|
||||
|
||||
# Show Menu
|
||||
show_main_menu(base_menus, menus, presets)
|
||||
|
||||
# Start setup
|
||||
clear_screen()
|
||||
print_standard(title)
|
||||
print('')
|
||||
print_info('Running setup')
|
||||
|
||||
# Run setup
|
||||
for group, menu in menus.items():
|
||||
if group in ('Main', 'Options'):
|
||||
continue
|
||||
try:
|
||||
run_group(group, menu)
|
||||
except KeyboardInterrupt:
|
||||
abort()
|
||||
|
||||
# Done
|
||||
print_info('Done')
|
||||
pause('Press Enter to exit...')
|
||||
|
||||
|
||||
def run_group(group, menu):
|
||||
"""Run entries in group if appropriate."""
|
||||
print_info(f' {group}')
|
||||
for name, details in menu.options.items():
|
||||
name_str = strip_colors(name)
|
||||
|
||||
# Not selected
|
||||
if not details.get('Selected', False):
|
||||
show_data(f'{name_str}...', 'Skipped', 'YELLOW', width=WIDTH)
|
||||
continue
|
||||
|
||||
# Selected
|
||||
details['Function'](group, name)
|
||||
|
||||
|
||||
def show_main_menu(base_menus, menus, presets):
|
||||
"""Show main menu and handle actions."""
|
||||
while True:
|
||||
update_main_menu(menus)
|
||||
selection = menus['Main'].simple_select(update=False)
|
||||
if selection[0] in base_menus['Groups'] or selection[0] == 'Options':
|
||||
show_sub_menu(menus[selection[0]])
|
||||
if selection[0] == 'Load Preset':
|
||||
load_preset(menus, presets)
|
||||
elif 'Start' in selection:
|
||||
break
|
||||
elif 'Quit' in selection:
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def show_sub_menu(menu):
|
||||
"""Show sub-menu and handle sub-menu actions."""
|
||||
while True:
|
||||
selection = menu.advanced_select()
|
||||
if 'Main Menu' in selection:
|
||||
break
|
||||
if 'Quit' in selection:
|
||||
raise SystemExit
|
||||
|
||||
# Select all or none
|
||||
value = 'All' in selection
|
||||
for name in menu.options:
|
||||
if not menu.options[name].get('Disabled', False):
|
||||
menu.options[name]['Selected'] = value
|
||||
|
||||
|
||||
def update_main_menu(menus):
|
||||
"""Update main menu based on current selections."""
|
||||
index = 1
|
||||
skip = 'Reboot'
|
||||
for name in menus['Main'].options:
|
||||
checkmark = ' '
|
||||
selected = [
|
||||
_v['Selected'] for _k, _v in menus[name].options.items() if _k != skip
|
||||
]
|
||||
if all(selected):
|
||||
checkmark = '✓'
|
||||
elif any(selected):
|
||||
checkmark = '-'
|
||||
display_name = f' {index}: [{checkmark}] {name}'
|
||||
index += 1
|
||||
menus['Main'].options[name]['Display Name'] = display_name
|
||||
|
||||
|
||||
# Auto Setup: Wrapper Functions
|
||||
## TODO
|
||||
|
||||
# Misc Functions
|
||||
## TODO?
|
||||
|
||||
# Tool Functions
|
||||
## TODO?
|
||||
|
||||
# OS Built-in Functions
|
||||
## TODO?
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
Loading…
Reference in a new issue