mirror of
https://github.com/derrod/legendary.git
synced 2025-08-26 20:11:04 +00:00
added install dialog (but install is still TODO)
This commit is contained in:
parent
5bea328678
commit
3377d13526
|
@ -7,6 +7,14 @@ from gi.repository import Gtk
|
|||
import legendary.core
|
||||
core = legendary.core.LegendaryCore()
|
||||
|
||||
def log_gtk(msg):
|
||||
dialog = Gtk.Dialog(title="Legendary Log")
|
||||
dialog.log = Gtk.Label(label=msg)
|
||||
dialog.log.set_selectable(True)
|
||||
box = dialog.get_content_area()
|
||||
box.add(dialog.log)
|
||||
dialog.show_all()
|
||||
|
||||
def is_installed(app_name):
|
||||
if core.get_installed_game(app_name) == None:
|
||||
return "No"
|
||||
|
@ -40,13 +48,518 @@ def update_avail(app_name):
|
|||
else:
|
||||
return ""
|
||||
|
||||
def log_gtk(msg):
|
||||
dialog = Gtk.Dialog(title="Legendary Log")
|
||||
dialog.log = Gtk.Label(label=msg)
|
||||
dialog.log.set_selectable(True)
|
||||
box = dialog.get_content_area()
|
||||
box.add(dialog.log)
|
||||
dialog.show_all()
|
||||
def install_gtk(app_name, app_title, parent):
|
||||
install_dialog = Gtk.MessageDialog( parent=parent,
|
||||
destroy_with_parent=True,
|
||||
message_type=Gtk.MessageType.QUESTION,
|
||||
buttons=Gtk.ButtonsType.OK_CANCEL,
|
||||
text=f"Install {app_title} (Leave entries blank to use the default)"
|
||||
)
|
||||
install_dialog.set_title(f"Install {app_title}")
|
||||
install_dialog.set_default_size(400, 0)
|
||||
# install_dialog.remove(install_dialog.get_content_area())
|
||||
|
||||
vbox = install_dialog.get_content_area()
|
||||
#box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
# advanced options declaration
|
||||
show_advanced = False
|
||||
show_advanced_check_button = Gtk.CheckButton(label="Show advanced options")
|
||||
vbox.add(show_advanced_check_button)
|
||||
advanced_options = Gtk.VBox(spacing=5)
|
||||
|
||||
# --base-path <path>
|
||||
base_path_box = Gtk.HBox()
|
||||
base_path_label = Gtk.Label(label="Base Path")
|
||||
base_path_entry = Gtk.Entry()
|
||||
base_path_box.pack_start(base_path_label, False, False, 10)
|
||||
base_path_box.pack_start(base_path_entry, True, True, 0)
|
||||
vbox.add(base_path_box)
|
||||
|
||||
# --game-folder <path>
|
||||
game_folder_box = Gtk.HBox()
|
||||
game_folder_label = Gtk.Label(label="Game Folder")
|
||||
game_folder_entry = Gtk.Entry()
|
||||
game_folder_box.pack_start(game_folder_label, False, False, 10)
|
||||
game_folder_box.pack_start(game_folder_entry, True, True, 0)
|
||||
vbox.add(game_folder_box)
|
||||
|
||||
# --max-shared-memory <size> (in MiB)
|
||||
max_shm_box = Gtk.HBox()
|
||||
max_shm_label = Gtk.Label(label="Max Shared Memory")
|
||||
max_shm_entry = Gtk.Entry()
|
||||
max_shm_box.pack_start(game_folder_label, False, False, 10)
|
||||
max_shm_box.pack_start(game_folder_entry, True, True, 0)
|
||||
advanced_options.add(max_shm_box)
|
||||
|
||||
# --max-workers <num>
|
||||
max_workers_box = Gtk.HBox()
|
||||
max_workers_label = Gtk.Label(label="Max Workers")
|
||||
max_workers_entry = Gtk.Entry()
|
||||
max_workers_box.pack_start(max_workers_label, False, False, 10)
|
||||
max_workers_box.pack_start(max_workers_entry, True, True, 0)
|
||||
advanced_options.add(max_workers_box)
|
||||
|
||||
# --manifest <uri>
|
||||
override_manifest_box = Gtk.HBox()
|
||||
override_manifest_label = Gtk.Label(label="Manifest")
|
||||
override_manifest_entry = Gtk.Entry()
|
||||
override_manifest_box.pack_start(override_manifest_label, False, False, 10)
|
||||
override_manifest_box.pack_start(override_manifest_entry, True, True, 0)
|
||||
advanced_options.add(override_manifest_box)
|
||||
|
||||
# --old-manifest <uri>
|
||||
override_old_manifest_box = Gtk.HBox()
|
||||
override_old_manifest_label = Gtk.Label(label="Old Manifest")
|
||||
override_old_manifest_entry = Gtk.Entry()
|
||||
override_old_manifest_box.pack_start(override_old_manifest_label, False, False, 10)
|
||||
override_old_manifest_box.pack_start(override_old_manifest_entry, True, True, 0)
|
||||
advanced_options.add(override_old_manifest_box)
|
||||
|
||||
# --delta-manifest <uri>
|
||||
override_delta_manifest_box = Gtk.HBox()
|
||||
override_delta_manifest_label = Gtk.Label(label="Delta Manifest")
|
||||
override_delta_manifest_entry = Gtk.Entry()
|
||||
override_delta_manifest_box.pack_start(override_delta_manifest_label, False, False, 10)
|
||||
override_delta_manifest_box.pack_start(override_delta_manifest_entry, True, True, 0)
|
||||
advanced_options.add(override_delta_manifest_box)
|
||||
|
||||
# --base-url <url>
|
||||
override_base_url_box = Gtk.HBox()
|
||||
override_base_url_label = Gtk.Label(label="Base Url")
|
||||
override_base_url_entry = Gtk.Entry()
|
||||
override_base_url_box.pack_start(override_base_url_label, False, False, 10)
|
||||
override_base_url_box.pack_start(override_base_url_entry, True, True, 0)
|
||||
advanced_options.add(override_base_url_box)
|
||||
|
||||
# --force
|
||||
force = False
|
||||
force_check_button = Gtk.CheckButton(label="Force install")
|
||||
def force_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
force = False
|
||||
else:
|
||||
force = True
|
||||
print(name, "is now", force)
|
||||
force_check_button.connect("toggled", force_button_toggled, "force")
|
||||
advanced_options.add(force_check_button)
|
||||
|
||||
# --disable-patching
|
||||
disable_patching = False
|
||||
disable_patching_check_button = Gtk.CheckButton(label="Disable patching")
|
||||
def disable_patching_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
disable_patching = False
|
||||
else:
|
||||
disable_patching = True
|
||||
print(name, " is now ", state)
|
||||
disable_patching_check_button.connect("toggled", disable_patching_button_toggled, "disable_patching")
|
||||
advanced_options.add(disable_patching_check_button)
|
||||
|
||||
# --download-only, --no-install
|
||||
download_only = False
|
||||
download_only_check_button = Gtk.CheckButton(label="Download only")
|
||||
def download_only_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
download_only = False
|
||||
else:
|
||||
download_only = True
|
||||
print(name, "is now", download_only)
|
||||
download_only_check_button.connect("toggled", download_only_button_toggled, "download_only")
|
||||
advanced_options.add(download_only_check_button)
|
||||
|
||||
# --update-only
|
||||
update_only = False
|
||||
update_only_check_button = Gtk.CheckButton(label="Update only")
|
||||
def update_only_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
update_only = False
|
||||
else:
|
||||
update_only = True
|
||||
print(name, "is now", update_only)
|
||||
update_only_check_button.connect("toggled", update_only_button_toggled, "update_only")
|
||||
advanced_options.add(update_only_check_button)
|
||||
|
||||
# --dlm-debug
|
||||
glm_debug = False
|
||||
glm_debug_check_button = Gtk.CheckButton(label="Downloader debug messages")
|
||||
def glm_debug_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
glm_debug = False
|
||||
else:
|
||||
glm_debug = True
|
||||
print(name, "is now", glm_debug)
|
||||
glm_debug_check_button.connect("toggled", glm_debug_button_toggled, "glm_debug")
|
||||
advanced_options.add(glm_debug_check_button)
|
||||
|
||||
# --platform <Platform>
|
||||
platform_override_box = Gtk.HBox()
|
||||
platform_override_label = Gtk.Label(label="Platform")
|
||||
platform_override_entry = Gtk.Entry()
|
||||
platform_override_box.pack_start(platform_override_label, False, False, 10)
|
||||
platform_override_box.pack_start(platform_override_entry, True, True, 0)
|
||||
advanced_options.add(platform_override_box)
|
||||
|
||||
# --prefix <prefix>
|
||||
file_prefix_filter_box = Gtk.HBox()
|
||||
file_prefix_filter_label = Gtk.Label(label="File prefix filter")
|
||||
file_prefix_filter_entry = Gtk.Entry()
|
||||
file_prefix_filter_box.pack_start(file_prefix_filter_label, False, False, 10)
|
||||
file_prefix_filter_box.pack_start(file_prefix_filter_entry, True, True, 0)
|
||||
advanced_options.add(file_prefix_filter_box)
|
||||
|
||||
# --exclude <prefix>
|
||||
file_exclude_filter_box = Gtk.HBox()
|
||||
file_exclude_filter_label = Gtk.Label(label="File exclude filter")
|
||||
file_exclude_filter_entry = Gtk.Entry()
|
||||
file_exclude_filter_box.pack_start(file_exclude_filter_label, False, False, 10)
|
||||
file_exclude_filter_box.pack_start(file_exclude_filter_entry, True, True, 0)
|
||||
advanced_options.add(file_exclude_filter_box)
|
||||
|
||||
# --install-tag <tag>
|
||||
file_install_tag_box = Gtk.HBox()
|
||||
file_install_tag_label = Gtk.Label(label="Install tag")
|
||||
file_install_tag_entry = Gtk.Entry()
|
||||
file_install_tag_box.pack_start(file_install_tag_label, False, False, 10)
|
||||
file_install_tag_box.pack_start(file_install_tag_entry, True, True, 0)
|
||||
advanced_options.add(file_install_tag_box)
|
||||
|
||||
# --enable-reordering
|
||||
enable_reordering = False
|
||||
enable_reordering_check_button = Gtk.CheckButton(label="Enable reordering optimization")
|
||||
def enable_reordering_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
enable_reordering = False
|
||||
else:
|
||||
enable_reordering = True
|
||||
print(name, "is now", enable_reordering)
|
||||
enable_reordering_check_button.connect("toggled", enable_reordering_button_toggled, "enable_reordering")
|
||||
advanced_options.add(enable_reordering_check_button)
|
||||
|
||||
# --dl-timeout <sec>
|
||||
dl_timeout_box = Gtk.HBox()
|
||||
dl_timeout_label = Gtk.Label(label="Downloader timeout")
|
||||
dl_timeout_entry = Gtk.Entry()
|
||||
dl_timeout_box.pack_start(dl_timeout_label, False, False, 10)
|
||||
dl_timeout_box.pack_start(dl_timeout_entry, True, True, 0)
|
||||
advanced_options.add(dl_timeout_box)
|
||||
|
||||
# --save-path <path>
|
||||
save_path_box = Gtk.HBox()
|
||||
save_path_label = Gtk.Label(label="Save path")
|
||||
save_path_entry = Gtk.Entry()
|
||||
save_path_box.pack_start(save_path_label, False, False, 10)
|
||||
save_path_box.pack_start(save_path_entry, True, True, 0)
|
||||
advanced_options.add(save_path_box)
|
||||
|
||||
# --repair
|
||||
repair = False
|
||||
repair_check_button = Gtk.CheckButton(label="Repair")
|
||||
def repair_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
repair = False
|
||||
else:
|
||||
repair = True
|
||||
print(name, "is now", repair)
|
||||
repair_check_button.connect("toggled", repair_button_toggled, "repair")
|
||||
advanced_options.add(repair_check_button)
|
||||
|
||||
# --repair-and-update
|
||||
repair_and_update = False # or repair_use_latest
|
||||
repair_and_update_check_button = Gtk.CheckButton(label="Repair and Update")
|
||||
def repair_and_update_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
repair_and_update = False
|
||||
else:
|
||||
repair_and_update = True
|
||||
print(name, "is now", repair_and_update)
|
||||
repair_and_update_check_button.connect("toggled", repair_and_update_button_toggled, "repair_and_update")
|
||||
advanced_options.add(repair_and_update_check_button)
|
||||
|
||||
# --ignore-free-space
|
||||
ignore_space_req = False
|
||||
ignore_space_req_check_button = Gtk.CheckButton(label="Ignore space requirements")
|
||||
def ignore_space_req_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
ignore_space_req = False
|
||||
else:
|
||||
ignore_space_req = True
|
||||
print(name, "is now", ignore_space_req)
|
||||
ignore_space_req_check_button.connect("toggled", ignore_space_req_button_toggled, "ignore_space_req")
|
||||
advanced_options.add(ignore_space_req_check_button)
|
||||
|
||||
# --disable-delta-manifests
|
||||
override_delta_manifest = False
|
||||
override_delta_manifest_check_button = Gtk.CheckButton(label="Disable delta manifests")
|
||||
def override_delta_manifest_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
override_delta_manifest = False
|
||||
else:
|
||||
override_delta_manifest = True
|
||||
print(name, "is now", override_delta_manifest)
|
||||
override_delta_manifest_check_button.connect("toggled", override_delta_manifest_button_toggled, "override_delta_manifest")
|
||||
advanced_options.add(override_delta_manifest_check_button)
|
||||
|
||||
# --reset-sdl
|
||||
reset_sdl = False
|
||||
reset_sdl_check_button = Gtk.CheckButton(label="Reset selective downloading choices")
|
||||
def reset_sdl_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
reset_sdl = False
|
||||
else:
|
||||
reset_sdl = True
|
||||
print(name, "is now", reset_sdl)
|
||||
reset_sdl_check_button.connect("toggled", reset_sdl_button_toggled, "reset_sdl")
|
||||
advanced_options.add(reset_sdl_check_button)
|
||||
|
||||
|
||||
vbox.add(advanced_options)
|
||||
# advanced_options function
|
||||
def show_advanced_button_toggled(button, name):
|
||||
if button.get_active():
|
||||
show_advanced = True
|
||||
advanced_options.show()
|
||||
else:
|
||||
show_advanced = False
|
||||
#vbox.remove(advanced_options)
|
||||
advanced_options.hide()
|
||||
install_dialog.resize(400,5)
|
||||
print(name, "is now", show_advanced)
|
||||
show_advanced_check_button.connect("toggled", show_advanced_button_toggled, "show_advanced")
|
||||
|
||||
# vbox.pack_start(base_path_box, False, False, 0)
|
||||
# vbox.pack_start(game_folder_box, False, False, 0)
|
||||
#vbox.pack_start(path_entry, True, True, 10)
|
||||
|
||||
install_dialog.show()
|
||||
vbox.show()
|
||||
#advanced_options.hide()
|
||||
#install_dialog.resize(400,5)
|
||||
response = install_dialog.run()
|
||||
base_path = base_path_entry.get_text()
|
||||
install_dialog.destroy()
|
||||
print(base_path)
|
||||
return 1
|
||||
|
||||
|
||||
if response != Gtk.ResponseType.OK:
|
||||
return 1
|
||||
|
||||
if core.is_installed(app_name):
|
||||
igame = core.get_installed_game(app_name)
|
||||
if igame.needs_verification:
|
||||
repair_mode = True
|
||||
repair_file = None
|
||||
if repair_mode:
|
||||
args.no_install = args.repair_and_update is False
|
||||
repair_file = os.path.join(self.core.lgd.get_tmp_path(), f'{args.app_name}.repair')
|
||||
|
||||
if not self.core.login():
|
||||
logger.error('Login failed! Cannot continue with download process.')
|
||||
exit(1)
|
||||
|
||||
if args.file_prefix or args.file_exclude_prefix or args.install_tag:
|
||||
args.no_install = True
|
||||
|
||||
if args.update_only:
|
||||
if not self.core.is_installed(args.app_name):
|
||||
logger.error(f'Update requested for "{args.app_name}", but app not installed!')
|
||||
exit(1)
|
||||
|
||||
if args.platform_override:
|
||||
args.no_install = True
|
||||
|
||||
game = self.core.get_game(args.app_name, update_meta=True)
|
||||
|
||||
if not game:
|
||||
logger.error(f'Could not find "{args.app_name}" in list of available games,'
|
||||
f'did you type the name correctly?')
|
||||
exit(1)
|
||||
|
||||
if game.is_dlc:
|
||||
logger.info('Install candidate is DLC')
|
||||
app_name = game.metadata['mainGameItem']['releaseInfo'][0]['appId']
|
||||
base_game = self.core.get_game(app_name)
|
||||
# check if base_game is actually installed
|
||||
if not self.core.is_installed(app_name):
|
||||
# download mode doesn't care about whether or not something's installed
|
||||
if not args.no_install:
|
||||
logger.fatal(f'Base game "{app_name}" is not installed!')
|
||||
exit(1)
|
||||
else:
|
||||
base_game = None
|
||||
|
||||
if args.repair_mode:
|
||||
if not self.core.is_installed(game.app_name):
|
||||
logger.error(f'Game "{game.app_title}" ({game.app_name}) is not installed!')
|
||||
exit(0)
|
||||
|
||||
if not os.path.exists(repair_file):
|
||||
logger.info('Game has not been verified yet.')
|
||||
if not args.yes:
|
||||
if not get_boolean_choice(f'Verify "{game.app_name}" now ("no" will abort repair)?'):
|
||||
print('Aborting...')
|
||||
exit(0)
|
||||
|
||||
self.verify_game(args, print_command=False)
|
||||
else:
|
||||
logger.info(f'Using existing repair file: {repair_file}')
|
||||
|
||||
# Workaround for Cyberpunk 2077 preload
|
||||
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)
|
||||
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)
|
||||
if game.app_name not in self.core.lgd.config:
|
||||
self.core.lgd.config[game.app_name] = dict()
|
||||
self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag))
|
||||
else:
|
||||
args.install_tag = config_tags.split(',')
|
||||
|
||||
logger.info('Preparing download...')
|
||||
# todo use status queue to print progress from CLI
|
||||
# This has become a little ridiculous hasn't it?
|
||||
dlm, analysis, igame = self.core.prepare_download(game=game, base_game=base_game, base_path=args.base_path,
|
||||
force=args.force, max_shm=args.shared_memory,
|
||||
max_workers=args.max_workers, game_folder=args.game_folder,
|
||||
disable_patching=args.disable_patching,
|
||||
override_manifest=args.override_manifest,
|
||||
override_old_manifest=args.override_old_manifest,
|
||||
override_base_url=args.override_base_url,
|
||||
platform_override=args.platform_override,
|
||||
file_prefix_filter=args.file_prefix,
|
||||
file_exclude_filter=args.file_exclude_prefix,
|
||||
file_install_tag=args.install_tag,
|
||||
dl_optimizations=args.order_opt,
|
||||
dl_timeout=args.dl_timeout,
|
||||
repair=args.repair_mode,
|
||||
repair_use_latest=args.repair_and_update,
|
||||
disable_delta=args.disable_delta,
|
||||
override_delta_manifest=args.override_delta_manifest)
|
||||
|
||||
# game is either up to date or hasn't changed, so we have nothing to do
|
||||
if not analysis.dl_size:
|
||||
old_igame = self.core.get_installed_game(game.app_name)
|
||||
logger.info('Download size is 0, the game is either already up to date or has not changed. Exiting...')
|
||||
if old_igame and args.repair_mode and os.path.exists(repair_file):
|
||||
if old_igame.needs_verification:
|
||||
old_igame.needs_verification = False
|
||||
self.core.install_game(old_igame)
|
||||
|
||||
logger.debug('Removing repair file.')
|
||||
os.remove(repair_file)
|
||||
|
||||
# check if install tags have changed, if they did; try deleting files that are no longer required.
|
||||
if old_igame and old_igame.install_tags != igame.install_tags:
|
||||
old_igame.install_tags = igame.install_tags
|
||||
self.logger.info('Deleting now untagged files.')
|
||||
self.core.uninstall_tag(old_igame)
|
||||
self.core.install_game(old_igame)
|
||||
|
||||
exit(0)
|
||||
|
||||
logger.info(f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB')
|
||||
compression = (1 - (analysis.dl_size / analysis.uncompressed_dl_size)) * 100
|
||||
logger.info(f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB '
|
||||
f'(Compression savings: {compression:.01f}%)')
|
||||
logger.info(f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / '
|
||||
f'{analysis.unchanged / 1024 / 1024:.02f} MiB (unchanged / skipped)')
|
||||
|
||||
res = self.core.check_installation_conditions(analysis=analysis, install=igame, game=game,
|
||||
updating=self.core.is_installed(args.app_name),
|
||||
ignore_space_req=args.ignore_space)
|
||||
|
||||
if res.warnings or res.failures:
|
||||
logger.info('Installation requirements check returned the following results:')
|
||||
|
||||
if res.warnings:
|
||||
for warn in sorted(res.warnings):
|
||||
logger.warning(warn)
|
||||
|
||||
if res.failures:
|
||||
for msg in sorted(res.failures):
|
||||
logger.fatal(msg)
|
||||
logger.error('Installation cannot proceed, exiting.')
|
||||
exit(1)
|
||||
|
||||
logger.info('Downloads are resumable, you can interrupt the download with '
|
||||
'CTRL-C and resume it using the same command later on.')
|
||||
|
||||
if not args.yes:
|
||||
if not get_boolean_choice(f'Do you wish to install "{igame.title}"?'):
|
||||
print('Aborting...')
|
||||
exit(0)
|
||||
|
||||
start_t = time.time()
|
||||
|
||||
try:
|
||||
# set up logging stuff (should be moved somewhere else later)
|
||||
dlm.logging_queue = self.logging_queue
|
||||
dlm.proc_debug = args.dlm_debug
|
||||
|
||||
dlm.start()
|
||||
dlm.join()
|
||||
except Exception as e:
|
||||
end_t = time.time()
|
||||
logger.info(f'Installation failed after {end_t - start_t:.02f} seconds.')
|
||||
logger.warning(f'The following exception occurred while waiting for the downloader to finish: {e!r}. '
|
||||
f'Try restarting the process, the resume file will be used to start where it failed. '
|
||||
f'If it continues to fail please open an issue on GitHub.')
|
||||
else:
|
||||
end_t = time.time()
|
||||
if not args.no_install:
|
||||
# Allow setting savegame directory at install time so sync-saves will work immediately
|
||||
if game.supports_cloud_saves and args.save_path:
|
||||
igame.save_path = args.save_path
|
||||
|
||||
postinstall = self.core.install_game(igame)
|
||||
if postinstall:
|
||||
self._handle_postinstall(postinstall, igame, yes=args.yes)
|
||||
|
||||
dlcs = self.core.get_dlc_for_game(game.app_name)
|
||||
if dlcs:
|
||||
print('The following DLCs are available for this game:')
|
||||
for dlc in dlcs:
|
||||
print(f' - {dlc.app_title} (App name: {dlc.app_name}, version: {dlc.app_version})')
|
||||
print('Manually installing DLCs works the same; just use the DLC app name instead.')
|
||||
|
||||
install_dlcs = True
|
||||
if not args.yes:
|
||||
if not get_boolean_choice(f'Do you wish to automatically install DLCs?'):
|
||||
install_dlcs = False
|
||||
|
||||
if install_dlcs:
|
||||
_yes, _app_name = args.yes, args.app_name
|
||||
args.yes = True
|
||||
for dlc in dlcs:
|
||||
args.app_name = dlc.app_name
|
||||
self.install_game(args)
|
||||
args.yes, args.app_name = _yes, _app_name
|
||||
|
||||
if game.supports_cloud_saves and not game.is_dlc:
|
||||
# todo option to automatically download saves after the installation
|
||||
# args does not have the required attributes for sync_saves in here,
|
||||
# not sure how to solve that elegantly.
|
||||
logger.info('This game supports cloud saves, syncing is handled by the "sync-saves" command.')
|
||||
logger.info(f'To download saves for this game run "legendary sync-saves {args.app_name}"')
|
||||
|
||||
old_igame = self.core.get_installed_game(game.app_name)
|
||||
if old_igame and args.repair_mode and os.path.exists(repair_file):
|
||||
if old_igame.needs_verification:
|
||||
old_igame.needs_verification = False
|
||||
self.core.install_game(old_igame)
|
||||
|
||||
logger.debug('Removing repair file.')
|
||||
os.remove(repair_file)
|
||||
|
||||
# check if install tags have changed, if they did; try deleting files that are no longer required.
|
||||
if old_igame and old_igame.install_tags != igame.install_tags:
|
||||
old_igame.install_tags = igame.install_tags
|
||||
self.logger.info('Deleting now untagged files.')
|
||||
self.core.uninstall_tag(old_igame)
|
||||
self.core.install_game(old_igame)
|
||||
|
||||
logger.info(f'Finished installation process in {end_t - start_t:.02f} seconds.')
|
||||
|
||||
class main_window(Gtk.Window):
|
||||
def __init__(self):
|
||||
|
@ -88,31 +601,36 @@ class main_window(Gtk.Window):
|
|||
self.scroll.set_border_width(10)
|
||||
self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS)
|
||||
self.box.pack_end(self.scroll, True, True, 0)
|
||||
self.scroll.games = Gtk.ListStore(str, str, str, str)
|
||||
gcols = ["Title","Installed","Size","Update Avaiable"]
|
||||
self.scroll.games = Gtk.ListStore(str, str, str, str, str)
|
||||
gcols = ["appname","Title","Installed","Size","Update Avaiable"]
|
||||
|
||||
if logged:
|
||||
# get games
|
||||
games, dlc_list = core.get_game_and_dlc_list()
|
||||
games = sorted(games, key=lambda x: x.app_title.lower())
|
||||
for citem_id in dlc_list.keys():
|
||||
dlc_list[citem_id] = sorted(dlc_list[citem_id], key=lambda d: d.app_title.lower())
|
||||
# add games to liststore for treeview
|
||||
for game in games:
|
||||
ls = ( game.app_title,
|
||||
ls = ( game.app_name,
|
||||
game.app_title,
|
||||
is_installed(game.app_name),
|
||||
installed_size(game.app_name),
|
||||
update_avail(game.app_name)
|
||||
update_avail(game.app_name),
|
||||
)
|
||||
self.scroll.games.append(list(ls))
|
||||
#print(f' * {game.app_title} (App name: {game.app_name} | Version: {game.app_version})')
|
||||
for dlc in dlc_list[game.asset_info.catalog_item_id]:
|
||||
ls = ( dlc.app_title+f" (DLC of {game.app_title})",
|
||||
ls = ( dlc.app_name,
|
||||
dlc.app_title+f" (DLC of {game.app_title})",
|
||||
is_installed(dlc.app_name),
|
||||
installed_size(dlc.app_name),
|
||||
update_avail(dlc.app_name)
|
||||
update_avail(dlc.app_name),
|
||||
)
|
||||
self.scroll.games.append(list(ls))
|
||||
#print(f' + {dlc.app_title} (App name: {dlc.app_name} | Version: {dlc.app_version})')
|
||||
|
||||
# add games to treeview
|
||||
#self.scroll.gview = Gtk.TreeView(Gtk.TreeModelSort(model=self.scroll.games))
|
||||
self.scroll.gview = Gtk.TreeView(model=self.scroll.games)
|
||||
for i, c in enumerate(gcols):
|
||||
|
@ -122,8 +640,12 @@ class main_window(Gtk.Window):
|
|||
col.set_resizable(True)
|
||||
col.set_reorderable(True)
|
||||
col.set_sort_column_id(i)
|
||||
if c == "appname":
|
||||
col.set_visible(False)
|
||||
self.scroll.gview.append_column(col)
|
||||
|
||||
self.scroll.gview.connect("row-activated", self.on_tree_selection_changed)
|
||||
|
||||
l = Gtk.Label()
|
||||
l.set_text("")
|
||||
g = Gtk.Grid()
|
||||
|
@ -153,6 +675,13 @@ class main_window(Gtk.Window):
|
|||
self.destroy()
|
||||
main()
|
||||
|
||||
def on_tree_selection_changed(self, selection,b,c):
|
||||
#print(selection,b,c)
|
||||
model, treeiter = selection.get_selection().get_selected()
|
||||
if treeiter is not None:
|
||||
install_gtk(model[treeiter][0], model[treeiter][1], self)
|
||||
#print(model[treeiter][0], model[treeiter][1])
|
||||
|
||||
def ask_sid(parent):
|
||||
dialog = Gtk.MessageDialog(parent=parent, destroy_with_parent=True, message_type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.OK_CANCEL)
|
||||
dialog.set_title("Enter Sid")
|
||||
|
|
Loading…
Reference in a new issue