[cli/core/lfs/utils] Fetch SDL data from API

This commit is contained in:
derrod 2021-09-05 09:41:54 +02:00
parent 82a2706e4c
commit b12798e6b0
4 changed files with 57 additions and 14 deletions

View file

@ -627,8 +627,12 @@ class LegendaryCLI:
if not args.install_tag and not game.is_dlc and ((sdl_name := get_sdl_appname(game.app_name)) is not None): if not args.install_tag and not game.is_dlc and ((sdl_name := get_sdl_appname(game.app_name)) is not None):
config_tags = self.core.lgd.config.get(game.app_name, 'install_tags', fallback=None) config_tags = self.core.lgd.config.get(game.app_name, 'install_tags', fallback=None)
if not self.core.is_installed(game.app_name) or config_tags is None or args.reset_sdl: if not self.core.is_installed(game.app_name) or config_tags is None or args.reset_sdl:
args.install_tag = sdl_prompt(sdl_name, game.app_title) sdl_data = self.core.get_sdl_data(sdl_name)
if sdl_data:
args.install_tag = sdl_prompt(sdl_data, game.app_title)
self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag)) self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag))
else:
logger.error(f'Unable to get SDL data for {sdl_name}')
else: else:
args.install_tag = config_tags.split(',') args.install_tag = config_tags.split(',')
elif args.install_tag and not game.is_dlc and not args.no_install: elif args.install_tag and not game.is_dlc and not args.no_install:

View file

@ -34,6 +34,7 @@ from legendary.models.chunk import Chunk
from legendary.utils.env import is_windows_or_pyi from legendary.utils.env import is_windows_or_pyi
from legendary.utils.game_workarounds import is_opt_enabled, update_workarounds from legendary.utils.game_workarounds import is_opt_enabled, update_workarounds
from legendary.utils.savegame_helper import SaveGameHelper from legendary.utils.savegame_helper import SaveGameHelper
from legendary.utils.selective_dl import games as sdl_games
from legendary.utils.manifests import combine_manifests from legendary.utils.manifests import combine_manifests
from legendary.utils.wine_helpers import read_registry, get_shell_folders from legendary.utils.wine_helpers import read_registry, get_shell_folders
@ -239,12 +240,39 @@ class LegendaryCore:
if 'egl_config' in version_info: if 'egl_config' in version_info:
self.egs.update_egs_params(version_info['egl_config']) self.egs.update_egs_params(version_info['egl_config'])
self._egl_version = version_info['egl_config'].get('version', self._egl_version) self._egl_version = version_info['egl_config'].get('version', self._egl_version)
if 'game_overrides' in version_info: if game_overrides := version_info.get('game_overrides'):
update_workarounds(version_info['game_overrides']) update_workarounds(game_overrides)
if sdl_config := game_overrides.get('sdl_config'):
# add placeholder for games to fetch from API that aren't hardcoded
for app_name in sdl_config.keys():
if app_name not in sdl_games:
sdl_games[app_name] = None
def get_update_info(self): def get_update_info(self):
return self.lgd.get_cached_version()['data'].get('release_info') return self.lgd.get_cached_version()['data'].get('release_info')
def get_sdl_data(self, app_name):
if app_name not in sdl_games:
return None
# load hardcoded data as fallback
sdl_data = sdl_games[app_name]
# get cached data
cached = self.lgd.get_cached_sdl_data(app_name)
# check if newer version is available and/or download if necessary
version_info = self.lgd.get_cached_version()['data']
latest = version_info.get('game_overrides', {}).get('sdl_config', {}).get(app_name)
if (not cached and latest) or (cached and latest and latest > cached['version']):
try:
sdl_data = self.lgdapi.get_sdl_config(app_name)
self.log.debug(f'Downloaded SDL data for "{app_name}", version: {latest}')
self.lgd.set_cached_sdl_data(app_name, latest, sdl_data)
except Exception as e:
self.log.warning(f'Downloading SDL data failed with {e!r}')
elif cached:
sdl_data = cached['data']
# return data if available
return sdl_data
def get_assets(self, update_assets=False, platform_override=None) -> List[GameAsset]: def get_assets(self, update_assets=False, platform_override=None) -> List[GameAsset]:
# do not save and always fetch list when platform is overridden # do not save and always fetch list when platform is overridden
if platform_override: if platform_override:

View file

@ -315,3 +315,17 @@ class LGDLFS:
self._update_info = dict(last_update=time(), data=version_data) self._update_info = dict(last_update=time(), data=version_data)
json.dump(self._update_info, open(os.path.join(self.path, 'version.json'), 'w'), json.dump(self._update_info, open(os.path.join(self.path, 'version.json'), 'w'),
indent=2, sort_keys=True) indent=2, sort_keys=True)
def get_cached_sdl_data(self, app_name):
try:
return json.load(open(os.path.join(self.path, 'tmp', f'{app_name}.json')))
except Exception as e:
self.log.debug(f'Failed to load cached update data: {e!r}')
return None
def set_cached_sdl_data(self, app_name, sdl_version, sdl_data):
if not app_name or not sdl_data:
return
json.dump(dict(version=sdl_version, data=sdl_data),
open(os.path.join(self.path, 'tmp', f'{app_name}.json'), 'w'),
indent=2, sort_keys=True)

View file

@ -1,6 +1,3 @@
from legendary.utils.selective_dl import games
def get_boolean_choice(prompt, default=True): def get_boolean_choice(prompt, default=True):
if default: if default:
yn = 'Y/n' yn = 'Y/n'
@ -16,28 +13,28 @@ def get_boolean_choice(prompt, default=True):
return False return False
def sdl_prompt(app_name, title): def sdl_prompt(sdl_data, title):
tags = [''] tags = ['']
if '__required' in games[app_name]: if '__required' in sdl_data:
tags.extend(games[app_name]['__required']['tags']) tags.extend(sdl_data['__required']['tags'])
print(f'You are about to install {title}, this game supports selective downloads.') print(f'You are about to install {title}, this game supports selective downloads.')
print('The following optional packs are available:') print('The following optional packs are available:')
for tag, info in games[app_name].items(): for tag, info in sdl_data.items():
if tag == '__required': if tag == '__required':
continue continue
print(' *', tag, '-', info['name']) print(' *', tag, '-', info['name'])
print('Please enter a comma-separated list of optional packs to install (leave blank for defaults)') print('Please enter a comma-separated list of optional packs to install (leave blank for defaults)')
examples = ','.join([g for g in games[app_name].keys() if g != '__required'][:2]) examples = ','.join([g for g in sdl_data.keys() if g != '__required'][:2])
choices = input(f'Additional packs [e.g. {examples}]: ') choices = input(f'Additional packs [e.g. {examples}]: ')
if not choices: if not choices:
return tags return tags
for c in choices.split(','): for c in choices.split(','):
c = c.strip() c = c.strip()
if c in games[app_name]: if c in sdl_data:
tags.extend(games[app_name][c]['tags']) tags.extend(sdl_data[c]['tags'])
else: else:
print('Invalid tag:', c) print('Invalid tag:', c)