2021-02-05_00-02-05

This commit is contained in:
koraynilay 2021-02-05 00:02:05 +01:00
parent 736983992c
commit 5ecd04abb0
5 changed files with 107 additions and 90 deletions

View file

@ -18,7 +18,8 @@ from typing import List, Dict
from uuid import uuid4
from legendary.api.egs import EPCAPI
from legendary.downloader.manager import DLManager
#from legendary.downloader.manager import DLManager
from legendary.gui.manager2 import DLManager
from legendary.lfs.egl import EPCLFS
from legendary.lfs.lgndry import LGDLFS
from legendary.utils.lfs import clean_filename, delete_folder, delete_filelist
@ -705,9 +706,10 @@ class LegendaryCore:
dl_optimizations: bool = False, dl_timeout: int = 10,
repair: bool = False, repair_use_latest: bool = False,
disable_delta: bool = False, override_delta_manifest: str = '',
egl_guid: str = '', main_window="cli") -> (DLManager, AnalysisResult, ManifestMeta):
egl_guid: str = '', main_window = "cli") -> (DLManager, AnalysisResult, ManifestMeta):
# load old manifest
old_manifest = None
print("prepare",main_window.get_title())
# load old manifest if we have one
if override_old_manifest:

View file

@ -1,10 +1,16 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class log_dlm:
def create(main_window):
def create(self, main_window):
if main_window == "cli":
print(main_window)
return "cli"
else:
bar = Gtk.ProgressBar()
main_window.login_vbox.pack_end(bar, False, False, 10)
print(main_window)
return bar
def update(self, perc, processed_chunks, num_chunk_tasks, rt_hours, rt_minutes, rt_seconds, hours, minutes, seconds, total_dl, total_write, total_used, dl_speed, dl_unc_speed, w_speed, r_speed, obj_out):
@ -50,6 +56,7 @@ class log_dlm:
def update_gui(self, perc, processed_chunks, num_chunk_tasks, rt_hours, rt_minutes, rt_seconds, hours, minutes, seconds, total_dl, total_write, total_used, dl_speed, dl_unc_speed, w_speed, r_speed, bar):
bar.set_fraction(perc)
bar.set_text(f"{dl_speed / 1024 / 1024:.02f} MiB/s - {(perc*100):.02f}% - ETA: {hours:02d}:{minutes:02d}:{seconds:02d}")
print(bar.get_text())
def update_cli(self, perc, processed_chunks, num_chunk_tasks, rt_hours, rt_minutes, rt_seconds, hours, minutes, seconds, total_dl, total_write, total_used, dl_speed, dl_unc_speed, w_speed, r_speed):
perc *= 100
@ -67,36 +74,22 @@ class log_dlm:
def init(parent):
bar = Gtk.ProgressBar()
parent.login_vbox.pack_end(bar, False, False, 10)
return bar
def update(self, perc, processed_chunks, num_chunk_tasks, rt_hours, rt_minutes, rt_seconds, hours, minutes, seconds, total_dl, total_write, total_used, dl_speed, dl_unc_speed, w_speed, r_speed):
self.
f'= Progress: {perc:.02f}% ({processed_chunks}/{num_chunk_tasks}), '
f'Running for {rt_hours:02d}:{rt_minutes:02d}:{rt_seconds:02d}, '
f'ETA: {hours:02d}:{minutes:02d}:{seconds:02d}')
f' - Downloaded: {total_dl / 1024 / 1024:.02f} MiB, '
f'Written: {total_write / 1024 / 1024:.02f} MiB')
f' - Cache usage: {total_used} MiB, active tasks: {self.active_tasks}')
f' + Download\t- {dl_speed / 1024 / 1024:.02f} MiB/s (raw) '
f'/ {dl_unc_speed / 1024 / 1024:.02f} MiB/s (decompressed)')
f' + Disk\t- {w_speed / 1024 / 1024:.02f} MiB/s (write) / '
f'{r_speed / 1024 / 1024:.02f} MiB/s (read)')
self.log.info(f'= Progress: {perc:.02f}% ({processed_chunks}/{num_chunk_tasks}), '
f'Running for {rt_hours:02d}:{rt_minutes:02d}:{rt_seconds:02d}, '
f'ETA: {hours:02d}:{minutes:02d}:{seconds:02d}')
self.log.info(f' - Downloaded: {total_dl / 1024 / 1024:.02f} MiB, '
f'Written: {total_write / 1024 / 1024:.02f} MiB')
self.log.info(f' - Cache usage: {total_used} MiB, active tasks: {self.active_tasks}')
self.log.info(f' + Download\t- {dl_speed / 1024 / 1024:.02f} MiB/s (raw) '
f'/ {dl_unc_speed / 1024 / 1024:.02f} MiB/s (decompressed)')
self.log.info(f' + Disk\t- {w_speed / 1024 / 1024:.02f} MiB/s (write) / '
f'{r_speed / 1024 / 1024:.02f} MiB/s (read)')
#
# self.log.info(f'= Progress: {perc:.02f}% ({processed_chunks}/{num_chunk_tasks}), '
# f'Running for {rt_hours:02d}:{rt_minutes:02d}:{rt_seconds:02d}, '
# f'ETA: {hours:02d}:{minutes:02d}:{seconds:02d}')
# self.log.info(f' - Downloaded: {total_dl / 1024 / 1024:.02f} MiB, '
# f'Written: {total_write / 1024 / 1024:.02f} MiB')
# self.log.info(f' - Cache usage: {total_used} MiB, active tasks: {self.active_tasks}')
# self.log.info(f' + Download\t- {dl_speed / 1024 / 1024:.02f} MiB/s (raw) '
# f'/ {dl_unc_speed / 1024 / 1024:.02f} MiB/s (decompressed)')
# self.log.info(f' + Disk\t- {w_speed / 1024 / 1024:.02f} MiB/s (write) / '
# f'{r_speed / 1024 / 1024:.02f} MiB/s (read)')

View file

@ -138,6 +138,7 @@ class FileWorker(Process):
logger = logging.getLogger(self.name)
logger.setLevel(self.log_level)
logger.debug(f'Download worker reporting for duty!')
print(f'Download worker reporting for duty! {self.name}')
last_filename = ''
current_file = None
@ -145,7 +146,9 @@ class FileWorker(Process):
while True:
try:
try:
j = self.q.get(timeout=10.0)
print(f'j = self.q.get - {self.name}')
#j = self.q.get(timeout=10.0)
j = self.q.get(timeout=0.5)
except Empty:
logger.warning('Writer queue empty!')
continue

View file

@ -1,11 +1,21 @@
#!/usr/bin/env python3
import gi
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '../..')
import webbrowser
import time
from multiprocessing import freeze_support, Queue as MPQueue
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import legendary.core
import legendary.cli
core = legendary.core.LegendaryCore()
cli = legendary.cli.LegendaryCLI()
class args_obj:
base_path = ''
@ -566,7 +576,7 @@ def install_gtk(app_name, app_title, parent):
f"reset_sdl:\t\t {args.reset_sdl}",
sep='\n'
)
return 1
#return 1
# TODO:
if install_dialog_response != Gtk.ResponseType.OK:
@ -577,7 +587,7 @@ def install_gtk(app_name, app_title, parent):
if igame.needs_verification:
repair_mode = True
repair_file = None
if repair_mode:
if args.repair_mode:
args.no_install = args.repair_and_update is False
repair_file = os.path.join(core.lgd.get_tmp_path(), f'{app_name}.repair')
@ -643,7 +653,7 @@ def install_gtk(app_name, app_title, parent):
# else:
# args.install_tag = config_tags.split(',')
log_gtk('Preparing download...')
print('Preparing download...')
# todo use status queue to print progress from CLI
# This has become a little ridiculous hasn't it?
dlm, analysis, igame = core.prepare_download(game=game, base_game=base_game, base_path=args.base_path,
@ -662,7 +672,7 @@ def install_gtk(app_name, app_title, parent):
repair=args.repair_mode,
repair_use_latest=args.repair_and_update,
disable_delta=args.disable_delta,
override_delta_manifest=args.override_delta_manifest
override_delta_manifest=args.override_delta_manifest,
main_window=parent)
# game is either up to date or hasn't changed, so we have nothing to do
@ -680,21 +690,21 @@ def install_gtk(app_name, app_title, parent):
# 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.log_gtk('Deleting now untagged files.')
log_gtk('Deleting now untagged files.')
core.uninstall_tag(old_igame)
core.install_game(old_igame)
exit(0)
log_gtk(f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB')
print(f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB')
compression = (1 - (analysis.dl_size / analysis.uncompressed_dl_size)) * 100
log_gtk(f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB '
print(f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB '
f'(Compression savings: {compression:.01f}%)')
log_gtk(f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / '
print(f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / '
f'{analysis.unchanged / 1024 / 1024:.02f} MiB (unchanged / skipped)')
res = core.check_installation_conditions(analysis=analysis, install=igame, game=game,
updating=self.core.is_installed(app_name),
updating=core.is_installed(app_name),
ignore_space_req=args.ignore_space)
if res.warnings or res.failures:
@ -710,16 +720,17 @@ def install_gtk(app_name, app_title, parent):
log_gtk('Installation cannot proceed, exiting.')
exit(1)
log_gtk('Downloads are resumable, you can interrupt the download with '
print('Downloads are resumable, you can interrupt the download with '
'CTRL-C and resume it using the same command later on.')
start_t = time.time()
try:
# set up logging stuff (should be moved somewhere else later)
dlm.logging_queue = self.logging_queue
dlm.logging_queue = cli.logging_queue
dlm.proc_debug = args.dlm_debug
#print("parent:",parent)
dlm.start()
dlm.join()
except Exception as e:
@ -728,60 +739,60 @@ def install_gtk(app_name, app_title, parent):
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
#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)
# 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.')
# 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
# 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, app_name
args.yes = True
for dlc in dlcs:
app_name = dlc.app_name
self.install_game(args)
args.yes, app_name = _yes, _app_name
# if install_dlcs:
# _yes, _app_name = args.yes, app_name
# args.yes = True
# for dlc in dlcs:
# app_name = dlc.app_name
# self.install_game(args)
# args.yes, 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.
log_gtk(f'This game supports cloud saves, syncing is handled by the "sync-saves" command.To download saves for this game run "legendary sync-saves {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.
# log_gtk(f'This game supports cloud saves, syncing is handled by the "sync-saves" command.To download saves for this game run "legendary sync-saves {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)
# 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)
log_gtk('Removing repair file.')
os.remove(repair_file)
# log_gtk('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
log_gtk('Deleting now untagged files.')
core.uninstall_tag(old_igame)
core.install_game(old_igame)
# # 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
# log_gtk('Deleting now untagged files.')
# core.uninstall_tag(old_igame)
# core.install_game(old_igame)
log_gtk(f'Finished installation process in {end_t - start_t:.02f} seconds.')
# log_gtk(f'Finished installation process in {end_t - start_t:.02f} seconds.')
class main_window(Gtk.Window):
def __init__(self):

View file

@ -17,13 +17,17 @@ from threading import Condition, Thread
from legendary.downloader.workers import DLWorker, FileWorker
from legendary.models.downloading import *
from legendary.models.manifest import ManifestComparison, Manifest
from legendary.downloader.log_dlm import log_dlm
log_dlm = log_dlm()
class DLManager(Process):
def __init__(self, download_dir, base_url, cache_dir=None, status_q=None,
max_workers=0, update_interval=1.0, dl_timeout=10, resume_file=None,
max_shared_memory=1024 * 1024 * 1024, main_window="cli"):
super().__init__(name='DLManager')
print("plip",main_window.get_title())
self.main_window = main_window
self.log = logging.getLogger('DLM')
self.proc_debug = False
@ -577,7 +581,7 @@ class DLManager(Process):
self.log.info(f'Download Manager running with process-id: {os.getpid()}')
try:
self.run_real(main_window)
self.run_real(self.main_window)
except KeyboardInterrupt:
self.log.warning('Immediate exit requested!')
self.running = False
@ -616,6 +620,9 @@ class DLManager(Process):
self.log.debug(f'Created {len(self.sms)} shared memory segments.')
obj_out = log_dlm.create(main_window)
print("created obj_out")
# Create queues
self.dl_worker_queue = MPQueue(-1)
self.writer_queue = MPQueue(-1)
@ -634,7 +641,9 @@ class DLManager(Process):
writer_p = FileWorker(self.writer_queue, self.writer_result_q, self.dl_dir,
self.shared_memory.name, self.cache_dir, self.logging_queue)
self.children.append(writer_p)
print("created obj_ou1t")
writer_p.start()
print("created obj_ou2t")
num_chunk_tasks = sum(isinstance(t, ChunkTask) for t in self.tasks)
num_dl_tasks = len(self.chunks_to_dl)
@ -660,8 +669,6 @@ class DLManager(Process):
self.threads.append(Thread(target=self.dl_results_handler, args=(task_cond,)))
self.threads.append(Thread(target=self.fw_results_handler, args=(shm_cond,)))
obj_out = log_dlm.create(main_window)
for t in self.threads:
t.start()
@ -728,6 +735,7 @@ class DLManager(Process):
r_speed,
obj_out
)
print("updated obj_out")
# send status update to back to instantiator (if queue exists)
if self.status_queue: