Commit 83f10c23 authored by Andreas Traczyk's avatar Andreas Traczyk Committed by Yang Wang

datatransfer: handle unique filenames within acceptTransfer

Change-Id: Id3fbb745f36219e29ae9c8929e78dbcaa00a2c05
parent 08b44fbc
......@@ -211,6 +211,8 @@ public:
void sendFile(const QString& convUid, const QString& path, const QString& filename);
void acceptTransfer(const QString & convUid, uint64_t interactionId);
void acceptTransfer(const QString& convUid, uint64_t interactionId, const QString& path);
void cancelTransfer(const QString& convUid, uint64_t interactionId);
......
......@@ -58,7 +58,7 @@ public:
void bytesProgress(int interactionId, int64_t& total, int64_t& progress);
void accept(int interactionId, const QString& file_path, std::size_t offset);
QString accept(int interactionId, const QString& file_path, std::size_t offset);
void cancel(int interactionId);
......
......@@ -2025,6 +2025,14 @@ ConversationModel::sendFile(const QString& convUid,
}
}
void
ConversationModel::acceptTransfer(const QString& convUid, uint64_t interactionId)
{
lrc::api::datatransfer::Info info = {};
getTransferInfo(interactionId, info);
acceptTransfer(convUid, interactionId, info.displayName);
}
void
ConversationModel::acceptTransfer(const QString& convUid, uint64_t interactionId, const QString& path)
{
......@@ -2175,31 +2183,17 @@ ConversationModelPimpl::slotTransferStatusAwaitingHost(long long dringId, datatr
if (emitUpdated) {
dirtyConversations = {true, true};
emit linked.interactionStatusUpdated(convId, interactionId, itCopy);
// If it's an accepted file type and less than 20 MB, accept transfer.
// TODO: Use Qt functions
auto extensionIdx = info.displayName.toStdString().find_last_of(".");
if (extensionIdx == std::string::npos)
return;
auto extension = QString(info.displayName).remove(0, extensionIdx);
// Only accept if contact is added
try {
auto contactInfo = linked.owner.contactModel->getContact(conversations[conversationIdx].participants.front());
// Only accept if contact is added
auto contactUri = conversations[conversationIdx].participants.front();
auto contactInfo = linked.owner.contactModel->getContact(contactUri);
if (contactInfo.profileInfo.type != profile::Type::RING) return;
} catch (...) {
return;
}
auto destinationDir = lrc.getDataTransferModel().downloadDirectory;
if (info.totalSize < 20 * 1024 * 1024 && !destinationDir.isEmpty()) {
auto wantedFilename = destinationDir + info.displayName;
auto duplicate = 0;
while (std::ifstream(wantedFilename.toStdString()).good()) {
++duplicate;
wantedFilename = destinationDir + info.displayName.left(extensionIdx) +
" (" + toQString(duplicate) + ")" + extension.toLower();
}
acceptTransfer(convId, interactionId, wantedFilename);
// If it's an accepted file type and less than 20 MB, accept transfer.
if (info.totalSize < 20 * 1024 * 1024 && info.displayName.contains(".")) {
acceptTransfer(convId, interactionId, info.displayName);
}
}
}
......@@ -2208,8 +2202,17 @@ ConversationModelPimpl::slotTransferStatusAwaitingHost(long long dringId, datatr
void
ConversationModelPimpl::acceptTransfer(const QString& convUid, uint64_t interactionId, const QString& path)
{
lrc.getDataTransferModel().accept(interactionId, path, 0);
storage::updateInteractionBody(db, interactionId, path);
auto destinationDir = lrc.getDataTransferModel().downloadDirectory;
if (destinationDir.isEmpty()) {
return;
}
#ifdef Q_OS_WIN
if (destinationDir.right(1) != '/') {
destinationDir += "/";
}
#endif
auto acceptedFilePath = lrc.getDataTransferModel().accept(interactionId, destinationDir + path, 0);
storage::updateInteractionBody(db, interactionId, acceptedFilePath);
storage::updateInteractionStatus(db, interactionId, interaction::Status::TRANSFER_ACCEPTED);
// prepare interaction Info and emit signal for the client
......@@ -2221,7 +2224,7 @@ ConversationModelPimpl::acceptTransfer(const QString& convUid, uint64_t interact
auto& interactions = conversations[conversationIdx].interactions;
auto it = interactions.find(interactionId);
if (it != interactions.end()) {
it->second.body = path;
it->second.body = acceptedFilePath;
it->second.status = interaction::Status::TRANSFER_ACCEPTED;
emitUpdated = true;
itCopy = it->second;
......
......@@ -32,6 +32,7 @@
// Qt
#include <QUuid>
#include <QFileInfo>
namespace lrc { namespace api {
......@@ -64,6 +65,8 @@ class DataTransferModel::Impl : public QObject
public:
Impl(DataTransferModel& up_link);
QString getUniqueFilePath(const QString& filename);
DataTransferModel& upLink;
std::map<long long, int> dring2lrcIdMap;
std::map<int, long long> lrc2dringIdMap; // stricly the reverse map of dring2lrcIdMap
......@@ -74,10 +77,30 @@ DataTransferModel::Impl::Impl(DataTransferModel& up_link)
, upLink {up_link}
{}
QString
DataTransferModel::Impl::getUniqueFilePath(const QString& filename)
{
if (!QFile::exists(filename)) {
return filename;
}
QString base(filename);
QString ext = QFileInfo(filename).completeSuffix();
if (!ext.isEmpty()) {
ext = ext.prepend(".");
}
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(long long dringId, int interactionId)
{
pimpl_->dring2lrcIdMap.emplace(dringId, interactionId);
pimpl_->lrc2dringIdMap.emplace(interactionId, dringId);
}
......@@ -135,13 +158,15 @@ DataTransferModel::bytesProgress(int interactionId, int64_t& total, int64_t& pro
reinterpret_cast<qlonglong&>(progress));
}
void
QString
DataTransferModel::accept(int interactionId,
const QString& file_path,
std::size_t offset)
{
auto unique_file_path = pimpl_->getUniqueFilePath(file_path);
auto dring_id = pimpl_->lrc2dringIdMap.at(interactionId);
ConfigurationManager::instance().acceptFileTransfer(dring_id, file_path, offset);
ConfigurationManager::instance().acceptFileTransfer(dring_id, unique_file_path, offset);
return unique_file_path;
}
void
......
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