diff --git a/debian/changelog b/debian/changelog index 8e6b4437e..fcb1e3cb3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,7 @@ lutris (0.5.10) impish; urgency=medium * Add a coverart format * Add integration with EA Origin * Add integration with Ubisoft Connect + * Download missing media on startup * Remove Winesteam runner (install Steam for Windows in Lutris instead) * PC (Linux and Windows) games have their own dedicated Nvidia shader cache * Add dgvoodoo2 option diff --git a/lutris/services/lutris.py b/lutris/services/lutris.py index 2abdfdc97..220c9820d 100644 --- a/lutris/services/lutris.py +++ b/lutris/services/lutris.py @@ -149,6 +149,7 @@ def download_lutris_media(slug): def sync_media(): + """Downlad all missing media""" banners_available = {fn.split(".")[0] for fn in os.listdir(settings.BANNER_PATH)} icons_available = { fn.split(".")[0].replace("lutris_", "") @@ -159,6 +160,8 @@ def sync_media(): complete_games = banners_available.intersection(icons_available).intersection(covers_available) all_slugs = {game["slug"] for game in get_games()} slugs = all_slugs - complete_games + if not slugs: + return games = get_api_games(list(slugs)) banner_urls = { game["slug"]: game["banner_url"] diff --git a/lutris/startup.py b/lutris/startup.py index 4dab0acae..9512c4fde 100644 --- a/lutris/startup.py +++ b/lutris/startup.py @@ -13,6 +13,7 @@ from lutris.runners.json import load_json_runners from lutris.runtime import RuntimeUpdater from lutris.services import DEFAULT_SERVICES from lutris.services.lutris import sync_media +from lutris.util import update_cache from lutris.util.graphics import drivers, vkquery from lutris.util.linux import LINUX_SYSTEM from lutris.util.log import logger @@ -178,15 +179,25 @@ def init_lutris(): settings.write_setting(service, True, section="services") -def update_runtime(): +def update_runtime(force=False): """Update runtime components""" - runtime_updater = RuntimeUpdater() - components_to_update = runtime_updater.update() - if components_to_update: - while runtime_updater.current_updates: - time.sleep(0.3) + runtime_call = update_cache.get_last_call("runtime") + if force or not runtime_call or runtime_call > 3600 * 12: + runtime_updater = RuntimeUpdater() + components_to_update = runtime_updater.update() + if components_to_update: + while runtime_updater.current_updates: + time.sleep(0.3) + update_cache.write_date_to_cache("runtime") for dll_manager_class in (DXVKManager, DXVKNVAPIManager, VKD3DManager, D3DExtrasManager, dgvoodoo2Manager): - dll_manager = dll_manager_class() - dll_manager.upgrade() - sync_media() + key = dll_manager_class.__name__ + key_call = update_cache.get_last_call(key) + if force or not key_call or key_call > 3600 * 6: + dll_manager = dll_manager_class() + dll_manager.upgrade() + update_cache.write_date_to_cache(key) + media_call = update_cache.get_last_call("media") + if force or not media_call or media_call > 3600 * 24: + sync_media() + update_cache.write_date_to_cache("media") logger.info("Startup complete") diff --git a/lutris/util/update_cache.py b/lutris/util/update_cache.py new file mode 100644 index 000000000..b0e0060c9 --- /dev/null +++ b/lutris/util/update_cache.py @@ -0,0 +1,45 @@ +"""Manage a cache file of execution times for updates""" +import json +import os +from datetime import datetime + +from lutris import settings + +UPDATE_CACHE_PATH = os.path.join(settings.CACHE_DIR, "updates.json") +DATE_FORMAT = "%d/%m/%Y %H:%M:%S" + + +def write_date_to_cache(key): + """Write current time to the cache for 'key'""" + cache = _read_cache_content() + cache[key] = datetime.strftime(datetime.now(), DATE_FORMAT) + with open(UPDATE_CACHE_PATH, "w", encoding='utf-8') as json_file: + json.dump(cache, json_file, indent=2) + + +def _read_cache_content(): + """Return the content of the cache""" + if not os.path.exists(UPDATE_CACHE_PATH): + return {} + with open(UPDATE_CACHE_PATH, "r", encoding='utf-8') as json_file: + cache = json.load(json_file) + return cache + + +def read_date_from_cache(key): + """Return a datetime object from 'key'""" + cache = _read_cache_content() + date = cache.get(key) + if not date: + return + date = datetime.strptime(date, DATE_FORMAT) + return date + + +def get_last_call(key): + """Return the time in second since the last update for 'key' was made""" + date = read_date_from_cache(key) + if not date: + return 0 + delta = datetime.now() - date + return delta.seconds