1
0
mirror of https://github.com/lutris/lutris synced 2024-07-01 06:34:26 +00:00
lutris/utils/cleanup_prefix.py

214 lines
5.7 KiB
Python

import os
import shutil
import sys
from copy import copy
PROGRAM_FILES_IGNORES = {
"Common Files": {"Microsoft Shared": "*", "System": "*", "InstallShield": "*"},
"Internet Explorer": "*",
"Windows Media Player": "*",
"Windows NT": "*",
"InstallShield Installation Information": "*",
"Microsoft XNA": "*",
"Microsoft.NET": "*",
"GameSpy Arcade": "*",
}
IGNORED_USER_FILES = {
"Desktop": "*",
"Videos": "*",
"Temp": "*",
"Cookies": "*",
"AppData": {
"LocalLow": "*",
"Local": {"Microsoft": "*"},
"Roaming": {"Microsoft": "*", "wine_gecko": "*"},
},
"Local Settings": {
"Application Data": {"Microsoft": "*"},
"History": "*",
"Temporary Internet Files": "*",
},
"Application Data": {"Microsoft": "*", "wine_gecko": "*"},
"Start Menu": "*",
"PrintHood": "*",
"Favorites": "*",
"Recent": "*",
"Downloads": "*",
"Templates": "*",
"NetHood": "*",
"My Pictures": "*",
}
IGNORED_DIRS = {
"ProgramData": {
"Microsoft": {"Windows": "*"},
"GOG.com": "*",
"Package Cache": "*",
},
"Program Files": PROGRAM_FILES_IGNORES,
"Program Files (x86)": PROGRAM_FILES_IGNORES,
"windows": "*",
"vrclient": "*",
"openxr": "*",
"users": {
"Public": IGNORED_USER_FILES,
os.getenv("USER"): IGNORED_USER_FILES,
"steamuser": IGNORED_USER_FILES,
},
}
IGNORED_EXES = [
"UNWISE.EXE",
"unins000.exe",
"Uninstall.exe",
"UnSetup.exe",
"UE3Redist.exe",
"dotNetFx40_Full_setup.exe",
"sysinfo.exe",
"register.exe",
"UNINSTAL.EXE",
"GSArcade.exe",
]
KNOWN_DIRS = [
"ProgramData/Microsoft/Windows",
"ProgramData/Package Cache",
"Program Files/Common Files/Microsoft Shared",
"Program Files/Common Files/System",
"Program Files (x86)/Common Files/System",
"Program Files/Internet Explorer",
"Program Files (x86)/Internet Explorer",
"Program Files/Windows Media Player",
"Program Files (x86)/Windows Media Player",
"Program Files/Windows NT",
"Program Files (x86)/Windows NT",
"Program Files (x86)/Steam",
"windows",
"openxr",
"vrclient",
"users/steamuser/Temp",
"users/steamuser/AppData/Local/Microsoft/Windows/INetCache",
"users/steamuser/AppData/Local/Microsoft/Windows/INetCookies",
]
def delete_known_dirs(prefix_path):
for known_dir in KNOWN_DIRS:
full_path = os.path.join(prefix_path, "drive_c", known_dir)
if not os.path.exists(full_path):
continue
print("Deleting %s", full_path)
shutil.rmtree(full_path)
devices = os.path.join(prefix_path, "dosdevices")
if os.path.exists(devices):
shutil.rmtree(devices)
regfiles = [
os.path.join(prefix_path, "system.reg"),
os.path.join(prefix_path, "user.reg"),
os.path.join(prefix_path, "userdef.reg"),
]
for regfile in regfiles:
if not os.path.exists(regfile):
continue
os.remove(regfile)
def remove_empty_dirs(dirname):
empty_folders = []
for root, dirs, files in os.walk(dirname, topdown=True):
if not files and not dirs:
empty_folders.append(root)
for folder in empty_folders:
os.rmdir(folder)
return empty_folders
def remove_broken_symlinks(dirname):
for root, _dirs, files in os.walk(dirname, topdown=False):
for filename in files:
path = os.path.join(root, filename)
if not os.path.islink(path):
continue
if not os.path.exists(path):
print("Deleting broken link %s" % path)
os.unlink(path)
def cleanup_prefix(path):
print("Cleanup prefix", path)
delete_known_dirs(path)
remove_broken_symlinks(path)
empty_folders = True
while empty_folders:
empty_folders = remove_empty_dirs(path)
remove_broken_symlinks(path)
remove_empty_dirs(path)
def is_ignored_path(path_parts):
ignored_dirs = copy(IGNORED_DIRS)
if len(path_parts) in (0, 1):
return True
for level, part in enumerate(path_parts):
if level == 0:
if part == "dosdevices":
return True
if part in ignored_dirs:
if ignored_dirs[part] == "*":
return True
ignored_dirs = ignored_dirs[part]
return False
def get_content_folders(path):
found_dirs = []
for root, _dirs, files in os.walk(path, topdown=True):
# print(root, files, dirs)
relpath = root[len(path) :].strip("/")
path_parts = relpath.split("/")
if is_ignored_path(path_parts):
continue
if files:
found_dirs.append(root)
folders = []
for found_dir in found_dirs:
skip = False
for _dir in folders:
if found_dir.startswith(_dir):
skip = True
if skip:
continue
folders.append(found_dir)
return folders
def find_exes_in_path(folder):
exes = []
for filename in os.listdir(folder):
abspath = os.path.join(folder, filename)
if os.path.isdir(abspath):
exes += find_exes_in_path(abspath)
if os.path.isfile(abspath):
if filename in IGNORED_EXES:
continue
if filename.lower().endswith(".exe"):
exes.append(os.path.join(folder, filename))
return exes
def scan_prefix(path):
print("Scanning prefix %s", path)
folders = get_content_folders(path)
exes = []
for folder in folders:
exes += find_exes_in_path(folder)
for exe in exes:
print("EXE", exe)
if __name__ == "__main__":
path = sys.argv[1]
scan_prefix(path)
cleanup_prefix(path)