linphone-desktop/Linphone/tool/file/FileExtractor.cpp
Gaelle Braud b17bc8cc27 Fixes:
fix get size with screen ratio function

fix chat sending area ui #LINQT-2068

print debug logs in linphone files for futur debugging

fix call history details ui when no video conference factory set

use remote name of each call if in local conference #LINQT-2058
2025-10-21 11:25:17 +02:00

239 lines
7.1 KiB
C++

/*
* Copyright (c) 2010-2024 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 <QProcess>
#include <QTimer>
#include "FileDownloader.hpp"
#include "FileExtractor.hpp"
#include "core/path/Paths.hpp"
#include "tool/Constants.hpp"
#include "tool/Utils.hpp"
DEFINE_ABSTRACT_OBJECT(FileExtractor)
// =============================================================================
using namespace std;
FileExtractor::FileExtractor(QObject *parent) : QObject(parent) {
}
FileExtractor::~FileExtractor() {
}
void FileExtractor::extract() {
if (mExtracting) {
lWarning() << log().arg("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;
}
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
QProcess process;
process.closeReadChannel(QProcess::StandardOutput);
process.closeReadChannel(QProcess::StandardError);
process.start("bzip2.exe", QStringList("--help"));
// int result = QProcess::execute("bzip2.exe", QStringList("--help"));
if (process.error() != QProcess::FailedToStart ||
QProcess::execute(Paths::getToolsDirPath() + "\\bzip2.exe", QStringList()) != -2) {
mTimer->start();
} else { // Download bzip2
qWarning() << "bzip2 was not found. Downloading it.";
QTimer *timer = mTimer;
FileDownloader *fileDownloader = new FileDownloader();
int downloadStep = 0;
fileDownloader->setUrl(QUrl(Constants::LinphoneBZip2_exe));
fileDownloader->setDownloadFolder(Paths::getToolsDirPath());
QObject::connect(fileDownloader, &FileDownloader::totalBytesChanged, this, &FileExtractor::setTotalBytes);
QObject::connect(fileDownloader, &FileDownloader::readBytesChanged, this, &FileExtractor::setReadBytes);
QObject::connect(fileDownloader, &FileDownloader::downloadFinished,
[fileDownloader, timer, downloadStep, this]() mutable {
if (downloadStep++ == 0) {
fileDownloader->setUrl(QUrl(Constants::LinphoneBZip2_dll));
fileDownloader->download();
} else {
fileDownloader->deleteLater();
QObject::disconnect(fileDownloader, &FileDownloader::totalBytesChanged, this,
&FileExtractor::setTotalBytes);
QObject::disconnect(fileDownloader, &FileDownloader::readBytesChanged, this,
&FileExtractor::setReadBytes);
timer->start();
}
});
QObject::connect(fileDownloader, &FileDownloader::downloadFailed, [fileDownloader, this]() {
fileDownloader->deleteLater();
emitExtractorFailed();
});
fileDownloader->download();
}
#else
mTimer->start();
#endif
}
bool FileExtractor::remove() {
return QFile::exists(mDestinationFile) && QFile::remove(mDestinationFile);
}
QString FileExtractor::getFile() const {
return mFile;
}
void FileExtractor::setFile(const QString &file) {
if (mExtracting) {
lWarning() << log().arg("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) {
lWarning() << log().arg("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;
}
void FileExtractor::setReadBytes(qint64 readBytes) {
mReadBytes = readBytes;
emit readBytesChanged(readBytes);
}
qint64 FileExtractor::getTotalBytes() const {
return mTotalBytes;
}
void FileExtractor::setTotalBytes(qint64 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 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);
#ifdef WIN32
int result = QProcess::execute("bzip2.exe", args);
if (result == -2) result = QProcess::execute(Paths::getToolsDirPath() + "\\bzip2.exe", args);
#else
int result = QProcess::execute("bzip2", args);
#endif
if (QFile::exists(tempDestination)) QFile::remove(tempDestination);
if (result == 0) {
setReadBytes(getTotalBytes());
emitExtractFinished();
} else if (result > 0) emitExtractFailed(result);
else if (result == -2) emitExtractorFailed();
else emitOutputError();
}