Remove completly Minizip

- Download on-demand BZIP2-Gnuwin32 from linphone website for Windows
- Use native bzip2 for Mac and Linux
This commit is contained in:
Julien Wadel 2020-04-14 23:40:20 +02:00
parent 09ec28dfc0
commit 7b591090a7
13 changed files with 132 additions and 470 deletions

View file

@ -17,7 +17,7 @@
- TelKeypad supports A, B, C and D keys.
- TelKeypad supports keyboard.
- OpenH264 codec can be download in the application.
- Use native BZip2 instead of Minizip to extract codec on Mac and Linux
- Use BZip2 instead of Minizip to extract codec
- New icons
- Disable screensaver on fullscreen video call.
- Add caller/callee on saved files.
@ -27,6 +27,7 @@
- Enable High DPI Displays support
- NSIS (Windows), DMG (MacOsX) and Appimage (Linux) deployments
### Fixes
- Display a busy indicator when a message is sent.
@ -41,6 +42,7 @@
- Prepare.py configuration
- Remove useless splashscreen.
- Minizip
## 4.1.0 - 2017-07-19

View file

@ -38,6 +38,11 @@ endforeach()
if(ENABLE_BUILD_VERBOSE)
message("User Args : ${USER_ARGS}")
endif()
if(NOT CMAKE_GENERATOR_PLATFORM AND WIN32)
set(CMAKE_GENERATOR_PLATFORM "Win32")
message(STATUS "Setting Platform to ${CMAKE_GENERATOR_PLATFORM}")
endif()
project(linphoneqt)
include(GNUInstallDirs)
@ -46,14 +51,12 @@ include(CheckCXXCompilerFlag)
# Prepare gobal CMAKE configuration specific to the current project
set(SDK_BUILD_DIR "${CMAKE_BINARY_DIR}/WORK") # SDK build in WORK. Keep all in it.
set(LINPHONE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/linphone-sdk/desktop")
set(MINIZIP_BUILD_DIR "${CMAKE_BINARY_DIR}/minizip_BUILD")
set(MINIZIP_OUTPUT_DIR "${CMAKE_BINARY_DIR}/minizip_OUTPUT")
set(APPLICATION_OUTPUT_DIR "${CMAKE_BINARY_DIR}/OUTPUT")
message("minizip=${MINIZIP_OUTPUT_DIR} sdk=${LINPHONE_OUTPUT_DIR}")
set(CMAKE_PREFIX_PATH "${LINPHONE_OUTPUT_DIR};${MINIZIP_OUTPUT_DIR};${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}")
set(APPLICATION_OUTPUT_DIR "${CMAKE_BINARY_DIR}/OUTPUT")
set(CMAKE_PREFIX_PATH "${LINPHONE_OUTPUT_DIR};${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}")
string(REPLACE ";" "|" PREFIX_PATH "${CMAKE_PREFIX_PATH}")
#set(PREFIX_PATH "${LINPHONE_OUTPUT_DIR}|${MINIZIP_OUTPUT_DIR}|${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}")
#set(PREFIX_PATH "${LINPHONE_OUTPUT_DIR}|${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}")
# Avoid cmake warning if CMP0071 is not set.
if (POLICY CMP0071)
@ -114,10 +117,6 @@ endif()
list(APPEND APP_OPTIONS "-DENABLE_RELATIVE_PREFIX=${ENABLE_RELATIVE_PREFIX}")
list(APPEND APP_OPTIONS "-DLINPHONE_OUTPUT_DIR=${LINPHONE_OUTPUT_DIR}")
if(NOT CMAKE_GENERATOR_PLATFORM AND WIN32)
set(CMAKE_GENERATOR_PLATFORM "Win32")
message(STATUS "Setting Platform to ${${var}}")
endif()
include(ExternalProject)
set(PROJECT_BUILD_COMMAND "")
@ -153,26 +152,9 @@ ExternalProject_Add_Step(sdk force_build
ALWAYS 1
)
include(FindPkgConfig)
if( WIN32)
#Don't use minizip as target name because it can be a conflict with link libraries names
ExternalProject_Add(miniziplib PREFIX "${CMAKE_BINARY_DIR}/minizip"
SOURCE_DIR "${CMAKE_SOURCE_DIR}/submodules/externals/minizip"
INSTALL_DIR "${MINIZIP_OUTPUT_DIR}"
DEPENDS sdk
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG> ${PROJECT_BUILD_COMMAND}
LIST_SEPARATOR | # Use the alternate list separator
CMAKE_ARGS ${APP_OPTIONS} ${USER_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${PREFIX_PATH}
)
if(ENABLE_BUILD_VERBOSE)
message("MINIZIP from superbuild :${MINIZIP_PREFIX}, ${MINIZIP_INCLUDE_DIRS} => ${MINIZIP_LIBRARIES}")
endif()
find_package(minizip QUIET)
set(NEED_MINIZIP NOT(MINIZIP_FOUND))
set(APP_DEPENDS miniziplib sdk)
else()
set(NEED_MINIZIP FALSE)
set(APP_DEPENDS sdk)
endif()
set(APP_DEPENDS sdk)
find_package(LinphoneCxx CONFIG QUIET)
find_package(Linphone CONFIG QUIET)
find_package(bctoolbox CONFIG QUIET)
@ -181,7 +163,7 @@ find_package(Mediastreamer2 CONFIG QUIET)
find_package(ortp CONFIG QUIET)
if(NOT (LinphoneCxx_FOUND) OR NOT (Linphone_FOUND) OR NOT (bctoolbox_FOUND) OR NOT (belcard_FOUND) OR NOT (Mediastreamer2_FOUND) OR NOT (ortp_FOUND) OR NEED_MINIZIP OR FORCE_APP_EXTERNAL_PROJECTS)
if(NOT (LinphoneCxx_FOUND) OR NOT (Linphone_FOUND) OR NOT (bctoolbox_FOUND) OR NOT (belcard_FOUND) OR NOT (Mediastreamer2_FOUND) OR NOT (ortp_FOUND) OR FORCE_APP_EXTERNAL_PROJECTS)
message("Projects are set as External projects. You can start building them by using for example : cmake --build . --target all")
ExternalProject_Add(linphone-qt PREFIX "${CMAKE_BINARY_DIR}/linphoneqt"
SOURCE_DIR "${CMAKE_SOURCE_DIR}/linphone-app"

View file

@ -61,7 +61,7 @@ Note: If you have `qtchooser` set in your `PATH`, the best use is :
### Building
The build is done by building the SDK, the submodule Minizip and the application. Their targets are `sdk`, `miniziplib` and `linphone-qt`.
The build is done by building the SDK and the application. Their targets are `sdk` and `linphone-qt`.
1. Create your build folder at the root of the project : `mkdir build`
Go to this new folder and begin the build process : `cd build`

View file

@ -64,13 +64,6 @@ find_package(Mediastreamer2 CONFIG)
find_package(ortp CONFIG)
find_package(bctoolbox CONFIG)
if(WIN32)
find_package(minizip)
set(MINIZIP_INCLUDE_DIRS "${MINIZIP_PREFIX}/${MINIZIP_INCLUDE_DIRS}")
if(ENABLE_BUILD_VERBOSE)
message("MINIZIP : ${MINIZIP_PREFIX}, ${MINIZIP_INCLUDE_DIRS} => ${MINIZIP_LIBRARIES}")
endif()
endif()
if(ENABLE_BUILD_VERBOSE)
message("INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} FRAMEWORK_PATH=${CMAKE_FRAMEWORK_PATH}, PREFIX_PATH=${CMAKE_PREFIX_PATH}")
message("LINPHONE : ${LINPHONE_INCLUDE_DIRS} => ${LINPHONE_LIBRARIES}")
@ -132,6 +125,7 @@ set(SOURCES
src/components/core/CoreManager.cpp
src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
src/components/file/FileDownloader.cpp
src/components/file/FileExtractor.cpp
src/components/notifier/Notifier.cpp
src/components/other/clipboard/Clipboard.cpp
src/components/other/colors/Colors.cpp
@ -190,6 +184,7 @@ set(HEADERS
src/components/core/CoreManager.hpp
src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
src/components/file/FileDownloader.hpp
src/components/file/FileExtractor.hpp
src/components/notifier/Notifier.hpp
src/components/other/clipboard/Clipboard.hpp
src/components/other/colors/Colors.hpp
@ -212,13 +207,7 @@ set(HEADERS
src/utils/QExifImageHeader.hpp
src/utils/Utils.hpp
)
if(WIN32)
list(APPEND SOURCES src/components/file/FileExtractor.cpp)
list(APPEND HEADERS src/components/file/FileExtractor.hpp)
else()
list(APPEND SOURCES src/components/file/FileProcessExtractor.cpp)
list(APPEND HEADERS src/components/file/FileProcessExtractor.hpp)
endif()
set(MAIN_FILE src/app/main.cpp)
if (APPLE)
@ -362,14 +351,6 @@ endif ()
add_subdirectory("${LANGUAGES_DIRECTORY}" "assets/languages")
list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${LANGUAGES_DIRECTORY}/${I18N_FILENAME}")
# Build and dependencies
if(WIN32)
link_directories("${MINIZIP_PREFIX}/${MINIZIP_LIBRARY_DIRS}")
endif()
#add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${RESOURCES} ${QML_SOURCES})
add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES} ${QRC_RESOURCES})
if(TARGET_NAME_ONLY)
@ -416,10 +397,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}"
set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" )
set(LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${OPUS_LIBRARIES})
if(WIN32)
list(APPEND INCLUDED_DIRECTORIES "${MINIZIP_INCLUDE_DIRS}")
list(APPEND LIBRARIES ${MINIZIP_LIBRARIES})
endif()
if(ENABLE_BUILD_VERBOSE)
message("LIBRARIES : ${LIBRARIES}")
endif()

View file

@ -120,7 +120,6 @@ if (WIN32)
install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/mediastreamer" DESTINATION "${CMAKE_INSTALL_LIBDIR}" USE_SOURCE_PERMISSIONS)
file(GLOB GRAMMAR_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Belr/grammars/*")
install(FILES ${GRAMMAR_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/belr/grammars/" )
install(FILES "${MINIZIP_PREFIX}/${CMAKE_INSTALL_BINDIR}/minizip.dll" DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/images" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS OPTIONAL)
install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/sounds" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS)
install(FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Linphone/rootca.pem" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}/")

View file

@ -39,6 +39,7 @@ namespace {
constexpr char PathAvatars[] = "/avatars/";
constexpr char PathCaptures[] = "/" EXECUTABLE_NAME "/captures/";
constexpr char PathCodecs[] = "/codecs/";
constexpr char PathTools[] = "/tools/";
constexpr char PathLogs[] = "/logs/";
//constexpr char PathPlugins[] = "/plugins/"; // Unused
constexpr char PathThumbnails[] = "/thumbnails/";
@ -256,7 +257,9 @@ string Paths::getRootCaFilePath () {
string Paths::getThumbnailsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathThumbnails);
}
string Paths::getToolsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathTools);
}
string Paths::getUserCertificatesDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathUserCertificates);
}

View file

@ -43,6 +43,7 @@ namespace Paths {
std::string getPackageMsPluginsDirPath ();
std::string getRootCaFilePath ();
std::string getThumbnailsDirPath ();
std::string getToolsDirPath ();
std::string getUserCertificatesDirPath ();
std::string getZrtpDataFilePath ();
std::string getZrtpSecretsFilePath ();

View file

@ -18,70 +18,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <mz_os.h>
#include <mz_strm_bzip.h>
#include <mz_strm.h>
#include <mz.h>
#include <QDebug>
#include <QDir>
#include <QTimer>
#include <QProcess>
#include "FileExtractor.hpp"
#include "FileDownloader.hpp"
#include "app/paths/Paths.hpp"
#include "utils/Utils.hpp"
// =============================================================================
using namespace std;
class FileExtractor::ExtractStream {
public:
ExtractStream () : mFileStream(nullptr), mBzipStream(nullptr) {}
~ExtractStream () {
if (mBzipStream) {
mz_stream_bzip_close(mBzipStream);
mz_stream_bzip_delete(&mBzipStream);
}
if (mFileStream) {
mz_stream_os_close(mFileStream);
mz_stream_os_delete(&mFileStream);
}
}
void *getInternalStream () const {
return mBzipStream;
}
int load (const char *filePath) {
Q_ASSERT(!mFileStream);
Q_ASSERT(!mBzipStream);
// 1. Open file stream.
if (!mz_stream_os_create(&mFileStream))
return MZ_MEM_ERROR;
Q_CHECK_PTR(mFileStream);
int error;
if ((error = mz_stream_os_open(mFileStream, filePath, MZ_OPEN_MODE_READ)) != MZ_OK)
return error;
// 2. Open bzip stream.
if (!mz_stream_bzip_create(&mBzipStream))
return MZ_MEM_ERROR;
Q_CHECK_PTR(mBzipStream);
if ((error = mz_stream_bzip_open(mBzipStream, NULL, MZ_OPEN_MODE_READ)) != MZ_OK)
return error;
// 3. Link file stream to bzip stream.
return mz_stream_set_base(mBzipStream, mFileStream);
}
private:
void *mFileStream;
void *mBzipStream;
};
// -----------------------------------------------------------------------------
constexpr char LinphoneBZip2_exe[] = "http://www.linphone.org/releases/windows/tools/bzip2/bzip2.exe";
constexpr char LinphoneBZip2_dll[] = "http://www.linphone.org/releases/windows/tools/bzip2/bzip2.dll";
FileExtractor::FileExtractor (QObject *parent) : QObject(parent) {}
@ -93,44 +45,58 @@ void FileExtractor::extract () {
return;
}
setExtracting(true);
QFileInfo fileInfo(mFile);
setReadBytes(0);
setTotalBytes(fileInfo.size());
// 1. Open archive stream.
// TODO: Test extension.
Q_ASSERT(!mStream);
mStream.reset(new ExtractStream());
int error = mStream->load(mFile.toLatin1().constData());
if (error != MZ_OK) {
emitExtractFailed(error);
return;
if(!fileInfo.isReadable()){
emitExtractFailed(-1);
return;
}
// 2. Open output file.
// TODO: Deal with existing files.
Q_ASSERT(!mDestinationFile.isOpen());
mDestinationFile.setFileName(
QDir::cleanPath(mExtractFolder) + QDir::separator() + (
mExtractName.isEmpty() ? fileInfo.completeBaseName() : mExtractName
)
);
if (!mDestinationFile.open(QIODevice::WriteOnly)) {
mDestinationFile = QDir::cleanPath(mExtractFolder) + QDir::separator() + (mExtractName.isEmpty() ? fileInfo.completeBaseName() : mExtractName);
if(QFile::exists(mDestinationFile) && !QFile::remove(mDestinationFile)){
emitOutputError();
return;
}
if( mTimer == nullptr){
mTimer = new QTimer(this);
QObject::connect(mTimer, &QTimer::timeout, this, &FileExtractor::handleExtraction);
}
#ifdef WIN32
// Test the presence of bzip2 in the system
int result = QProcess::execute("bzip2.exe", QStringList());
if( result != -2 || QProcess::execute(Utils::coreStringToAppString(Paths::getToolsDirPath())+"\\bzip2.exe", QStringList())!=-2){
mTimer->start();
}else{// Download bzip2
QTimer * timer = mTimer;
FileDownloader * fileDownloader = new FileDownloader();
int downloadStep = 0;
fileDownloader->setUrl(QUrl(LinphoneBZip2_exe));
fileDownloader->setDownloadFolder(Utils::coreStringToAppString(Paths::getToolsDirPath()));
QObject::connect(fileDownloader, &FileDownloader::totalBytesChanged, this, &FileExtractor::setTotalBytes);
QObject::connect(fileDownloader, &FileDownloader::readBytesChanged, this, &FileExtractor::setReadBytes);
// 3. Connect!
mTimer = new QTimer(this);
QObject::connect(mTimer, &QTimer::timeout, this, &FileExtractor::handleExtraction);
mTimer->start();
QObject::connect(fileDownloader, &FileDownloader::downloadFinished, [fileDownloader, timer, downloadStep ]()mutable {
if( downloadStep++ == 0){
fileDownloader->setUrl(QUrl(LinphoneBZip2_dll));
fileDownloader->download();
}else {
fileDownloader->deleteLater();
timer->start();
}
});
QObject::connect(fileDownloader, &FileDownloader::downloadFailed, [fileDownloader, this]() {
fileDownloader->deleteLater();
emitExtractorFailed();
});
fileDownloader->download();
}
#else
mTimer->start();
#endif
}
bool FileExtractor::remove () {
return mDestinationFile.exists() && !mDestinationFile.isOpen() && mDestinationFile.remove();
return QFile::exists(mDestinationFile) && QFile::remove(mDestinationFile);
}
QString FileExtractor::getFile () const {
@ -142,7 +108,6 @@ void FileExtractor::setFile (const QString &file) {
qWarning() << QStringLiteral("Unable to set file, a file is extracting.");
return;
}
if (mFile != file) {
mFile = file;
emit fileChanged(mFile);
@ -158,7 +123,6 @@ void FileExtractor::setExtractFolder (const QString &extractFolder) {
qWarning() << QStringLiteral("Unable to set extract folder, a file is extracting.");
return;
}
if (mExtractFolder != extractFolder) {
mExtractFolder = extractFolder;
emit extractFolderChanged(mExtractFolder);
@ -174,35 +138,12 @@ void FileExtractor::setExtractName (const QString &extractName) {
qWarning() << QStringLiteral("Unable to set extract name, a file is extracting.");
return;
}
if (mExtractName != extractName) {
mExtractName = extractName;
emit extractNameChanged(mExtractName);
}
}
qint64 FileExtractor::getReadBytes () const {
return mReadBytes;
}
void FileExtractor::setReadBytes (qint64 readBytes) {
if (mReadBytes != readBytes) {
mReadBytes = readBytes;
emit readBytesChanged(readBytes);
}
}
qint64 FileExtractor::getTotalBytes () const {
return mTotalBytes;
}
void FileExtractor::setTotalBytes (qint64 totalBytes) {
if (mTotalBytes != totalBytes) {
mTotalBytes = totalBytes;
emit totalBytesChanged(totalBytes);
}
}
bool FileExtractor::getExtracting () const {
return mExtracting;
}
@ -214,23 +155,45 @@ void FileExtractor::setExtracting (bool extracting) {
}
}
void FileExtractor::clean () {
mStream.reset(nullptr);
mDestinationFile.close();
qint64 FileExtractor::getReadBytes () const {
return mReadBytes;
}
void FileExtractor::setReadBytes (qint64 readBytes) {
if (mReadBytes != readBytes) {
mReadBytes = readBytes;
emit readBytesChanged(readBytes);
}
}
qint64 FileExtractor::getTotalBytes () const {
return mTotalBytes;
}
void FileExtractor::setTotalBytes (qint64 totalBytes) {
if (mTotalBytes != totalBytes) {
mTotalBytes = totalBytes;
emit totalBytesChanged(totalBytes);
}
}
void FileExtractor::clean () {
if (mTimer) {
mTimer->stop();
mTimer->deleteLater();
mTimer = nullptr;
}
setExtracting(false);
}
void FileExtractor::emitExtractorFailed () {
qWarning() << QStringLiteral("Unable to extract file `%1`. bzip2 is unavailable, please install it.")
.arg(mFile);
clean();
emit extractFailed();
}
void FileExtractor::emitExtractFailed (int error) {
qWarning() << QStringLiteral("Unable to extract file: `%1` (code: %2).")
qWarning() << QStringLiteral("Unable to extract file with bzip2: `%1` (code: %2).")
.arg(mFile).arg(error);
mDestinationFile.remove();
clean();
emit extractFailed();
}
@ -241,28 +204,33 @@ void FileExtractor::emitExtractFinished () {
}
void FileExtractor::emitOutputError () {
qWarning() << QStringLiteral("Could not write into `%1` (%2).")
.arg(mDestinationFile.fileName()).arg(mDestinationFile.errorString());
mDestinationFile.remove();
qWarning() << QStringLiteral("Could not write into `%1`.")
.arg(mDestinationFile);
clean();
emit extractFailed();
}
void FileExtractor::handleExtraction () {
char buffer[4096];
void *stream = mStream.data()->getInternalStream();
int32_t readBytes = mz_stream_bzip_read(stream, buffer, sizeof buffer);
if (readBytes == 0)
QString tempDestination = mDestinationFile+"."+QFileInfo(mFile).suffix();
QStringList args;
args.push_back("-dq");
args.push_back(tempDestination);
QFile::copy(mFile, tempDestination);
#ifdef WIN32
int result = QProcess::execute("bzip2.exe", args);
if( result == -2)
result = QProcess::execute(Utils::coreStringToAppString(Paths::getToolsDirPath())+"\\bzip2.exe", args);
#else
int result = QProcess::execute("bzip2", args);
#endif
if(QFile::exists(tempDestination))
QFile::remove(tempDestination);
if (result == 0)
emitExtractFinished();
else if (readBytes < 0)
emitExtractFailed(readBytes);
else {
int64_t inputReadBytes;
mz_stream_bzip_get_prop_int64(stream, MZ_STREAM_PROP_TOTAL_IN, &inputReadBytes);
setReadBytes(inputReadBytes);
if (mDestinationFile.write(buffer, readBytes) == -1)
emitOutputError();
}
else if (result > 0)
emitExtractFailed(result);
else if(result == -2)
emitExtractorFailed();
else
emitOutputError();
}

View file

@ -29,7 +29,6 @@ class QTimer;
// Supports only bzip file.
class FileExtractor : public QObject {
class ExtractStream;
Q_OBJECT;
@ -38,10 +37,9 @@ class FileExtractor : public QObject {
Q_PROPERTY(QString file READ getFile WRITE setFile NOTIFY fileChanged);
Q_PROPERTY(QString extractFolder READ getExtractFolder WRITE setExtractFolder NOTIFY extractFolderChanged);
Q_PROPERTY(QString extractName READ getExtractName WRITE setExtractName NOTIFY extractNameChanged);
Q_PROPERTY(bool extracting READ getExtracting NOTIFY extractingChanged);
Q_PROPERTY(qint64 readBytes READ getReadBytes NOTIFY readBytesChanged);
Q_PROPERTY(qint64 totalBytes READ getTotalBytes NOTIFY totalBytesChanged);
Q_PROPERTY(bool extracting READ getExtracting NOTIFY extractingChanged);
public:
FileExtractor (QObject *parent = nullptr);
~FileExtractor ();
@ -65,7 +63,7 @@ signals:
void extractNameChanged (const QString &extractName);
void readBytesChanged (qint64 readBytes);
void totalBytesChanged (qint64 totalBytes);
void totalBytesChanged (qint64 totalBytes);
void extractingChanged (bool extracting);
void extractFinished ();
@ -77,13 +75,14 @@ private:
qint64 getTotalBytes () const;
void setTotalBytes (qint64 totalBytes);
bool getExtracting () const;
void setExtracting (bool extracting);
void clean ();
void emitExtractFinished ();
void emitExtractorFailed (); // Used when bzip2 cannot be used
void emitExtractFailed (int error);
void emitOutputError ();
@ -92,13 +91,11 @@ private:
QString mFile;
QString mExtractFolder;
QString mExtractName;
QFile mDestinationFile;
QString mDestinationFile;
bool mExtracting = false;
qint64 mReadBytes = 0;
qint64 mTotalBytes = 0;
bool mExtracting = false;
QScopedPointer<ExtractStream> mStream;
QTimer *mTimer = nullptr;
};

View file

@ -1,168 +0,0 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QDebug>
#include <QDir>
#include <QTimer>
#include <QProcess>
#include "FileProcessExtractor.hpp"
// =============================================================================
using namespace std;
FileExtractor::FileExtractor (QObject *parent) : QObject(parent) {}
FileExtractor::~FileExtractor () {}
void FileExtractor::extract () {
if (mExtracting) {
qWarning() << "Unable to extract file. Already extracting!";
return;
}
setExtracting(true);
QFileInfo fileInfo(mFile);
if(!fileInfo.isReadable()){
emitExtractFailed(-1);
return;
}
mDestinationFile = QDir::cleanPath(mExtractFolder) + QDir::separator() + (mExtractName.isEmpty() ? fileInfo.completeBaseName() : mExtractName);
if(QFile::exists(mDestinationFile) && !QFile::remove(mDestinationFile)){
emitOutputError();
return;
}
mTimer = new QTimer(this);
QObject::connect(mTimer, &QTimer::timeout, this, &FileExtractor::handleExtraction);
mTimer->start();
}
bool FileExtractor::remove () {
return QFile::exists(mDestinationFile) && QFile::remove(mDestinationFile);
}
QString FileExtractor::getFile () const {
return mFile;
}
void FileExtractor::setFile (const QString &file) {
if (mExtracting) {
qWarning() << QStringLiteral("Unable to set file, a file is extracting.");
return;
}
if (mFile != file) {
mFile = file;
emit fileChanged(mFile);
}
}
QString FileExtractor::getExtractFolder () const {
return mExtractFolder;
}
void FileExtractor::setExtractFolder (const QString &extractFolder) {
if (mExtracting) {
qWarning() << QStringLiteral("Unable to set extract folder, a file is extracting.");
return;
}
if (mExtractFolder != extractFolder) {
mExtractFolder = extractFolder;
emit extractFolderChanged(mExtractFolder);
}
}
QString FileExtractor::getExtractName () const {
return mExtractName;
}
void FileExtractor::setExtractName (const QString &extractName) {
if (mExtracting) {
qWarning() << QStringLiteral("Unable to set extract name, a file is extracting.");
return;
}
if (mExtractName != extractName) {
mExtractName = extractName;
emit extractNameChanged(mExtractName);
}
}
bool FileExtractor::getExtracting () const {
return mExtracting;
}
void FileExtractor::setExtracting (bool extracting) {
if (mExtracting != extracting) {
mExtracting = extracting;
emit extractingChanged(extracting);
}
}
qint64 FileExtractor::getReadBytes () const {
return mReadBytes;
}
qint64 FileExtractor::getTotalBytes () const {
return mTotalBytes;
}
void FileExtractor::clean () {
if (mTimer) {
mTimer->stop();
mTimer->deleteLater();
mTimer = nullptr;
}
setExtracting(false);
}
void FileExtractor::emitExtractFailed (int error) {
qWarning() << QStringLiteral("Unable to extract file with bzip2: `%1` (code: %2).")
.arg(mFile).arg(error);
clean();
emit extractFailed();
}
void FileExtractor::emitExtractFinished () {
clean();
emit extractFinished();
}
void FileExtractor::emitOutputError () {
qWarning() << QStringLiteral("Could not write into `%1`.")
.arg(mDestinationFile);
clean();
emit extractFailed();
}
void FileExtractor::handleExtraction () {
QString tempDestination = mDestinationFile+"."+QFileInfo(mFile).suffix();
QStringList args;
args.push_back("-dq");
args.push_back(tempDestination);
QFile::copy(mFile, tempDestination);
int result = QProcess::execute("bzip2", args);
if(QFile::exists(tempDestination))
QFile::remove(tempDestination);
if (result == 0)
emitExtractFinished();
else if (result > 0)
emitExtractFailed(result);
else
emitOutputError();
}

View file

@ -1,99 +0,0 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FILE_EXTRACTOR_H_
#define FILE_EXTRACTOR_H_
#include <QFile>
// =============================================================================
class QTimer;
// Supports only bzip file.
class FileExtractor : public QObject {
Q_OBJECT;
// TODO: Add an error property to use in UI.
Q_PROPERTY(QString file READ getFile WRITE setFile NOTIFY fileChanged);
Q_PROPERTY(QString extractFolder READ getExtractFolder WRITE setExtractFolder NOTIFY extractFolderChanged);
Q_PROPERTY(QString extractName READ getExtractName WRITE setExtractName NOTIFY extractNameChanged);
Q_PROPERTY(bool extracting READ getExtracting NOTIFY extractingChanged);
Q_PROPERTY(qint64 readBytes READ getReadBytes NOTIFY readBytesChanged);
Q_PROPERTY(qint64 totalBytes READ getTotalBytes NOTIFY totalBytesChanged);
public:
FileExtractor (QObject *parent = nullptr);
~FileExtractor ();
Q_INVOKABLE void extract ();
Q_INVOKABLE bool remove ();
QString getFile () const;
void setFile (const QString &file);
QString getExtractFolder () const;
void setExtractFolder (const QString &extractFolder);
QString getExtractName () const;
void setExtractName (const QString &extractName);
signals:
void fileChanged (const QString &file);
void extractFolderChanged (const QString &extractFolder);
void extractNameChanged (const QString &extractName);
void readBytesChanged (qint64 readBytes);
void totalBytesChanged (qint64 totalBytes);
void extractingChanged (bool extracting);
void extractFinished ();
void extractFailed ();
private:
qint64 getReadBytes () const;
qint64 getTotalBytes () const;
bool getExtracting () const;
void setExtracting (bool extracting);
void clean ();
void emitExtractFinished ();
void emitExtractFailed (int error);
void emitOutputError ();
void handleExtraction ();
QString mFile;
QString mExtractFolder;
QString mExtractName;
QString mDestinationFile;
bool mExtracting = false;
qint64 mReadBytes = 0;
qint64 mTotalBytes = 0;
QTimer *mTimer = nullptr;
};
#endif // FILE_EXTRACTOR_H_

@ -1 +1 @@
Subproject commit 1108b7be26759b61cd6e72c6c4830b8daf6e1fdf
Subproject commit 730ea1dda0bf899895b6af849240adfeef9b6270

@ -1 +0,0 @@
Subproject commit 40b728857cd0cedfe8a122861cb6944cbcdcf2ac