mirror of
https://github.com/lutris/lutris
synced 2024-09-15 22:09:55 +00:00
Move most file-collection specific code to virtual methods.
This is to separate out all uses of 'dest_file', so it can be treated specially by the file collection
This commit is contained in:
parent
55008b8b69
commit
ea278e8b2c
|
@ -1,6 +1,2 @@
|
|||
class NotInstallerFile(Exception):
|
||||
"""Error that represents a installer file type that is not supported"""
|
||||
|
||||
|
||||
class UnsupportedProvider(Exception):
|
||||
"""Error that represents a unsupported provider"""
|
||||
"""Error that represents an unsupported provider"""
|
||||
|
|
|
@ -4,13 +4,9 @@ from gettext import gettext as _
|
|||
|
||||
from gi.repository import GObject, Gtk
|
||||
|
||||
from lutris.cache import save_to_cache
|
||||
from lutris.gui.installer import NotInstallerFile, UnsupportedProvider
|
||||
from lutris.gui.installer import UnsupportedProvider
|
||||
from lutris.gui.installer.widgets import InstallerLabel
|
||||
from lutris.gui.widgets.common import FileChooserEntry
|
||||
from lutris.gui.widgets.download_collection_progress_box import DownloadCollectionProgressBox
|
||||
from lutris.gui.widgets.download_progress_box import DownloadProgressBox
|
||||
from lutris.installer.installer_file import InstallerFile
|
||||
from lutris.installer.installer_file_collection import InstallerFileCollection
|
||||
from lutris.installer.steam_installer import SteamInstaller
|
||||
from lutris.util import system
|
||||
|
@ -37,49 +33,22 @@ class InstallerFileBox(Gtk.VBox):
|
|||
self.state_label = None # Use this label to display status update
|
||||
self.set_margin_left(12)
|
||||
self.set_margin_right(12)
|
||||
self.provider = self.installer_file.provider
|
||||
self.provider = self.installer_file.default_provider
|
||||
self.file_provider_widget = None
|
||||
self.add(self.get_widgets())
|
||||
|
||||
@property
|
||||
def is_ready(self):
|
||||
"""Whether the file is ready to be downloaded / fetched from its provider"""
|
||||
if (
|
||||
self.provider in ("user", "pga")
|
||||
and not system.path_exists(self.installer_file.dest_file)
|
||||
):
|
||||
return False
|
||||
return True
|
||||
return self.installer_file.is_ready(self.provider)
|
||||
|
||||
def get_download_progress(self):
|
||||
"""Return the widget for the download progress bar"""
|
||||
download_progress = None
|
||||
if isinstance(self.installer_file, InstallerFile):
|
||||
download_progress = DownloadProgressBox({
|
||||
"url": self.installer_file.url,
|
||||
"dest": self.installer_file.dest_file,
|
||||
"referer": self.installer_file.referer
|
||||
}, downloader=self.installer_file.downloader)
|
||||
elif isinstance(self.installer_file, InstallerFileCollection):
|
||||
download_progress = DownloadCollectionProgressBox(self.installer_file)
|
||||
else:
|
||||
raise NotInstallerFile(
|
||||
"Installer file isn't type InstallerFile or InstallerFileCollection\n{}"
|
||||
.format(self.installer_file))
|
||||
download_progress = self.installer_file.create_download_progress_box()
|
||||
download_progress.connect("complete", self.on_download_complete)
|
||||
download_progress.connect("cancel", self.on_download_cancelled)
|
||||
download_progress.show()
|
||||
if (
|
||||
not self.installer_file.uses_pga_cache()
|
||||
and system.path_exists(self.installer_file.dest_file)
|
||||
):
|
||||
# If we've previously downloaded a directory, we'll need to get rid of it
|
||||
# to download a file now. Since we are not using the cache, we don't keep
|
||||
# these files anyway - so it should be safe to just nuke and pave all this.
|
||||
if os.path.isdir(self.installer_file.dest_file):
|
||||
system.remove_folder(self.installer_file.dest_file)
|
||||
else:
|
||||
os.remove(self.installer_file.dest_file)
|
||||
self.installer_file.remove_previous()
|
||||
return download_progress
|
||||
|
||||
def get_file_provider_widget(self):
|
||||
|
@ -212,8 +181,10 @@ class InstallerFileBox(Gtk.VBox):
|
|||
source_box = Gtk.HBox()
|
||||
source_box.props.valign = Gtk.Align.START
|
||||
box.pack_start(source_box, False, False, 0)
|
||||
if isinstance(self.installer_file, InstallerFileCollection):
|
||||
source_box.pack_start(InstallerLabel(f"{self.installer_file.num_files} {_('Files')}"), False, False, 0)
|
||||
|
||||
aux_info = self.installer_file.auxiliary_info
|
||||
if aux_info:
|
||||
source_box.pack_start(InstallerLabel(aux_info), False, False, 0)
|
||||
source_box.pack_start(InstallerLabel(_("Source:")), False, False, 0)
|
||||
combobox = self.get_combobox()
|
||||
source_box.pack_start(combobox, False, False, 0)
|
||||
|
@ -251,11 +222,7 @@ class InstallerFileBox(Gtk.VBox):
|
|||
def cache_file(self):
|
||||
"""Copy file to the PGA cache"""
|
||||
if self.cache_to_pga:
|
||||
if isinstance(self.installer_file, InstallerFile):
|
||||
save_to_cache(self.installer_file.dest_file, self.installer_file.cache_path)
|
||||
elif isinstance(self.installer_file, InstallerFileCollection):
|
||||
for installer_file in self.installer_file.files_list:
|
||||
save_to_cache(installer_file.dest_file, installer_file.cache_path)
|
||||
self.installer_file.save_to_cache()
|
||||
|
||||
def on_download_cancelled(self, downloader):
|
||||
"""Handle cancellation of installers"""
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from gi.repository import GObject, Gtk
|
||||
|
||||
from lutris.gui.installer.file_box import InstallerFileBox
|
||||
from lutris.installer.installer_file_collection import InstallerFileCollection
|
||||
from lutris.util.log import logger
|
||||
|
||||
|
||||
|
@ -117,11 +116,7 @@ class InstallerFilesBox(Gtk.ListBox):
|
|||
|
||||
def get_game_files(self):
|
||||
"""Return a mapping of the local files usable by the interpreter"""
|
||||
out = {}
|
||||
files = {}
|
||||
for installer_file in self.installer.files:
|
||||
if isinstance(installer_file, InstallerFileCollection):
|
||||
for file in installer_file.files_list:
|
||||
out.update({file.id: file.dest_file})
|
||||
else:
|
||||
out.update({installer_file.id: installer_file.dest_file})
|
||||
return out
|
||||
files.update(installer_file.get_dest_files_by_id())
|
||||
return files
|
||||
|
|
|
@ -4,6 +4,8 @@ from gettext import gettext as _
|
|||
from urllib.parse import urlparse
|
||||
|
||||
from lutris import cache, settings
|
||||
from lutris.cache import save_to_cache
|
||||
from lutris.gui.widgets.download_progress_box import DownloadProgressBox
|
||||
from lutris.installer.errors import ScriptingError
|
||||
from lutris.util import system
|
||||
from lutris.util.log import logger
|
||||
|
@ -88,12 +90,20 @@ class InstallerFile:
|
|||
def dest_file(self, value):
|
||||
self._dest_file = value
|
||||
|
||||
def get_dest_files_by_id(self):
|
||||
return {self.id: self.dest_file}
|
||||
|
||||
def __str__(self):
|
||||
return "%s/%s" % (self.game_slug, self.id)
|
||||
|
||||
@property
|
||||
def auxiliary_info(self):
|
||||
"""Provides a small bit of additional descriptive texts to show in the UI."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def human_url(self):
|
||||
"""Return the url in human readable format"""
|
||||
"""Return the url in human-readable format"""
|
||||
if self.url.startswith("N/A"):
|
||||
# Ask the user where the file is located
|
||||
parts = self.url.split(":", 1)
|
||||
|
@ -123,7 +133,7 @@ class InstallerFile:
|
|||
return ""
|
||||
|
||||
@property
|
||||
def provider(self):
|
||||
def default_provider(self):
|
||||
"""Return file provider used"""
|
||||
if self.url.startswith("$STEAM"):
|
||||
return "steam"
|
||||
|
@ -195,6 +205,13 @@ class InstallerFile:
|
|||
if not system.path_exists(self.cache_path):
|
||||
os.makedirs(self.cache_path)
|
||||
|
||||
def create_download_progress_box(self):
|
||||
return DownloadProgressBox({
|
||||
"url": self.url,
|
||||
"dest": self.dest_file,
|
||||
"referer": self.referer
|
||||
}, downloader=self.downloader)
|
||||
|
||||
def check_hash(self):
|
||||
"""Checks the checksum of `file` and compare it to `value`
|
||||
|
||||
|
@ -219,7 +236,29 @@ class InstallerFile:
|
|||
return self._file_meta["size"]
|
||||
return 0
|
||||
|
||||
def is_ready(self, provider):
|
||||
"""Is the file already present at the destination (if applicable)?"""
|
||||
return provider not in ("user", "pga") or system.path_exists(self.dest_file)
|
||||
|
||||
@property
|
||||
def is_cached(self):
|
||||
"""Is the file available in the local PGA cache?"""
|
||||
return self.uses_pga_cache() and system.path_exists(self.dest_file)
|
||||
|
||||
def save_to_cache(self):
|
||||
"""Copy the file into the PGA cache."""
|
||||
save_to_cache(self.dest_file, self.cache_path)
|
||||
|
||||
def remove_previous(self):
|
||||
"""Remove file at already at destination, prior to starting the download."""
|
||||
if (
|
||||
not self.uses_pga_cache()
|
||||
and system.path_exists(self.dest_file)
|
||||
):
|
||||
# If we've previously downloaded a directory, we'll need to get rid of it
|
||||
# to download a file now. Since we are not using the cache, we don't keep
|
||||
# these files anyway - so it should be safe to just nuke and pave all this.
|
||||
if os.path.isdir(self.dest_file):
|
||||
system.remove_folder(self.dest_file)
|
||||
else:
|
||||
os.remove(self.dest_file)
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
import os
|
||||
from functools import reduce
|
||||
from urllib.parse import urlparse
|
||||
from gettext import gettext as _
|
||||
|
||||
from lutris import cache, settings
|
||||
from lutris.gui.widgets.download_collection_progress_box import DownloadCollectionProgressBox
|
||||
from lutris.util import system
|
||||
from lutris.util.log import logger
|
||||
from lutris.util.strings import add_url_tags, gtk_safe
|
||||
|
@ -15,12 +17,12 @@ class InstallerFileCollection:
|
|||
"""Representation of a collection of files in the `files` sections of an installer.
|
||||
Store files in a folder"""
|
||||
|
||||
def __init__(self, game_slug, file_id, files_list, dest_folder=None):
|
||||
def __init__(self, game_slug, file_id, files_list, dest_file=None):
|
||||
self.game_slug = game_slug
|
||||
self.id = file_id.replace("-", "_") # pylint: disable=invalid-name
|
||||
self.num_files = len(files_list)
|
||||
self.files_list = files_list
|
||||
self._dest_folder = dest_folder # Used to override the destination
|
||||
self._dest_file = dest_file # Used to override the destination
|
||||
self.full_size = 0
|
||||
self._get_files_size()
|
||||
self._get_service()
|
||||
|
@ -50,21 +52,35 @@ class InstallerFileCollection:
|
|||
@property
|
||||
def dest_file(self):
|
||||
"""dest_file represents destination folder to all file collection"""
|
||||
if self._dest_folder:
|
||||
return self._dest_folder
|
||||
if self._dest_file:
|
||||
return self._dest_file
|
||||
return self.cache_path
|
||||
|
||||
@dest_file.setter
|
||||
def dest_file(self, value):
|
||||
self._dest_folder = value
|
||||
self._dest_file = value
|
||||
# try to set main gog file to dest_file
|
||||
for installer_file in self.files_list:
|
||||
if installer_file.id == "goginstaller":
|
||||
installer_file.dest_file = value
|
||||
|
||||
def get_dest_files_by_id(self):
|
||||
files = {}
|
||||
for file in self.files_list:
|
||||
files.update({file.id: file.dest_file})
|
||||
return files
|
||||
|
||||
def __str__(self):
|
||||
return "%s/%s" % (self.game_slug, self.id)
|
||||
|
||||
@property
|
||||
def auxiliary_info(self):
|
||||
"""Provides a small bit of additional descriptive texts to show in the UI."""
|
||||
if self.num_files == 1:
|
||||
return f"{self.num_files} {_('File')}"
|
||||
|
||||
return f"{self.num_files} {_('Files')}"
|
||||
|
||||
@property
|
||||
def human_url(self):
|
||||
"""Return game_slug"""
|
||||
|
@ -75,7 +91,7 @@ class InstallerFileCollection:
|
|||
return add_url_tags(gtk_safe(self.game_slug))
|
||||
|
||||
@property
|
||||
def provider(self):
|
||||
def default_provider(self):
|
||||
"""Return file provider used. File Collection only supports 'pga' and 'download'"""
|
||||
if self.is_cached:
|
||||
return "pga"
|
||||
|
@ -127,8 +143,18 @@ class InstallerFileCollection:
|
|||
def prepare(self):
|
||||
"""Prepare all files for download"""
|
||||
# File Collection do not need to prepare, only the files_list
|
||||
for file in self.files_list:
|
||||
file.prepare()
|
||||
for installer_file in self.files_list:
|
||||
installer_file.prepare()
|
||||
|
||||
def create_download_progress_box(self):
|
||||
return DownloadCollectionProgressBox(self)
|
||||
|
||||
def is_ready(self, provider):
|
||||
"""Are all the files already present at the destination?"""
|
||||
for installer_file in self.files_list:
|
||||
if not installer_file.is_ready(provider):
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_cached(self):
|
||||
|
@ -140,3 +166,13 @@ class InstallerFileCollection:
|
|||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
def save_to_cache(self):
|
||||
"""Copy the files into the PGA cache."""
|
||||
for installer_file in self.files_list:
|
||||
installer_file.save_to_cache()
|
||||
|
||||
def remove_previous(self):
|
||||
"""Remove file at already at destination, prior to starting the download."""
|
||||
for installer_file in self.files_list:
|
||||
installer_file.remove_previous()
|
||||
|
|
Loading…
Reference in a new issue