Skip to content

Commit

Permalink
Merge pull request #597 from viacheslavka/master
Browse files Browse the repository at this point in the history
Fix Windows games installation
  • Loading branch information
sharkwouter committed Apr 24, 2024
2 parents 86ac46a + c9381e9 commit 1ce0eb4
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 21 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,9 @@
**1.3.0**
- Fix race when preparing download location (thanks to viacheslavka)
- Fix multithreaded downloads of Windows games (thanks to viacheslavka)
- Fix DLC installation for Windows games (thanks to viacheslavka)
- Allow users to specify the download directory (thanks to viacheslavka)

**1.2.6**
- Fix changing the install path causing an exception
- Fix error detection & reporting on wineprefix creation failure (thanks to LeXofLeviafan)
Expand Down
2 changes: 1 addition & 1 deletion minigalaxy/api.py
Expand Up @@ -156,7 +156,7 @@ def get_download_info(self, game: Game, operating_system="linux", dlc_installers
possible_downloads.append(installer)
if not possible_downloads:
if operating_system == "linux":
return self.get_download_info(game, "windows")
return self.get_download_info(game, "windows", dlc_installers)
else:
raise NoDownloadLinkFound("Error: {} with id {} couldn't be installed".format(game.name, game.id))

Expand Down
10 changes: 4 additions & 6 deletions minigalaxy/download_manager.py
Expand Up @@ -294,10 +294,9 @@ def __download_file(self, download, download_queue):
download_attempt += 1
# Successful downloads
if result:
if download.number == download.out_of_amount:
self.logger.debug("Download finished, thread {}".format(threading.get_ident()))
finish_thread = threading.Thread(target=download.finish)
finish_thread.start()
self.logger.debug("Download finished, thread {}".format(threading.get_ident()))
finish_thread = threading.Thread(target=download.finish)
finish_thread.start()
self.__remove_download_from_active_downloads(download)
# Unsuccessful downloads and cancels
else:
Expand All @@ -318,8 +317,7 @@ def __prepare_location(self, save_location):
"""
# Make sure the directory exists
save_directory = os.path.dirname(save_location)
if not os.path.isdir(save_directory):
os.makedirs(save_directory, mode=0o755)
os.makedirs(save_directory, mode=0o755, exist_ok=True)

# Fail if the file already exists
if os.path.isdir(save_location):
Expand Down
1 change: 1 addition & 0 deletions minigalaxy/paths.py
Expand Up @@ -9,6 +9,7 @@
CONFIG_GAMES_DIR = os.path.join(CONFIG_DIR, "games")
CONFIG_FILE_PATH = os.path.join(CONFIG_DIR, "config.json")
CACHE_DIR = os.path.join(os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')), "minigalaxy")
DOWNLOAD_DIR = os.path.join(os.getenv('MINIGALAXY_DOWNLOAD_DIR', CACHE_DIR), "download")

THUMBNAIL_DIR = os.path.join(CACHE_DIR, "thumbnails")
COVER_DIR = os.path.join(CACHE_DIR, "covers")
Expand Down
25 changes: 18 additions & 7 deletions minigalaxy/ui/gametile.py
Expand Up @@ -11,7 +11,7 @@
from minigalaxy.game import Game
from minigalaxy.logger import logger
from minigalaxy.translation import _
from minigalaxy.paths import CACHE_DIR, THUMBNAIL_DIR, ICON_DIR, UI_DIR
from minigalaxy.paths import CACHE_DIR, THUMBNAIL_DIR, ICON_DIR, UI_DIR, DOWNLOAD_DIR
from minigalaxy.download import Download, DownloadType
from minigalaxy.download_manager import DownloadManager
from minigalaxy.launcher import start_game
Expand Down Expand Up @@ -67,7 +67,7 @@ def __init__(self, parent, game: Game, config: Config, api: Api, download_manage
self.image.set_tooltip_text(self.game.name)

# Set folder for download installer
self.download_dir = os.path.join(CACHE_DIR, "download", self.game.get_install_directory_name())
self.download_dir = os.path.join(DOWNLOAD_DIR, self.game.get_install_directory_name())

# Set folder if user wants to keep installer (disabled by default)
self.keep_dir = os.path.join(self.config.install_dir, "installer")
Expand Down Expand Up @@ -259,8 +259,22 @@ def __download(self, download_info, download_type, finish_func, cancel_to_state)
self.download_list = []
number_of_files = len(download_info['files'])
total_file_size = 0
executable_path = None
download_files = []
self.download_finished = 0

def finish_func_wrapper(func):
def wrapper(*args):
self.download_finished += 1
if self.download_finished == number_of_files:
# Assume the first item in download_info['files] is the executable
# This item ends up last in self.download_list because it's reversed
finish_func(self.download_list[-1].save_location)

if func is not None:
return wrapper
else:
return None

for key, file_info in enumerate(download_info['files']):
try:
download_url = self.api.get_real_download_link(file_info["downlink"])
Expand All @@ -277,16 +291,13 @@ def __download(self, download_info, download_type, finish_func, cancel_to_state)
except AttributeError:
filename = "{}-{}.bin".format(self.game.get_stripped_name(), key)
download_path = os.path.join(self.download_dir, filename)
if key == 0:
# If key = 0, denote the file as the executable's path
executable_path = download_path
if info.md5:
self.game.md5sum[os.path.basename(download_path)] = info.md5
download = Download(
url=download_url,
save_location=download_path,
download_type=DownloadType.GAME,
finish_func=finish_func if download_path == executable_path else None,
finish_func=finish_func_wrapper(finish_func),
progress_func=self.set_progress,
cancel_func=lambda: self.__cancel(to_state=cancel_to_state),
number=number_of_files - key,
Expand Down
25 changes: 18 additions & 7 deletions minigalaxy/ui/gametilelist.py
Expand Up @@ -11,7 +11,7 @@
from minigalaxy.game import Game
from minigalaxy.logger import logger
from minigalaxy.translation import _
from minigalaxy.paths import CACHE_DIR, THUMBNAIL_DIR, ICON_DIR, UI_DIR
from minigalaxy.paths import CACHE_DIR, THUMBNAIL_DIR, ICON_DIR, UI_DIR, DOWNLOAD_DIR
from minigalaxy.download import Download, DownloadType
from minigalaxy.download_manager import DownloadManager
from minigalaxy.launcher import start_game
Expand Down Expand Up @@ -73,7 +73,7 @@ def __init__(self, parent, game: Game, config: Config, api: Api, download_manage
self.game_label.set_label(self.game.name)

# Set folder for download installer
self.download_dir = os.path.join(CACHE_DIR, "download", self.game.get_install_directory_name())
self.download_dir = os.path.join(DOWNLOAD_DIR, self.game.get_install_directory_name())

# Set folder if user wants to keep installer (disabled by default)
self.keep_dir = os.path.join(self.config.install_dir, "installer")
Expand Down Expand Up @@ -265,8 +265,22 @@ def __download(self, download_info, download_type, finish_func, cancel_to_state)
self.download_list = []
number_of_files = len(download_info['files'])
total_file_size = 0
executable_path = None
download_files = []
self.download_finished = 0

def finish_func_wrapper(func):
def wrapper(*args):
self.download_finished += 1
if self.download_finished == number_of_files:
# Assume the first item in download_info['files] is the executable
# This item ends up last in self.download_list because it's reversed
finish_func(self.download_list[-1].save_location)

if func is not None:
return wrapper
else:
return None

for key, file_info in enumerate(download_info['files']):
try:
download_url = self.api.get_real_download_link(file_info["downlink"])
Expand All @@ -283,16 +297,13 @@ def __download(self, download_info, download_type, finish_func, cancel_to_state)
except AttributeError:
filename = "{}-{}.bin".format(self.game.get_stripped_name(), key)
download_path = os.path.join(self.download_dir, filename)
if key == 0:
# If key = 0, denote the file as the executable's path
executable_path = download_path
if info.md5:
self.game.md5sum[os.path.basename(download_path)] = info.md5
download = Download(
url=download_url,
save_location=download_path,
download_type=DownloadType.GAME,
finish_func=finish_func if download_path == executable_path else None,
finish_func=finish_func_wrapper(finish_func),
progress_func=self.set_progress,
cancel_func=lambda: self.__cancel(to_state=cancel_to_state),
number=number_of_files - key,
Expand Down

0 comments on commit 1ce0eb4

Please sign in to comment.