[cli/core/downloader] Add support for filtering downloaded files by prefix

This commit is contained in:
derrod 2020-04-29 22:08:28 +02:00
parent d61ce7dc6d
commit ef0ea26372
3 changed files with 23 additions and 6 deletions

View file

@ -205,7 +205,8 @@ class LegendaryCLI:
override_manifest=args.override_manifest,
override_old_manifest=args.override_old_manifest,
override_base_url=args.override_base_url,
platform_override=args.platform_override)
platform_override=args.platform_override,
file_prefix_filter=args.file_prefix)
# game is either up to date or hasn't changed, so we have nothing to do
if not analysis.dl_size:
@ -380,6 +381,8 @@ def main():
help='Set download manager and worker processes\' loglevel to debug')
install_parser.add_argument('--platform', dest='platform_override', action='store', metavar='<Platform>',
type=str, help='Platform override for download (disables install)')
install_parser.add_argument('--prefix-filter', dest='file_prefix', action='store', metavar='<prefix>',
type=str, help='Only fetch files whose path starts with <prefix> (case insensitive)')
launch_parser.add_argument('--offline', dest='offline', action='store_true',
default=False, help='Skip login and launch game without online authentication')

View file

@ -307,9 +307,10 @@ class LegendaryCore:
def prepare_download(self, game: Game, base_game: Game = None, base_path: str = '',
status_q: Queue = None, max_shm: int = 0, max_workers: int = 0,
force: bool = False, disable_patching: bool = False, game_folder: str = '',
override_manifest: str = '', override_old_manifest: str = '',
override_base_url: str = '', platform_override: str = '',
force: bool = False, disable_patching: bool = False,
game_folder: str = '', override_manifest: str = '',
override_old_manifest: str = '', override_base_url: str = '',
platform_override: str = '', file_prefix_filter: str = ''
) -> (DLManager, AnalysisResult, ManifestMeta):
# load old manifest
@ -418,7 +419,8 @@ class LegendaryCore:
dlm = DLManager(install_path, base_url, resume_file=resume_file, status_q=status_q,
max_shared_memory=max_shm * 1024 * 1024, max_workers=max_workers)
anlres = dlm.run_analysis(manifest=new_manifest, old_manifest=old_manifest,
patch=not disable_patching, resume=not force)
patch=not disable_patching, resume=not force,
file_prefix_filter=file_prefix_filter)
prereq = None
if new_manifest.meta.prereq_ids:

View file

@ -242,7 +242,7 @@ class DLManager(Process):
self.log.info('Writer result handler quitting...')
def run_analysis(self, manifest: Manifest, old_manifest: Manifest = None,
patch=True, resume=True) -> AnalysisResult:
patch=True, resume=True, file_prefix_filter=None) -> AnalysisResult:
"""
Run analysis on manifest and old manifest (if not None) and return a result
with a summary resources required in order to install the provided manifest.
@ -251,9 +251,13 @@ class DLManager(Process):
:param old_manifest: Old manifest to patch from (if applicable)
:param patch: Patch instead of redownloading the entire file
:param resume: Continue based on resume file if it exists
:param file_prefix_filter: Only download files that start with this prefix
:return: AnalysisResult
"""
if file_prefix_filter:
file_prefix_filter = file_prefix_filter.lower()
analysis_res = AnalysisResult()
analysis_res.install_size = sum(fm.file_size for fm in manifest.file_manifest_list.elements)
analysis_res.biggest_chunk = max(c.window_size for c in manifest.chunk_data_list.elements)
@ -276,6 +280,14 @@ class DLManager(Process):
except Exception as e:
self.log.warning(f'Reading resume file failed: {e!r}, continuing as normal...')
# if prefix has been set: mark all files that are not to be downloaded as unchanged (not removed)
if file_prefix_filter:
files_to_skip = set(i for i in mc.added | mc.changed if not i.lower().startswith(file_prefix_filter))
self.log.info(f'Found {len(files_to_skip)} files to skip based on prefix.')
mc.added -= files_to_skip
mc.changed -= files_to_skip
mc.unchanged |= files_to_skip
if mc.removed:
analysis_res.removed = len(mc.removed)
self.log.debug(f'{analysis_res.removed} removed files')