diff --git a/scripts/wk/cfg/setup.py b/scripts/wk/cfg/setup.py index 5ad229fa..38655b7c 100644 --- a/scripts/wk/cfg/setup.py +++ b/scripts/wk/cfg/setup.py @@ -120,7 +120,7 @@ REG_OPEN_SHELL_SETTINGS = { ( 'SkinOptionsW7', [ - # NOTE: Seems to need all options specified to work? + # NOTE: All options need to be specified to work 'DARK_MAIN=1', 'METRO_MAIN=0', 'LIGHT_MAIN=0', 'AUTOMODE_MAIN=0', 'DARK_SUBMENU=0', 'METRO_SUBMENU=0', 'LIGHT_SUBMENU=0', 'AUTOMODE_SUBMENU=1', 'SUBMENU_SEPARATORS=1', 'DARK_SEARCH=0', 'METRO_SEARCH=0', 'LIGHT_SEARCH=1', @@ -143,6 +143,56 @@ REG_OPEN_SHELL_SETTINGS = { ), }, } +REG_OPEN_SHELL_LOW_POWER_IDLE = { + 'HKCU': { + r'Software\OpenShell\StartMenu': ( + ( + 'CSettingsDlg', + b'h\x02\x00\x00\xa7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\r\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00', + 'BINARY', + ), + ( + 'CEditMenuDlg7', + b'\xde\x02\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + 'BINARY', + ), + ), + r'Software\OpenShell\StartMenu\Settings': ( + ('ShutdownW7', 'switch_user, logoff, lock, restart, hibernate', 'SZ'), + ( + 'MenuItems7', + [ + 'Item1.Command=user_files', 'Item1.Settings=NOEXPAND', + 'Item2.Command=user_documents', 'Item2.Settings=NOEXPAND', + 'Item3.Command=user_pictures', 'Item3.Settings=NOEXPAND', + 'Item4.Command=user_music', 'Item4.Settings=NOEXPAND', + 'Item5.Command=user_videos', 'Item5.Settings=ITEM_DISABLED', + 'Item6.Command=downloads', 'Item6.Settings=ITEM_DISABLED', + 'Item7.Command=homegroup', 'Item7.Settings=ITEM_DISABLED', + 'Item8.Command=separator', + 'Item9.Command=games', 'Item9.Settings=TRACK_RECENT|NOEXPAND|ITEM_DISABLED', + 'Item10.Command=favorites', 'Item10.Settings=ITEM_DISABLED', + 'Item11.Command=recent_documents', + 'Item12.Command=computer', 'Item12.Settings=NOEXPAND', + 'Item13.Command=network', 'Item13.Settings=ITEM_DISABLED', + 'Item14.Command=network_connections', 'Item14.Settings=ITEM_DISABLED', + 'Item15.Command=separator', + 'Item16.Command=control_panel', 'Item16.Settings=TRACK_RECENT', + 'Item17.Command=pc_settings', 'Item17.Settings=TRACK_RECENT', + 'Item18.Command=admin', 'Item18.Settings=TRACK_RECENT|ITEM_DISABLED', + 'Item19.Command=devices', 'Item19.Settings=NOEXPAND', + 'Item20.Command=defaults', + 'Item21.Command=help', + 'Item22.Command=run', + 'Item23.Command=monitor_off', 'Item23.Label=Sleep', 'Item23.Settings=NOEXPAND', + 'Item24.Command=apps', 'Item24.Settings=ITEM_DISABLED', + 'Item25.Command=windows_security', + ], + 'MULTI_SZ', + ), + ), + }, + } UBLOCK_ORIGIN_URLS = { 'Google Chrome': 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm', 'Microsoft Edge': 'https://microsoftedge.microsoft.com/addons/detail/ublock-origin/odfafepnkmbhccpbejgmiehpchacaeak', diff --git a/scripts/wk/clone/ddrescue.py b/scripts/wk/clone/ddrescue.py index 036673d6..07f65423 100644 --- a/scripts/wk/clone/ddrescue.py +++ b/scripts/wk/clone/ddrescue.py @@ -252,28 +252,34 @@ class BlockPair(): self.map_data.update(data) def pass_complete(self, pass_name): - """Check if pass_num is complete based on map data, returns bool.""" - complete = False - pending_size = 0 + """Check if pass_name is complete based on map data, returns bool.""" + pending_size = self.map_data['non-tried'] - # Check map data + # Full recovery if self.map_data.get('full recovery', False): - complete = True - elif 'non-tried' not in self.map_data: - # Assuming recovery has not been attempted yet - complete = False - else: - # Check that current and previous passes are complete - pending_size = self.map_data['non-tried'] - if pass_name in ('trim', 'scrape'): - pending_size += self.map_data['non-trimmed'] - if pass_name == 'scrape': - pending_size += self.map_data['non-scraped'] - if pending_size == 0: - complete = True + return True - # Done - return complete + # New recovery + if 'non-tried' not in self.map_data: + return False + + # Initial read skip pass + if pass_name == 'read-skip': + pass_threshold = cfg.ddrescue.AUTO_PASS_THRESHOLDS[pass_name] + if self.get_percent_recovered() >= pass_threshold: + return True + + # Recovery in progress + if pass_name in ('trim', 'scrape'): + pending_size += self.map_data['non-trimmed'] + if pass_name == 'scrape': + pending_size += self.map_data['non-scraped'] + if pending_size == 0: + # This is true when the previous and current passes are complete + return True + + # This should never be reached + return False def reset_progress(self): """Reset progress to start fresh recovery.""" diff --git a/scripts/wk/setup/win.py b/scripts/wk/setup/win.py index d61e7cd6..3bd8bcc8 100644 --- a/scripts/wk/setup/win.py +++ b/scripts/wk/setup/win.py @@ -20,6 +20,7 @@ from wk.cfg.setup import ( REG_CHROME_UBLOCK_ORIGIN, REG_WINDOWS_EXPLORER, REG_OPEN_SHELL_SETTINGS, + REG_OPEN_SHELL_LOW_POWER_IDLE, UBLOCK_ORIGIN_URLS, ) from wk.exe import kill_procs, run_program, popen_program @@ -467,7 +468,7 @@ def auto_config_explorer(): def auto_config_open_shell(): """Configure Open Shell.""" - TRY_PRINT.run('Open Shell...', reg_write_settings, REG_OPEN_SHELL_SETTINGS) + TRY_PRINT.run('Open Shell...', config_open_shell) def auto_disable_fast_startup(): @@ -626,6 +627,26 @@ def config_explorer(): popen_program(['explorer.exe']) +def config_open_shell(): + """Configure Open Shell.""" + has_low_power_idle = False + + # Check if the system supports S0 Low Power Idle + proc = run_program(['powercfg', '/AvailableSleepStates'], check=False) + for line in proc.stdout.splitlines(): + if 'Low Power Idle' in line: + # NOTE: This is safe since we break before the listed unsupported states + has_low_power_idle = True + break + if line.startswith('The following sleep states are not available'): + break + + # Apply registry settings + reg_write_settings(REG_OPEN_SHELL_SETTINGS) + if has_low_power_idle: + reg_write_settings(REG_OPEN_SHELL_LOW_POWER_IDLE) + + def disable_chrome_notifications(): """Disable notifications in Google Chrome.""" defaults_key = 'default_content_setting_values' diff --git a/scripts/wk/std.py b/scripts/wk/std.py index f86da901..793a5319 100644 --- a/scripts/wk/std.py +++ b/scripts/wk/std.py @@ -134,7 +134,7 @@ class Menu(): def _get_display_name( self, name, details, index=None, no_checkboxes=True, setting_item=False): - # pylint: disable=no-self-use,too-many-arguments + # pylint: disable=too-many-arguments """Format display name based on details and args, returns str.""" disabled = details.get('Disabled', False) if setting_item and not details['Selected']: @@ -503,7 +503,6 @@ class TryAndPrint(): @cache def _get_exception(self, name): - # pylint: disable=no-self-use """Get exception by name, returns exception object. [Doctest]