Use py7zr for extracting package 7z archive

Signed-off-by: Hiroshi Miura <miurahr@linux.com>
This commit is contained in:
Hiroshi Miura
2019-03-16 10:48:03 +09:00
parent e45e1cf21a
commit 4fa64b9f5d
7 changed files with 47 additions and 32 deletions

View File

@@ -2,7 +2,7 @@ language: python
python: 3.6
install:
- pip install wheel flake8 requests six
- pip install wheel flake8 requests six py7zr bringbuf
script:
- flake8 aqt bin

View File

@@ -21,6 +21,7 @@ Changed
* CI: Improve azure-pipelines configurations by Nelson (#20)
* Check parameter combination allowance and add winrt variant.
* Support installation of mingw runtime package.
* Use `py7zr` instead of external `7zip` command for extracting package archives.
Fixed
-----

View File

@@ -32,14 +32,8 @@ Another Qt installer(aqt)
This is an utility replacing the official graphical Qt installer. It can
automatically download prebuilt Qt binaries for any target (you're not bound to
Linux binaries on Linux; you could also download iOS binaries).
It's working with python on Linux, OS X and Windows.
It's working with Python > 3.5 on Linux, OS X and Windows.
Prerequisite
------------
**Dependencies**: python, 7z
It is required `p7zip` for windows, `7zip` for mac or `p7zip-full` for Ubuntu.
Install
-------
@@ -57,14 +51,20 @@ General usage looks like this:
.. code-block:: bash
aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>] install <qt-version> <host> <target> [<arch>]
python -m aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>] install <qt-version> <host> <target> [<arch>]
aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>][-E | --external <7zip command>] \
install <qt-version> <host> <target> [<arch>]
.. code-block:: bash
python -m aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>] \
install <qt-version> <host> <target> [<arch>]
* The Qt version is formatted like this: `5.11.3`
* Host is one of: `linux`, `mac`, `windows`
* Target is one of: `desktop`, `android`, `ios` (iOS only works with mac host)
* For android and windows you also need to specify an arch: `win64_msvc2017_64`,
`win64_msvc2015_64`, `win32_msvc2015`, `win32_mingw53`, 'win64_mingw73', `android_x86`, `android_armv7`
`win64_msvc2015_64`, `win32_msvc2015`, `win32_mingw53`, `win64_mingw73`, `android_x86`, `android_armv7`
* You can also use external 7zip command instead of internal extration function.
The Qt packages are installed under current directory as such `Qt<ver>/<ver>/gcc_64/`

View File

@@ -21,6 +21,8 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import argparse
import os
import platform
import sys
from aqt.archives import QtArchives
@@ -64,6 +66,16 @@ class Cli():
os_name = args.host
output_dir = args.outputdir
mirror = args.base
sevenzip = args.external
if sevenzip is not None:
if not os.path.exists(sevenzip):
print('Specified unexist external command in option -E')
exit(1)
elif sys.version_info.major == 2:
if platform.system() == 'Windows':
sevenzip = r'C:\Program Files\7-Zip\7z.exe'
else:
sevenzip = r'7zr'
if arch is None:
if os_name == "linux" and target == "desktop":
arch = "gcc_64"
@@ -84,9 +96,10 @@ class Cli():
args.print_help()
exit(1)
if output_dir is not None:
QtInstaller(QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install(target_dir=output_dir)
QtInstaller(QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install(command=sevenzip,
target_dir=output_dir)
else:
QtInstaller(QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install()
QtInstaller(QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install(command=sevenzip)
sys.stdout.write("\033[K")
print("Finished installation")
@@ -122,6 +135,8 @@ class Cli():
install_parser.add_argument('-b', '--base', nargs='?',
help="Specify mirror base url such as http://mirrors.ocf.berkeley.edu/qt/, "
"where 'online' folder exist.")
install_parser.add_argument('-E', '--external', nargs='?',
help='Use external 7zip command instead of internal extractor.')
list_parser = subparsers.add_parser('list')
list_parser.set_defaults(func=self.run_list)
list_parser.add_argument("qt_version", help="Qt version in the format of \"5.X.Y\"")

View File

@@ -23,19 +23,14 @@
import functools
import logging
import os
import platform
import py7zr
import requests
import sys
import traceback
import xml.etree.ElementTree as ElementTree
from six import StringIO
from multiprocessing.dummy import Pool
from operator import and_
if sys.version_info.major == 3:
from subprocess import run
else:
from subprocess import call as run
from subprocess import run
NUM_PROCESS = 3
blacklist = ['http://mirrors.ustc.edu.cn',
@@ -43,6 +38,10 @@ blacklist = ['http://mirrors.ustc.edu.cn',
'http://mirrors.geekpie.club']
class BadPackageFile(Exception):
pass
class QtInstaller:
"""
Installer class to download packages and extract it.
@@ -52,7 +51,7 @@ class QtInstaller:
self.qt_archives = qt_archives
@staticmethod
def retrieve_archive(package, path=None):
def retrieve_archive(package, path=None, command=None):
archive = package.archive
url = package.url
print("-Downloading {}...".format(url))
@@ -73,18 +72,16 @@ class QtInstaller:
with open(archive, 'wb') as fd:
for chunk in r.iter_content(chunk_size=8196):
fd.write(chunk)
sys.stdout.write("\033[K")
print("-Extracting {}...".format(archive))
if platform.system() == 'Windows':
if path is not None:
run([r'C:\Program Files\7-Zip\7z.exe', 'x', '-aoa', '-bd', '-y', '-o{}'.format(path), archive])
else:
run([r'C:\Program Files\7-Zip\7z.exe', 'x', '-aoa', '-bd', '-y', archive])
if not py7zr.is_7zfile(archive):
raise BadPackageFile
if command is None:
py7zr.SevenZipFile(archive).extractall(path=path)
else:
if path is not None:
run([r'7zr', 'x', '-aoa', '-bd', '-y', '-o{}'.format(path), archive])
run([command, 'x', '-aoa', '-bd', '-y', '-o{}'.format(path), archive])
else:
run([r'7zr', 'x', '-aoa', '-bd', '-y', archive])
run([command, 'x', '-aoa', '-bd', '-y', archive])
os.unlink(archive)
return True
@@ -95,12 +92,12 @@ class QtInstaller:
else:
return os.path.join(os.getcwd(), 'Qt{}'.format(qt_version))
def install(self, target_dir=None):
def install(self, command=None, target_dir=None):
qt_version, target, arch = self.qt_archives.get_target_config()
base_dir = self.get_base_dir(qt_version, target_dir)
archives = self.qt_archives.get_archives()
p = Pool(NUM_PROCESS)
ret_arr = p.map(functools.partial(self.retrieve_archive, path=base_dir), archives)
ret_arr = p.map(functools.partial(self.retrieve_archive, command=command, path=base_dir), archives)
ret = functools.reduce(and_, ret_arr)
if ret:
if arch.startswith('win64_mingw'):

View File

@@ -6,3 +6,5 @@ pytest-cov
flake8
wheel
twine
py7zr
bringbuf

View File

@@ -20,7 +20,7 @@ setup(name='aqtinstall',
author='Hioshi Miura',
author_email='miurahr@linux.com',
packages=["aqt"],
install_requires=['requests', 'six'],
install_requires=['requests', 'six', 'py7zr'],
extras_require={
'dev': [
'pytest',