Updated browsers.py

This commit is contained in:
2Shirt 2018-12-27 19:43:12 -07:00
parent a269859b17
commit 6a3e225192
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C

View file

@ -7,42 +7,42 @@ 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 = {
'Error': { 'Error': {
'MultipleInstallationsError': 'Multiple installations detected', 'MultipleInstallationsError': 'Multiple installations detected',
}, },
'Warning': { 'Warning': {
'NotInstalledError': 'Not installed', 'NotInstalledError': 'Not installed',
'NoProfilesError': 'No profiles found', 'NoProfilesError': 'No profiles found',
}
} }
}
# Regex # Regex
REGEX_BACKUP = re.compile( REGEX_BACKUP = re.compile(
r'\.\w*bak.*', r'\.\w*bak.*',
re.IGNORECASE) re.IGNORECASE)
REGEX_CHROMIUM_PROFILE = re.compile( REGEX_CHROMIUM_PROFILE = re.compile(
r'^(Default|Profile)', r'^(Default|Profile)',
re.IGNORECASE) re.IGNORECASE)
REGEX_CHROMIUM_ITEMS = re.compile( REGEX_CHROMIUM_ITEMS = re.compile(
r'^(Bookmarks|Cookies|Favicons|Google Profile' r'^(Bookmarks|Cookies|Favicons|Google Profile'
r'|History|Login Data|Top Sites|TransportSecurity' r'|History|Login Data|Top Sites|TransportSecurity'
r'|Visited Links|Web Data)', r'|Visited Links|Web Data)',
re.IGNORECASE) re.IGNORECASE)
REGEX_MOZILLA = re.compile( REGEX_MOZILLA = re.compile(
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite' r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
r'|key3.db|logins.json|persdict.dat)$', r'|key3.db|logins.json|persdict.dat)$',
re.IGNORECASE) re.IGNORECASE)
# STATIC VARIABLES # STATIC VARIABLES
DEFAULT_HOMEPAGE = 'https://www.google.com/' DEFAULT_HOMEPAGE = 'https://www.google.com/'
IE_GALLERY = 'https://www.microsoft.com/en-us/iegallery' IE_GALLERY = 'https://www.microsoft.com/en-us/iegallery'
MOZILLA_PREFS = { MOZILLA_PREFS = {
'browser.search.defaultenginename': '"Google"', 'browser.search.defaultenginename': '"Google"',
'browser.search.defaultenginename.US': '"Google"', 'browser.search.defaultenginename.US': '"Google"',
'browser.search.geoSpecificDefaults': 'false', 'browser.search.geoSpecificDefaults': 'false',
'browser.startup.homepage': '"{}"'.format(DEFAULT_HOMEPAGE), 'browser.startup.homepage': '"{}"'.format(DEFAULT_HOMEPAGE),
'extensions.ui.lastCategory': '"addons://list/extension"', 'extensions.ui.lastCategory': '"addons://list/extension"',
} }
UBO_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=en' UBO_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=en'
UBO_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm' UBO_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm'
UBO_EXTRA_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin-extra/pgdnlhfefecpicbbihgmbmffkjpaplco?hl=en' UBO_EXTRA_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin-extra/pgdnlhfefecpicbbihgmbmffkjpaplco?hl=en'
@ -53,456 +53,459 @@ UBO_MOZILLA_REG = r'Software\Mozilla\Firefox\Extensions'
UBO_MOZILLA_REG_NAME = 'uBlock0@raymondhill.net' UBO_MOZILLA_REG_NAME = 'uBlock0@raymondhill.net'
UBO_OPERA = 'https://addons.opera.com/en/extensions/details/ublock/?display=en' UBO_OPERA = 'https://addons.opera.com/en/extensions/details/ublock/?display=en'
SUPPORTED_BROWSERS = { SUPPORTED_BROWSERS = {
'Internet Explorer': { 'Internet Explorer': {
'base': 'ie', 'base': 'ie',
'exe_name': 'iexplore.exe', 'exe_name': 'iexplore.exe',
'rel_install_path': 'Internet Explorer', 'rel_install_path': 'Internet Explorer',
'user_data_path': r'{USERPROFILE}\Favorites', 'user_data_path': r'{USERPROFILE}\Favorites',
}, },
'Google Chrome': { 'Google Chrome': {
'base': 'chromium', 'base': 'chromium',
'exe_name': 'chrome.exe', 'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome\Application', 'rel_install_path': r'Google\Chrome\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome\User Data', 'user_data_path': r'{LOCALAPPDATA}\Google\Chrome\User Data',
}, },
'Google Chrome Canary': { 'Google Chrome Canary': {
'base': 'chromium', 'base': 'chromium',
'exe_name': 'chrome.exe', 'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome SxS\Application', 'rel_install_path': r'Google\Chrome SxS\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome SxS\User Data', 'user_data_path': r'{LOCALAPPDATA}\Google\Chrome SxS\User Data',
}, },
'Mozilla Firefox': { 'Mozilla Firefox': {
'base': 'mozilla', 'base': 'mozilla',
'exe_name': 'firefox.exe', 'exe_name': 'firefox.exe',
'rel_install_path': 'Mozilla Firefox', 'rel_install_path': 'Mozilla Firefox',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles', 'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
}, },
'Mozilla Firefox Dev': { 'Mozilla Firefox Dev': {
'base': 'mozilla', 'base': 'mozilla',
'exe_name': 'firefox.exe', 'exe_name': 'firefox.exe',
'rel_install_path': 'Firefox Developer Edition', 'rel_install_path': 'Firefox Developer Edition',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles', 'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
}, },
'Opera': { 'Opera': {
'base': 'chromium', 'base': 'chromium',
'exe_name': 'launcher.exe', 'exe_name': 'launcher.exe',
'rel_install_path': 'Opera', 'rel_install_path': 'Opera',
'user_data_path': r'{APPDATA}\Opera Software\Opera Stable', 'user_data_path': r'{APPDATA}\Opera Software\Opera Stable',
}, },
'Opera Beta': { 'Opera Beta': {
'base': 'chromium', 'base': 'chromium',
'exe_name': 'launcher.exe', 'exe_name': 'launcher.exe',
'rel_install_path': 'Opera beta', 'rel_install_path': 'Opera beta',
'user_data_path': r'{APPDATA}\Opera Software\Opera Next', 'user_data_path': r'{APPDATA}\Opera Software\Opera Next',
}, },
'Opera Dev': { 'Opera Dev': {
'base': 'chromium', 'base': 'chromium',
'exe_name': 'launcher.exe', 'exe_name': 'launcher.exe',
'rel_install_path': 'Opera developer', 'rel_install_path': 'Opera developer',
'user_data_path': r'{APPDATA}\Opera Software\Opera Developer', 'user_data_path': r'{APPDATA}\Opera Software\Opera Developer',
}, },
} }
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'])
user_envs = [] user_envs = []
# Build list of valid users # Build list of valid users
for user_name in os.listdir(users_root): for user_name in os.listdir(users_root):
valid_user = True valid_user = True
if user_name in ('Default', 'Default User'): if user_name in ('Default', 'Default User'):
# Skip default users # Skip default users
continue continue
user_path = os.path.join(users_root, user_name) user_path = os.path.join(users_root, user_name)
appdata_local = os.path.join(user_path, r'AppData\Local') appdata_local = os.path.join(user_path, r'AppData\Local')
appdata_roaming = os.path.join(user_path, r'AppData\Roaming') appdata_roaming = os.path.join(user_path, r'AppData\Roaming')
valid_user &= os.path.exists(appdata_local) valid_user &= os.path.exists(appdata_local)
valid_user &= os.path.exists(appdata_roaming) valid_user &= os.path.exists(appdata_roaming)
if valid_user: if valid_user:
user_envs.append({ user_envs.append({
'USERNAME': user_name, 'USERNAME': user_name,
'USERPROFILE': user_path, 'USERPROFILE': user_path,
'APPDATA': appdata_roaming, 'APPDATA': appdata_roaming,
'LOCALAPPDATA': appdata_local}) 'LOCALAPPDATA': appdata_local})
# Backup browsers for all valid users # Backup browsers for all valid users
print_info('Backing up browsers') print_info('Backing up browsers')
for fake_env in sorted(user_envs, key=itemgetter('USERPROFILE')): for fake_env in sorted(user_envs, key=itemgetter('USERPROFILE')):
print_standard(' {}'.format(fake_env['USERNAME'])) print_standard(' {}'.format(fake_env['USERNAME']))
for b_k, b_v in sorted(SUPPORTED_BROWSERS.items()): for b_k, b_v in sorted(SUPPORTED_BROWSERS.items()):
if b_k == 'Mozilla Firefox Dev': if b_k == 'Mozilla Firefox Dev':
continue continue
source_path = b_v['user_data_path'].format(**fake_env) source_path = b_v['user_data_path'].format(**fake_env)
if not os.path.exists(source_path): if not os.path.exists(source_path):
continue continue
source_items = source_path + '*' source_items = source_path + '*'
archive_path = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format( archive_path = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
**global_vars, **fake_env) **global_vars, **fake_env)
os.makedirs(archive_path, exist_ok=True) os.makedirs(archive_path, exist_ok=True)
archive_path += r'\{}.7z'.format(b_k) archive_path += r'\{}.7z'.format(b_k)
cmd = [ cmd = [
global_vars['Tools']['SevenZip'],
'a', '-aoa', '-bso0', '-bse0', '-mx=1',
archive_path, source_items]
try_and_print(message='{}...'.format(b_k),
function=run_program, cmd=cmd)
print_standard(' ')
def archive_browser(name):
"""Create backup of Browser saved in the BackupDir."""
source = '{}*'.format(browser_data[name]['user_data_path'])
dest = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
**global_vars, **global_vars['Env'])
archive = r'{}\{}.7z'.format(dest, name)
os.makedirs(dest, exist_ok=True)
cmd = [
global_vars['Tools']['SevenZip'], global_vars['Tools']['SevenZip'],
'a', '-aoa', '-bso0', '-bse0', '-mx=1', 'a', '-aoa', '-bso0', '-bse0', '-mx=1',
'-mhe=on', '-p{}'.format(ARCHIVE_PASSWORD), archive_path, source_items]
archive, source] try_and_print(message='{}...'.format(b_k),
run_program(cmd) function=run_program, cmd=cmd)
print_standard(' ')
def archive_browser(name):
"""Create backup of Browser saved in the BackupDir."""
source = '{}*'.format(browser_data[name]['user_data_path'])
dest = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
**global_vars, **global_vars['Env'])
archive = r'{}\{}.7z'.format(dest, name)
os.makedirs(dest, exist_ok=True)
cmd = [
global_vars['Tools']['SevenZip'],
'a', '-aoa', '-bso0', '-bse0', '-mx=1',
'-mhe=on', '-p{}'.format(ARCHIVE_PASSWORD),
archive, source]
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):
"""Renames profile, creates a new folder, and copies the user data to it.""" """Renames profile, creates a new folder, and copies the user data to it."""
if profile is None: if profile is None:
raise Exception raise Exception
backup_path = '{path}_{Date}.bak'.format( backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars) path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path) backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path) shutil.move(profile['path'], backup_path)
os.makedirs(profile['path'], exist_ok=True) os.makedirs(profile['path'], exist_ok=True)
# Restore essential files from backup_path # Restore essential files from backup_path
for entry in os.scandir(backup_path): for entry in os.scandir(backup_path):
if REGEX_CHROMIUM_ITEMS.search(entry.name): if REGEX_CHROMIUM_ITEMS.search(entry.name):
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.
NOTE: kwargs set but unused as a workaround.""" NOTE: kwargs set but unused as a workaround."""
kill_process('iexplore.exe') kill_process('iexplore.exe')
run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False) run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False)
key = r'Software\Microsoft\Internet Explorer\Main' key = r'Software\Microsoft\Internet Explorer\Main'
# Set homepage # Set homepage
with winreg.OpenKey(HKCU, key, access=winreg.KEY_WRITE) as _key: with winreg.OpenKey(HKCU, key, access=winreg.KEY_WRITE) as _key:
winreg.SetValueEx(_key, 'Start Page', 0, winreg.SetValueEx(_key, 'Start Page', 0,
winreg.REG_SZ, DEFAULT_HOMEPAGE) winreg.REG_SZ, DEFAULT_HOMEPAGE)
try: try:
winreg.DeleteValue(_key, 'Secondary Start Pages') winreg.DeleteValue(_key, 'Secondary Start Pages')
except FileNotFoundError: except FileNotFoundError:
pass pass
def clean_mozilla_profile(profile): def clean_mozilla_profile(profile):
"""Renames profile, creates a new folder, and copies the user data to it.""" """Renames profile, creates a new folder, and copies the user data to it."""
if profile is None: if profile is None:
raise Exception raise Exception
backup_path = '{path}_{Date}.bak'.format( backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars) path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path) backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path) shutil.move(profile['path'], backup_path)
homepages = [] homepages = []
os.makedirs(profile['path'], exist_ok=True) os.makedirs(profile['path'], exist_ok=True)
# Restore essential files from backup_path # Restore essential files from backup_path
for entry in os.scandir(backup_path): for entry in os.scandir(backup_path):
if REGEX_MOZILLA.search(entry.name): if REGEX_MOZILLA.search(entry.name):
if entry.is_dir(): if entry.is_dir():
shutil.copytree(entry.path, r'{}\{}'.format( shutil.copytree(entry.path, r'{}\{}'.format(
profile['path'], entry.name)) profile['path'], entry.name))
else: else:
shutil.copy(entry.path, r'{}\{}'.format( shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name)) profile['path'], entry.name))
# Set profile defaults # Set profile defaults
with open(r'{path}\prefs.js'.format(**profile), 'a', encoding='ascii') as f: with open(r'{path}\prefs.js'.format(**profile), 'a', encoding='ascii') as f:
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 status and profile details for all supported browsers.""" """Get install status and profile details for all supported browsers."""
browser = SUPPORTED_BROWSERS[name].copy() browser = SUPPORTED_BROWSERS[name].copy()
# Update user_data_path # Update user_data_path
browser['user_data_path'] = browser['user_data_path'].format( browser['user_data_path'] = browser['user_data_path'].format(
**global_vars['Env']) **global_vars['Env'])
# Find executable (if multiple files are found, the last one is used) # Find executable (if multiple files are found, the last one is used)
exe_path = None exe_path = None
num_installs = 0 num_installs = 0
for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']: for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']:
test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format( test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format(
install_path = global_vars['Env'].get(install_path, ''), install_path = global_vars['Env'].get(install_path, ''),
**browser) **browser)
if os.path.exists(test_path): if os.path.exists(test_path):
num_installs += 1 num_installs += 1
exe_path = test_path exe_path = test_path
# Find profile(s) # Find profile(s)
profiles = [] profiles = []
if browser['base'] == 'ie': if browser['base'] == 'ie':
profiles.append({'name': 'Default', 'path': None}) profiles.append({'name': 'Default', 'path': None})
elif 'Google Chrome' in name: elif 'Google Chrome' in name:
profiles.extend( profiles.extend(
get_chromium_profiles( get_chromium_profiles(
search_path=browser['user_data_path'])) search_path=browser['user_data_path']))
elif browser['base'] == 'mozilla': elif browser['base'] == 'mozilla':
dev = 'Dev' in name dev = 'Dev' in name
profiles.extend( profiles.extend(
get_mozilla_profiles( get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev)) search_path=browser['user_data_path'], dev=dev))
if exe_path and not dev and len(profiles) == 0: if exe_path and not dev and len(profiles) == 0:
# e.g. If Firefox is installed but no profiles were found. # e.g. If Firefox is installed but no profiles were found.
## Rename profiles.ini and create a new default profile ## Rename profiles.ini and create a new default profile
profiles_ini_path = browser['user_data_path'].replace( profiles_ini_path = browser['user_data_path'].replace(
'Profiles', 'profiles.ini') 'Profiles', 'profiles.ini')
if os.path.exists(profiles_ini_path): if os.path.exists(profiles_ini_path):
backup_path = '{path}_{Date}.bak'.format( backup_path = '{path}_{Date}.bak'.format(
path=profiles_ini_path, **global_vars) path=profiles_ini_path, **global_vars)
backup_path = non_clobber_rename(backup_path) backup_path = non_clobber_rename(backup_path)
shutil.move(profiles_ini_path, backup_path) shutil.move(profiles_ini_path, backup_path)
run_program([exe_path, '-createprofile', 'default'], check=False) run_program([exe_path, '-createprofile', 'default'], check=False)
profiles.extend( profiles.extend(
get_mozilla_profiles( get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev)) search_path=browser['user_data_path'], dev=dev))
elif 'Opera' in name: elif 'Opera' in name:
if os.path.exists(browser['user_data_path']): if os.path.exists(browser['user_data_path']):
profiles.append( profiles.append(
{'name': 'Default', 'path': browser['user_data_path']}) {'name': 'Default', 'path': browser['user_data_path']})
# Get homepages # Get homepages
if browser['base'] == 'ie': if browser['base'] == 'ie':
# IE is set to only have one profile above # IE is set to only have one profile above
profiles[0]['homepages'] = get_ie_homepages() profiles[0]['homepages'] = get_ie_homepages()
elif browser['base'] == 'mozilla': elif browser['base'] == 'mozilla':
for profile in profiles: for profile in profiles:
prefs_path = r'{path}\prefs.js'.format(**profile) prefs_path = r'{path}\prefs.js'.format(**profile)
profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path) profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path)
# Add to browser_data # Add to browser_data
browser_data[name] = browser browser_data[name] = browser
browser_data[name].update({ browser_data[name].update({
'exe_path': exe_path, 'exe_path': exe_path,
'profiles': profiles, 'profiles': profiles,
}) })
# Raise installation warnings (if any) # Raise installation warnings (if any)
if num_installs == 0: if num_installs == 0:
raise NotInstalledError raise NotInstalledError
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 = []
try: try:
for entry in os.scandir(search_path): for entry in os.scandir(search_path):
if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name): if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name):
profiles.append(entry) profiles.append(entry)
REGEX_PROFILE_BACKUP = r'\.\w+bak.*' REGEX_PROFILE_BACKUP = r'\.\w+bak.*'
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)] profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts # Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles] profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception: except Exception:
pass pass
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 = []
main_page = '' main_page = ''
extra_pages = [] extra_pages = []
key = r'Software\Microsoft\Internet Explorer\Main' key = r'Software\Microsoft\Internet Explorer\Main'
with winreg.OpenKey(HKCU, key) as _key: with winreg.OpenKey(HKCU, key) as _key:
try: try:
main_page = winreg.QueryValueEx(_key, 'Start Page')[0] main_page = winreg.QueryValueEx(_key, 'Start Page')[0]
except FileNotFoundError: except FileNotFoundError:
pass pass
try: try:
extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0] extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0]
except FileNotFoundError: except FileNotFoundError:
pass pass
if main_page != '': if main_page != '':
homepages.append(main_page) homepages.append(main_page)
if len(extra_pages) > 0: if len(extra_pages) > 0:
homepages.extend(extra_pages) homepages.extend(extra_pages)
# Remove all curly braces # Remove all curly braces
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 = []
try: try:
with open(prefs_path, 'r') as f: with open(prefs_path, 'r') as f:
search = re.search( search = re.search(
r'browser\.startup\.homepage", "([^"]*)"', r'browser\.startup\.homepage", "([^"]*)"',
f.read(), re.IGNORECASE) f.read(), re.IGNORECASE)
if search: if search:
homepages = search.group(1).split('|') homepages = search.group(1).split('|')
except Exception: except Exception:
pass pass
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 = []
try: try:
for entry in os.scandir(search_path): for entry in os.scandir(search_path):
if entry.is_dir(): if entry.is_dir():
if 'dev-edition' in entry.name: if 'dev-edition' in entry.name:
# NOTE: Not always present which can lead # NOTE: Not always present which can lead
# to Dev profiles being marked as non-Dev # to Dev profiles being marked as non-Dev
## NOTE 2: It is possible that a non-Dev profile ## NOTE 2: It is possible that a non-Dev profile
## to be created with 'dev-edition' in the name. ## to be created with 'dev-edition' in the name.
## (It wouldn't make sense, but possible) ## (It wouldn't make sense, but possible)
if dev: if dev:
profiles.append(entry) profiles.append(entry)
elif not dev: elif not dev:
profiles.append(entry) profiles.append(entry)
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)] profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts # Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles] profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception: except Exception:
pass pass
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):
if just_firefox and browser_data[browser]['base'] != 'mozilla': if just_firefox and browser_data[browser]['base'] != 'mozilla':
continue continue
exe_path = browser_data[browser].get('exe_path', None) exe_path = browser_data[browser].get('exe_path', None)
function=run_program function=run_program
if not exe_path: if not exe_path:
if browser_data[browser]['profiles']: if browser_data[browser]['profiles']:
print_standard( print_standard(
'{indent}{browser:<{width}}'.format( '{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'), indent=' '*indent, width=width, browser=browser+'...'),
end='', flush=True) end='', flush=True)
print_warning('Profile(s) detected but browser not installed', print_warning('Profile(s) detected but browser not installed',
timestamp=False) timestamp=False)
else: else:
# Only warn if profile(s) are detected. # Only warn if profile(s) are detected.
pass pass
else:
# Set urls to open
urls = []
if browser_data[browser]['base'] == 'chromium':
if browser == 'Google Chrome':
# Check for system exensions
try:
winreg.QueryValue(HKLM, UBO_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_CHROME)
try:
winreg.QueryValue(HKLM, UBO_EXTRA_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME)
if len(urls) == 0:
urls = ['chrome://extensions']
elif 'Opera' in browser:
urls.append(UBO_OPERA)
else: else:
# Set urls to open urls.append(UBO_CHROME)
urls = [] urls.append(UBO_EXTRA_CHROME)
if browser_data[browser]['base'] == 'chromium':
if browser == 'Google Chrome':
# Check for system exensions
try:
winreg.QueryValue(HKLM, UBO_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_CHROME)
try:
winreg.QueryValue(HKLM, UBO_EXTRA_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME)
if len(urls) == 0: elif browser_data[browser]['base'] == 'mozilla':
urls = ['chrome://extensions'] # Check for system extensions
elif 'Opera' in browser: try:
urls.append(UBO_OPERA) with winreg.OpenKey(HKLM, UBO_MOZILLA_REG) as key:
else: winreg.QueryValueEx(key, UBO_MOZILLA_REG_NAME)
urls.append(UBO_CHROME) except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME) urls = [UBO_MOZILLA]
else:
if os.path.exists(UBO_MOZZILA_PATH):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
elif browser_data[browser]['base'] == 'mozilla': elif browser_data[browser]['base'] == 'ie':
# Check for system extensions urls.append(IE_GALLERY)
try: function=popen_program
with winreg.OpenKey(HKLM, UBO_MOZILLA_REG) as key:
winreg.QueryValueEx(key, UBO_MOZILLA_REG_NAME)
except FileNotFoundError:
urls = [UBO_MOZILLA]
else:
if os.path.exists(UBO_MOZZILA_PATH):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
elif browser_data[browser]['base'] == 'ie': # By using check=False we're skipping any return codes so
urls.append(IE_GALLERY) # it should only fail if the program can't be run
function=popen_program # (or can't be found).
# In other words, this isn't tracking the addon/extension's
# By using check=False we're skipping any return codes so # installation status.
# it should only fail if the program can't be run try_and_print(message='{}...'.format(browser),
# (or can't be found). indent=indent, width=width,
# In other words, this isn't tracking the addon/extension's cs='Done', function=function,
# installation status. cmd=[exe_path, *urls], check=False)
try_and_print(message='{}...'.format(browser),
indent=indent, width=width,
cs='Done', function=function,
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']]
for browser in browser_list:
# Skip Chromium-based browsers
if browser_data[browser]['base'] == 'chromium':
print_info(
'{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'),
end='', flush=True)
print_warning('Not implemented', timestamp=False)
continue
for browser in [k for k, v in sorted(browser_data.items()) if v['exe_path']]: # All other browsers
# Skip Chromium-based browsers print_info('{indent}{browser:<{width}}'.format(
if browser_data[browser]['base'] == 'chromium': indent=' '*indent, width=width, browser=browser+'...'))
print_info( for profile in browser_data[browser].get('profiles', []):
'{indent}{browser:<{width}}'.format( name = profile.get('name', '?')
indent=' '*indent, width=width, browser=browser+'...'), homepages = profile.get('homepages', [])
end='', flush=True) if len(homepages) == 0:
print_warning('Not implemented', timestamp=False) print_standard(
continue '{indent}{name:<{width}}'.format(
indent=' '*indent, width=width, name=name),
# All other browsers end='', flush=True)
print_info('{indent}{browser:<{width}}'.format( print_warning('None found', timestamp=False)
indent=' '*indent, width=width, browser=browser+'...')) else:
for profile in browser_data[browser].get('profiles', []): for page in homepages:
name = profile.get('name', '?') print_standard('{indent}{name:<{width}}{page}'.format(
homepages = profile.get('homepages', []) indent=' '*indent, width=width, name=name, page=page))
if len(homepages) == 0:
print_standard(
'{indent}{name:<{width}}'.format(
indent=' '*indent, width=width, name=name),
end='', flush=True)
print_warning('None found', timestamp=False)
else:
for page in homepages:
print_standard('{indent}{name:<{width}}{page}'.format(
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."""
for browser in [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']]
print_info('{indent}{name}'.format(indent=' '*indent, name=browser)) for browser in browser_list:
for profile in browser_data[browser]['profiles']: print_info('{indent}{name}'.format(indent=' '*indent, name=browser))
if browser_data[browser]['base'] == 'chromium': for profile in browser_data[browser]['profiles']:
function = clean_chromium_profile if browser_data[browser]['base'] == 'chromium':
elif browser_data[browser]['base'] == 'ie': function = clean_chromium_profile
function = clean_internet_explorer elif browser_data[browser]['base'] == 'ie':
elif browser_data[browser]['base'] == 'mozilla': function = clean_internet_explorer
function = clean_mozilla_profile elif browser_data[browser]['base'] == 'mozilla':
try_and_print( function = clean_mozilla_profile
message='{}...'.format(profile['name']), try_and_print(
indent=indent, width=width, function=function, message='{}...'.format(profile['name']),
other_results=other_results, profile=profile) indent=indent, width=width, function=function,
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()):
if just_firefox and details['base'] != 'mozilla': if just_firefox and details['base'] != 'mozilla':
continue continue
try_and_print(message='{}...'.format(name), try_and_print(message='{}...'.format(name),
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.")
# vim: sts=2 sw=2 ts=2