Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vdf_safe_load function #455

Merged
merged 2 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pupgui2/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ def get_internal_name(self) -> str:
"""
compat_tool_vdf_path = os.path.join(self.install_dir, self.install_folder, 'compatibilitytool.vdf')
if os.path.exists(compat_tool_vdf_path):
compat_tool_vdf = vdf.load(open(compat_tool_vdf_path))
# TODO: Move this somewhere else and use steamutil.py#vdf_safe_load
with open(compat_tool_vdf_path, 'r', encoding='utf-8', errors='replace') as f:
compat_tool_vdf = vdf.loads(f.read())
if 'compatibilitytools' in compat_tool_vdf and 'compat_tools' in compat_tool_vdf['compatibilitytools']:
return list(compat_tool_vdf['compatibilitytools']['compat_tools'].keys())[0]

Expand Down
60 changes: 39 additions & 21 deletions pupgui2/steamutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ def get_steam_app_list(steam_config_folder: str, cached=False, no_shortcuts=Fals
apps = []

try:
v = vdf.load(open(libraryfolders_vdf_file))
c = get_steam_vdf_compat_tool_mapping(vdf.load(open(config_vdf_file)))
v = vdf_safe_load(libraryfolders_vdf_file)
c = get_steam_vdf_compat_tool_mapping(vdf_safe_load(config_vdf_file))

for fid in v.get('libraryfolders'):
if 'apps' not in v.get('libraryfolders').get(fid):
Expand All @@ -73,7 +73,7 @@ def get_steam_app_list(steam_config_folder: str, cached=False, no_shortcuts=Fals
fid_steamapps_path = os.path.join(fid_libraryfolder_path, 'steamapps') # e.g. /home/gaben/Games/steamapps
appmanifest_path = os.path.join(fid_steamapps_path, f'appmanifest_{appid}.acf')
if os.path.isfile(appmanifest_path):
appmanifest_install_path = vdf.load(open(appmanifest_path)).get('AppState', {}).get('installdir', None)
appmanifest_install_path = vdf_safe_load(appmanifest_path).get('AppState', {}).get('installdir', None)
if not appmanifest_install_path or not os.path.isdir(os.path.join(fid_steamapps_path, 'common', appmanifest_install_path)):
continue

Expand Down Expand Up @@ -111,7 +111,7 @@ def get_steam_shortcuts_list(steam_config_folder: str, compat_tools: dict=None)

try:
if not compat_tools:
compat_tools = get_steam_vdf_compat_tool_mapping(vdf.load(open(config_vdf_file)))
compat_tools = get_steam_vdf_compat_tool_mapping(vdf_safe_load(config_vdf_file))

for userf in os.listdir(users_folder):
user_directory = os.path.join(users_folder, userf)
Expand Down Expand Up @@ -218,7 +218,7 @@ def get_steam_global_ctool_name(steam_config_folder: str) -> str:
"""

config_vdf_file = os.path.join(os.path.expanduser(steam_config_folder), 'config.vdf')
d = get_steam_vdf_compat_tool_mapping(vdf.load(open(config_vdf_file)))
d = get_steam_vdf_compat_tool_mapping(vdf_safe_load(config_vdf_file))

return d.get('0', {}).get('name', '')

Expand Down Expand Up @@ -388,7 +388,7 @@ def steam_update_ctool(game: SteamApp, new_ctool=None, steam_config_folder='') -
game_id = game.app_id

try:
d = vdf.load(open(config_vdf_file))
d = vdf_safe_load(config_vdf_file)
c = get_steam_vdf_compat_tool_mapping(d)

if str(game_id) in c:
Expand Down Expand Up @@ -417,7 +417,7 @@ def steam_update_ctools(games: Dict[SteamApp, str], steam_config_folder='') -> b
return False

try:
d = vdf.load(open(config_vdf_file))
d = vdf_safe_load(config_vdf_file)
c = get_steam_vdf_compat_tool_mapping(d)

for game, new_ctool in games.items():
Expand Down Expand Up @@ -751,20 +751,19 @@ def get_steam_user_list(steam_config_folder: str) -> List[SteamUser]:
return []

try:
with open(loginusers_vdf_file) as f:
d = vdf.load(f)
u = d.get('users', {})
for uid in list(u.keys()):
uvalue = u.get(uid, {})

user = SteamUser()
user.long_id = int(uid)
user.account_name = uvalue.get('AccountName', '')
user.persona_name = uvalue.get('PersonaName', '')
user.most_recent = bool(int(uvalue.get('MostRecent', '0')))
user.timestamp = int(uvalue.get('Timestamp', '-1'))

users.append(user)
d = vdf_safe_load(loginusers_vdf_file)
u = d.get('users', {})
for uid in list(u.keys()):
uvalue = u.get(uid, {})

user = SteamUser()
user.long_id = int(uid)
user.account_name = uvalue.get('AccountName', '')
user.persona_name = uvalue.get('PersonaName', '')
user.most_recent = bool(int(uvalue.get('MostRecent', '0')))
user.timestamp = int(uvalue.get('Timestamp', '-1'))

users.append(user)
except Exception as e:
print('Error: Could not get a list of Steam users:', e)

Expand Down Expand Up @@ -809,3 +808,22 @@ def is_valid_steam_install(steam_path) -> bool:
is_valid_steam_install = os.path.exists(config_vdf) and os.path.exists(libraryfolders_vdf)

return is_valid_steam_install

def vdf_safe_load(vdf_file: str) -> dict:
"""
Loads a vdf file and returns its contents as a dict.
In case of an error, the error is printed and {} is returned.

Args:
vdf_file (str): Path to the vdf file

Returns:
dict
"""

try:
# See https://github.com/DavidoTek/ProtonUp-Qt/issues/424 (unicode errors)
with open(vdf_file, 'r', encoding='utf-8', errors='replace') as f:
return vdf.loads(f.read())
except Exception as e:
print(f'An error occured while calling vdf_safe_load({vdf_file}): {e}')