Added extra line break after classes/functions/etc

* Also reordered some class/regex/static sections
This commit is contained in:
2Shirt 2018-12-27 21:33:37 -07:00
parent 3b4668e61b
commit d0c49240d8
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
23 changed files with 430 additions and 92 deletions

View file

@ -6,9 +6,11 @@ from borrowed import acpi
from functions.common import * from functions.common import *
from os import environ from os import environ
# Variables
# STATIC VARIABLES
SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT')) SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT'))
def activate_with_bios(): def activate_with_bios():
"""Attempt to activate Windows with a key stored in the BIOS.""" """Attempt to activate Windows with a key stored in the BIOS."""
# Code borrowed from https://github.com/aeruder/get_win8key # Code borrowed from https://github.com/aeruder/get_win8key
@ -43,6 +45,7 @@ def activate_with_bios():
if not windows_is_activated(): if not windows_is_activated():
raise Exception('Activation Failed') raise Exception('Activation Failed')
def get_activation_string(): def get_activation_string():
"""Get activation status, returns str.""" """Get activation status, returns str."""
act_str = subprocess.run( act_str = subprocess.run(
@ -53,6 +56,7 @@ def get_activation_string():
act_str = act_str[1].strip() act_str = act_str[1].strip()
return act_str return act_str
def windows_is_activated(): def windows_is_activated():
"""Check if Windows is activated via slmgr.vbs and return bool.""" """Check if Windows is activated via slmgr.vbs and return bool."""
activation_string = subprocess.run( activation_string = subprocess.run(
@ -62,6 +66,7 @@ def windows_is_activated():
return bool(activation_string and 'permanent' in activation_string) return bool(activation_string and 'permanent' in activation_string)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -4,6 +4,7 @@ import ctypes
from functions.disk import * from functions.disk import *
# Regex # Regex
REGEX_BAD_PATH_NAMES = re.compile( REGEX_BAD_PATH_NAMES = re.compile(
r'([<>:"/\|\?\*]' r'([<>:"/\|\?\*]'
@ -12,6 +13,7 @@ REGEX_BAD_PATH_NAMES = re.compile(
r'|[\s\.]+$', r'|[\s\.]+$',
re.IGNORECASE) re.IGNORECASE)
def backup_partition(disk, par): def backup_partition(disk, par):
"""Create a backup image of a partition.""" """Create a backup image of a partition."""
if (par.get('Image Exists', False) if (par.get('Image Exists', False)
@ -31,6 +33,7 @@ def backup_partition(disk, par):
os.makedirs(dest_dir, exist_ok=True) os.makedirs(dest_dir, exist_ok=True)
run_program(cmd) run_program(cmd)
def fix_path(path): def fix_path(path):
"""Replace invalid filename characters with underscores.""" """Replace invalid filename characters with underscores."""
local_drive = path[1:2] == ':' local_drive = path[1:2] == ':'
@ -39,6 +42,7 @@ def fix_path(path):
new_path = '{}:{}'.format(new_path[0:1], new_path[2:]) new_path = '{}:{}'.format(new_path[0:1], new_path[2:])
return new_path return new_path
def get_volume_display_name(mountpoint): def get_volume_display_name(mountpoint):
"""Get display name from volume mountpoint and label, returns str.""" """Get display name from volume mountpoint and label, returns str."""
name = mountpoint name = mountpoint
@ -67,6 +71,7 @@ def get_volume_display_name(mountpoint):
return name return name
def prep_disk_for_backup(destination, disk, backup_prefix): def prep_disk_for_backup(destination, disk, backup_prefix):
"""Gather details about the disk and its partitions. """Gather details about the disk and its partitions.
@ -143,6 +148,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
COLORS['YELLOW'], COLORS['CLEAR']) COLORS['YELLOW'], COLORS['CLEAR'])
disk['Backup Warnings'] = warnings disk['Backup Warnings'] = warnings
def select_backup_destination(auto_select=True): def select_backup_destination(auto_select=True):
"""Select a backup destination from a menu, returns server dict.""" """Select a backup destination from a menu, returns server dict."""
destinations = [s for s in BACKUP_SERVERS if s['Mounted']] destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
@ -193,6 +199,7 @@ def select_backup_destination(auto_select=True):
else: else:
return destinations[int(selection)-1] return destinations[int(selection)-1]
def verify_wim_backup(partition): def verify_wim_backup(partition):
"""Verify WIM integrity.""" """Verify WIM integrity."""
if not os.path.exists(partition['Image Path']): if not os.path.exists(partition['Image Path']):
@ -205,6 +212,7 @@ def verify_wim_backup(partition):
] ]
run_program(cmd) run_program(cmd)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -4,6 +4,7 @@ from functions.common import *
from operator import itemgetter from operator import itemgetter
# Define other_results for later try_and_print # Define other_results for later try_and_print
browser_data = {} browser_data = {}
other_results = { other_results = {
@ -16,22 +17,6 @@ other_results = {
} }
} }
# Regex
REGEX_BACKUP = re.compile(
r'\.\w*bak.*',
re.IGNORECASE)
REGEX_CHROMIUM_PROFILE = re.compile(
r'^(Default|Profile)',
re.IGNORECASE)
REGEX_CHROMIUM_ITEMS = re.compile(
r'^(Bookmarks|Cookies|Favicons|Google Profile'
r'|History|Login Data|Top Sites|TransportSecurity'
r'|Visited Links|Web Data)',
re.IGNORECASE)
REGEX_MOZILLA = re.compile(
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
r'|key3.db|logins.json|persdict.dat)$',
re.IGNORECASE)
# STATIC VARIABLES # STATIC VARIABLES
DEFAULT_HOMEPAGE = 'https://www.google.com/' DEFAULT_HOMEPAGE = 'https://www.google.com/'
@ -103,6 +88,25 @@ SUPPORTED_BROWSERS = {
}, },
} }
# Regex
REGEX_BACKUP = re.compile(
r'\.\w*bak.*',
re.IGNORECASE)
REGEX_CHROMIUM_PROFILE = re.compile(
r'^(Default|Profile)',
re.IGNORECASE)
REGEX_CHROMIUM_ITEMS = re.compile(
r'^(Bookmarks|Cookies|Favicons|Google Profile'
r'|History|Login Data|Top Sites|TransportSecurity'
r'|Visited Links|Web Data)',
re.IGNORECASE)
REGEX_MOZILLA = re.compile(
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
r'|key3.db|logins.json|persdict.dat)$',
re.IGNORECASE)
def archive_all_users(): def archive_all_users():
"""Create backups for all browsers for all users.""" """Create backups for all browsers for all users."""
users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE']) users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE'])
@ -149,6 +153,7 @@ def archive_all_users():
function=run_program, cmd=cmd) function=run_program, cmd=cmd)
print_standard(' ') print_standard(' ')
def archive_browser(name): def archive_browser(name):
"""Create backup of Browser saved in the BackupDir.""" """Create backup of Browser saved in the BackupDir."""
source = '{}*'.format(browser_data[name]['user_data_path']) source = '{}*'.format(browser_data[name]['user_data_path'])
@ -163,12 +168,14 @@ def archive_browser(name):
archive, source] archive, source]
run_program(cmd) run_program(cmd)
def backup_browsers(): def backup_browsers():
"""Create backup of all detected browser profiles.""" """Create backup of all detected browser profiles."""
for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]: for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
try_and_print(message='{}...'.format(name), try_and_print(message='{}...'.format(name),
function=archive_browser, name=name) function=archive_browser, name=name)
def clean_chromium_profile(profile): def clean_chromium_profile(profile):
"""Recreate profile with only the essential user data. """Recreate profile with only the essential user data.
@ -191,6 +198,7 @@ def clean_chromium_profile(profile):
shutil.copy(entry.path, r'{}\{}'.format( shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name)) profile['path'], entry.name))
def clean_internet_explorer(**kwargs): def clean_internet_explorer(**kwargs):
"""Uses the built-in function to reset IE and sets the homepage. """Uses the built-in function to reset IE and sets the homepage.
@ -208,6 +216,7 @@ def clean_internet_explorer(**kwargs):
except FileNotFoundError: except FileNotFoundError:
pass pass
def clean_mozilla_profile(profile): def clean_mozilla_profile(profile):
"""Recreate profile with only the essential user data. """Recreate profile with only the essential user data.
@ -240,6 +249,7 @@ def clean_mozilla_profile(profile):
for k, v in MOZILLA_PREFS.items(): for k, v in MOZILLA_PREFS.items():
f.write('user_pref("{}", {});\n'.format(k, v)) f.write('user_pref("{}", {});\n'.format(k, v))
def get_browser_details(name): def get_browser_details(name):
"""Get installation and profile details for all supported browsers.""" """Get installation and profile details for all supported browsers."""
browser = SUPPORTED_BROWSERS[name].copy() browser = SUPPORTED_BROWSERS[name].copy()
@ -314,6 +324,7 @@ def get_browser_details(name):
elif num_installs > 1 and browser['base'] != 'ie': elif num_installs > 1 and browser['base'] != 'ie':
raise MultipleInstallationsError raise MultipleInstallationsError
def get_chromium_profiles(search_path): def get_chromium_profiles(search_path):
"""Find any chromium-style profiles and return as a list of dicts.""" """Find any chromium-style profiles and return as a list of dicts."""
profiles = [] profiles = []
@ -330,6 +341,7 @@ def get_chromium_profiles(search_path):
return profiles return profiles
def get_ie_homepages(): def get_ie_homepages():
"""Read homepages from the registry and return as a list.""" """Read homepages from the registry and return as a list."""
homepages = [] homepages = []
@ -354,6 +366,7 @@ def get_ie_homepages():
homepages = [h.replace('{', '').replace('}', '') for h in homepages] homepages = [h.replace('{', '').replace('}', '') for h in homepages]
return homepages return homepages
def get_mozilla_homepages(prefs_path): def get_mozilla_homepages(prefs_path):
"""Read homepages from prefs.js and return as a list.""" """Read homepages from prefs.js and return as a list."""
homepages = [] homepages = []
@ -369,6 +382,7 @@ def get_mozilla_homepages(prefs_path):
return homepages return homepages
def get_mozilla_profiles(search_path, dev=False): def get_mozilla_profiles(search_path, dev=False):
"""Find any mozilla-style profiles and return as a list of dicts.""" """Find any mozilla-style profiles and return as a list of dicts."""
profiles = [] profiles = []
@ -393,6 +407,7 @@ def get_mozilla_profiles(search_path, dev=False):
return profiles return profiles
def install_adblock(indent=8, width=32, just_firefox=False): def install_adblock(indent=8, width=32, just_firefox=False):
"""Install adblock for all supported browsers.""" """Install adblock for all supported browsers."""
for browser in sorted(browser_data): for browser in sorted(browser_data):
@ -461,6 +476,7 @@ def install_adblock(indent=8, width=32, just_firefox=False):
cs='Done', function=function, cs='Done', function=function,
cmd=[exe_path, *urls], check=False) cmd=[exe_path, *urls], check=False)
def list_homepages(indent=8, width=32): def list_homepages(indent=8, width=32):
"""List current homepages for reference.""" """List current homepages for reference."""
browser_list = [k for k, v in sorted(browser_data.items()) if v['exe_path']] browser_list = [k for k, v in sorted(browser_data.items()) if v['exe_path']]
@ -491,6 +507,7 @@ def list_homepages(indent=8, width=32):
print_standard('{indent}{name:<{width}}{page}'.format( print_standard('{indent}{name:<{width}}{page}'.format(
indent=' '*indent, width=width, name=name, page=page)) indent=' '*indent, width=width, name=name, page=page))
def reset_browsers(indent=8, width=32): def reset_browsers(indent=8, width=32):
"""Reset all detected browsers to safe defaults.""" """Reset all detected browsers to safe defaults."""
browser_list = [k for k, v in sorted(browser_data.items()) if v['profiles']] browser_list = [k for k, v in sorted(browser_data.items()) if v['profiles']]
@ -508,6 +525,7 @@ def reset_browsers(indent=8, width=32):
indent=indent, width=width, function=function, indent=indent, width=width, function=function,
other_results=other_results, profile=profile) other_results=other_results, profile=profile)
def scan_for_browsers(just_firefox=False): def scan_for_browsers(just_firefox=False):
"""Scan system for any supported browsers.""" """Scan system for any supported browsers."""
for name, details in sorted(SUPPORTED_BROWSERS.items()): for name, details in sorted(SUPPORTED_BROWSERS.items()):
@ -517,6 +535,7 @@ def scan_for_browsers(just_firefox=False):
function=get_browser_details, cs='Detected', function=get_browser_details, cs='Detected',
other_results=other_results, name=name) other_results=other_results, name=name)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -2,6 +2,7 @@
from functions.common import * from functions.common import *
def cleanup_adwcleaner(): def cleanup_adwcleaner():
"""Move AdwCleaner folders into the ClientDir.""" """Move AdwCleaner folders into the ClientDir."""
source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env']) source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env'])
@ -26,6 +27,7 @@ def cleanup_adwcleaner():
dest_name = non_clobber_rename(dest_name) dest_name = non_clobber_rename(dest_name)
shutil.move(source_path, dest_name) shutil.move(source_path, dest_name)
def cleanup_cbs(dest_folder): def cleanup_cbs(dest_folder):
"""Safely cleanup a known CBS archive bug under Windows 7. """Safely cleanup a known CBS archive bug under Windows 7.
@ -65,6 +67,7 @@ def cleanup_cbs(dest_folder):
r'{}\CbsPersist*'.format(temp_folder)] r'{}\CbsPersist*'.format(temp_folder)]
run_program(cmd) run_program(cmd)
def cleanup_desktop(): def cleanup_desktop():
"""Move known backup files and reports into the ClientDir.""" """Move known backup files and reports into the ClientDir."""
dest_folder = r'{LogDir}\Tools'.format(**global_vars) dest_folder = r'{LogDir}\Tools'.format(**global_vars)
@ -81,6 +84,7 @@ def cleanup_desktop():
# Remove dir if empty # Remove dir if empty
delete_empty_folders(dest_folder) delete_empty_folders(dest_folder)
def delete_empty_folders(folder_path): def delete_empty_folders(folder_path):
"""Delete all empty folders in path (depth first).""" """Delete all empty folders in path (depth first)."""
if not os.path.exists(folder_path) or not os.path.isdir(folder_path): if not os.path.exists(folder_path) or not os.path.isdir(folder_path):
@ -98,6 +102,7 @@ def delete_empty_folders(folder_path):
except OSError: except OSError:
pass pass
def delete_registry_key(hive, key, recurse=False): def delete_registry_key(hive, key, recurse=False):
"""Delete a registry key and all it's subkeys.""" """Delete a registry key and all it's subkeys."""
access = winreg.KEY_ALL_ACCESS access = winreg.KEY_ALL_ACCESS
@ -117,12 +122,14 @@ def delete_registry_key(hive, key, recurse=False):
# Ignore # Ignore
pass pass
def delete_registry_value(hive, key, value): def delete_registry_value(hive, key, value):
"""Delete a registry value.""" """Delete a registry value."""
access = winreg.KEY_ALL_ACCESS access = winreg.KEY_ALL_ACCESS
with winreg.OpenKeyEx(hive, key, 0, access) as k: with winreg.OpenKeyEx(hive, key, 0, access) as k:
winreg.DeleteValue(k, value) winreg.DeleteValue(k, value)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -20,9 +20,11 @@ from settings.main import *
from settings.tools import * from settings.tools import *
from settings.windows_builds import * from settings.windows_builds import *
# Global variables # Global variables
global_vars = {} global_vars = {}
# STATIC VARIABLES # STATIC VARIABLES
COLORS = { COLORS = {
'CLEAR': '\033[0m', 'CLEAR': '\033[0m',
@ -42,6 +44,7 @@ except NameError:
if psutil.WINDOWS: if psutil.WINDOWS:
raise raise
# Error Classes # Error Classes
class BIOSKeyNotFoundError(Exception): class BIOSKeyNotFoundError(Exception):
pass pass
@ -85,6 +88,7 @@ class SecureBootNotAvailError(Exception):
class SecureBootUnknownError(Exception): class SecureBootUnknownError(Exception):
pass pass
# General functions # General functions
def abort(): def abort():
"""Abort script.""" """Abort script."""
@ -93,6 +97,7 @@ def abort():
pause(prompt='Press Enter to exit... ') pause(prompt='Press Enter to exit... ')
exit_script() exit_script()
def ask(prompt='Kotaero!'): def ask(prompt='Kotaero!'):
"""Prompt the user with a Y/N question, returns bool.""" """Prompt the user with a Y/N question, returns bool."""
answer = None answer = None
@ -109,6 +114,7 @@ def ask(prompt='Kotaero!'):
print_log(message=message) print_log(message=message)
return answer return answer
def choice(choices, prompt='Kotaero!'): def choice(choices, prompt='Kotaero!'):
"""Prompt the user with a choice question, returns str.""" """Prompt the user with a choice question, returns str."""
answer = None answer = None
@ -137,6 +143,7 @@ def choice(choices, prompt='Kotaero!'):
# Done # Done
return answer return answer
def clear_screen(): def clear_screen():
"""Simple wrapper for cls/clear.""" """Simple wrapper for cls/clear."""
if psutil.WINDOWS: if psutil.WINDOWS:
@ -144,6 +151,7 @@ def clear_screen():
else: else:
os.system('clear') os.system('clear')
def convert_to_bytes(size): def convert_to_bytes(size):
"""Convert human-readable size str to bytes and return an int.""" """Convert human-readable size str to bytes and return an int."""
size = str(size) size = str(size)
@ -165,6 +173,7 @@ def convert_to_bytes(size):
return size return size
def exit_script(return_value=0): def exit_script(return_value=0):
"""Exits the script after some cleanup and opens the log (if set).""" """Exits the script after some cleanup and opens the log (if set)."""
# Remove dirs (if empty) # Remove dirs (if empty)
@ -192,6 +201,7 @@ def exit_script(return_value=0):
# Exit # Exit
sys.exit(return_value) sys.exit(return_value)
def extract_item(item, filter='', silent=False): def extract_item(item, filter='', silent=False):
"""Extract item from .cbin into .bin.""" """Extract item from .cbin into .bin."""
cmd = [ cmd = [
@ -211,6 +221,7 @@ def extract_item(item, filter='', silent=False):
if not silent: if not silent:
print_warning('WARNING: Errors encountered while exctracting data') print_warning('WARNING: Errors encountered while exctracting data')
def get_process(name=None): def get_process(name=None):
"""Get process by name, returns psutil.Process obj.""" """Get process by name, returns psutil.Process obj."""
proc = None proc = None
@ -226,6 +237,7 @@ def get_process(name=None):
pass pass
return proc return proc
def get_simple_string(prompt='Enter string'): def get_simple_string(prompt='Enter string'):
"""Get string from user (restricted character set), returns str.""" """Get string from user (restricted character set), returns str."""
simple_string = None simple_string = None
@ -235,6 +247,7 @@ def get_simple_string(prompt='Enter string'):
simple_string = _input.strip() simple_string = _input.strip()
return simple_string return simple_string
def get_ticket_number(): def get_ticket_number():
"""Get TicketNumber from user, save in LogDir, and return as str.""" """Get TicketNumber from user, save in LogDir, and return as str."""
if not ENABLED_TICKET_NUMBERS: if not ENABLED_TICKET_NUMBERS:
@ -251,6 +264,7 @@ def get_ticket_number():
f.write(ticket_number) f.write(ticket_number)
return ticket_number return ticket_number
def human_readable_size(size, decimals=0): def human_readable_size(size, decimals=0):
"""Convert size from bytes to a human-readable format, returns str.""" """Convert size from bytes to a human-readable format, returns str."""
# Prep string formatting # Prep string formatting
@ -290,12 +304,14 @@ def human_readable_size(size, decimals=0):
return '{size:>{width}.{decimals}f} {units}'.format( return '{size:>{width}.{decimals}f} {units}'.format(
size=size, width=width, decimals=decimals, units=units) size=size, width=width, decimals=decimals, units=units)
def kill_process(name): def kill_process(name):
"""Kill any running caffeine.exe processes.""" """Kill any running caffeine.exe processes."""
for proc in psutil.process_iter(): for proc in psutil.process_iter():
if proc.name() == name: if proc.name() == name:
proc.kill() proc.kill()
def major_exception(): def major_exception():
"""Display traceback and exit""" """Display traceback and exit"""
print_error('Major exception') print_error('Major exception')
@ -319,6 +335,7 @@ def major_exception():
pause('Press Enter to exit...') pause('Press Enter to exit...')
exit_script(1) exit_script(1)
def menu_select( def menu_select(
title='[Untitled Menu]', title='[Untitled Menu]',
prompt='Please make a selection', secret_actions=[], secret_exit=False, prompt='Please make a selection', secret_actions=[], secret_exit=False,
@ -382,6 +399,7 @@ def menu_select(
return answer.upper() return answer.upper()
def non_clobber_rename(full_path): def non_clobber_rename(full_path):
"""Append suffix to path, if necessary, to avoid clobbering path""" """Append suffix to path, if necessary, to avoid clobbering path"""
new_path = full_path new_path = full_path
@ -392,10 +410,12 @@ def non_clobber_rename(full_path):
return new_path return new_path
def pause(prompt='Press Enter to continue... '): def pause(prompt='Press Enter to continue... '):
"""Simple pause implementation.""" """Simple pause implementation."""
input(prompt) input(prompt)
def ping(addr='google.com'): def ping(addr='google.com'):
"""Attempt to ping addr.""" """Attempt to ping addr."""
cmd = [ cmd = [
@ -405,6 +425,7 @@ def ping(addr='google.com'):
addr] addr]
run_program(cmd) run_program(cmd)
def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs): def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
"""Run program and return a subprocess.Popen object.""" """Run program and return a subprocess.Popen object."""
cmd_kwargs = {'args': cmd, 'shell': shell} cmd_kwargs = {'args': cmd, 'shell': shell}
@ -426,14 +447,17 @@ def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
return subprocess.Popen(**cmd_kwargs) return subprocess.Popen(**cmd_kwargs)
def print_error(*args, **kwargs): def print_error(*args, **kwargs):
"""Prints message to screen in RED.""" """Prints message to screen in RED."""
print_standard(*args, color=COLORS['RED'], **kwargs) print_standard(*args, color=COLORS['RED'], **kwargs)
def print_info(*args, **kwargs): def print_info(*args, **kwargs):
"""Prints message to screen in BLUE.""" """Prints message to screen in BLUE."""
print_standard(*args, color=COLORS['BLUE'], **kwargs) print_standard(*args, color=COLORS['BLUE'], **kwargs)
def print_standard(message='Generic info', def print_standard(message='Generic info',
color=None, end='\n', timestamp=True, **kwargs): color=None, end='\n', timestamp=True, **kwargs):
"""Prints message to screen and log (if set).""" """Prints message to screen and log (if set)."""
@ -444,14 +468,17 @@ def print_standard(message='Generic info',
print(display_message.format(**COLORS), end=end, **kwargs) print(display_message.format(**COLORS), end=end, **kwargs)
print_log(message, end, timestamp) print_log(message, end, timestamp)
def print_success(*args, **kwargs): def print_success(*args, **kwargs):
"""Prints message to screen in GREEN.""" """Prints message to screen in GREEN."""
print_standard(*args, color=COLORS['GREEN'], **kwargs) print_standard(*args, color=COLORS['GREEN'], **kwargs)
def print_warning(*args, **kwargs): def print_warning(*args, **kwargs):
"""Prints message to screen in YELLOW.""" """Prints message to screen in YELLOW."""
print_standard(*args, color=COLORS['YELLOW'], **kwargs) print_standard(*args, color=COLORS['YELLOW'], **kwargs)
def print_log(message='', end='\n', timestamp=True): def print_log(message='', end='\n', timestamp=True):
"""Writes message to a log if LogFile is set.""" """Writes message to a log if LogFile is set."""
time_str = time.strftime("%Y-%m-%d %H%M%z: ") if timestamp else '' time_str = time.strftime("%Y-%m-%d %H%M%z: ") if timestamp else ''
@ -463,6 +490,7 @@ def print_log(message='', end='\n', timestamp=True):
line = line, line = line,
end = end)) end = end))
def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs): def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs):
"""Run program and return a subprocess.CompletedProcess object.""" """Run program and return a subprocess.CompletedProcess object."""
if args: if args:
@ -486,6 +514,7 @@ def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs):
return subprocess.run(**cmd_kwargs) return subprocess.run(**cmd_kwargs)
def set_title(title='[Some Title]'): def set_title(title='[Some Title]'):
"""Set title. """Set title.
@ -493,6 +522,7 @@ def set_title(title='[Some Title]'):
global_vars['Title'] = title global_vars['Title'] = title
os.system('title {}'.format(title)) os.system('title {}'.format(title))
def show_data( def show_data(
message='[Some message]', data='[Some data]', message='[Some message]', data='[Some data]',
indent=8, width=32, indent=8, width=32,
@ -509,10 +539,12 @@ def show_data(
else: else:
print_standard(message) print_standard(message)
def sleep(seconds=2): def sleep(seconds=2):
"""Wait for a while.""" """Wait for a while."""
time.sleep(seconds) time.sleep(seconds)
def stay_awake(): def stay_awake():
"""Prevent the system from sleeping or hibernating.""" """Prevent the system from sleeping or hibernating."""
# DISABLED due to VCR2008 dependency # DISABLED due to VCR2008 dependency
@ -529,12 +561,14 @@ def stay_awake():
print_error('ERROR: No caffeine available.') print_error('ERROR: No caffeine available.')
print_warning('Please set the power setting to High Performance.') print_warning('Please set the power setting to High Performance.')
def strip_colors(s): def strip_colors(s):
"""Remove all ASCII color escapes from string, returns str.""" """Remove all ASCII color escapes from string, returns str."""
for c in COLORS.values(): for c in COLORS.values():
s = s.replace(c, '') s = s.replace(c, '')
return s return s
def get_exception(s): def get_exception(s):
"""Get exception by name, returns Exception object.""" """Get exception by name, returns Exception object."""
try: try:
@ -544,6 +578,7 @@ def get_exception(s):
obj = getattr(sys.modules['builtins'], s) obj = getattr(sys.modules['builtins'], s)
return obj return obj
def try_and_print(message='Trying...', def try_and_print(message='Trying...',
function=None, cs='CS', ns='NS', other_results={}, function=None, cs='CS', ns='NS', other_results={},
catch_all=True, print_return=False, silent_function=True, catch_all=True, print_return=False, silent_function=True,
@ -600,6 +635,7 @@ def try_and_print(message='Trying...',
else: else:
return {'CS': not bool(err), 'Error': err, 'Out': out} return {'CS': not bool(err), 'Error': err, 'Out': out}
def upload_crash_details(): def upload_crash_details():
"""Upload log and runtime data to the CRASH_SERVER. """Upload log and runtime data to the CRASH_SERVER.
@ -611,13 +647,11 @@ def upload_crash_details():
if 'LogFile' in global_vars and global_vars['LogFile']: if 'LogFile' in global_vars and global_vars['LogFile']:
if ask('Upload crash details to {}?'.format(CRASH_SERVER['Name'])): if ask('Upload crash details to {}?'.format(CRASH_SERVER['Name'])):
with open(global_vars['LogFile']) as f: with open(global_vars['LogFile']) as f:
data = '''{} data = '{}\n'.format(f.read())
############################# data += '#############################\n'
Runtime Details: data += 'Runtime Details:\n\n'
data += 'sys.argv: {}\n\n'.format(sys.argv)
sys.argv: {} data += 'global_vars: {}\n'.format(global_vars)
global_vars: {}'''.format(f.read(), sys.argv, global_vars)
filename = global_vars.get('LogFile', 'Unknown') filename = global_vars.get('LogFile', 'Unknown')
filename = re.sub(r'.*(\\|/)', '', filename) filename = re.sub(r'.*(\\|/)', '', filename)
filename += '.txt' filename += '.txt'
@ -639,6 +673,7 @@ global_vars: {}'''.format(f.read(), sys.argv, global_vars)
# No LogFile defined (or invalid LogFile) # No LogFile defined (or invalid LogFile)
raise GenericError raise GenericError
def wait_for_process(name, poll_rate=3): def wait_for_process(name, poll_rate=3):
"""Wait for process by name.""" """Wait for process by name."""
running = True running = True
@ -654,6 +689,7 @@ def wait_for_process(name, poll_rate=3):
pass pass
sleep(1) sleep(1)
# global_vars functions # global_vars functions
def init_global_vars(silent=False): def init_global_vars(silent=False):
"""Sets global variables based on system info.""" """Sets global variables based on system info."""
@ -687,6 +723,7 @@ def init_global_vars(silent=False):
except: except:
major_exception() major_exception()
def check_os(): def check_os():
"""Set OS specific variables.""" """Set OS specific variables."""
tmp = {} tmp = {}
@ -749,6 +786,7 @@ def check_os():
global_vars['OS'] = tmp global_vars['OS'] = tmp
def check_tools(): def check_tools():
"""Set tool variables based on OS bit-depth and tool availability.""" """Set tool variables based on OS bit-depth and tool availability."""
if global_vars['OS'].get('Arch', 32) == 64: if global_vars['OS'].get('Arch', 32) == 64:
@ -761,6 +799,7 @@ def check_tools():
global_vars['Tools'] = {k: os.path.join(global_vars['BinDir'], v) global_vars['Tools'] = {k: os.path.join(global_vars['BinDir'], v)
for (k, v) in global_vars['Tools'].items()} for (k, v) in global_vars['Tools'].items()}
def clean_env_vars(): def clean_env_vars():
"""Remove conflicting global_vars and env variables. """Remove conflicting global_vars and env variables.
@ -769,6 +808,7 @@ def clean_env_vars():
for key in global_vars.keys(): for key in global_vars.keys():
global_vars['Env'].pop(key, None) global_vars['Env'].pop(key, None)
def find_bin(): def find_bin():
"""Find .bin folder in the cwd or it's parents.""" """Find .bin folder in the cwd or it's parents."""
wd = os.getcwd() wd = os.getcwd()
@ -785,6 +825,7 @@ def find_bin():
raise BinNotFoundError raise BinNotFoundError
global_vars['BaseDir'] = base global_vars['BaseDir'] = base
def make_tmp_dirs(): def make_tmp_dirs():
"""Make temp directories.""" """Make temp directories."""
os.makedirs(global_vars['BackupDir'], exist_ok=True) os.makedirs(global_vars['BackupDir'], exist_ok=True)
@ -794,6 +835,7 @@ def make_tmp_dirs():
os.makedirs(r'{}\Tools'.format(global_vars['LogDir']), exist_ok=True) os.makedirs(r'{}\Tools'.format(global_vars['LogDir']), exist_ok=True)
os.makedirs(global_vars['TmpDir'], exist_ok=True) os.makedirs(global_vars['TmpDir'], exist_ok=True)
def set_common_vars(): def set_common_vars():
"""Set common variables.""" """Set common variables."""
global_vars['Date'] = time.strftime("%Y-%m-%d") global_vars['Date'] = time.strftime("%Y-%m-%d")
@ -816,6 +858,7 @@ def set_common_vars():
global_vars['TmpDir'] = r'{BinDir}\tmp'.format( global_vars['TmpDir'] = r'{BinDir}\tmp'.format(
**global_vars) **global_vars)
def set_linux_vars(): def set_linux_vars():
"""Set common variables in a Linux environment. """Set common variables in a Linux environment.
@ -832,6 +875,7 @@ def set_linux_vars():
'SevenZip': '7z', 'SevenZip': '7z',
} }
def set_log_file(log_name): def set_log_file(log_name):
"""Sets global var LogFile and creates path as needed.""" """Sets global var LogFile and creates path as needed."""
folder_path = r'{}\{}'.format(global_vars['LogDir'], KIT_NAME_FULL) folder_path = r'{}\{}'.format(global_vars['LogDir'], KIT_NAME_FULL)
@ -839,6 +883,7 @@ def set_log_file(log_name):
os.makedirs(folder_path, exist_ok=True) os.makedirs(folder_path, exist_ok=True)
global_vars['LogFile'] = log_file global_vars['LogFile'] = log_file
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -7,57 +7,6 @@ from operator import itemgetter
from functions.common import * from functions.common import *
# Classes
class LocalDisk():
def __init__(self, disk):
self.disk = disk
self.name = disk.mountpoint.upper()
self.path = self.name
def is_dir(self):
# Should always be true
return True
def is_file(self):
# Should always be false
return False
class SourceItem():
def __init__(self, name, path):
self.name = name
self.path = path
# Regex
REGEX_EXCL_ITEMS = re.compile(
r'^(\.(AppleDB|AppleDesktop|AppleDouble'
r'|com\.apple\.timemachine\.supported|dbfseventsd'
r'|DocumentRevisions-V100.*|DS_Store|fseventsd|PKInstallSandboxManager'
r'|Spotlight.*|SymAV.*|symSchedScanLockxz|TemporaryItems|Trash.*'
r'|vol|VolumeIcon\.icns)|desktop\.(ini|.*DB|.*DF)'
r'|(hiberfil|pagefile)\.sys|lost\+found|Network\.*Trash\.*Folder'
r'|Recycle[dr]|System\.*Volume\.*Information|Temporary\.*Items'
r'|Thumbs\.db)$',
re.IGNORECASE)
REGEX_EXCL_ROOT_ITEMS = re.compile(
r'^(boot(mgr|nxt)$|Config.msi'
r'|(eula|globdata|install|vc_?red)'
r'|.*.sys$|System Volume Information|RECYCLER?|\$Recycle\.bin'
r'|\$?Win(dows(.old.*|\. BT|)$|RE_)|\$GetCurrent|Windows10Upgrade'
r'|PerfLogs|Program Files|SYSTEM.SAV'
r'|.*\.(esd|swm|wim|dd|map|dmg|image)$)',
re.IGNORECASE)
REGEX_INCL_ROOT_ITEMS = re.compile(
r'^(AdwCleaner|(My\s*|)(Doc(uments?( and Settings|)|s?)|Downloads'
r'|Media|Music|Pic(ture|)s?|Vid(eo|)s?)'
r'|{prefix}(-?Info|-?Transfer|)'
r'|(ProgramData|Recovery|Temp.*|Users)$'
r'|.*\.(log|txt|rtf|qb\w*|avi|m4a|m4v|mp4|mkv|jpg|png|tiff?)$)'
r''.format(prefix=KIT_NAME_SHORT),
re.IGNORECASE)
REGEX_WIM_FILE = re.compile(
r'\.wim$',
re.IGNORECASE)
REGEX_WINDOWS_OLD = re.compile(
r'^Win(dows|)\.old',
re.IGNORECASE)
# STATIC VARIABLES # STATIC VARIABLES
FAST_COPY_EXCLUDES = [ FAST_COPY_EXCLUDES = [
@ -116,6 +65,63 @@ SEM_FAILCRITICALERRORS = 1
SEM_NOOPENFILEERRORBOX = 0x8000 SEM_NOOPENFILEERRORBOX = 0x8000
SEM_FAIL = SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS SEM_FAIL = SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS
# Regex
REGEX_EXCL_ITEMS = re.compile(
r'^(\.(AppleDB|AppleDesktop|AppleDouble'
r'|com\.apple\.timemachine\.supported|dbfseventsd'
r'|DocumentRevisions-V100.*|DS_Store|fseventsd|PKInstallSandboxManager'
r'|Spotlight.*|SymAV.*|symSchedScanLockxz|TemporaryItems|Trash.*'
r'|vol|VolumeIcon\.icns)|desktop\.(ini|.*DB|.*DF)'
r'|(hiberfil|pagefile)\.sys|lost\+found|Network\.*Trash\.*Folder'
r'|Recycle[dr]|System\.*Volume\.*Information|Temporary\.*Items'
r'|Thumbs\.db)$',
re.IGNORECASE)
REGEX_EXCL_ROOT_ITEMS = re.compile(
r'^(boot(mgr|nxt)$|Config.msi'
r'|(eula|globdata|install|vc_?red)'
r'|.*.sys$|System Volume Information|RECYCLER?|\$Recycle\.bin'
r'|\$?Win(dows(.old.*|\. BT|)$|RE_)|\$GetCurrent|Windows10Upgrade'
r'|PerfLogs|Program Files|SYSTEM.SAV'
r'|.*\.(esd|swm|wim|dd|map|dmg|image)$)',
re.IGNORECASE)
REGEX_INCL_ROOT_ITEMS = re.compile(
r'^(AdwCleaner|(My\s*|)(Doc(uments?( and Settings|)|s?)|Downloads'
r'|Media|Music|Pic(ture|)s?|Vid(eo|)s?)'
r'|{prefix}(-?Info|-?Transfer|)'
r'|(ProgramData|Recovery|Temp.*|Users)$'
r'|.*\.(log|txt|rtf|qb\w*|avi|m4a|m4v|mp4|mkv|jpg|png|tiff?)$)'
r''.format(prefix=KIT_NAME_SHORT),
re.IGNORECASE)
REGEX_WIM_FILE = re.compile(
r'\.wim$',
re.IGNORECASE)
REGEX_WINDOWS_OLD = re.compile(
r'^Win(dows|)\.old',
re.IGNORECASE)
# Classes
class LocalDisk():
def __init__(self, disk):
self.disk = disk
self.name = disk.mountpoint.upper()
self.path = self.name
def is_dir(self):
# Should always be true
return True
def is_file(self):
# Should always be false
return False
class SourceItem():
def __init__(self, name, path):
self.name = name
self.path = path
# Functions
def cleanup_transfer(dest_path): def cleanup_transfer(dest_path):
"""Fix attributes and move excluded items to separate folder.""" """Fix attributes and move excluded items to separate folder."""
try: try:
@ -153,6 +159,7 @@ def cleanup_transfer(dest_path):
except Exception: except Exception:
pass pass
def find_core_storage_volumes(device_path=None): def find_core_storage_volumes(device_path=None):
"""Try to create block devices for any Apple CoreStorage volumes.""" """Try to create block devices for any Apple CoreStorage volumes."""
corestorage_uuid = '53746f72-6167-11aa-aa11-00306543ecac' corestorage_uuid = '53746f72-6167-11aa-aa11-00306543ecac'
@ -216,10 +223,12 @@ def find_core_storage_volumes(device_path=None):
cmd = ['sudo', 'dmsetup', 'create', name, dmsetup_cmd_file] cmd = ['sudo', 'dmsetup', 'create', name, dmsetup_cmd_file]
run_program(cmd, check=False) run_program(cmd, check=False)
def fix_path_sep(path_str): def fix_path_sep(path_str):
"""Replace non-native and duplicate dir separators, returns str.""" """Replace non-native and duplicate dir separators, returns str."""
return re.sub(r'(\\|/)+', lambda s: os.sep, path_str) return re.sub(r'(\\|/)+', lambda s: os.sep, path_str)
def is_valid_wim_file(item): def is_valid_wim_file(item):
"""Checks if the item is a valid WIM file, returns bool.""" """Checks if the item is a valid WIM file, returns bool."""
valid = bool(item.is_file() and REGEX_WIM_FILE.search(item.name)) valid = bool(item.is_file() and REGEX_WIM_FILE.search(item.name))
@ -233,6 +242,7 @@ def is_valid_wim_file(item):
print_log('WARNING: Image "{}" damaged.'.format(item.name)) print_log('WARNING: Image "{}" damaged.'.format(item.name))
return valid return valid
def get_mounted_volumes(): def get_mounted_volumes():
"""Get mounted volumes, returns dict.""" """Get mounted volumes, returns dict."""
cmd = [ cmd = [
@ -250,6 +260,7 @@ def get_mounted_volumes():
mounted_volumes.extend(item.get('children', [])) mounted_volumes.extend(item.get('children', []))
return {item['source']: item for item in mounted_volumes} return {item['source']: item for item in mounted_volumes}
def mount_volumes( def mount_volumes(
all_devices=True, device_path=None, all_devices=True, device_path=None,
read_write=False, core_storage=True): read_write=False, core_storage=True):
@ -342,6 +353,7 @@ def mount_volumes(
return report return report
def mount_backup_shares(read_write=False): def mount_backup_shares(read_write=False):
"""Mount the backup shares unless labeled as already mounted.""" """Mount the backup shares unless labeled as already mounted."""
if psutil.LINUX: if psutil.LINUX:
@ -363,6 +375,7 @@ def mount_backup_shares(read_write=False):
mount_network_share(server, read_write) mount_network_share(server, read_write)
def mount_network_share(server, read_write=False): def mount_network_share(server, read_write=False):
"""Mount a network share defined by server.""" """Mount a network share defined by server."""
if read_write: if read_write:
@ -415,6 +428,7 @@ def mount_network_share(server, read_write=False):
print_info(success) print_info(success)
server['Mounted'] = True server['Mounted'] = True
def run_fast_copy(items, dest): def run_fast_copy(items, dest):
"""Copy items to dest using FastCopy.""" """Copy items to dest using FastCopy."""
if not items: if not items:
@ -427,6 +441,7 @@ def run_fast_copy(items, dest):
run_program(cmd) run_program(cmd)
def run_wimextract(source, items, dest): def run_wimextract(source, items, dest):
"""Extract items from source WIM to dest folder.""" """Extract items from source WIM to dest folder."""
if not items: if not items:
@ -452,6 +467,7 @@ def run_wimextract(source, items, dest):
'--nullglob'] '--nullglob']
run_program(cmd) run_program(cmd)
def list_source_items(source_obj, rel_path=None): def list_source_items(source_obj, rel_path=None):
"""List items in a dir or WIM, returns list of SourceItem objects.""" """List items in a dir or WIM, returns list of SourceItem objects."""
items = [] items = []
@ -489,6 +505,7 @@ def list_source_items(source_obj, rel_path=None):
# Done # Done
return items return items
def scan_source(source_obj, dest_path, rel_path='', interactive=True): def scan_source(source_obj, dest_path, rel_path='', interactive=True):
"""Scan source for files/folders to transfer, returns list. """Scan source for files/folders to transfer, returns list.
@ -572,6 +589,7 @@ def scan_source(source_obj, dest_path, rel_path='', interactive=True):
# Done # Done
return selected_items return selected_items
def get_source_item_obj(source_obj, rel_path, item_path): def get_source_item_obj(source_obj, rel_path, item_path):
"""Check if the item exists, returns SourceItem object or None.""" """Check if the item exists, returns SourceItem object or None."""
item_obj = None item_obj = None
@ -611,6 +629,7 @@ def get_source_item_obj(source_obj, rel_path, item_path):
item_path)) item_path))
return item_obj return item_obj
def select_destination(folder_path, prompt='Select destination'): def select_destination(folder_path, prompt='Select destination'):
"""Select destination drive, returns path as string.""" """Select destination drive, returns path as string."""
disk = select_volume(prompt) disk = select_volume(prompt)
@ -627,6 +646,7 @@ def select_destination(folder_path, prompt='Select destination'):
return path return path
def select_source(backup_prefix): def select_source(backup_prefix):
"""Select matching backup from BACKUP_SERVERS, returns obj.""" """Select matching backup from BACKUP_SERVERS, returns obj."""
selected_source = None selected_source = None
@ -792,6 +812,7 @@ def select_source(backup_prefix):
# Done # Done
return selected_source return selected_source
def select_volume(title='Select disk', auto_select=True): def select_volume(title='Select disk', auto_select=True):
"""Select disk from attached disks. returns dict.""" """Select disk from attached disks. returns dict."""
actions = [{'Name': 'Quit', 'Letter': 'Q'}] actions = [{'Name': 'Quit', 'Letter': 'Q'}]
@ -829,6 +850,7 @@ def select_volume(title='Select disk', auto_select=True):
else: else:
return disks[int(selection)-1] return disks[int(selection)-1]
def set_thread_error_mode(silent=True): def set_thread_error_mode(silent=True):
"""Disable or Enable Windows error message dialogs. """Disable or Enable Windows error message dialogs.
@ -842,6 +864,7 @@ def set_thread_error_mode(silent=True):
else: else:
kernel32.SetThreadErrorMode(SEM_NORMAL, ctypes.byref(SEM_NORMAL)) kernel32.SetThreadErrorMode(SEM_NORMAL, ctypes.byref(SEM_NORMAL))
def transfer_source(source_obj, dest_path, selected_items): def transfer_source(source_obj, dest_path, selected_items):
"""Transfer, or extract, files/folders from source to destination.""" """Transfer, or extract, files/folders from source to destination."""
if source_obj.is_dir(): if source_obj.is_dir():
@ -864,11 +887,13 @@ def transfer_source(source_obj, dest_path, selected_items):
print_error('ERROR: Unsupported image: {}'.format(source_obj.path)) print_error('ERROR: Unsupported image: {}'.format(source_obj.path))
raise GenericError raise GenericError
def umount_backup_shares(): def umount_backup_shares():
"""Unmount the backup shares regardless of current status.""" """Unmount the backup shares regardless of current status."""
for server in BACKUP_SERVERS: for server in BACKUP_SERVERS:
umount_network_share(server) umount_network_share(server)
def umount_network_share(server): def umount_network_share(server):
"""Unmount a network share defined by server.""" """Unmount a network share defined by server."""
cmd = r'net use \\{IP}\{Share} /delete'.format(**server) cmd = r'net use \\{IP}\{Share} /delete'.format(**server)
@ -882,6 +907,7 @@ def umount_network_share(server):
print_info('Umounted {Name}'.format(**server)) print_info('Umounted {Name}'.format(**server))
server['Mounted'] = False server['Mounted'] = False
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -15,6 +15,7 @@ from functions.hw_diags import *
from functions.tmux import * from functions.tmux import *
from operator import itemgetter from operator import itemgetter
# STATIC VARIABLES # STATIC VARIABLES
AUTO_PASS_1_THRESHOLD = 95 AUTO_PASS_1_THRESHOLD = 95
AUTO_PASS_2_THRESHOLD = 98 AUTO_PASS_2_THRESHOLD = 98
@ -778,6 +779,7 @@ def menu_ddrescue(source_path, dest_path, run_mode):
run_program(['tmux', 'kill-window']) run_program(['tmux', 'kill-window'])
exit_script() exit_script()
def menu_main(state): def menu_main(state):
"""Main menu is used to set ddrescue settings.""" """Main menu is used to set ddrescue settings."""
title = '{GREEN}ddrescue TUI: Main Menu{CLEAR}\n\n'.format(**COLORS) title = '{GREEN}ddrescue TUI: Main Menu{CLEAR}\n\n'.format(**COLORS)

View file

@ -3,6 +3,7 @@
from functions.common import * from functions.common import *
from settings.partition_uids import * from settings.partition_uids import *
# Regex # Regex
REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE) REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE)
REGEX_DISK_GPT = re.compile( REGEX_DISK_GPT = re.compile(
@ -11,6 +12,7 @@ REGEX_DISK_GPT = re.compile(
REGEX_DISK_MBR = re.compile(r'Disk ID: [A-Z0-9]+', re.IGNORECASE) REGEX_DISK_MBR = re.compile(r'Disk ID: [A-Z0-9]+', re.IGNORECASE)
REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE) REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
def assign_volume_letters(): def assign_volume_letters():
"""Assign a volume letter to all available volumes.""" """Assign a volume letter to all available volumes."""
remove_volume_letters() remove_volume_letters()
@ -24,6 +26,7 @@ def assign_volume_letters():
# Run # Run
run_diskpart(script) run_diskpart(script)
def get_boot_mode(): def get_boot_mode():
"""Check if the boot mode was UEFI or legacy.""" """Check if the boot mode was UEFI or legacy."""
boot_mode = 'Legacy' boot_mode = 'Legacy'
@ -38,6 +41,7 @@ def get_boot_mode():
return boot_mode return boot_mode
def get_disk_details(disk): def get_disk_details(disk):
"""Get disk details using DiskPart.""" """Get disk details using DiskPart."""
details = {} details = {}
@ -63,6 +67,7 @@ def get_disk_details(disk):
return details return details
def get_disks(): def get_disks():
"""Get list of attached disks using DiskPart.""" """Get list of attached disks using DiskPart."""
disks = [] disks = []
@ -82,6 +87,7 @@ def get_disks():
return disks return disks
def get_partition_details(disk, partition): def get_partition_details(disk, partition):
"""Get partition details using DiskPart and fsutil.""" """Get partition details using DiskPart and fsutil."""
details = {} details = {}
@ -161,6 +167,7 @@ def get_partition_details(disk, partition):
return details return details
def get_partitions(disk): def get_partitions(disk):
"""Get list of partition using DiskPart.""" """Get list of partition using DiskPart."""
partitions = [] partitions = []
@ -184,6 +191,7 @@ def get_partitions(disk):
return partitions return partitions
def get_table_type(disk): def get_table_type(disk):
"""Get disk partition table type using DiskPart.""" """Get disk partition table type using DiskPart."""
part_type = 'Unknown' part_type = 'Unknown'
@ -206,6 +214,7 @@ def get_table_type(disk):
return part_type return part_type
def get_volumes(): def get_volumes():
"""Get list of volumes using DiskPart.""" """Get list of volumes using DiskPart."""
vols = [] vols = []
@ -221,10 +230,12 @@ def get_volumes():
return vols return vols
def is_bad_partition(par): def is_bad_partition(par):
"""Check if the partition is accessible.""" """Check if the partition is accessible."""
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem']) return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
def prep_disk_for_formatting(disk=None): def prep_disk_for_formatting(disk=None):
"""Gather details about the disk and its partitions.""" """Gather details about the disk and its partitions."""
disk['Format Warnings'] = '\n' disk['Format Warnings'] = '\n'
@ -270,6 +281,7 @@ def prep_disk_for_formatting(disk=None):
# For all partitions # For all partitions
partition['Display String'] = display partition['Display String'] = display
def reassign_volume_letter(letter, new_letter='I'): def reassign_volume_letter(letter, new_letter='I'):
"""Assign a new letter to a volume using DiskPart.""" """Assign a new letter to a volume using DiskPart."""
if not letter: if not letter:
@ -286,6 +298,7 @@ def reassign_volume_letter(letter, new_letter='I'):
else: else:
return new_letter return new_letter
def remove_volume_letters(keep=None): def remove_volume_letters(keep=None):
"""Remove all assigned volume letters using DiskPart.""" """Remove all assigned volume letters using DiskPart."""
if not keep: if not keep:
@ -303,6 +316,7 @@ def remove_volume_letters(keep=None):
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
def run_diskpart(script): def run_diskpart(script):
"""Run DiskPart script.""" """Run DiskPart script."""
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP']) tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
@ -321,6 +335,7 @@ def run_diskpart(script):
sleep(2) sleep(2)
return result return result
def scan_disks(): def scan_disks():
"""Get details about the attached disks""" """Get details about the attached disks"""
disks = get_disks() disks = get_disks()
@ -343,6 +358,7 @@ def scan_disks():
# Done # Done
return disks return disks
def select_disk(title='Which disk?', disks=[]): def select_disk(title='Which disk?', disks=[]):
"""Select a disk from the attached disks""" """Select a disk from the attached disks"""
# Build menu # Build menu
@ -391,6 +407,7 @@ def select_disk(title='Which disk?', disks=[]):
elif (selection == 'M'): elif (selection == 'M'):
raise GenericAbort raise GenericAbort
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -8,6 +8,7 @@ from collections import OrderedDict
from functions.sensors import * from functions.sensors import *
from functions.tmux import * from functions.tmux import *
# STATIC VARIABLES # STATIC VARIABLES
ATTRIBUTES = { ATTRIBUTES = {
'NVMe': { 'NVMe': {
@ -83,13 +84,16 @@ TMUX_LAYOUT = OrderedDict({
'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True}, 'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True},
}) })
# Regex # Regex
REGEX_ERROR_STATUS = re.compile('|'.join(STATUSES['RED'])) REGEX_ERROR_STATUS = re.compile('|'.join(STATUSES['RED']))
# Error Classes # Error Classes
class DeviceTooSmallError(Exception): class DeviceTooSmallError(Exception):
pass pass
# Classes # Classes
class CpuObj(): class CpuObj():
"""Object for tracking CPU specific data.""" """Object for tracking CPU specific data."""
@ -130,6 +134,7 @@ class CpuObj():
return report return report
class DiskObj(): class DiskObj():
"""Object for tracking disk specific data.""" """Object for tracking disk specific data."""
def __init__(self, disk_path): def __init__(self, disk_path):
@ -487,6 +492,7 @@ class DiskObj():
for t in ['badblocks', 'I/O Benchmark']: for t in ['badblocks', 'I/O Benchmark']:
self.disable_test(t, 'Denied') self.disable_test(t, 'Denied')
class State(): class State():
"""Object to track device objects and overall state.""" """Object to track device objects and overall state."""
def __init__(self): def __init__(self):
@ -559,6 +565,7 @@ class State():
if not skip_disk: if not skip_disk:
self.disks.append(disk_obj) self.disks.append(disk_obj)
class TestObj(): class TestObj():
"""Object to track test data.""" """Object to track test data."""
def __init__(self, dev, label=None, info_label=False): def __init__(self, dev, label=None, info_label=False):
@ -589,6 +596,7 @@ class TestObj():
self.status = build_status_string( self.status = build_status_string(
self.label, 'Working', self.info_label) self.label, 'Working', self.info_label)
# Functions # Functions
def build_outer_panes(state): def build_outer_panes(state):
"""Build top and side panes.""" """Build top and side panes."""
@ -611,6 +619,7 @@ def build_outer_panes(state):
lines=SIDE_PANE_WIDTH, lines=SIDE_PANE_WIDTH,
watch=state.progress_out) watch=state.progress_out)
def build_status_string(label, status, info_label=False): def build_status_string(label, status, info_label=False):
"""Build status string with appropriate colors.""" """Build status string with appropriate colors."""
status_color = COLORS['CLEAR'] status_color = COLORS['CLEAR']
@ -626,6 +635,7 @@ def build_status_string(label, status, info_label=False):
s_w=SIDE_PANE_WIDTH-len(label), s_w=SIDE_PANE_WIDTH-len(label),
**COLORS) **COLORS)
def fix_tmux_panes(state, tmux_layout): def fix_tmux_panes(state, tmux_layout):
"""Fix pane sizes if the window has been resized.""" """Fix pane sizes if the window has been resized."""
needs_fixed = False needs_fixed = False
@ -669,6 +679,7 @@ def fix_tmux_panes(state, tmux_layout):
# Resize pane # Resize pane
tmux_resize_pane(pane_id=target, **v) tmux_resize_pane(pane_id=target, **v)
def generate_horizontal_graph(rates, oneline=False): def generate_horizontal_graph(rates, oneline=False):
"""Generate horizontal graph from rates, returns list.""" """Generate horizontal graph from rates, returns list."""
graph = ['', '', '', ''] graph = ['', '', '', '']
@ -714,6 +725,7 @@ def generate_horizontal_graph(rates, oneline=False):
else: else:
return graph return graph
def get_graph_step(rate, scale=16): def get_graph_step(rate, scale=16):
"""Get graph step based on rate and scale, returns int.""" """Get graph step based on rate and scale, returns int."""
m_rate = rate / (1024**2) m_rate = rate / (1024**2)
@ -726,6 +738,7 @@ def get_graph_step(rate, scale=16):
break break
return step return step
def get_read_rate(s): def get_read_rate(s):
"""Get read rate in bytes/s from dd progress output.""" """Get read rate in bytes/s from dd progress output."""
real_rate = None real_rate = None
@ -734,6 +747,7 @@ def get_read_rate(s):
real_rate = convert_to_bytes(human_rate) real_rate = convert_to_bytes(human_rate)
return real_rate return real_rate
def menu_diags(state, args): def menu_diags(state, args):
"""Main menu to select and run HW tests.""" """Main menu to select and run HW tests."""
args = [a.lower() for a in args] args = [a.lower() for a in args]
@ -840,12 +854,14 @@ def menu_diags(state, args):
elif selection == 'S': elif selection == 'S':
run_hw_tests(state) run_hw_tests(state)
def run_audio_test(): def run_audio_test():
"""Run audio test.""" """Run audio test."""
clear_screen() clear_screen()
run_program(['hw-diags-audio'], check=False, pipe=False) run_program(['hw-diags-audio'], check=False, pipe=False)
pause('Press Enter to return to main menu... ') pause('Press Enter to return to main menu... ')
def run_badblocks_test(state, test): def run_badblocks_test(state, test):
"""Run a read-only surface scan with badblocks.""" """Run a read-only surface scan with badblocks."""
# Bail early # Bail early
@ -939,6 +955,7 @@ def run_badblocks_test(state, test):
# Cleanup # Cleanup
tmux_kill_pane(state.panes['badblocks']) tmux_kill_pane(state.panes['badblocks'])
def run_hw_tests(state): def run_hw_tests(state):
"""Run enabled hardware tests.""" """Run enabled hardware tests."""
print_standard('Scanning devices...') print_standard('Scanning devices...')
@ -1016,6 +1033,7 @@ def run_hw_tests(state):
# Cleanup # Cleanup
tmux_kill_pane(*state.panes.values()) tmux_kill_pane(*state.panes.values())
def run_io_benchmark(state, test): def run_io_benchmark(state, test):
"""Run a read-only I/O benchmark using dd.""" """Run a read-only I/O benchmark using dd."""
# Bail early # Bail early
@ -1173,11 +1191,13 @@ def run_io_benchmark(state, test):
# Cleanup # Cleanup
tmux_kill_pane(state.panes['io_benchmark']) tmux_kill_pane(state.panes['io_benchmark'])
def run_keyboard_test(): def run_keyboard_test():
"""Run keyboard test.""" """Run keyboard test."""
clear_screen() clear_screen()
run_program(['xev', '-event', 'keyboard'], check=False, pipe=False) run_program(['xev', '-event', 'keyboard'], check=False, pipe=False)
def run_mprime_test(state, test): def run_mprime_test(state, test):
"""Test CPU with Prime95 and track temps.""" """Test CPU with Prime95 and track temps."""
# Bail early # Bail early
@ -1371,12 +1391,14 @@ def run_mprime_test(state, test):
tmux_kill_pane(state.panes['mprime'], state.panes['Temps']) tmux_kill_pane(state.panes['mprime'], state.panes['Temps'])
test.monitor_proc.kill() test.monitor_proc.kill()
def run_network_test(): def run_network_test():
"""Run network test.""" """Run network test."""
clear_screen() clear_screen()
run_program(['hw-diags-network'], check=False, pipe=False) run_program(['hw-diags-network'], check=False, pipe=False)
pause('Press Enter to return to main menu... ') pause('Press Enter to return to main menu... ')
def run_nvme_smart_tests(state, test): def run_nvme_smart_tests(state, test):
"""Run NVMe or SMART test for test.dev.""" """Run NVMe or SMART test for test.dev."""
# Bail early # Bail early
@ -1520,6 +1542,7 @@ def run_nvme_smart_tests(state, test):
# Done # Done
update_progress_pane(state) update_progress_pane(state)
def secret_screensaver(screensaver=None): def secret_screensaver(screensaver=None):
"""Show screensaver.""" """Show screensaver."""
if screensaver == 'matrix': if screensaver == 'matrix':
@ -1530,6 +1553,7 @@ def secret_screensaver(screensaver=None):
raise Exception('Invalid screensaver') raise Exception('Invalid screensaver')
run_program(cmd, check=False, pipe=False) run_program(cmd, check=False, pipe=False)
def show_report(report, log_report=False): def show_report(report, log_report=False):
"""Show report on screen and optionally save to log w/out color.""" """Show report on screen and optionally save to log w/out color."""
for line in report: for line in report:
@ -1537,6 +1561,7 @@ def show_report(report, log_report=False):
if log_report: if log_report:
print_log(strip_colors(line)) print_log(strip_colors(line))
def show_results(state): def show_results(state):
"""Show results for all tests.""" """Show results for all tests."""
clear_screen() clear_screen()
@ -1564,6 +1589,7 @@ def show_results(state):
show_report(disk.generate_disk_report(), log_report=True) show_report(disk.generate_disk_report(), log_report=True)
print_standard(' ') print_standard(' ')
def update_main_options(state, selection, main_options): def update_main_options(state, selection, main_options):
"""Update menu and state based on selection.""" """Update menu and state based on selection."""
index = int(selection) - 1 index = int(selection) - 1
@ -1607,6 +1633,7 @@ def update_main_options(state, selection, main_options):
# Done # Done
return main_options return main_options
def update_io_progress(percent, rate, progress_file): def update_io_progress(percent, rate, progress_file):
"""Update I/O progress file.""" """Update I/O progress file."""
bar_color = COLORS['CLEAR'] bar_color = COLORS['CLEAR']
@ -1631,6 +1658,7 @@ def update_io_progress(percent, rate, progress_file):
with open(progress_file, 'a') as f: with open(progress_file, 'a') as f:
f.write(line) f.write(line)
def update_progress_pane(state): def update_progress_pane(state):
"""Update progress file for side pane.""" """Update progress file for side pane."""
output = [] output = []
@ -1658,6 +1686,7 @@ def update_progress_pane(state):
with open(state.progress_out, 'w') as f: with open(state.progress_out, 'w') as f:
f.writelines(output) f.writelines(output)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -6,15 +6,6 @@ from operator import itemgetter
from functions.common import * from functions.common import *
from functions.activation import * from functions.activation import *
# Regex
REGEX_OFFICE = re.compile(
r'(Microsoft (Office\s+'
r'(365|Enterprise|Home|Pro(\s|fessional)'
r'|Single|Small|Standard|Starter|Ultimate|system)'
r'|Works[-\s\d]+\d)'
r'|(Libre|Open|Star)\s*Office'
r'|WordPerfect|Gnumeric|Abiword)',
re.IGNORECASE)
# STATIC VARIABLES # STATIC VARIABLES
REG_PROFILE_LIST = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' REG_PROFILE_LIST = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
@ -55,6 +46,18 @@ SHELL_FOLDERS = {
), ),
} }
# Regex
REGEX_OFFICE = re.compile(
r'(Microsoft (Office\s+'
r'(365|Enterprise|Home|Pro(\s|fessional)'
r'|Single|Small|Standard|Starter|Ultimate|system)'
r'|Works[-\s\d]+\d)'
r'|(Libre|Open|Star)\s*Office'
r'|WordPerfect|Gnumeric|Abiword)',
re.IGNORECASE)
def backup_file_list(): def backup_file_list():
"""Export current file listing for the system.""" """Export current file listing for the system."""
extract_item('Everything', silent=True) extract_item('Everything', silent=True)
@ -66,6 +69,7 @@ def backup_file_list():
global_vars['Env']['SYSTEMDRIVE']] global_vars['Env']['SYSTEMDRIVE']]
run_program(cmd) run_program(cmd)
def backup_power_plans(): def backup_power_plans():
"""Export current power plans.""" """Export current power plans."""
os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format( os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format(
@ -83,6 +87,7 @@ def backup_power_plans():
cmd = ['powercfg', '-export', out, guid] cmd = ['powercfg', '-export', out, guid]
run_program(cmd, check=False) run_program(cmd, check=False)
def backup_registry(overwrite=False): def backup_registry(overwrite=False):
"""Backup registry including user hives.""" """Backup registry including user hives."""
extract_item('erunt', silent=True) extract_item('erunt', silent=True)
@ -97,6 +102,7 @@ def backup_registry(overwrite=False):
cmd.append('/noconfirmdelete') cmd.append('/noconfirmdelete')
run_program(cmd) run_program(cmd)
def get_folder_size(path): def get_folder_size(path):
"""Get (human-readable) size of folder passed, returns str.""" """Get (human-readable) size of folder passed, returns str."""
size = 'Unknown' size = 'Unknown'
@ -119,6 +125,7 @@ def get_folder_size(path):
size = human_readable_size(size) size = human_readable_size(size)
return size return size
def get_installed_antivirus(): def get_installed_antivirus():
"""Get list of installed Antivirus programs.""" """Get list of installed Antivirus programs."""
programs = [] programs = []
@ -149,6 +156,7 @@ def get_installed_antivirus():
programs = ['No programs found'] programs = ['No programs found']
return programs return programs
def get_installed_office(): def get_installed_office():
"""Get list of installed Office programs.""" """Get list of installed Office programs."""
programs = [] programs = []
@ -163,6 +171,7 @@ def get_installed_office():
programs = ['No programs found'] programs = ['No programs found']
return programs return programs
def get_shell_path(folder, user='current'): def get_shell_path(folder, user='current'):
"""Get shell path using knownpaths, returns str. """Get shell path using knownpaths, returns str.
@ -189,6 +198,7 @@ def get_shell_path(folder, user='current'):
return path return path
def get_user_data_paths(user): def get_user_data_paths(user):
"""Get user data paths for provided user, returns dict.""" """Get user data paths for provided user, returns dict."""
hive_path = user['SID'] hive_path = user['SID']
@ -273,6 +283,7 @@ def get_user_data_paths(user):
# Done # Done
return paths return paths
def get_user_folder_sizes(users): def get_user_folder_sizes(users):
"""Update list(users) to include folder paths and sizes.""" """Update list(users) to include folder paths and sizes."""
extract_item('du', filter='du*', silent=True) extract_item('du', filter='du*', silent=True)
@ -293,6 +304,7 @@ def get_user_folder_sizes(users):
u['Extra Folders'][folder]['Size'] = get_folder_size( u['Extra Folders'][folder]['Size'] = get_folder_size(
u['Extra Folders'][folder]['Path']) u['Extra Folders'][folder]['Path'])
def get_user_list(): def get_user_list():
"""Get user list via WMIC, returns list of dicts.""" """Get user list via WMIC, returns list of dicts."""
users = [] users = []
@ -325,6 +337,7 @@ def get_user_list():
# Done # Done
return users return users
def reg_path_exists(hive, path): def reg_path_exists(hive, path):
"""Test if specified path exists, returns bool.""" """Test if specified path exists, returns bool."""
try: try:
@ -334,6 +347,7 @@ def reg_path_exists(hive, path):
else: else:
return True return True
def run_aida64(): def run_aida64():
"""Run AIDA64 to save system reports.""" """Run AIDA64 to save system reports."""
extract_item('AIDA64', silent=True) extract_item('AIDA64', silent=True)
@ -372,6 +386,7 @@ def run_aida64():
'/TEXT', '/SILENT', '/SAFEST'] '/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False) run_program(cmd, check=False)
def run_bleachbit(cleaners=None, preview=True): def run_bleachbit(cleaners=None, preview=True):
"""Run BleachBit preview and save log. """Run BleachBit preview and save log.
@ -404,6 +419,7 @@ def run_bleachbit(cleaners=None, preview=True):
for line in out.stdout.decode().splitlines(): for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n') f.write(line.strip() + '\n')
def show_disk_usage(disk): def show_disk_usage(disk):
"""Show free and used space for a specified disk.""" """Show free and used space for a specified disk."""
print_standard('{:5}'.format(disk.device.replace('/', ' ')), print_standard('{:5}'.format(disk.device.replace('/', ' ')),
@ -423,6 +439,7 @@ def show_disk_usage(disk):
except Exception: except Exception:
print_warning('Unknown', timestamp=False) print_warning('Unknown', timestamp=False)
def show_free_space(indent=8, width=32): def show_free_space(indent=8, width=32):
"""Show free space info for all fixed disks.""" """Show free space info for all fixed disks."""
message = 'Free Space:' message = 'Free Space:'
@ -436,6 +453,7 @@ def show_free_space(indent=8, width=32):
except Exception: except Exception:
pass pass
def show_installed_ram(): def show_installed_ram():
"""Show installed RAM.""" """Show installed RAM."""
mem = psutil.virtual_memory() mem = psutil.virtual_memory()
@ -448,6 +466,7 @@ def show_installed_ram():
else: else:
print_error(human_readable_size(mem.total).strip(), timestamp=False) print_error(human_readable_size(mem.total).strip(), timestamp=False)
def show_os_activation(): def show_os_activation():
"""Show OS activation info.""" """Show OS activation info."""
act_str = get_activation_string() act_str = get_activation_string()
@ -458,6 +477,7 @@ def show_os_activation():
else: else:
print_error(act_str, timestamp=False) print_error(act_str, timestamp=False)
def show_os_name(): def show_os_name():
"""Show extended OS name (including warnings).""" """Show extended OS name (including warnings)."""
os_name = global_vars['OS']['DisplayName'] os_name = global_vars['OS']['DisplayName']
@ -475,6 +495,7 @@ def show_os_name():
else: else:
print_standard(os_name, timestamp=False) print_standard(os_name, timestamp=False)
def show_temp_files_size(): def show_temp_files_size():
"""Show total size of temp files identified by BleachBit.""" """Show total size of temp files identified by BleachBit."""
size = None size = None
@ -488,6 +509,7 @@ def show_temp_files_size():
else: else:
print_standard(size, timestamp=False) print_standard(size, timestamp=False)
def show_user_data_summary(indent=8, width=32): def show_user_data_summary(indent=8, width=32):
"""Print user data folder sizes for all users.""" """Print user data folder sizes for all users."""
users = get_user_list() users = get_user_list()
@ -520,6 +542,7 @@ def show_user_data_summary(indent=8, width=32):
size = folders[folder].get('Size', 'Unknown'), size = folders[folder].get('Size', 'Unknown'),
path = folders[folder].get('Path', 'Unknown'))) path = folders[folder].get('Path', 'Unknown')))
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -11,6 +11,7 @@ os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd()) sys.path.append(os.getcwd())
from functions.common import * from functions.common import *
# REGEX # REGEX
REGEX_VALID_IP = re.compile( REGEX_VALID_IP = re.compile(
r'(10.\d+.\d+.\d+' r'(10.\d+.\d+.\d+'
@ -18,6 +19,7 @@ REGEX_VALID_IP = re.compile(
r'|192.168.\d+.\d+)', r'|192.168.\d+.\d+)',
re.IGNORECASE) re.IGNORECASE)
def connect_to_network(): def connect_to_network():
"""Connect to network if not already connected.""" """Connect to network if not already connected."""
net_ifs = psutil.net_if_addrs() net_ifs = psutil.net_if_addrs()
@ -38,6 +40,7 @@ def connect_to_network():
function = run_program, function = run_program,
cmd = cmd) cmd = cmd)
def is_connected(): def is_connected():
"""Check for a valid private IP.""" """Check for a valid private IP."""
devs = psutil.net_if_addrs() devs = psutil.net_if_addrs()
@ -49,6 +52,7 @@ def is_connected():
# Else # Else
return False return False
def show_valid_addresses(): def show_valid_addresses():
"""Show all valid private IP addresses assigned to the system.""" """Show all valid private IP addresses assigned to the system."""
devs = psutil.net_if_addrs() devs = psutil.net_if_addrs()
@ -58,6 +62,7 @@ def show_valid_addresses():
# Valid IP found # Valid IP found
show_data(message=dev, data=family.address) show_data(message=dev, data=family.address)
def speedtest(): def speedtest():
"""Run a network speedtest using speedtest-cli.""" """Run a network speedtest using speedtest-cli."""
result = run_program(['speedtest-cli', '--simple']) result = run_program(['speedtest-cli', '--simple'])
@ -67,6 +72,7 @@ def speedtest():
output = [(a, float(b), c) for a, b, c in output] output = [(a, float(b), c) for a, b, c in output]
return ['{:10}{:6.2f} {}'.format(*line) for line in output] return ['{:10}{:6.2f} {}'.format(*line) for line in output]
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -2,12 +2,14 @@
from functions.common import * from functions.common import *
# Regex # Regex
REGEX_REGISTRY_DIRS = re.compile( REGEX_REGISTRY_DIRS = re.compile(
r'^(config$|RegBack$|System32$|Transfer|Win)', r'^(config$|RegBack$|System32$|Transfer|Win)',
re.IGNORECASE) re.IGNORECASE)
REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE) REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE)
def extract_keys(): def extract_keys():
"""Extract keys from provided hives and return a dict.""" """Extract keys from provided hives and return a dict."""
keys = {} keys = {}
@ -43,6 +45,7 @@ def extract_keys():
# Done # Done
return keys return keys
def list_clientdir_keys(): def list_clientdir_keys():
"""List product keys found in hives inside the ClientDir.""" """List product keys found in hives inside the ClientDir."""
keys = extract_keys() keys = extract_keys()
@ -57,6 +60,7 @@ def list_clientdir_keys():
return key_list return key_list
def find_software_hives(): def find_software_hives():
"""Search for transferred SW hives and return a list.""" """Search for transferred SW hives and return a list."""
hives = [] hives = []
@ -71,6 +75,7 @@ def find_software_hives():
return hives return hives
def get_product_keys(): def get_product_keys():
"""List product keys from saved report.""" """List product keys from saved report."""
keys = [] keys = []
@ -86,6 +91,7 @@ def get_product_keys():
else: else:
return ['No product keys found'] return ['No product keys found']
def run_produkey(): def run_produkey():
"""Run ProduKey and save report in the ClientDir.""" """Run ProduKey and save report in the ClientDir."""
extract_item('ProduKey', silent=True) extract_item('ProduKey', silent=True)
@ -107,6 +113,7 @@ def run_produkey():
log_file] log_file]
run_program(cmd, check=False) run_program(cmd, check=False)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -2,6 +2,7 @@
from functions.common import * from functions.common import *
def run_chkdsk(repair=False): def run_chkdsk(repair=False):
"""Run CHKDSK scan or schedule offline repairs.""" """Run CHKDSK scan or schedule offline repairs."""
if repair: if repair:
@ -9,6 +10,7 @@ def run_chkdsk(repair=False):
else: else:
run_chkdsk_scan() run_chkdsk_scan()
def run_chkdsk_scan(): def run_chkdsk_scan():
"""Run CHKDSK in a "split window" and report errors.""" """Run CHKDSK in a "split window" and report errors."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
@ -32,6 +34,7 @@ def run_chkdsk_scan():
for line in out.stdout.decode().splitlines(): for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n') f.write(line.strip() + '\n')
def run_chkdsk_offline(): def run_chkdsk_offline():
"""Set filesystem 'dirty bit' to force a chkdsk during next boot.""" """Set filesystem 'dirty bit' to force a chkdsk during next boot."""
cmd = [ cmd = [
@ -42,6 +45,7 @@ def run_chkdsk_offline():
if int(out.returncode) > 0: if int(out.returncode) > 0:
raise GenericError raise GenericError
def run_dism(repair=False): def run_dism(repair=False):
"""Run DISM to either scan or repair component store health.""" """Run DISM to either scan or repair component store health."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
@ -75,6 +79,7 @@ def run_dism(repair=False):
else: else:
raise UnsupportedOSError raise UnsupportedOSError
def run_kvrt(): def run_kvrt():
"""Run KVRT.""" """Run KVRT."""
extract_item('KVRT', silent=True) extract_item('KVRT', silent=True)
@ -86,6 +91,7 @@ def run_kvrt():
'-processlevel', '3'] '-processlevel', '3']
popen_program(cmd, pipe=False) popen_program(cmd, pipe=False)
def run_sfc_scan(): def run_sfc_scan():
"""Run SFC in a "split window" and report errors.""" """Run SFC in a "split window" and report errors."""
cmd = [ cmd = [
@ -109,6 +115,7 @@ def run_sfc_scan():
else: else:
raise GenericError raise GenericError
def run_tdsskiller(): def run_tdsskiller():
"""Run TDSSKiller.""" """Run TDSSKiller."""
extract_item('TDSSKiller', silent=True) extract_item('TDSSKiller', silent=True)
@ -122,6 +129,7 @@ def run_tdsskiller():
'-dcexact', '-tdlfs'] '-dcexact', '-tdlfs']
run_program(cmd, pipe=False) run_program(cmd, pipe=False)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -2,19 +2,23 @@
from functions.common import * from functions.common import *
# STATIC VARIABLES # STATIC VARIABLES
REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer' REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer'
def disable_safemode_msi(): def disable_safemode_msi():
"""Disable MSI access under safemode.""" """Disable MSI access under safemode."""
cmd = ['reg', 'delete', REG_MSISERVER, '/f'] cmd = ['reg', 'delete', REG_MSISERVER, '/f']
run_program(cmd) run_program(cmd)
def disable_safemode(): def disable_safemode():
"""Edit BCD to remove safeboot value.""" """Edit BCD to remove safeboot value."""
cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot'] cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot']
run_program(cmd) run_program(cmd)
def enable_safemode_msi(): def enable_safemode_msi():
"""Enable MSI access under safemode.""" """Enable MSI access under safemode."""
cmd = ['reg', 'add', REG_MSISERVER, '/f'] cmd = ['reg', 'add', REG_MSISERVER, '/f']
@ -23,15 +27,18 @@ def enable_safemode_msi():
'/t', 'REG_SZ', '/d', 'Service', '/f'] '/t', 'REG_SZ', '/d', 'Service', '/f']
run_program(cmd) run_program(cmd)
def enable_safemode(): def enable_safemode():
"""Edit BCD to set safeboot as default.""" """Edit BCD to set safeboot as default."""
cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network'] cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network']
run_program(cmd) run_program(cmd)
def reboot(delay=3): def reboot(delay=3):
cmd = ['shutdown', '-r', '-t', '{}'.format(delay)] cmd = ['shutdown', '-r', '-t', '{}'.format(delay)]
run_program(cmd, check=False) run_program(cmd, check=False)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -5,6 +5,7 @@ import re
from functions.tmux import * from functions.tmux import *
# STATIC VARIABLES # STATIC VARIABLES
TEMP_LIMITS = { TEMP_LIMITS = {
'GREEN': 60, 'GREEN': 60,
@ -13,9 +14,11 @@ TEMP_LIMITS = {
'RED': 90, 'RED': 90,
} }
# REGEX # REGEX
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m') REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
def clear_temps(sensor_data): def clear_temps(sensor_data):
"""Clear saved temps but keep structure, returns dict.""" """Clear saved temps but keep structure, returns dict."""
for _section, _adapters in sensor_data.items(): for _section, _adapters in sensor_data.items():
@ -23,6 +26,7 @@ def clear_temps(sensor_data):
for _source, _data in _sources.items(): for _source, _data in _sources.items():
_data['Temps'] = [] _data['Temps'] = []
def fix_sensor_str(s): def fix_sensor_str(s):
"""Cleanup string and return str.""" """Cleanup string and return str."""
s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', s, re.IGNORECASE) s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', s, re.IGNORECASE)
@ -36,6 +40,7 @@ def fix_sensor_str(s):
s = s.replace(' ', ' ') s = s.replace(' ', ' ')
return s return s
def generate_sensor_report( def generate_sensor_report(
sensor_data, *temp_labels, sensor_data, *temp_labels,
colors=True, core_only=False): colors=True, core_only=False):
@ -73,6 +78,7 @@ def generate_sensor_report(
# Done # Done
return report return report
def get_colored_temp_str(temp): def get_colored_temp_str(temp):
"""Get colored string based on temp, returns str.""" """Get colored string based on temp, returns str."""
try: try:
@ -97,6 +103,7 @@ def get_colored_temp_str(temp):
temp = temp, temp = temp,
**COLORS) **COLORS)
def get_raw_sensor_data(): def get_raw_sensor_data():
"""Read sensor data and return dict.""" """Read sensor data and return dict."""
data = {} data = {}
@ -110,6 +117,7 @@ def get_raw_sensor_data():
return data return data
def get_sensor_data(): def get_sensor_data():
"""Parse raw sensor data and return new dict.""" """Parse raw sensor data and return new dict."""
json_data = get_raw_sensor_data() json_data = get_raw_sensor_data()
@ -141,6 +149,7 @@ def get_sensor_data():
# Done # Done
return sensor_data return sensor_data
def get_temp_str(temp, colors=True): def get_temp_str(temp, colors=True):
"""Get temp string, returns str.""" """Get temp string, returns str."""
if colors: if colors:
@ -154,6 +163,7 @@ def get_temp_str(temp, colors=True):
'-' if temp < 0 else '', '-' if temp < 0 else '',
temp) temp)
def monitor_sensors(monitor_pane, monitor_file): def monitor_sensors(monitor_pane, monitor_file):
"""Continually update sensor data and report to screen.""" """Continually update sensor data and report to screen."""
sensor_data = get_sensor_data() sensor_data = get_sensor_data()
@ -166,6 +176,7 @@ def monitor_sensors(monitor_pane, monitor_file):
if monitor_pane and not tmux_poll_pane(monitor_pane): if monitor_pane and not tmux_poll_pane(monitor_pane):
break break
def save_average_temp(sensor_data, temp_label, seconds=10): def save_average_temp(sensor_data, temp_label, seconds=10):
"""Save average temps under temp_label, returns dict.""" """Save average temps under temp_label, returns dict."""
clear_temps(sensor_data) clear_temps(sensor_data)
@ -181,6 +192,7 @@ def save_average_temp(sensor_data, temp_label, seconds=10):
for _source, _data in _sources.items(): for _source, _data in _sources.items():
_data[temp_label] = sum(_data['Temps']) / len(_data['Temps']) _data[temp_label] = sum(_data['Temps']) / len(_data['Temps'])
def update_sensor_data(sensor_data): def update_sensor_data(sensor_data):
"""Read sensors and update existing sensor_data, returns dict.""" """Read sensors and update existing sensor_data, returns dict."""
json_data = get_raw_sensor_data() json_data = get_raw_sensor_data()
@ -193,12 +205,14 @@ def update_sensor_data(sensor_data):
_data['Max'] = max(_temp, _data['Max']) _data['Max'] = max(_temp, _data['Max'])
_data['Temps'].append(_temp) _data['Temps'].append(_temp)
def join_columns(column1, column2, width=55): def join_columns(column1, column2, width=55):
return '{:<{}}{}'.format( return '{:<{}}{}'.format(
column1, column1,
55+len(column1)-len(REGEX_COLORS.sub('', column1)), 55+len(column1)-len(REGEX_COLORS.sub('', column1)),
column2) column2)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -3,6 +3,7 @@
from functions.common import * from functions.common import *
from functions.update import * from functions.update import *
# STATIC VARIABLES # STATIC VARIABLES
HKU = winreg.HKEY_USERS HKU = winreg.HKEY_USERS
HKCR = winreg.HKEY_CLASSES_ROOT HKCR = winreg.HKEY_CLASSES_ROOT
@ -128,6 +129,7 @@ VCR_REDISTS = [
'/passive', '/norestart']}, '/passive', '/norestart']},
] ]
def config_classicstart(): def config_classicstart():
"""Configure ClassicStart.""" """Configure ClassicStart."""
# User level, not system level # User level, not system level
@ -180,14 +182,17 @@ def config_classicstart():
sleep(1) sleep(1)
popen_program(cs_exe) popen_program(cs_exe)
def config_explorer_system(): def config_explorer_system():
"""Configure Windows Explorer for all users.""" """Configure Windows Explorer for all users."""
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True) write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True)
def config_explorer_user(): def config_explorer_user():
"""Configure Windows Explorer for current user.""" """Configure Windows Explorer for current user."""
write_registry_settings(SETTINGS_EXPLORER_USER, all_users=False) write_registry_settings(SETTINGS_EXPLORER_USER, all_users=False)
def disable_windows_telemetry(): def disable_windows_telemetry():
"""Disable Windows 10 telemetry settings with O&O ShutUp10.""" """Disable Windows 10 telemetry settings with O&O ShutUp10."""
extract_item('ShutUp10', silent=True) extract_item('ShutUp10', silent=True)
@ -197,6 +202,7 @@ def disable_windows_telemetry():
'/quiet'] '/quiet']
run_program(cmd) run_program(cmd)
def update_clock(): def update_clock():
"""Set Timezone and sync clock.""" """Set Timezone and sync clock."""
run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False) run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False)
@ -209,6 +215,7 @@ def update_clock():
run_program(['net', 'start', 'w32ime'], check=False) run_program(['net', 'start', 'w32ime'], check=False)
run_program(['w32tm', '/resync', '/nowait'], check=False) run_program(['w32tm', '/resync', '/nowait'], check=False)
def write_registry_settings(settings, all_users=False): def write_registry_settings(settings, all_users=False):
"""Write registry values from custom dict of dicts.""" """Write registry values from custom dict of dicts."""
hive = HKCU hive = HKCU
@ -228,6 +235,7 @@ def write_registry_settings(settings, all_users=False):
for name, value in v.get('SZ Items', {}).items(): for name, value in v.get('SZ Items', {}).items():
winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value) winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value)
# Installations # Installations
def install_adobe_reader(): def install_adobe_reader():
"""Install Adobe Reader.""" """Install Adobe Reader."""
@ -240,10 +248,12 @@ def install_adobe_reader():
'EULA_ACCEPT=YES'] 'EULA_ACCEPT=YES']
run_program(cmd) run_program(cmd)
def install_chrome_extensions(): def install_chrome_extensions():
"""Install Google Chrome extensions for all users.""" """Install Google Chrome extensions for all users."""
write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True) write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True)
def install_classicstart_skin(): def install_classicstart_skin():
"""Extract ClassicStart skin to installation folder.""" """Extract ClassicStart skin to installation folder."""
if global_vars['OS']['Version'] not in ('8', '8.1', '10'): if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
@ -257,6 +267,7 @@ def install_classicstart_skin():
os.makedirs(dest_path, exist_ok=True) os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest) shutil.copy(source, dest)
def install_firefox_extensions(): def install_firefox_extensions():
"""Install Firefox extensions for all users.""" """Install Firefox extensions for all users."""
dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format( dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format(
@ -277,6 +288,7 @@ def install_firefox_extensions():
source_path] source_path]
run_program(cmd) run_program(cmd)
def install_ninite_bundle(mse=False): def install_ninite_bundle(mse=False):
"""Run Ninite file(s) based on OS version.""" """Run Ninite file(s) based on OS version."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
@ -292,6 +304,7 @@ def install_ninite_bundle(mse=False):
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Legacy.exe'.format( popen_program(r'{BaseDir}\Installers\Extras\Bundles\Legacy.exe'.format(
**global_vars)) **global_vars))
def install_vcredists(): def install_vcredists():
"""Install all supported Visual C++ runtimes.""" """Install all supported Visual C++ runtimes."""
extract_item('_vcredists', silent=True) extract_item('_vcredists', silent=True)
@ -307,16 +320,20 @@ def install_vcredists():
os.chdir(prev_dir) os.chdir(prev_dir)
# Misc # Misc
def open_device_manager(): def open_device_manager():
popen_program(['mmc', 'devmgmt.msc']) popen_program(['mmc', 'devmgmt.msc'])
def open_windows_activation(): def open_windows_activation():
popen_program(['slui']) popen_program(['slui'])
def open_windows_updates(): def open_windows_updates():
popen_program(['control', '/name', 'Microsoft.WindowsUpdate']) popen_program(['control', '/name', 'Microsoft.WindowsUpdate'])
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -4,6 +4,7 @@ import ctypes
from functions.common import * from functions.common import *
# STATIC VARIABLES # STATIC VARIABLES
AUTORUNS_SETTINGS = { AUTORUNS_SETTINGS = {
r'Software\Sysinternals\AutoRuns': { r'Software\Sysinternals\AutoRuns': {
@ -26,6 +27,7 @@ AUTORUNS_SETTINGS = {
}, },
} }
def check_connection(): def check_connection():
"""Check if the system is online and optionally abort the script.""" """Check if the system is online and optionally abort the script."""
while True: while True:
@ -38,6 +40,7 @@ def check_connection():
else: else:
abort() abort()
def check_secure_boot_status(show_alert=False): def check_secure_boot_status(show_alert=False):
"""Checks UEFI Secure Boot status via PowerShell.""" """Checks UEFI Secure Boot status via PowerShell."""
boot_mode = get_boot_mode() boot_mode = get_boot_mode()
@ -77,6 +80,7 @@ def check_secure_boot_status(show_alert=False):
show_alert_box('Secure Boot ERROR') show_alert_box('Secure Boot ERROR')
raise GenericError raise GenericError
def get_boot_mode(): def get_boot_mode():
"""Check if Windows is booted in UEFI or Legacy mode, returns str.""" """Check if Windows is booted in UEFI or Legacy mode, returns str."""
kernel = ctypes.windll.kernel32 kernel = ctypes.windll.kernel32
@ -98,6 +102,7 @@ def get_boot_mode():
return type_str return type_str
def run_autoruns(): def run_autoruns():
"""Run AutoRuns in the background with VirusTotal checks enabled.""" """Run AutoRuns in the background with VirusTotal checks enabled."""
extract_item('Autoruns', filter='autoruns*', silent=True) extract_item('Autoruns', filter='autoruns*', silent=True)
@ -109,6 +114,7 @@ def run_autoruns():
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value) winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
popen_program(global_vars['Tools']['AutoRuns'], minimized=True) popen_program(global_vars['Tools']['AutoRuns'], minimized=True)
def run_hwinfo_sensors(): def run_hwinfo_sensors():
"""Run HWiNFO sensors.""" """Run HWiNFO sensors."""
path = r'{BinDir}\HWiNFO'.format(**global_vars) path = r'{BinDir}\HWiNFO'.format(**global_vars)
@ -122,12 +128,14 @@ def run_hwinfo_sensors():
f.write('SummaryOnly=0\n') f.write('SummaryOnly=0\n')
popen_program(global_vars['Tools']['HWiNFO']) popen_program(global_vars['Tools']['HWiNFO'])
def run_nircmd(*cmd): def run_nircmd(*cmd):
"""Run custom NirCmd.""" """Run custom NirCmd."""
extract_item('NirCmd', silent=True) extract_item('NirCmd', silent=True)
cmd = [global_vars['Tools']['NirCmd'], *cmd] cmd = [global_vars['Tools']['NirCmd'], *cmd]
run_program(cmd, check=False) run_program(cmd, check=False)
def run_xmplay(): def run_xmplay():
"""Run XMPlay to test audio.""" """Run XMPlay to test audio."""
extract_item('XMPlay', silent=True) extract_item('XMPlay', silent=True)
@ -141,6 +149,7 @@ def run_xmplay():
# Open XMPlay # Open XMPlay
popen_program(cmd) popen_program(cmd)
def run_hitmanpro(): def run_hitmanpro():
"""Run HitmanPro in the background.""" """Run HitmanPro in the background."""
extract_item('HitmanPro', silent=True) extract_item('HitmanPro', silent=True)
@ -150,6 +159,7 @@ def run_hitmanpro():
r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)] r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)]
popen_program(cmd) popen_program(cmd)
def run_process_killer(): def run_process_killer():
"""Kill most running processes skipping those in the whitelist.txt.""" """Kill most running processes skipping those in the whitelist.txt."""
# borrowed from TronScript (reddit.com/r/TronScript) # borrowed from TronScript (reddit.com/r/TronScript)
@ -160,6 +170,7 @@ def run_process_killer():
run_program(['ProcessKiller.exe', '/silent'], check=False) run_program(['ProcessKiller.exe', '/silent'], check=False)
os.chdir(prev_dir) os.chdir(prev_dir)
def run_rkill(): def run_rkill():
"""Run RKill and cleanup afterwards.""" """Run RKill and cleanup afterwards."""
extract_item('RKill', silent=True) extract_item('RKill', silent=True)
@ -180,11 +191,13 @@ def run_rkill():
dest = non_clobber_rename(dest) dest = non_clobber_rename(dest)
shutil.move(item.path, dest) shutil.move(item.path, dest)
def show_alert_box(message, title='Wizard Kit Warning'): def show_alert_box(message, title='Wizard Kit Warning'):
"""Show Windows alert box with message.""" """Show Windows alert box with message."""
message_box = ctypes.windll.user32.MessageBoxW message_box = ctypes.windll.user32.MessageBoxW
message_box(None, message, title, 0x00001030) message_box(None, message, title, 0x00001030)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -2,12 +2,14 @@
from functions.common import * from functions.common import *
def create_file(filepath): def create_file(filepath):
"""Create file if it doesn't exist.""" """Create file if it doesn't exist."""
if not os.path.exists(filepath): if not os.path.exists(filepath):
with open(filepath, 'w') as f: with open(filepath, 'w') as f:
f.write('') f.write('')
def tmux_get_pane_size(pane_id=None): def tmux_get_pane_size(pane_id=None):
"""Get target, or current, pane size, returns tuple.""" """Get target, or current, pane size, returns tuple."""
x = -1 x = -1
@ -29,6 +31,7 @@ def tmux_get_pane_size(pane_id=None):
return (x, y) return (x, y)
def tmux_kill_all_panes(pane_id=None): def tmux_kill_all_panes(pane_id=None):
"""Kill all tmux panes except the active pane or pane_id if specified.""" """Kill all tmux panes except the active pane or pane_id if specified."""
cmd = ['tmux', 'kill-pane', '-a'] cmd = ['tmux', 'kill-pane', '-a']
@ -36,12 +39,14 @@ def tmux_kill_all_panes(pane_id=None):
cmd.extend(['-t', pane_id]) cmd.extend(['-t', pane_id])
run_program(cmd, check=False) run_program(cmd, check=False)
def tmux_kill_pane(*panes): def tmux_kill_pane(*panes):
"""Kill tmux pane by id.""" """Kill tmux pane by id."""
cmd = ['tmux', 'kill-pane', '-t'] cmd = ['tmux', 'kill-pane', '-t']
for pane_id in panes: for pane_id in panes:
run_program(cmd+[pane_id], check=False) run_program(cmd+[pane_id], check=False)
def tmux_poll_pane(pane_id): def tmux_poll_pane(pane_id):
"""Check if pane exists, returns bool.""" """Check if pane exists, returns bool."""
cmd = ['tmux', 'list-panes', '-F', '#D'] cmd = ['tmux', 'list-panes', '-F', '#D']
@ -49,6 +54,7 @@ def tmux_poll_pane(pane_id):
panes = result.stdout.decode().splitlines() panes = result.stdout.decode().splitlines()
return pane_id in panes return pane_id in panes
def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs): def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
"""Resize pane to specific hieght or width.""" """Resize pane to specific hieght or width."""
if not x and not y: if not x and not y:
@ -65,6 +71,7 @@ def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
run_program(cmd, check=False) run_program(cmd, check=False)
def tmux_split_window( def tmux_split_window(
lines=None, percent=None, lines=None, percent=None,
behind=False, vertical=False, behind=False, vertical=False,
@ -115,6 +122,7 @@ def tmux_split_window(
result = run_program(cmd) result = run_program(cmd)
return result.stdout.decode().strip() return result.stdout.decode().strip()
def tmux_update_pane( def tmux_update_pane(
pane_id, command=None, working_dir=None, pane_id, command=None, working_dir=None,
text=None, watch=None, watch_cmd='cat'): text=None, watch=None, watch_cmd='cat'):
@ -142,6 +150,7 @@ def tmux_update_pane(
run_program(cmd) run_program(cmd)
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -8,6 +8,7 @@ from settings.launchers import *
from settings.music import * from settings.music import *
from settings.sources import * from settings.sources import *
def compress_and_remove_item(item): def compress_and_remove_item(item):
"""Compress and delete an item unless an error is encountered.""" """Compress and delete an item unless an error is encountered."""
try: try:
@ -17,6 +18,7 @@ def compress_and_remove_item(item):
else: else:
remove_item(item.path) remove_item(item.path)
def compress_item(item): def compress_item(item):
"""Compress an item in a 7-Zip archive using the ARCHIVE_PASSWORD.""" """Compress an item in a 7-Zip archive using the ARCHIVE_PASSWORD."""
# Prep # Prep
@ -42,6 +44,7 @@ def compress_item(item):
# Done # Done
os.chdir(prev_dir) os.chdir(prev_dir)
def download_generic(out_dir, out_name, source_url): def download_generic(out_dir, out_name, source_url):
"""Downloads a file using requests.""" """Downloads a file using requests."""
## Code based on this Q&A: https://stackoverflow.com/q/16694907 ## Code based on this Q&A: https://stackoverflow.com/q/16694907
@ -59,10 +62,12 @@ def download_generic(out_dir, out_name, source_url):
except: except:
raise GenericError('Failed to download file.') raise GenericError('Failed to download file.')
def download_to_temp(out_name, source_url): def download_to_temp(out_name, source_url):
"""Download a file to the TmpDir.""" """Download a file to the TmpDir."""
download_generic(global_vars['TmpDir'], out_name, source_url) download_generic(global_vars['TmpDir'], out_name, source_url)
def extract_generic(source, dest, mode='x', sz_args=[]): def extract_generic(source, dest, mode='x', sz_args=[]):
"""Extract a file to a destination.""" """Extract a file to a destination."""
cmd = [ cmd = [
@ -73,12 +78,14 @@ def extract_generic(source, dest, mode='x', sz_args=[]):
cmd.extend(sz_args) cmd.extend(sz_args)
run_program(cmd) run_program(cmd)
def extract_temp_to_bin(source, item, mode='x', sz_args=[]): def extract_temp_to_bin(source, item, mode='x', sz_args=[]):
"""Extract a file to the .bin folder.""" """Extract a file to the .bin folder."""
source = r'{}\{}'.format(global_vars['TmpDir'], source) source = r'{}\{}'.format(global_vars['TmpDir'], source)
dest = r'{}\{}'.format(global_vars['BinDir'], item) dest = r'{}\{}'.format(global_vars['BinDir'], item)
extract_generic(source, dest, mode, sz_args) extract_generic(source, dest, mode, sz_args)
def extract_temp_to_cbin(source, item, mode='x', sz_args=[]): def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
"""Extract a file to the .cbin folder.""" """Extract a file to the .cbin folder."""
source = r'{}\{}'.format(global_vars['TmpDir'], source) source = r'{}\{}'.format(global_vars['TmpDir'], source)
@ -88,6 +95,7 @@ def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
shutil.copytree(include_path, dest) shutil.copytree(include_path, dest)
extract_generic(source, dest, mode, sz_args) extract_generic(source, dest, mode, sz_args)
def generate_launcher(section, name, options): def generate_launcher(section, name, options):
"""Generate a launcher script.""" """Generate a launcher script."""
# Prep # Prep
@ -125,6 +133,7 @@ def generate_launcher(section, name, options):
# f.writelines(out_text) # f.writelines(out_text)
f.write('\n'.join(out_text)) f.write('\n'.join(out_text))
def remove_item(item_path): def remove_item(item_path):
"""Delete a file or folder.""" """Delete a file or folder."""
if os.path.exists(item_path): if os.path.exists(item_path):
@ -133,6 +142,7 @@ def remove_item(item_path):
else: else:
os.remove(item_path) os.remove(item_path)
def remove_from_kit(item): def remove_from_kit(item):
"""Delete a file or folder from the .bin/.cbin folders.""" """Delete a file or folder from the .bin/.cbin folders."""
item_locations = [] item_locations = []
@ -144,11 +154,13 @@ def remove_from_kit(item):
for item_path in item_locations: for item_path in item_locations:
remove_item(item_path) remove_item(item_path)
def remove_from_temp(item): def remove_from_temp(item):
"""Delete a file or folder from the TmpDir folder.""" """Delete a file or folder from the TmpDir folder."""
item_path = r'{}\{}'.format(global_vars['TmpDir'], item) item_path = r'{}\{}'.format(global_vars['TmpDir'], item)
remove_item(item_path) remove_item(item_path)
def resolve_dynamic_url(source_url, regex): def resolve_dynamic_url(source_url, regex):
"""Scan source_url for a url using the regex provided; returns str.""" """Scan source_url for a url using the regex provided; returns str."""
# Load the download page # Load the download page
@ -170,6 +182,7 @@ def resolve_dynamic_url(source_url, regex):
# Return # Return
return url return url
def scan_for_net_installers(server, family_name, min_year): def scan_for_net_installers(server, family_name, min_year):
"""Scan network shares for installers.""" """Scan network shares for installers."""
if not server['Mounted']: if not server['Mounted']:
@ -200,7 +213,8 @@ def scan_for_net_installers(server, family_name, min_year):
} }
umount_network_share(server) umount_network_share(server)
## Data Recovery ##
# Data Recovery
def update_testdisk(): def update_testdisk():
# Stop running processes # Stop running processes
for exe in ['fidentify_win.exe', 'photorec_win.exe', for exe in ['fidentify_win.exe', 'photorec_win.exe',
@ -226,7 +240,8 @@ def update_testdisk():
# Cleanup # Cleanup
remove_from_temp('testdisk_wip.zip') remove_from_temp('testdisk_wip.zip')
## Data Transfers ##
# Data Transfers
def update_fastcopy(): def update_fastcopy():
## NOTE: Lives in .bin uncompressed ## NOTE: Lives in .bin uncompressed
# Stop running processes # Stop running processes
@ -266,6 +281,7 @@ def update_fastcopy():
os.remove(r'{}\setup.exe'.format(_path, _installer)) os.remove(r'{}\setup.exe'.format(_path, _installer))
remove_from_temp('FastCopy.zip') remove_from_temp('FastCopy.zip')
def update_wimlib(): def update_wimlib():
# Stop running processes # Stop running processes
kill_process('wimlib-imagex.exe') kill_process('wimlib-imagex.exe')
@ -289,6 +305,7 @@ def update_wimlib():
remove_from_temp('wimlib32.zip') remove_from_temp('wimlib32.zip')
remove_from_temp('wimlib64.zip') remove_from_temp('wimlib64.zip')
def update_xyplorer(): def update_xyplorer():
# Stop running processes # Stop running processes
kill_process('XYplorerFree.exe') kill_process('XYplorerFree.exe')
@ -305,7 +322,8 @@ def update_xyplorer():
# Cleanup # Cleanup
remove_from_temp('xyplorer_free.zip') remove_from_temp('xyplorer_free.zip')
## Diagnostics ##
# Diagnostics
def update_aida64(): def update_aida64():
# Stop running processes # Stop running processes
kill_process('notepadplusplus.exe') kill_process('notepadplusplus.exe')
@ -322,6 +340,7 @@ def update_aida64():
# Cleanup # Cleanup
remove_from_temp('aida64.zip') remove_from_temp('aida64.zip')
def update_autoruns(): def update_autoruns():
# Stop running processes # Stop running processes
kill_process('Autoruns.exe') kill_process('Autoruns.exe')
@ -339,6 +358,7 @@ def update_autoruns():
# Cleanup # Cleanup
remove_from_temp('Autoruns.zip') remove_from_temp('Autoruns.zip')
def update_bleachbit(): def update_bleachbit():
# Stop running processes # Stop running processes
kill_process('bleachbit.exe') kill_process('bleachbit.exe')
@ -370,6 +390,7 @@ def update_bleachbit():
remove_from_temp('bleachbit.zip') remove_from_temp('bleachbit.zip')
remove_from_temp('Winapp2.zip') remove_from_temp('Winapp2.zip')
def update_bluescreenview(): def update_bluescreenview():
# Stop running processes # Stop running processes
for exe in ['BlueScreenView.exe', 'BlueScreenView64.exe']: for exe in ['BlueScreenView.exe', 'BlueScreenView64.exe']:
@ -394,6 +415,7 @@ def update_bluescreenview():
remove_from_temp('bluescreenview32.zip') remove_from_temp('bluescreenview32.zip')
remove_from_temp('bluescreenview64.zip') remove_from_temp('bluescreenview64.zip')
def update_erunt(): def update_erunt():
# Stop running processes # Stop running processes
kill_process('ERUNT.EXE') kill_process('ERUNT.EXE')
@ -410,6 +432,7 @@ def update_erunt():
# Cleanup # Cleanup
remove_from_temp('erunt.zip') remove_from_temp('erunt.zip')
def update_hitmanpro(): def update_hitmanpro():
# Stop running processes # Stop running processes
for exe in ['HitmanPro.exe', 'HitmanPro64.exe']: for exe in ['HitmanPro.exe', 'HitmanPro64.exe']:
@ -423,6 +446,7 @@ def update_hitmanpro():
download_generic(dest, 'HitmanPro.exe', SOURCE_URLS['HitmanPro32']) download_generic(dest, 'HitmanPro.exe', SOURCE_URLS['HitmanPro32'])
download_generic(dest, 'HitmanPro64.exe', SOURCE_URLS['HitmanPro64']) download_generic(dest, 'HitmanPro64.exe', SOURCE_URLS['HitmanPro64'])
def update_hwinfo(): def update_hwinfo():
## NOTE: Lives in .bin uncompressed ## NOTE: Lives in .bin uncompressed
# Stop running processes # Stop running processes
@ -438,6 +462,7 @@ def update_hwinfo():
# Cleanup # Cleanup
remove_from_temp('HWiNFO.zip') remove_from_temp('HWiNFO.zip')
def update_nircmd(): def update_nircmd():
# Stop running processes # Stop running processes
for exe in ['nircmdc.exe', 'nircmdc64.exe']: for exe in ['nircmdc.exe', 'nircmdc64.exe']:
@ -461,6 +486,7 @@ def update_nircmd():
remove_from_temp('nircmd32.zip') remove_from_temp('nircmd32.zip')
remove_from_temp('nircmd64.zip') remove_from_temp('nircmd64.zip')
def update_produkey(): def update_produkey():
# Stop running processes # Stop running processes
for exe in ['ProduKey.exe', 'ProduKey64.exe']: for exe in ['ProduKey.exe', 'ProduKey64.exe']:
@ -484,7 +510,8 @@ def update_produkey():
remove_from_temp('produkey32.zip') remove_from_temp('produkey32.zip')
remove_from_temp('produkey64.zip') remove_from_temp('produkey64.zip')
## Drivers ##
# Drivers
def update_intel_rst(): def update_intel_rst():
# Remove existing folders # Remove existing folders
remove_from_kit('Intel RST') remove_from_kit('Intel RST')
@ -500,6 +527,7 @@ def update_intel_rst():
for name, url in RST_SOURCES.items(): for name, url in RST_SOURCES.items():
download_generic(dest, name, url) download_generic(dest, name, url)
def update_intel_ssd_toolbox(): def update_intel_ssd_toolbox():
# Remove existing folders # Remove existing folders
remove_from_kit('Intel SSD Toolbox.exe') remove_from_kit('Intel SSD Toolbox.exe')
@ -510,6 +538,7 @@ def update_intel_ssd_toolbox():
'Intel SSD Toolbox.exe', 'Intel SSD Toolbox.exe',
SOURCE_URLS['Intel SSD Toolbox']) SOURCE_URLS['Intel SSD Toolbox'])
def update_samsung_magician(): def update_samsung_magician():
# Remove existing folders # Remove existing folders
remove_from_kit('Samsung Magician.exe') remove_from_kit('Samsung Magician.exe')
@ -528,6 +557,7 @@ def update_samsung_magician():
# Cleanup # Cleanup
remove_from_temp('Samsung Magician.zip') remove_from_temp('Samsung Magician.zip')
def update_sdi_origin(): def update_sdi_origin():
# Download aria2 # Download aria2
download_to_temp('aria2.zip', SOURCE_URLS['aria2']) download_to_temp('aria2.zip', SOURCE_URLS['aria2'])
@ -585,7 +615,8 @@ def update_sdi_origin():
remove_from_temp('sdio.torrent') remove_from_temp('sdio.torrent')
remove_from_temp('sdio_themes.zip') remove_from_temp('sdio_themes.zip')
## Installers ##
# Installers
def update_adobe_reader_dc(): def update_adobe_reader_dc():
# Prep # Prep
dest = r'{}\Installers\Extras\Office'.format( dest = r'{}\Installers\Extras\Office'.format(
@ -601,6 +632,7 @@ def update_adobe_reader_dc():
download_generic( download_generic(
dest, 'Adobe Reader DC.exe', SOURCE_URLS['Adobe Reader DC']) dest, 'Adobe Reader DC.exe', SOURCE_URLS['Adobe Reader DC'])
def update_macs_fan_control(): def update_macs_fan_control():
# Prep # Prep
dest = r'{}\Installers'.format( dest = r'{}\Installers'.format(
@ -616,6 +648,7 @@ def update_macs_fan_control():
download_generic( download_generic(
dest, 'Macs Fan Control.exe', SOURCE_URLS['Macs Fan Control']) dest, 'Macs Fan Control.exe', SOURCE_URLS['Macs Fan Control'])
def update_office(): def update_office():
# Remove existing folders # Remove existing folders
remove_from_kit('_Office') remove_from_kit('_Office')
@ -644,6 +677,7 @@ def update_office():
# Cleanup # Cleanup
remove_from_temp('odt{}.exe'.format(year)) remove_from_temp('odt{}.exe'.format(year))
def update_classic_start_skin(): def update_classic_start_skin():
# Remove existing folders # Remove existing folders
remove_from_kit('ClassicStartSkin') remove_from_kit('ClassicStartSkin')
@ -654,6 +688,7 @@ def update_classic_start_skin():
'Metro-Win10-Black.skin7', 'Metro-Win10-Black.skin7',
SOURCE_URLS['ClassicStartSkin']) SOURCE_URLS['ClassicStartSkin'])
def update_vcredists(): def update_vcredists():
# Remove existing folders # Remove existing folders
remove_from_kit('_vcredists') remove_from_kit('_vcredists')
@ -674,6 +709,7 @@ def update_vcredists():
'vcredist.exe', 'vcredist.exe',
VCREDIST_SOURCES[year][bit]) VCREDIST_SOURCES[year][bit])
def update_one_ninite(section, dest, name, url, indent=8, width=40): def update_one_ninite(section, dest, name, url, indent=8, width=40):
# Prep # Prep
url = 'https://ninite.com/{}/ninite.exe'.format(url) url = 'https://ninite.com/{}/ninite.exe'.format(url)
@ -690,6 +726,7 @@ def update_one_ninite(section, dest, name, url, indent=8, width=40):
remove_item(installer_dest) remove_item(installer_dest)
shutil.copy(r'{}\{}'.format(dest, name), installer_dest) shutil.copy(r'{}\{}'.format(dest, name), installer_dest)
def update_all_ninite(indent=8, width=40, other_results={}): def update_all_ninite(indent=8, width=40, other_results={}):
print_info('{}Ninite'.format(' '*int(indent/2))) print_info('{}Ninite'.format(' '*int(indent/2)))
for section in sorted(NINITE_SOURCES.keys()): for section in sorted(NINITE_SOURCES.keys()):
@ -700,7 +737,8 @@ def update_all_ninite(indent=8, width=40, other_results={}):
other_results=other_results, indent=indent, width=width, other_results=other_results, indent=indent, width=width,
section=section, dest=dest, name=name, url=url) section=section, dest=dest, name=name, url=url)
## Misc ##
# Misc
def update_caffeine(): def update_caffeine():
# Stop running processes # Stop running processes
kill_process('caffeine.exe') kill_process('caffeine.exe')
@ -717,6 +755,7 @@ def update_caffeine():
# Cleanup # Cleanup
remove_from_temp('caffeine.zip') remove_from_temp('caffeine.zip')
def update_du(): def update_du():
# Stop running processes # Stop running processes
kill_process('du.exe') kill_process('du.exe')
@ -734,6 +773,7 @@ def update_du():
# Cleanup # Cleanup
remove_from_temp('du.zip') remove_from_temp('du.zip')
def update_everything(): def update_everything():
# Stop running processes # Stop running processes
for exe in ['Everything.exe', 'Everything64.exe']: for exe in ['Everything.exe', 'Everything64.exe']:
@ -758,6 +798,7 @@ def update_everything():
remove_from_temp('everything32.zip') remove_from_temp('everything32.zip')
remove_from_temp('everything64.zip') remove_from_temp('everything64.zip')
def update_firefox_ublock_origin(): def update_firefox_ublock_origin():
# Remove existing folders # Remove existing folders
remove_from_kit('FirefoxExtensions') remove_from_kit('FirefoxExtensions')
@ -768,6 +809,7 @@ def update_firefox_ublock_origin():
'ublock_origin.xpi', 'ublock_origin.xpi',
SOURCE_URLS['Firefox uBO']) SOURCE_URLS['Firefox uBO'])
def update_notepadplusplus(): def update_notepadplusplus():
# Stop running processes # Stop running processes
kill_process('notepadplusplus.exe') kill_process('notepadplusplus.exe')
@ -788,6 +830,7 @@ def update_notepadplusplus():
# Cleanup # Cleanup
remove_from_temp('npp.7z') remove_from_temp('npp.7z')
def update_putty(): def update_putty():
# Stop running processes # Stop running processes
kill_process('PUTTY.EXE') kill_process('PUTTY.EXE')
@ -804,6 +847,7 @@ def update_putty():
# Cleanup # Cleanup
remove_from_temp('putty.zip') remove_from_temp('putty.zip')
def update_wiztree(): def update_wiztree():
# Stop running processes # Stop running processes
for process in ['WizTree.exe', 'WizTree64.exe']: for process in ['WizTree.exe', 'WizTree64.exe']:
@ -822,6 +866,7 @@ def update_wiztree():
# Cleanup # Cleanup
remove_from_temp('wiztree.zip') remove_from_temp('wiztree.zip')
def update_xmplay(): def update_xmplay():
# Stop running processes # Stop running processes
kill_process('xmplay.exe') kill_process('xmplay.exe')
@ -877,7 +922,8 @@ def update_xmplay():
remove_from_temp('xmp-rar.zip') remove_from_temp('xmp-rar.zip')
remove_from_temp('WAModern.zip') remove_from_temp('WAModern.zip')
## Repairs ##
# Repairs
def update_adwcleaner(): def update_adwcleaner():
# Stop running processes # Stop running processes
kill_process('AdwCleaner.exe') kill_process('AdwCleaner.exe')
@ -891,6 +937,7 @@ def update_adwcleaner():
'AdwCleaner.exe', 'AdwCleaner.exe',
SOURCE_URLS['AdwCleaner']) SOURCE_URLS['AdwCleaner'])
def update_kvrt(): def update_kvrt():
# Stop running processes # Stop running processes
kill_process('KVRT.exe') kill_process('KVRT.exe')
@ -904,6 +951,7 @@ def update_kvrt():
'KVRT.exe', 'KVRT.exe',
SOURCE_URLS['KVRT']) SOURCE_URLS['KVRT'])
def update_rkill(): def update_rkill():
# Stop running processes # Stop running processes
kill_process('RKill.exe') kill_process('RKill.exe')
@ -918,6 +966,7 @@ def update_rkill():
download_generic( download_generic(
r'{}\RKill'.format(global_vars['CBinDir']), 'RKill.exe', url) r'{}\RKill'.format(global_vars['CBinDir']), 'RKill.exe', url)
def update_tdsskiller(): def update_tdsskiller():
# Stop running processes # Stop running processes
kill_process('TDSSKiller.exe') kill_process('TDSSKiller.exe')
@ -931,7 +980,8 @@ def update_tdsskiller():
'TDSSKiller.exe', 'TDSSKiller.exe',
SOURCE_URLS['TDSSKiller']) SOURCE_URLS['TDSSKiller'])
## Uninstallers ##
# Uninstallers
def update_iobit_uninstaller(): def update_iobit_uninstaller():
# Stop running processes # Stop running processes
kill_process('IObitUninstallerPortable.exe') kill_process('IObitUninstallerPortable.exe')
@ -954,6 +1004,7 @@ def update_iobit_uninstaller():
# Cleanup # Cleanup
remove_from_kit('IObitUninstallerPortable.exe') remove_from_kit('IObitUninstallerPortable.exe')
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -3,6 +3,7 @@
from functions.data import * from functions.data import *
from functions.disk import * from functions.disk import *
# STATIC VARIABLES # STATIC VARIABLES
WINDOWS_VERSIONS = [ WINDOWS_VERSIONS = [
{'Name': 'Windows 7 Home Basic', {'Name': 'Windows 7 Home Basic',
@ -35,6 +36,7 @@ WINDOWS_VERSIONS = [
'Image Name': 'Windows 10 Pro'}, 'Image Name': 'Windows 10 Pro'},
] ]
def find_windows_image(windows_version): def find_windows_image(windows_version):
"""Search for a Windows source image file, returns dict. """Search for a Windows source image file, returns dict.
@ -85,6 +87,7 @@ def find_windows_image(windows_version):
windows_version['Name'])) windows_version['Name']))
raise GenericAbort raise GenericAbort
def format_disk(disk, use_gpt): def format_disk(disk, use_gpt):
"""Format disk for use as a Windows OS disk.""" """Format disk for use as a Windows OS disk."""
if use_gpt: if use_gpt:
@ -92,6 +95,7 @@ def format_disk(disk, use_gpt):
else: else:
format_mbr(disk) format_mbr(disk)
def format_gpt(disk): def format_gpt(disk):
"""Format disk for use as a Windows OS disk using the GPT layout.""" """Format disk for use as a Windows OS disk using the GPT layout."""
script = [ script = [
@ -126,6 +130,7 @@ def format_gpt(disk):
# Run # Run
run_diskpart(script) run_diskpart(script)
def format_mbr(disk): def format_mbr(disk):
"""Format disk for use as a Windows OS disk using the MBR layout.""" """Format disk for use as a Windows OS disk using the MBR layout."""
script = [ script = [
@ -155,6 +160,7 @@ def format_mbr(disk):
# Run # Run
run_diskpart(script) run_diskpart(script)
def mount_windows_share(): def mount_windows_share():
"""Mount the Windows images share unless already mounted.""" """Mount the Windows images share unless already mounted."""
if not WINDOWS_SERVER['Mounted']: if not WINDOWS_SERVER['Mounted']:
@ -163,6 +169,7 @@ def mount_windows_share():
# error by trying to mount the same server with multiple credentials. # error by trying to mount the same server with multiple credentials.
mount_network_share(WINDOWS_SERVER, read_write=True) mount_network_share(WINDOWS_SERVER, read_write=True)
def select_windows_version(): def select_windows_version():
"""Select Windows version from a menu, returns dict.""" """Select Windows version from a menu, returns dict."""
actions = [ actions = [
@ -180,6 +187,7 @@ def select_windows_version():
elif selection == 'M': elif selection == 'M':
raise GenericAbort raise GenericAbort
def setup_windows(windows_image, windows_version): def setup_windows(windows_image, windows_version):
"""Apply a Windows image to W:""" """Apply a Windows image to W:"""
cmd = [ cmd = [
@ -192,6 +200,7 @@ def setup_windows(windows_image, windows_version):
cmd.extend(windows_image['Glob']) cmd.extend(windows_image['Glob'])
run_program(cmd) run_program(cmd)
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'): def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
"""Setup the WinRE partition.""" """Setup the WinRE partition."""
win = r'{}:\Windows'.format(windows_letter) win = r'{}:\Windows'.format(windows_letter)
@ -210,6 +219,7 @@ def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
'/target', win] '/target', win]
run_program(cmd) run_program(cmd)
def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'): def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
"""Setup the Windows boot partition.""" """Setup the Windows boot partition."""
cmd = [ cmd = [
@ -220,6 +230,7 @@ def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
'/f', mode] '/f', mode]
run_program(cmd) run_program(cmd)
def wim_contains_image(filename, imagename): def wim_contains_image(filename, imagename):
"""Check if an ESD/WIM contains the specified image, returns bool.""" """Check if an ESD/WIM contains the specified image, returns bool."""
cmd = [ cmd = [
@ -234,6 +245,7 @@ def wim_contains_image(filename, imagename):
return True return True
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -4,6 +4,7 @@ from functions.backup import *
from functions.disk import * from functions.disk import *
from functions.windows_setup import * from functions.windows_setup import *
# STATIC VARIABLES # STATIC VARIABLES
FAST_COPY_PE_ARGS = [ FAST_COPY_PE_ARGS = [
'/cmd=noexist_only', '/cmd=noexist_only',
@ -50,6 +51,7 @@ PE_TOOLS = {
}, },
} }
def check_pe_tools(): def check_pe_tools():
"""Fix tool paths for WinPE layout.""" """Fix tool paths for WinPE layout."""
for k in PE_TOOLS.keys(): for k in PE_TOOLS.keys():
@ -61,6 +63,7 @@ def check_pe_tools():
global_vars['Tools']['wimlib-imagex'], global_vars['Tools']['wimlib-imagex'],
re.IGNORECASE) re.IGNORECASE)
def menu_backup(): def menu_backup():
"""Take backup images of partition(s) in the WIM format.""" """Take backup images of partition(s) in the WIM format."""
errors = False errors = False
@ -211,6 +214,7 @@ def menu_backup():
sleep(30) sleep(30)
pause('\nPress Enter to return to main menu... ') pause('\nPress Enter to return to main menu... ')
def menu_root(): def menu_root():
"""Main WinPE menu.""" """Main WinPE menu."""
check_pe_tools() check_pe_tools()
@ -249,6 +253,7 @@ def menu_root():
else: else:
sys.exit() sys.exit()
def menu_setup(): def menu_setup():
"""Format a disk, apply a Windows image, and create boot files.""" """Format a disk, apply a Windows image, and create boot files."""
errors = False errors = False
@ -409,6 +414,7 @@ def menu_setup():
sleep(30) sleep(30)
pause('\nPress Enter to return to main menu... ') pause('\nPress Enter to return to main menu... ')
def menu_tools(): def menu_tools():
"""Tool launcher menu.""" """Tool launcher menu."""
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())] tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
@ -438,6 +444,7 @@ def menu_tools():
elif (selection == 'M'): elif (selection == 'M'):
break break
def select_minidump_path(): def select_minidump_path():
"""Select BSOD minidump path from a menu.""" """Select BSOD minidump path from a menu."""
dumps = [] dumps = []
@ -467,6 +474,7 @@ def select_minidump_path():
main_entries = dumps) main_entries = dumps)
return dumps[int(selection) - 1]['Name'] return dumps[int(selection) - 1]['Name']
if __name__ == '__main__': if __name__ == '__main__':
print("This file is not meant to be called directly.") print("This file is not meant to be called directly.")

View file

@ -10,11 +10,13 @@ os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd()) sys.path.append(os.getcwd())
from functions.network import * from functions.network import *
def check_connection(): def check_connection():
if not is_connected(): if not is_connected():
# Raise to cause NS in try_and_print() # Raise to cause NS in try_and_print()
raise Exception raise Exception
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep

View file

@ -22,6 +22,7 @@ init_global_vars()
REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE) REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE)
def scan_for_docs(path): def scan_for_docs(path):
for entry in os.scandir(path): for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False): if entry.is_dir(follow_symlinks=False):
@ -29,6 +30,7 @@ def scan_for_docs(path):
elif entry.is_file and REGEX_DOC_FILES.search(entry.name): elif entry.is_file and REGEX_DOC_FILES.search(entry.name):
yield entry yield entry
def scan_file(file_path, search): def scan_file(file_path, search):
match = False match = False
try: try:
@ -45,6 +47,7 @@ def scan_file(file_path, search):
return entry.path if match else None return entry.path if match else None
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep