From 83f10c23d859b13513d6aff099e64f0a84a63229 Mon Sep 17 00:00:00 2001 From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> Date: Thu, 20 Feb 2020 16:54:53 -0500 Subject: [PATCH] datatransfer: handle unique filenames within acceptTransfer Change-Id: Id3fbb745f36219e29ae9c8929e78dbcaa00a2c05 --- src/api/conversationmodel.h | 2 ++ src/api/datatransfermodel.h | 2 +- src/conversationmodel.cpp | 49 ++++++++++++++++++++----------------- src/datatransfermodel.cpp | 31 ++++++++++++++++++++--- 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/api/conversationmodel.h b/src/api/conversationmodel.h index e9bde275..6974272b 100644 --- a/src/api/conversationmodel.h +++ b/src/api/conversationmodel.h @@ -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); diff --git a/src/api/datatransfermodel.h b/src/api/datatransfermodel.h index 2d36c2eb..5fc79de7 100644 --- a/src/api/datatransfermodel.h +++ b/src/api/datatransfermodel.h @@ -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); diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp index 3e2b2db3..21ff7f35 100644 --- a/src/conversationmodel.cpp +++ b/src/conversationmodel.cpp @@ -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; diff --git a/src/datatransfermodel.cpp b/src/datatransfermodel.cpp index 4c05ac4c..23823d41 100644 --- a/src/datatransfermodel.cpp +++ b/src/datatransfermodel.cpp @@ -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 -- GitLab