Commit 5d85c4fa authored by Leander Schulten's avatar Leander Schulten

Updater: Use QuaZip to unzip folders and not external programs

parent 5d92e4d0
Pipeline #287899 failed with stage
in 1 minute and 59 seconds
......@@ -101,8 +101,7 @@ SOURCES += \
spotify/segmentobject.cpp \
spotify/audioanalysisobject.cpp \
spotify/userobject.cpp \
sortedmodelview.cpp \
zip.cpp
sortedmodelview.cpp
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
......@@ -207,8 +206,7 @@ HEADERS += \
spotify/util.h \
modules/spotifyobjetcs.hpp \
modules/spotify.hpp \
sortedmodelview.h \
zip.h
sortedmodelview.h
# Default rules for deployment.
......@@ -299,3 +297,14 @@ linux{
INCLUDEPATH += $$PWD/lib/qtmqtt/include
LIBS += -L$$PWD/lib/qtmqtt/lib -lQt5Mqtt
# QuaZip
INCLUDEPATH += $$PWD/lib/quazip/dist/include
LIBS += -L$$PWD/lib/quazip/dist/bin -lQt5Quazip1
win32 {
LIBS += -L$$PWD/lib/quazip/zlib_windows/bin -lzlib1
} else {
LIBS += -lz
}
......@@ -34,4 +34,10 @@ cd qtmqtt
./getAndUpdate.sh
cd ..
echo $'\n\nUpdate quazip'
cd quazip
./update_and_build.sh
cd ..
echo "Lib installation complete"
dist/
quazip/
zlib_windows/*/*
#!/bin/bash
set -e
# set -o xtrace to debug commands
# see https://stachenov.github.io/quazip/
source ../scripts/set_env.sh
# if we are on windows, we first have to build zlib
if [[ "$OSTYPE" == "msys" ]] || ! [[ -z "$GITLAB_CI" ]]; then
cd zlib_windows
./build_windows.sh
cd ..
fi
GIT_DIR=quazip
# add or update git
../scripts/clone_or_pull.sh $GIT_DIR https://github.com/stachenov/quazip.git && exit 0
cd $GIT_DIR
# we are in the "$GIT_DIR" now
if [[ "$OSTYPE" == "msys" ]] || ! [[ -z "$GITLAB_CI" ]]; then
qmakeOptions=("LIBS += -L'\$\$PWD/../../zlib_windows/bin' -lzlib1" "INCLUDEPATH += '\$\$PWD../../zlib_windows/include'" PREFIX=../../dist quazip.pro)
else
qmakeOptions=("LIBS += -lz" PREFIX=../../dist quazip.pro)
fi
# see https://unix.stackexchange.com/questions/459367/using-shell-variables-for-command-options for "${qmakeOptions[@]}"
echo "Qmake options" "${qmakeOptions[@]}"
# we only want to build quazip and not the tests
cd quazip
# build the project
$qmake "${qmakeOptions[@]}"
$make install
#!/bin/bash
set -e
source ../../scripts/set_env.sh
# see https://github.com/madler/zlib/issues/268
GIT_DIR=zlib
# add or update git
../../scripts/clone_or_pull.sh $GIT_DIR https://github.com/madler/zlib.git && exit 0
cd $GIT_DIR
# we are in the "$GIT_DIR" now
# with the default gcc compiler we need that:
# apply fix from here: https://github.com/madler/zlib/issues/268
#if [[ -f "gzguts.h" ]]; then
# sed -i 's/defined(_WIN32) || defined(__CYGWIN__)/defined(_WIN32)/g' gzguts.h
# sed -i 's/gzopen_w//g' win32/zlib.def
#fi
sh configure --prefix=../
export BINARY_PATH=../bin
export INCLUDE_PATH=../include
export LIBRARY_PATH=../lib
$make install -fwin32/Makefile.gcc SHARED_MODE=1
\ No newline at end of file
#include "updater.h"
#include "zip.h"
#include <QDir>
#include <QFileInfo>
#include <QFuture>
#include <QFutureWatcher>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QProcess>
#include <QTemporaryFile>
#include <QtConcurrent/QtConcurrentRun>
#include <quazip/JlCompress.h>
QByteArray getFileContent(const QString & filename){
QFile file(filename);
......@@ -44,7 +47,11 @@ void Updater::checkForUpdate(){
version.write(response->readAll());
version.close();
response->deleteLater();
Zip::unzip(QFileInfo(version), QFileInfo(version).absolutePath(), [this, version = QFileInfo(version)](auto success) {
auto watcher = new QFutureWatcher<bool>;
connect(watcher, &QFutureWatcher<bool>::finished, [this, version = QFileInfo(version), watcher]() {
watcher->deleteLater();
bool success = watcher->future().result();
if (!success) {
qDebug() << "not successful when unzipping version.zip";
state = UpdaterState::NoUpdateAvailible;
......@@ -66,6 +73,10 @@ void Updater::checkForUpdate(){
emit stateChanged();
}
});
// Start the computation.
QFuture<bool> future = QtConcurrent::run([path = QFileInfo(version).absoluteFilePath(), dest = QFileInfo(version).absolutePath()] { return !JlCompress::extractDir(path, dest).empty(); });
watcher->setFuture(future);
});
}
......@@ -106,7 +117,10 @@ void Updater::update(){
deploy->close();
state = UpdaterState::UnzippingUpdate;
emit stateChanged();
Zip::unzip(QFileInfo(*deploy), QFileInfo(*deploy).absolutePath(), [this, deploy](auto success) {
auto watcher = new QFutureWatcher<bool>;
connect(watcher, &QFutureWatcher<bool>::finished, [this, deploy, watcher]() {
watcher->deleteLater();
bool success = watcher->future().result();
std::unique_ptr<QFile> deleteMe(deploy);
if (!success) {
qDebug() << "not successful when unzipping deploy.zip";
......@@ -139,6 +153,10 @@ void Updater::update(){
state = UpdaterState::ReadyToInstall;
emit stateChanged();
});
// Start the computation.
QFuture<bool> future = QtConcurrent::run([path = QFileInfo(*deploy).absoluteFilePath(), dest = QFileInfo(*deploy).absolutePath()] { return !JlCompress::extractDir(path, dest).empty(); });
watcher->setFuture(future);
});
}
......
#include "zip.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QProcess>
#include <memory>
void unzipPowershellNew(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback){
// https://www.reddit.com/r/Windows10/comments/71z96c/unzip_from_command_line/
// Expand-Archive "<PathToZIPFile>" "<FolderWhereToExtract>" -Force
auto p = new QProcess();
p->start(QStringLiteral("powershell.exe"), QStringList() << QStringLiteral("Expand-Archive") << QStringLiteral("-Force") << "\"" + zip.absoluteFilePath() + "\"" << "\"" + unzip.absoluteFilePath() + "\"");
QObject::connect(p,qOverload<int,QProcess::ExitStatus>(&QProcess::finished),[p,zip,unzip,callback](auto exitCode, auto exitStatus){
Q_UNUSED(exitStatus)
if(exitCode != 0){
qDebug() << "Failed to unzip " << zip << " to " << unzip << " with powershell new";
qDebug().noquote() << "stderr : " << p->readAllStandardError();
qDebug().noquote() << "stdout : " << p->readAllStandardOutput();
}
callback(p->error() == QProcess::ProcessError::UnknownError ? !exitCode : false);
p->deleteLater();
});
}
void unzipPowershell(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback){
// from https://stackoverflow.com/questions/17546016/how-can-you-zip-or-unzip-from-the-script-using-only-windows-built-in-capabiliti/26843122#26843122
// powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', 'bar'); }"
auto p = new QProcess();
p->start(QStringLiteral("powershell.exe"), QStringList() << QStringLiteral("-nologo") << QStringLiteral("-noprofile") << "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('"+zip.absoluteFilePath()+"', '"+unzip.absoluteFilePath()+"/unzippedDir'); }");
QObject::connect(p,qOverload<int,QProcess::ExitStatus>(&QProcess::finished),[p,zip,unzip,callback](auto exitCode, auto exitStatus){
Q_UNUSED(exitStatus)
if(exitCode != 0){
qDebug() << "Failed to unzip " << zip << " to " << unzip << " with powershell";
qDebug().noquote() << "stderr : " << p->readAllStandardError();
qDebug().noquote() << "stdout : " << p->readAllStandardOutput();
}
callback(p->error() == QProcess::ProcessError::UnknownError ? !exitCode : false);
p->deleteLater();
});
}
void unzipWinrar(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback){
// from https://stackoverflow.com/questions/1315662/how-to-extract-zip-files-with-winrar-command-line
// "%ProgramFiles%\WinRAR\winrar.exe" x -ibck c:\file.zip *.* c:\folder
auto p = new QProcess();
p->start(QStringLiteral("C:\\Program Files\\WinRAR\\winrar.exe"), QStringList() << QStringLiteral("x") << QStringLiteral("-ibck") << QStringLiteral("-o+") << zip.absoluteFilePath() << QStringLiteral("*.*") << unzip.absoluteFilePath());
QObject::connect(p,qOverload<int,QProcess::ExitStatus>(&QProcess::finished),[p,zip,unzip,callback](auto exitCode, auto exitStatus){
Q_UNUSED(exitStatus)
if(exitCode != 0){
qDebug() << "Failed to unzip " << zip << " to " << unzip << " with winrar";
qDebug().noquote() << "stderr : " << p->readAllStandardError();
qDebug().noquote() << "stdout : " << p->readAllStandardOutput();
}
callback(p->error() == QProcess::ProcessError::UnknownError ? !exitCode : false);
p->deleteLater();
});
}
void unzip7Zip(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback){
// from https://superuser.com/questions/95902/7-zip-and-unzipping-from-command-line
// 7z x example.zip -oexample
auto p = new QProcess();
p->start(QStringLiteral("C:\\Program Files\\7-Zip\\7z.exe"), QStringList() << QStringLiteral("x") << QStringLiteral("-y") << zip.absoluteFilePath() << "-o" + unzip.absoluteFilePath());
QObject::connect(p,qOverload<int,QProcess::ExitStatus>(&QProcess::finished),[p,zip,unzip,callback](auto exitCode, auto exitStatus){
Q_UNUSED(exitStatus)
if(exitCode != 0){
qDebug() << "Failed to unzip " << zip << " to " << unzip << " with 7zip";
qDebug().noquote() << "stderr : " << p->readAllStandardError();
qDebug().noquote() << "stdout : " << p->readAllStandardOutput();
}
callback(p->error() == QProcess::ProcessError::UnknownError ? !exitCode : false);
p->deleteLater();
});
}
void Zip::unzip(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback){
if(!zip.exists()){
return;
}
QDir().mkpath(unzip.absoluteFilePath());
unzipWinrar(zip,unzip,[=](bool success){
if (success) {
callback(true);
} else {
unzip7Zip(zip,unzip,[=](bool success){
if (success) {
callback(true);
} else {
unzipPowershellNew(zip,unzip,[=](bool success){
if (success) {
callback(true);
} else {
unzipPowershell(zip,unzip,[=](bool success){
callback(success);
});
}
});
}
});
}
});
}
#ifndef ZIP_H
#define ZIP_H
#include <QFileInfo>
#include <functional>
namespace Zip {
void unzip(const QFileInfo& zip, const QFileInfo& unzip, const std::function<void(bool)>& callback);
} // namespace Zip
#endif // ZIP_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment