downloads: implement cross-platform unzips

This commit is contained in:
jj
2025-09-19 19:51:58 +00:00
parent c8be580734
commit b0f30bffcf
3 changed files with 46 additions and 3 deletions

View File

@@ -1,5 +1,9 @@
# -*- coding: UTF-8 -*-
# Copyright 2025 The Helium Authors
# You can use, redistribute, and/or modify this source code under
# the terms of the GPL-3.0 license that can be found in the LICENSE file.
# Copyright (c) 2020 The ungoogled-chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE.ungoogled_chromium file.
@@ -30,6 +34,7 @@ class PlatformEnum(enum.Enum):
class ExtractorEnum: #pylint: disable=too-few-public-methods
"""Enum for extraction binaries"""
SEVENZIP = '7z'
ZIP = 'zip'
TAR = 'tar'
WINRAR = 'winrar'

View File

@@ -1,5 +1,9 @@
# -*- coding: UTF-8 -*-
# Copyright 2025 The Helium Authors
# You can use, redistribute, and/or modify this source code under
# the terms of the GPL-3.0 license that can be found in the LICENSE file.
# Copyright (c) 2019 The ungoogled-chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE.ungoogled_chromium file.
@@ -11,6 +15,7 @@ import os
import shutil
import subprocess
import tarfile
import zipfile
from pathlib import Path, PurePosixPath
from _common import (USE_REGISTRY, PlatformEnum, ExtractorEnum, get_logger, get_running_platform)
@@ -240,6 +245,23 @@ def extract_tar_file(archive_path, output_dir, relative_to, extractors=None):
_extract_tar_with_python(archive_path, output_dir, relative_to)
# pylint: disable=unused-argument
def extract_zip_file(archive_path, output_dir, relative_to, extractors=None):
"""
Extracts archives using the pure Python zip extractor
"""
get_logger().debug('Using pure Python zip extractor')
with zipfile.ZipFile(str(archive_path), 'r') as zip_file_obj:
for filename in zip_file_obj.namelist():
try:
zipinfo = zip_file_obj.getinfo(filename)
zip_file_obj.extract(zipinfo, output_dir, None)
except BaseException:
get_logger().exception('Exception thrown for zip member: %s', filename)
raise
def extract_with_7z(archive_path, output_dir, relative_to, extractors=None):
"""
Extract archives with 7-zip into the output directory.

View File

@@ -1,6 +1,10 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# Copyright 2025 The Helium Authors
# You can use, redistribute, and/or modify this source code under
# the terms of the GPL-3.0 license that can be found in the LICENSE file.
# Copyright (c) 2019 The ungoogled-chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE.ungoogled_chromium file.
@@ -21,7 +25,7 @@ from pathlib import Path
from _common import ENCODING, USE_REGISTRY, ExtractorEnum, PlatformEnum, \
get_logger, get_chromium_version, get_running_platform, add_common_params
from _extraction import extract_tar_file, extract_with_7z, extract_with_winrar
from _extraction import extract_tar_file, extract_zip_file, extract_with_7z, extract_with_winrar
sys.path.insert(0, str(Path(__file__).parent / 'third_party'))
import schema #pylint: disable=wrong-import-position, wrong-import-order
@@ -336,6 +340,14 @@ def check_downloads(download_info, cache_dir, components, chunk_bytes=262144):
raise HashMismatchError(download_path)
def get_extractor_for(filename):
"""Determines the most appropriate default downloader for the format."""
if Path(filename).suffix == '.zip':
return ExtractorEnum.ZIP
return ExtractorEnum.TAR
def unpack_downloads(download_info, cache_dir, components, output_dir, extractors=None):
"""
Unpack downloads in the downloads cache to output_dir. Assumes all downloads are retrieved.
@@ -355,8 +367,12 @@ def unpack_downloads(download_info, cache_dir, components, output_dir, extractor
download_path = cache_dir / download_properties.download_filename
get_logger().info('Unpacking "%s" to %s ...', download_name,
download_properties.output_path)
extractor_name = download_properties.extractor or ExtractorEnum.TAR
if extractor_name == ExtractorEnum.SEVENZIP:
extractor_name = download_properties.extractor \
or get_extractor_for(download_properties.download_filename)
if extractor_name == ExtractorEnum.ZIP:
extractor_func = extract_zip_file
elif extractor_name == ExtractorEnum.SEVENZIP:
extractor_func = extract_with_7z
elif extractor_name == ExtractorEnum.WINRAR:
extractor_func = extract_with_winrar