mirror of
https://github.com/lutris/lutris
synced 2024-10-14 11:42:36 +00:00
Create RuntimeUpdater class
This commit is contained in:
parent
17962d9832
commit
9c95bfc853
|
@ -42,7 +42,8 @@ if LAUNCH_PATH != "/usr/bin":
|
|||
|
||||
from lutris.migrations import migrate
|
||||
|
||||
from lutris import pga, runtime
|
||||
from lutris import pga
|
||||
from lutris.runtime import RuntimeUpdater
|
||||
from lutris.config import check_config # , register_handler
|
||||
from lutris.util.log import logger
|
||||
from lutris.game import Game
|
||||
|
@ -182,12 +183,14 @@ if game_slug or installer:
|
|||
or pga.get_game_by_field(game_slug, 'slug')
|
||||
or pga.get_game_by_field(game_slug, 'installer_slug'))
|
||||
|
||||
runtime_updater = RuntimeUpdater()
|
||||
|
||||
if db_game and db_game['installed'] and not options.reinstall:
|
||||
logger.info("Launching %s", db_game['name'])
|
||||
if lutris.is_running():
|
||||
lutris.run_game(db_game['id'])
|
||||
else:
|
||||
runtime.update()
|
||||
runtime_updater.update()
|
||||
lutris_game = Game(db_game['id'])
|
||||
lutris_game.exit_main_loop = True
|
||||
lutris_game.play()
|
||||
|
@ -200,7 +203,7 @@ if game_slug or installer:
|
|||
if lutris.is_running():
|
||||
lutris.install_game(installer or game_slug)
|
||||
else:
|
||||
runtime.update()
|
||||
runtime_updater.update()
|
||||
InstallerDialog(installer or game_slug)
|
||||
GObject.threads_init()
|
||||
Gtk.main()
|
||||
|
|
|
@ -6,9 +6,10 @@ import subprocess
|
|||
|
||||
from gi.repository import Gtk, Gdk, GLib, Gio
|
||||
|
||||
from lutris import api, pga, runtime, settings, shortcuts
|
||||
from lutris import api, pga, settings, shortcuts
|
||||
from lutris.game import Game, get_game_list
|
||||
from lutris.sync import Sync
|
||||
from lutris.runtime import RuntimeUpdater
|
||||
|
||||
from lutris.util import display, resources
|
||||
from lutris.util.log import logger
|
||||
|
@ -54,6 +55,7 @@ class LutrisWindow(Gtk.Application):
|
|||
raise IOError('File %s not found' % ui_filename)
|
||||
|
||||
self.service = service
|
||||
self.runtime_updater = RuntimeUpdater()
|
||||
self.running_game = None
|
||||
self.threads_stoppers = []
|
||||
|
||||
|
@ -345,7 +347,8 @@ class LutrisWindow(Gtk.Application):
|
|||
self.set_status("")
|
||||
|
||||
def update_runtime(self):
|
||||
cancellables = runtime.update(self.set_status)
|
||||
|
||||
cancellables = self.runtime_updater.update(self.set_status)
|
||||
self.threads_stoppers += cancellables
|
||||
|
||||
def sync_icons(self, stop_request=None):
|
||||
|
|
|
@ -8,104 +8,94 @@ from lutris.util import http, jobs, system
|
|||
from lutris.util.extract import extract_archive
|
||||
from lutris.util.log import logger
|
||||
|
||||
CURRENT_UPDATES = None
|
||||
STATUS_UPDATER = None
|
||||
|
||||
class RuntimeUpdater:
|
||||
current_updates = None
|
||||
status_updater = None
|
||||
|
||||
def is_updating(include_pending_updates=True):
|
||||
if include_pending_updates and CURRENT_UPDATES is None:
|
||||
def is_updating(self, include_pending_updates=True):
|
||||
if include_pending_updates and self.current_updates is None:
|
||||
return True
|
||||
if self.current_updates:
|
||||
return self.current_updates > 0
|
||||
return False
|
||||
|
||||
def get_created_at(self, name):
|
||||
path = os.path.join(RUNTIME_DIR, name)
|
||||
if not os.path.exists(path):
|
||||
return time.gmtime(0)
|
||||
return time.gmtime(os.path.getctime(path))
|
||||
|
||||
def update(self, status_updater=None):
|
||||
if self.is_updating(False):
|
||||
logger.debug("Runtime already updating")
|
||||
return []
|
||||
|
||||
if status_updater:
|
||||
self.status_updater = status_updater
|
||||
|
||||
return self.get_runtimes()
|
||||
|
||||
def get_runtimes(self):
|
||||
if self.current_updates is None:
|
||||
self.current_updates = 0
|
||||
request = http.Request(RUNTIME_URL)
|
||||
response = request.get()
|
||||
cancellables = []
|
||||
runtimes = response.json or []
|
||||
for runtime in runtimes:
|
||||
name = runtime['name']
|
||||
if '64' in name and not system.is_64bit:
|
||||
continue
|
||||
created_at = runtime['created_at']
|
||||
created_at = time.strptime(created_at[:created_at.find('.')],
|
||||
"%Y-%m-%dT%H:%M:%S")
|
||||
if self.get_created_at(name) < created_at:
|
||||
if self.status_updater:
|
||||
self.status_updater("Updating Runtime")
|
||||
logger.debug('Updating runtime %s', name)
|
||||
url = runtime['url']
|
||||
archive_path = os.path.join(RUNTIME_DIR, os.path.basename(url))
|
||||
self.current_updates += 1
|
||||
downloader = Downloader(url, archive_path, overwrite=True)
|
||||
cancellables.append(downloader.cancel)
|
||||
downloader.start()
|
||||
GLib.timeout_add(100, self.check_download_progress, downloader)
|
||||
else:
|
||||
logger.debug("Runtime %s up to date", name)
|
||||
return cancellables
|
||||
|
||||
def check_download_progress(self, downloader):
|
||||
"""Call download.check_progress(), return True if download finished."""
|
||||
if (not downloader or downloader.state in [downloader.CANCELLED,
|
||||
downloader.ERROR]):
|
||||
logger.debug("Runtime update interrupted")
|
||||
return False
|
||||
|
||||
downloader.check_progress()
|
||||
if downloader.state == downloader.COMPLETED:
|
||||
self.on_downloaded(downloader.dest)
|
||||
return False
|
||||
return True
|
||||
if CURRENT_UPDATES:
|
||||
return CURRENT_UPDATES > 0
|
||||
return False
|
||||
|
||||
def on_downloaded(self, path):
|
||||
dir, filename = os.path.split(path)
|
||||
folder = os.path.join(dir, filename[:filename.find('.')])
|
||||
system.remove_folder(folder)
|
||||
jobs.AsyncCall(extract_archive, self.on_extracted, path, RUNTIME_DIR,
|
||||
merge_single=False)
|
||||
|
||||
def get_created_at(name):
|
||||
path = os.path.join(RUNTIME_DIR, name)
|
||||
if not os.path.exists(path):
|
||||
return time.gmtime(0)
|
||||
return time.gmtime(os.path.getctime(path))
|
||||
def on_extracted(self, result, error):
|
||||
self.current_updates -= 1
|
||||
if error:
|
||||
logger.debug("Runtime update failed")
|
||||
return
|
||||
archive_path = result[0]
|
||||
os.unlink(archive_path)
|
||||
|
||||
|
||||
def update(status_updater=None):
|
||||
global STATUS_UPDATER
|
||||
if is_updating(False):
|
||||
logger.debug("Runtime already updating")
|
||||
return []
|
||||
|
||||
if status_updater:
|
||||
STATUS_UPDATER = status_updater
|
||||
|
||||
return get_runtimes()
|
||||
|
||||
|
||||
def get_runtimes():
|
||||
global CURRENT_UPDATES
|
||||
global STATUS_UPDATER
|
||||
if CURRENT_UPDATES is None:
|
||||
CURRENT_UPDATES = 0
|
||||
request = http.Request(RUNTIME_URL)
|
||||
response = request.get()
|
||||
cancellables = []
|
||||
runtimes = response.json or []
|
||||
for runtime in runtimes:
|
||||
name = runtime['name']
|
||||
if '64' in name and not system.is_64bit:
|
||||
continue
|
||||
created_at = runtime['created_at']
|
||||
created_at = time.strptime(created_at[:created_at.find('.')],
|
||||
"%Y-%m-%dT%H:%M:%S")
|
||||
if get_created_at(name) < created_at:
|
||||
if STATUS_UPDATER:
|
||||
STATUS_UPDATER("Updating Runtime")
|
||||
logger.debug('Updating runtime %s', name)
|
||||
url = runtime['url']
|
||||
archive_path = os.path.join(RUNTIME_DIR, os.path.basename(url))
|
||||
CURRENT_UPDATES += 1
|
||||
downloader = Downloader(url, archive_path, overwrite=True)
|
||||
cancellables.append(downloader.cancel)
|
||||
downloader.start()
|
||||
GLib.timeout_add(100, check_download_progress, downloader)
|
||||
else:
|
||||
logger.debug("Runtime %s up to date", name)
|
||||
return cancellables
|
||||
|
||||
|
||||
def check_download_progress(downloader):
|
||||
"""Call download.check_progress(), return True if download finished."""
|
||||
if (not downloader or downloader.state in [downloader.CANCELLED,
|
||||
downloader.ERROR]):
|
||||
logger.debug("Runtime update interrupted")
|
||||
return False
|
||||
|
||||
downloader.check_progress()
|
||||
if downloader.state == downloader.COMPLETED:
|
||||
on_downloaded(downloader.dest)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def on_downloaded(path):
|
||||
dir, filename = os.path.split(path)
|
||||
folder = os.path.join(dir, filename[:filename.find('.')])
|
||||
system.remove_folder(folder)
|
||||
jobs.AsyncCall(extract_archive, on_extracted, path, RUNTIME_DIR,
|
||||
merge_single=False)
|
||||
|
||||
|
||||
def on_extracted(result, error):
|
||||
global CURRENT_UPDATES
|
||||
global STATUS_UPDATER
|
||||
CURRENT_UPDATES -= 1
|
||||
if error:
|
||||
logger.debug("Runtime update failed")
|
||||
return
|
||||
archive_path = result[0]
|
||||
os.unlink(archive_path)
|
||||
|
||||
if STATUS_UPDATER and CURRENT_UPDATES == 0:
|
||||
STATUS_UPDATER("Runtime updated")
|
||||
logger.debug("Runtime updated")
|
||||
if self.status_updater and self.current_updates == 0:
|
||||
self.status_updater("Runtime updated")
|
||||
logger.debug("Runtime updated")
|
||||
|
||||
|
||||
def get_env():
|
||||
|
|
Loading…
Reference in a new issue