Implement --suffix parameter for install/download command

This makes it possible to download only files with a given suffix, which
is helpful in case you want all files of a certain type
This commit is contained in:
Katharina Dröge 2025-11-03 17:50:25 +01:00
parent 42af7b5db7
commit 16123f7259
No known key found for this signature in database
GPG key ID: 3D586C5E334E5A26
3 changed files with 25 additions and 14 deletions

View file

@ -969,6 +969,7 @@ class LegendaryCLI:
override_base_url=args.override_base_url,
platform=args.platform,
file_prefix_filter=args.file_prefix,
file_suffix_filter=args.file_suffix,
file_exclude_filter=args.file_exclude_prefix,
file_install_tag=args.install_tag,
dl_optimizations=args.order_opt,
@ -2764,6 +2765,8 @@ def main():
help='Platform for install (default: installed or Windows)')
install_parser.add_argument('--prefix', dest='file_prefix', action='append', metavar='<prefix>',
help='Only fetch files whose path starts with <prefix> (case insensitive)')
install_parser.add_argument('--suffix', dest='file_suffix', action='append', metavar='<suffix>',
help='Only fetch files whose path ends with <prefix> (case insensitive)')
install_parser.add_argument('--exclude', dest='file_exclude_prefix', action='append', metavar='<prefix>',
type=str, help='Exclude files starting with <prefix> (case insensitive)')
install_parser.add_argument('--install-tag', dest='install_tag', action='append', metavar='<tag>',

View file

@ -1326,12 +1326,13 @@ class LegendaryCore:
game_folder: str = '', override_manifest: str = '',
override_old_manifest: str = '', override_base_url: str = '',
platform: str = 'Windows', file_prefix_filter: list = None,
file_exclude_filter: list = None, file_install_tag: list = None,
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 = '', preferred_cdn: str = None,
disable_https: bool = False, bind_ip: str = None) -> (DLManager, AnalysisResult, ManifestMeta):
file_suffix_filter: list = None, file_exclude_filter: list = None,
file_install_tag: list = None, 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 = '',
preferred_cdn: str = None, disable_https: bool = False,
bind_ip: str = None) -> (DLManager, AnalysisResult, ManifestMeta):
# load old manifest
old_manifest = None
@ -1502,6 +1503,7 @@ class LegendaryCore:
anlres = dlm.run_analysis(manifest=new_manifest, old_manifest=old_manifest,
patch=not disable_patching, resume=not force,
file_prefix_filter=file_prefix_filter,
file_suffix_filter=file_suffix_filter,
file_exclude_filter=file_exclude_filter,
file_install_tag=file_install_tag,
processing_optimization=process_opt)

View file

@ -81,8 +81,8 @@ class DLManager(Process):
def run_analysis(self, manifest: Manifest, old_manifest: Manifest = None,
patch=True, resume=True, file_prefix_filter=None,
file_exclude_filter=None, file_install_tag=None,
processing_optimization=False) -> AnalysisResult:
file_suffix_filter=None, file_exclude_filter=None,
file_install_tag=None, processing_optimization=False) -> 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.
@ -92,6 +92,7 @@ class DLManager(Process):
: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
:param file_suffix_filter: Only download files that end with this prefix
:param file_exclude_filter: Exclude files with this prefix from download
:param file_install_tag: Only install files with the specified tag
:param processing_optimization: Attempt to optimize processing order and RAM usage
@ -187,19 +188,24 @@ class DLManager(Process):
mc.changed -= files_to_skip
mc.unchanged |= files_to_skip
if file_prefix_filter:
if isinstance(file_prefix_filter, str):
file_prefix_filter = [file_prefix_filter]
if file_prefix_filter or file_suffix_filter:
file_prefix_filter = file_prefix_filter or []
file_suffix_filter = file_suffix_filter or []
file_prefix_filter = [f.lower() for f in file_prefix_filter]
files_to_skip = set(i.filename for i in manifest.file_manifest_list.elements if not
any(i.filename.lower().startswith(pfx) for pfx in file_prefix_filter))
file_suffix_filter = [f.lower() for f in file_suffix_filter]
files_to_skip = set(
i.filename
for i in manifest.file_manifest_list.elements
if not any(i.filename.lower().startswith(pfx) for pfx in file_prefix_filter)
and not any(i.filename.lower().endswith(sfx) for sfx in file_suffix_filter)
)
self.log.info(f'Found {len(files_to_skip)} files to skip based on include prefix(es)')
mc.added -= files_to_skip
mc.changed -= files_to_skip
mc.unchanged |= files_to_skip
if file_prefix_filter or file_exclude_filter or file_install_tag:
if file_prefix_filter or file_suffix_filter or file_exclude_filter or file_install_tag:
self.log.info(f'Remaining files after filtering: {len(mc.added) + len(mc.changed)}')
# correct install size after filtering
analysis_res.install_size = sum(fm.file_size for fm in manifest.file_manifest_list.elements