1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-15 13:05:23 +02:00
jami-client-qt/src/libclient/datatransfermodel.cpp
Sébastien Blin 84150e8977 misc: bump copyright to 2024
Change-Id: I8d5f968fbedbc884c91416246049a0ef4cd652eb
2024-01-03 09:54:49 -05:00

241 lines
8.2 KiB
C++

/****************************************************************************
* Copyright (C) 2018-2024 Savoir-faire Linux Inc. *
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser 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/>. *
***************************************************************************/
// LRC
#include "api/datatransfermodel.h"
// Dbus
#include "dbus/configurationmanager.h"
// libjami
#include <datatransfer_interface.h>
// Std
#include <map>
#include <stdexcept>
#include <type_traits>
// Qt
#include <QDir>
#include <QFileInfo>
#include <QtCore/QStandardPaths>
#include <QUuid>
namespace lrc {
namespace api {
// LIBJAMI to LRC event code conversion
static inline datatransfer::Status
convertDataTransferEvent(libjami::DataTransferEventCode event)
{
switch (event) {
case libjami::DataTransferEventCode::invalid:
return datatransfer::Status::INVALID;
case libjami::DataTransferEventCode::created:
return datatransfer::Status::on_connection;
case libjami::DataTransferEventCode::unsupported:
return datatransfer::Status::unsupported;
case libjami::DataTransferEventCode::wait_peer_acceptance:
return datatransfer::Status::on_connection;
case libjami::DataTransferEventCode::wait_host_acceptance:
return datatransfer::Status::on_connection;
case libjami::DataTransferEventCode::ongoing:
return datatransfer::Status::on_progress;
case libjami::DataTransferEventCode::finished:
return datatransfer::Status::success;
case libjami::DataTransferEventCode::closed_by_host:
return datatransfer::Status::stop_by_host;
case libjami::DataTransferEventCode::closed_by_peer:
return datatransfer::Status::stop_by_peer;
case libjami::DataTransferEventCode::invalid_pathname:
return datatransfer::Status::invalid_pathname;
case libjami::DataTransferEventCode::unjoinable_peer:
return datatransfer::Status::unjoinable_peer;
case libjami::DataTransferEventCode::timeout_expired:
return datatransfer::Status::timeout_expired;
}
throw std::runtime_error("BUG: broken convertDataTransferEvent() switch");
}
class DataTransferModel::Impl : public QObject
{
Q_OBJECT
public:
Impl(DataTransferModel& up_link);
QString getUniqueFilePath(const QString& filename, const QString& path = "");
DataTransferModel& upLink;
MapStringString file2InteractionId;
MapStringString interactionToFileId; // stricly the reverse map of file2InteractionId
};
DataTransferModel::Impl::Impl(DataTransferModel& up_link)
: QObject {}
, upLink {up_link}
{}
QString
DataTransferModel::Impl::getUniqueFilePath(const QString& filename, const QString& path)
{
auto base = filename;
QString ext = QFileInfo(base).completeSuffix();
if (!ext.isEmpty())
ext = ext.prepend(".");
QFileInfo fi(filename);
auto p = !path.isEmpty() ? path : fi.dir().path();
base = QDir(p).filePath(fi.baseName() + ext);
if (!QFile::exists(base))
return base;
base.chop(ext.size());
QString ret;
for (int suffix = 1;; suffix++) {
ret = QString("%1 (%2)%3").arg(base).arg(suffix).arg(ext);
if (!QFile::exists(ret)) {
return ret;
}
}
}
void
DataTransferModel::registerTransferId(const QString& fileId, const QString& interactionId)
{
pimpl_->file2InteractionId[fileId] = interactionId;
pimpl_->interactionToFileId.remove(interactionId); // Because a file transfer can be retried
pimpl_->interactionToFileId[interactionId] = fileId;
}
DataTransferModel::DataTransferModel()
: QObject(nullptr)
, pimpl_ {std::make_unique<Impl>(*this)}
{}
DataTransferModel::~DataTransferModel() = default;
void
DataTransferModel::sendFile(const QString& accountId,
const QString& conversationId,
const QString& filePath,
const QString& displayName,
const QString& parent)
{
ConfigurationManager::instance().sendFile(accountId,
conversationId,
filePath,
displayName,
parent);
}
void
DataTransferModel::fileTransferInfo(const QString& accountId,
const QString& conversationId,
const QString& fileId,
QString& path,
qlonglong& total,
qlonglong& progress)
{
ConfigurationManager::instance()
.fileTransferInfo(accountId, conversationId, fileId, path, total, progress);
}
void
DataTransferModel::download(const QString& accountId,
const QString& convId,
const QString& interactionId,
const QString& fileId,
const QString& path)
{
ConfigurationManager::instance().downloadFile(accountId, convId, interactionId, fileId, path);
}
QString
DataTransferModel::copyTo(const QString& accountId,
const QString& convId,
const QString& interactionId,
const QString& destPath,
const QString& displayName)
{
auto fileId = getFileIdFromInteractionId(interactionId);
if (fileId.isEmpty()) {
qWarning() << "Cannot find any file for " << interactionId;
return {};
}
QString path;
qlonglong total, progress;
fileTransferInfo(accountId, convId, fileId, path, total, progress);
auto src = QFile(path);
auto srcfi = QFileInfo(path);
if (!src.exists())
return {};
auto filename = displayName;
if (displayName.isEmpty())
filename = srcfi.isSymLink() ? srcfi.symLinkTarget() : path;
auto dest = pimpl_->getUniqueFilePath(filename, destPath);
qDebug() << "Copy to " << dest;
// create directory if it does not exist
QDir dir(destPath);
if (!dir.exists())
dir.mkpath(".");
src.copy(dest);
return dest;
}
void
DataTransferModel::cancel(const QString& accountId,
const QString& conversationId,
const QString& interactionId)
{
ConfigurationManager::instance().cancelDataTransfer(accountId,
conversationId,
getFileIdFromInteractionId(interactionId));
}
QString
DataTransferModel::getInteractionIdFromFileId(const QString& fileId)
{
return pimpl_->file2InteractionId[fileId];
}
QString
DataTransferModel::getFileIdFromInteractionId(const QString& interactionId)
{
return pimpl_->interactionToFileId[interactionId];
}
QString
DataTransferModel::createDefaultDirectory()
{
auto defaultDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)
+ "/Jami";
QDir dir(defaultDirectory);
if (!dir.exists())
dir.mkpath(".");
return defaultDirectory;
}
} // namespace api
} // namespace lrc
#include "api/moc_datatransfermodel.cpp"
#include "datatransfermodel.moc"