First steps on the new idea of file up/downloading
This commit is contained in:
parent
8f914c02a7
commit
3a7735b192
@ -33,6 +33,7 @@ set(squawk_SRC
|
|||||||
shared/message.cpp
|
shared/message.cpp
|
||||||
shared/vcard.cpp
|
shared/vcard.cpp
|
||||||
shared/icons.cpp
|
shared/icons.cpp
|
||||||
|
shared/messageinfo.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(squawk_HEAD
|
set(squawk_HEAD
|
||||||
@ -45,6 +46,7 @@ set(squawk_HEAD
|
|||||||
shared/utils.h
|
shared/utils.h
|
||||||
shared/vcard.h
|
shared/vcard.h
|
||||||
shared/icons.h
|
shared/icons.h
|
||||||
|
shared/messageinfo.h
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(resources/images/logo.svg squawk.svg COPYONLY)
|
configure_file(resources/images/logo.svg squawk.svg COPYONLY)
|
||||||
|
@ -84,8 +84,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
QObject::connect(dm, &QXmppDiscoveryManager::itemsReceived, this, &Account::onDiscoveryItemsReceived);
|
QObject::connect(dm, &QXmppDiscoveryManager::itemsReceived, this, &Account::onDiscoveryItemsReceived);
|
||||||
QObject::connect(dm, &QXmppDiscoveryManager::infoReceived, this, &Account::onDiscoveryInfoReceived);
|
QObject::connect(dm, &QXmppDiscoveryManager::infoReceived, this, &Account::onDiscoveryInfoReceived);
|
||||||
|
|
||||||
QObject::connect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onFileUploaded);
|
QObject::connect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onUploadFileComplete);
|
||||||
QObject::connect(network, &NetworkAccess::uploadFileError, mh, &MessageHandler::onFileUploadError);
|
QObject::connect(network, &NetworkAccess::downloadFileComplete, mh, &MessageHandler::onDownloadFileComplete);
|
||||||
|
QObject::connect(network, &NetworkAccess::loadFileError, mh, &MessageHandler::onLoadFileError);
|
||||||
|
|
||||||
client.addExtension(rcpm);
|
client.addExtension(rcpm);
|
||||||
QObject::connect(rcpm, &QXmppMessageReceiptManager::messageDelivered, mh, &MessageHandler::onReceiptReceived);
|
QObject::connect(rcpm, &QXmppMessageReceiptManager::messageDelivered, mh, &MessageHandler::onReceiptReceived);
|
||||||
@ -155,8 +156,9 @@ Account::~Account()
|
|||||||
reconnectTimer->stop();
|
reconnectTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::disconnect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onFileUploaded);
|
QObject::disconnect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onUploadFileComplete);
|
||||||
QObject::disconnect(network, &NetworkAccess::uploadFileError, mh, &MessageHandler::onFileUploadError);
|
QObject::disconnect(network, &NetworkAccess::downloadFileComplete, mh, &MessageHandler::onDownloadFileComplete);
|
||||||
|
QObject::disconnect(network, &NetworkAccess::loadFileError, mh, &MessageHandler::onLoadFileError);
|
||||||
|
|
||||||
delete mh;
|
delete mh;
|
||||||
delete rh;
|
delete rh;
|
||||||
@ -549,9 +551,11 @@ void Core::Account::onClientError(QXmppClient::Error err)
|
|||||||
case QXmppStanza::Error::NotAuthorized:
|
case QXmppStanza::Error::NotAuthorized:
|
||||||
errorText = "Authentication error";
|
errorText = "Authentication error";
|
||||||
break;
|
break;
|
||||||
|
#if (QXMPP_VERSION) < QT_VERSION_CHECK(1, 3, 0)
|
||||||
case QXmppStanza::Error::PaymentRequired:
|
case QXmppStanza::Error::PaymentRequired:
|
||||||
errorText = "Payment is required";
|
errorText = "Payment is required";
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case QXmppStanza::Error::RecipientUnavailable:
|
case QXmppStanza::Error::RecipientUnavailable:
|
||||||
errorText = "Recipient is unavailable";
|
errorText = "Recipient is unavailable";
|
||||||
break;
|
break;
|
||||||
|
@ -133,7 +133,7 @@ signals:
|
|||||||
void removeRoomParticipant(const QString& jid, const QString& nickName);
|
void removeRoomParticipant(const QString& jid, const QString& nickName);
|
||||||
void receivedVCard(const QString& jid, const Shared::VCard& card);
|
void receivedVCard(const QString& jid, const Shared::VCard& card);
|
||||||
void uploadFile(const QFileInfo& file, const QUrl& set, const QUrl& get, QMap<QString, QString> headers);
|
void uploadFile(const QFileInfo& file, const QUrl& set, const QUrl& get, QMap<QString, QString> headers);
|
||||||
void uploadFileError(const QString& messageId, const QString& error);
|
void uploadFileError(const QString& jid, const QString& messageId, const QString& error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
|
@ -168,14 +168,16 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
|
|||||||
id = source.id();
|
id = source.id();
|
||||||
#endif
|
#endif
|
||||||
target.setId(id);
|
target.setId(id);
|
||||||
if (target.getId().size() == 0) {
|
QString messageId = target.getId();
|
||||||
|
if (messageId.size() == 0) {
|
||||||
target.generateRandomId(); //TODO out of desperation, I need at least a random ID
|
target.generateRandomId(); //TODO out of desperation, I need at least a random ID
|
||||||
|
messageId = target.getId();
|
||||||
}
|
}
|
||||||
target.setFrom(source.from());
|
target.setFrom(source.from());
|
||||||
target.setTo(source.to());
|
target.setTo(source.to());
|
||||||
target.setBody(source.body());
|
target.setBody(source.body());
|
||||||
target.setForwarded(forwarded);
|
target.setForwarded(forwarded);
|
||||||
target.setOutOfBandUrl(source.outOfBandUrl());
|
|
||||||
if (guessing) {
|
if (guessing) {
|
||||||
if (target.getFromJid() == acc->getLogin() + "@" + acc->getServer()) {
|
if (target.getFromJid() == acc->getLogin() + "@" + acc->getServer()) {
|
||||||
outgoing = true;
|
outgoing = true;
|
||||||
@ -189,6 +191,12 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
|
|||||||
} else {
|
} else {
|
||||||
target.setCurrentTime();
|
target.setCurrentTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString oob = source.outOfBandUrl();
|
||||||
|
if (oob.size() > 0) {
|
||||||
|
target.setAttachPath(acc->network->addMessageAndCheckForPath(oob, acc->getName(), target.getPenPalJid(), messageId));
|
||||||
|
}
|
||||||
|
target.setOutOfBandUrl(oob);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& reason)
|
void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& reason)
|
||||||
@ -292,7 +300,7 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data)
|
|||||||
if (url.size() != 0) {
|
if (url.size() != 0) {
|
||||||
sendMessageWithLocalUploadedFile(data, url);
|
sendMessageWithLocalUploadedFile(data, url);
|
||||||
} else {
|
} else {
|
||||||
if (acc->network->isUploading(path, data.getId())) {
|
if (acc->network->checkAndAddToUploading(acc->getName(), data.getPenPalJid(), data.getId(), path)) {
|
||||||
pendingMessages.emplace(data.getId(), data);
|
pendingMessages.emplace(data.getId(), data);
|
||||||
} else {
|
} else {
|
||||||
if (acc->um->serviceFound()) {
|
if (acc->um->serviceFound()) {
|
||||||
@ -303,17 +311,17 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data)
|
|||||||
acc->um->requestUploadSlot(file);
|
acc->um->requestUploadSlot(file);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onFileUploadError(data.getId(), "Uploading file no longer exists or your system user has no permission to read it");
|
handleUploadError(data.getPenPalJid(), data.getId(), "Uploading file no longer exists or your system user has no permission to read it");
|
||||||
qDebug() << "Requested upload slot in account" << acc->name << "for file" << path << "but the file doesn't exist or is not readable";
|
qDebug() << "Requested upload slot in account" << acc->name << "for file" << path << "but the file doesn't exist or is not readable";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onFileUploadError(data.getId(), "Your server doesn't support file upload service, or it's prohibited for your account");
|
handleUploadError(data.getPenPalJid(), data.getId(), "Your server doesn't support file upload service, or it's prohibited for your account");
|
||||||
qDebug() << "Requested upload slot in account" << acc->name << "for file" << path << "but upload manager didn't discover any upload services";
|
qDebug() << "Requested upload slot in account" << acc->name << "for file" << path << "but upload manager didn't discover any upload services";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onFileUploadError(data.getId(), "Account is offline or reconnecting");
|
handleUploadError(data.getPenPalJid(), data.getId(), "Account is offline or reconnecting");
|
||||||
qDebug() << "An attempt to send message with not connected account " << acc->name << ", skipping";
|
qDebug() << "An attempt to send message with not connected account " << acc->name << ", skipping";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,10 +334,10 @@ void Core::MessageHandler::onUploadSlotReceived(const QXmppHttpUploadSlotIq& slo
|
|||||||
} else {
|
} else {
|
||||||
const std::pair<QString, Shared::Message>& pair = uploadingSlotsQueue.front();
|
const std::pair<QString, Shared::Message>& pair = uploadingSlotsQueue.front();
|
||||||
const QString& mId = pair.second.getId();
|
const QString& mId = pair.second.getId();
|
||||||
acc->network->uploadFile(mId, pair.first, slot.putUrl(), slot.getUrl(), slot.putHeaders());
|
acc->network->uploadFile({acc->name, pair.second.getPenPalJid(), mId}, pair.first, slot.putUrl(), slot.getUrl(), slot.putHeaders());
|
||||||
pendingMessages.emplace(mId, pair.second);
|
pendingMessages.emplace(mId, pair.second);
|
||||||
uploadingSlotsQueue.pop_front();
|
|
||||||
|
|
||||||
|
uploadingSlotsQueue.pop_front();
|
||||||
if (uploadingSlotsQueue.size() > 0) {
|
if (uploadingSlotsQueue.size() > 0) {
|
||||||
acc->um->requestUploadSlot(uploadingSlotsQueue.front().first);
|
acc->um->requestUploadSlot(uploadingSlotsQueue.front().first);
|
||||||
}
|
}
|
||||||
@ -338,35 +346,69 @@ void Core::MessageHandler::onUploadSlotReceived(const QXmppHttpUploadSlotIq& slo
|
|||||||
|
|
||||||
void Core::MessageHandler::onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request)
|
void Core::MessageHandler::onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request)
|
||||||
{
|
{
|
||||||
|
QString err(request.error().text());
|
||||||
if (uploadingSlotsQueue.size() == 0) {
|
if (uploadingSlotsQueue.size() == 0) {
|
||||||
qDebug() << "HTTP Upload manager of account" << acc->name << "reports about an error requesting upload slot, but none was requested";
|
qDebug() << "HTTP Upload manager of account" << acc->name << "reports about an error requesting upload slot, but none was requested";
|
||||||
qDebug() << request.error().text();
|
qDebug() << err;
|
||||||
} else {
|
} else {
|
||||||
const std::pair<QString, Shared::Message>& pair = uploadingSlotsQueue.front();
|
const std::pair<QString, Shared::Message>& pair = uploadingSlotsQueue.front();
|
||||||
qDebug() << "Error requesting upload slot for file" << pair.first << "in account" << acc->name << ":" << request.error().text();
|
qDebug() << "Error requesting upload slot for file" << pair.first << "in account" << acc->name << ":" << err;
|
||||||
emit acc->uploadFileError(pair.second.getId(), "Error requesting slot to upload file: " + request.error().text());
|
emit acc->uploadFileError(pair.second.getPenPalJid(), pair.second.getId(), "Error requesting slot to upload file: " + err);
|
||||||
|
|
||||||
|
uploadingSlotsQueue.pop_front();
|
||||||
if (uploadingSlotsQueue.size() > 0) {
|
if (uploadingSlotsQueue.size() > 0) {
|
||||||
acc->um->requestUploadSlot(uploadingSlotsQueue.front().first);
|
acc->um->requestUploadSlot(uploadingSlotsQueue.front().first);
|
||||||
}
|
}
|
||||||
uploadingSlotsQueue.pop_front();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::MessageHandler::onFileUploaded(const QString& messageId, const QString& url)
|
void Core::MessageHandler::onDownloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path)
|
||||||
{
|
{
|
||||||
std::map<QString, Shared::Message>::const_iterator itr = pendingMessages.find(messageId);
|
QMap<QString, QVariant> cData = {
|
||||||
if (itr != pendingMessages.end()) {
|
{"attachPath", path}
|
||||||
sendMessageWithLocalUploadedFile(itr->second, url);
|
};
|
||||||
pendingMessages.erase(itr);
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
if (info.account == acc->getName()) {
|
||||||
|
Contact* cnt = acc->rh->getContact(info.jid);
|
||||||
|
if (cnt != 0) {
|
||||||
|
if (cnt->changeMessage(info.messageId, cData)) {
|
||||||
|
emit acc->changeMessage(info.jid, info.messageId, cData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::MessageHandler::onFileUploadError(const QString& messageId, const QString& errMsg)
|
void Core::MessageHandler::onLoadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& text, bool up)
|
||||||
|
{
|
||||||
|
if (up) {
|
||||||
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
if (info.account == acc->getName()) {
|
||||||
|
handleUploadError(info.jid, info.messageId, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::MessageHandler::handleUploadError(const QString& jid, const QString& messageId, const QString& errorText)
|
||||||
{
|
{
|
||||||
std::map<QString, Shared::Message>::const_iterator itr = pendingMessages.find(messageId);
|
std::map<QString, Shared::Message>::const_iterator itr = pendingMessages.find(messageId);
|
||||||
if (itr != pendingMessages.end()) {
|
if (itr != pendingMessages.end()) {
|
||||||
pendingMessages.erase(itr);
|
pendingMessages.erase(itr);
|
||||||
|
//TODO move the storage of pending messages to the database and change them there
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::MessageHandler::onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path)
|
||||||
|
{
|
||||||
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
if (info.account == acc->getName()) {
|
||||||
|
std::map<QString, Shared::Message>::const_iterator itr = pendingMessages.find(info.messageId);
|
||||||
|
if (itr != pendingMessages.end()) {
|
||||||
|
sendMessageWithLocalUploadedFile(itr->second, path);
|
||||||
|
pendingMessages.erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <QXmppHttpUploadIq.h>
|
#include <QXmppHttpUploadIq.h>
|
||||||
|
|
||||||
#include <shared/message.h>
|
#include <shared/message.h>
|
||||||
|
#include <shared/messageinfo.h>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
@ -54,8 +55,9 @@ public slots:
|
|||||||
void onReceiptReceived(const QString& jid, const QString& id);
|
void onReceiptReceived(const QString& jid, const QString& id);
|
||||||
void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot);
|
void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot);
|
||||||
void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request);
|
void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request);
|
||||||
void onFileUploaded(const QString& messageId, const QString& url);
|
void onDownloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
|
||||||
void onFileUploadError(const QString& messageId, const QString& errMsg);
|
void onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
|
||||||
|
void onLoadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& path, bool up);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
|
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
|
||||||
@ -64,6 +66,7 @@ private:
|
|||||||
void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url);
|
void sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url);
|
||||||
void performSending(Shared::Message data);
|
void performSending(Shared::Message data);
|
||||||
void prepareUpload(const Shared::Message& data);
|
void prepareUpload(const Shared::Message& data);
|
||||||
|
void handleUploadError(const QString& jid, const QString& messageId, const QString& errorText);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Account* acc;
|
Account* acc;
|
||||||
|
@ -16,13 +16,17 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
#include "networkaccess.h"
|
#include "networkaccess.h"
|
||||||
|
|
||||||
Core::NetworkAccess::NetworkAccess(QObject* parent):
|
Core::NetworkAccess::NetworkAccess(QObject* parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
running(false),
|
running(false),
|
||||||
manager(0),
|
manager(0),
|
||||||
files("files"),
|
storage("fileURLStorage"),
|
||||||
downloads(),
|
downloads(),
|
||||||
uploads()
|
uploads()
|
||||||
{
|
{
|
||||||
@ -33,60 +37,31 @@ Core::NetworkAccess::~NetworkAccess()
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const QString& url)
|
void Core::NetworkAccess::downladFile(const QString& url)
|
||||||
{
|
{
|
||||||
std::map<QString, Transfer*>::iterator itr = downloads.find(url);
|
std::map<QString, Transfer*>::iterator itr = downloads.find(url);
|
||||||
if (itr != downloads.end()) {
|
if (itr != downloads.end()) {
|
||||||
Transfer* dwn = itr->second;
|
qDebug() << "NetworkAccess received a request to download a file" << url << ", but the file is currently downloading, skipping";
|
||||||
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
|
|
||||||
if (mItr == dwn->messages.end()) {
|
|
||||||
dwn->messages.insert(messageId);
|
|
||||||
}
|
|
||||||
emit downloadFileProgress(messageId, dwn->progress);
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
QString path = files.getRecord(url);
|
std::pair<QString, std::list<Shared::MessageInfo>> p = storage.getPath(url);
|
||||||
QFileInfo info(path);
|
if (p.first.size() > 0) {
|
||||||
if (info.exists() && info.isFile()) {
|
QFileInfo info(p.first);
|
||||||
emit fileLocalPathResponse(messageId, path);
|
if (info.exists() && info.isFile()) {
|
||||||
|
emit downloadFileComplete(p.second, p.first);
|
||||||
|
} else {
|
||||||
|
startDownload(p.second, url);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
files.removeRecord(url);
|
startDownload(p.second, url);
|
||||||
emit fileLocalPathResponse(messageId, "");
|
|
||||||
}
|
}
|
||||||
} catch (const Archive::NotFound& e) {
|
} catch (const Archive::NotFound& e) {
|
||||||
emit fileLocalPathResponse(messageId, "");
|
qDebug() << "NetworkAccess received a request to download a file" << url << ", but there is now record of which message uses that file, downloading anyway";
|
||||||
|
storage.addFile(url);
|
||||||
|
startDownload(std::list<Shared::MessageInfo>(), url);
|
||||||
} catch (const Archive::Unknown& e) {
|
} catch (const Archive::Unknown& e) {
|
||||||
qDebug() << "Error requesting file path:" << e.what();
|
qDebug() << "Error requesting file path:" << e.what();
|
||||||
emit fileLocalPathResponse(messageId, "");
|
emit loadFileError(std::list<Shared::MessageInfo>(), QString("Database error: ") + e.what(), false);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QString& url)
|
|
||||||
{
|
|
||||||
std::map<QString, Transfer*>::iterator itr = downloads.find(url);
|
|
||||||
if (itr != downloads.end()) {
|
|
||||||
Transfer* dwn = itr->second;
|
|
||||||
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
|
|
||||||
if (mItr == dwn->messages.end()) {
|
|
||||||
dwn->messages.insert(messageId);
|
|
||||||
}
|
|
||||||
emit downloadFileProgress(messageId, dwn->progress);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
QString path = files.getRecord(url);
|
|
||||||
QFileInfo info(path);
|
|
||||||
if (info.exists() && info.isFile()) {
|
|
||||||
emit fileLocalPathResponse(messageId, path);
|
|
||||||
} else {
|
|
||||||
files.removeRecord(url);
|
|
||||||
startDownload(messageId, url);
|
|
||||||
}
|
|
||||||
} catch (const Archive::NotFound& e) {
|
|
||||||
startDownload(messageId, url);
|
|
||||||
} catch (const Archive::Unknown& e) {
|
|
||||||
qDebug() << "Error requesting file path:" << e.what();
|
|
||||||
emit downloadFileError(messageId, QString("Database error: ") + e.what());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +70,7 @@ void Core::NetworkAccess::start()
|
|||||||
{
|
{
|
||||||
if (!running) {
|
if (!running) {
|
||||||
manager = new QNetworkAccessManager();
|
manager = new QNetworkAccessManager();
|
||||||
files.open();
|
storage.open();
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,7 +78,7 @@ void Core::NetworkAccess::start()
|
|||||||
void Core::NetworkAccess::stop()
|
void Core::NetworkAccess::stop()
|
||||||
{
|
{
|
||||||
if (running) {
|
if (running) {
|
||||||
files.close();
|
storage.close();
|
||||||
manager->deleteLater();
|
manager->deleteLater();
|
||||||
manager = 0;
|
manager = 0;
|
||||||
running = false;
|
running = false;
|
||||||
@ -128,9 +103,7 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT
|
|||||||
qreal total = bytesTotal;
|
qreal total = bytesTotal;
|
||||||
qreal progress = received/total;
|
qreal progress = received/total;
|
||||||
dwn->progress = progress;
|
dwn->progress = progress;
|
||||||
for (std::set<QString>::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) {
|
emit loadFileProgress(dwn->messages, progress, false);
|
||||||
emit downloadFileProgress(*mItr, progress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,9 +119,7 @@ void Core::NetworkAccess::onDownloadError(QNetworkReply::NetworkError code)
|
|||||||
if (errorText.size() > 0) {
|
if (errorText.size() > 0) {
|
||||||
itr->second->success = false;
|
itr->second->success = false;
|
||||||
Transfer* dwn = itr->second;
|
Transfer* dwn = itr->second;
|
||||||
for (std::set<QString>::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) {
|
emit loadFileError(dwn->messages, errorText, false);
|
||||||
emit downloadFileError(*mItr, errorText);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,61 +247,54 @@ QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code)
|
|||||||
|
|
||||||
void Core::NetworkAccess::onDownloadFinished()
|
void Core::NetworkAccess::onDownloadFinished()
|
||||||
{
|
{
|
||||||
QString path("");
|
|
||||||
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
|
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
|
||||||
QString url = rpl->url().toString();
|
QString url = rpl->url().toString();
|
||||||
std::map<QString, Transfer*>::const_iterator itr = downloads.find(url);
|
std::map<QString, Transfer*>::const_iterator itr = downloads.find(url);
|
||||||
if (itr == downloads.end()) {
|
if (itr == downloads.end()) {
|
||||||
qDebug() << "an error downloading" << url << ": the request is done but seems like noone is waiting for it, skipping";
|
qDebug() << "an error downloading" << url << ": the request is done but there is no record of it being downloaded, ignoring";
|
||||||
} else {
|
} else {
|
||||||
Transfer* dwn = itr->second;
|
Transfer* dwn = itr->second;
|
||||||
if (dwn->success) {
|
if (dwn->success) {
|
||||||
qDebug() << "download success for" << url;
|
qDebug() << "download success for" << url;
|
||||||
QStringList hops = url.split("/");
|
QStringList hops = url.split("/");
|
||||||
QString fileName = hops.back();
|
QString fileName = hops.back();
|
||||||
QStringList parts = fileName.split(".");
|
QString jid;
|
||||||
path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/";
|
if (dwn->messages.size() > 0) {
|
||||||
QString suffix("");
|
jid = dwn->messages.front().jid;
|
||||||
QStringList::const_iterator sItr = parts.begin();
|
|
||||||
QString realName = *sItr;
|
|
||||||
++sItr;
|
|
||||||
for (QStringList::const_iterator sEnd = parts.end(); sItr != sEnd; ++sItr) {
|
|
||||||
suffix += "." + (*sItr);
|
|
||||||
}
|
}
|
||||||
QString postfix("");
|
QString path = prepareDirectory(jid);
|
||||||
QFileInfo proposedName(path + realName + postfix + suffix);
|
if (path.size() > 0) {
|
||||||
int counter = 0;
|
path = checkFileName(fileName, path);
|
||||||
while (proposedName.exists()) {
|
|
||||||
postfix = QString("(") + std::to_string(++counter).c_str() + ")";
|
QFile file(path);
|
||||||
proposedName = QFileInfo(path + realName + postfix + suffix);
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
|
file.write(dwn->reply->readAll());
|
||||||
|
file.close();
|
||||||
|
storage.setPath(url, path);
|
||||||
|
qDebug() << "file" << path << "was successfully downloaded";
|
||||||
|
} else {
|
||||||
|
qDebug() << "couldn't save file" << path;
|
||||||
|
path = QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path = proposedName.absoluteFilePath();
|
if (path.size() > 0) {
|
||||||
QFile file(path);
|
emit downloadFileComplete(dwn->messages, path);
|
||||||
if (file.open(QIODevice::WriteOnly)) {
|
|
||||||
file.write(dwn->reply->readAll());
|
|
||||||
file.close();
|
|
||||||
files.addRecord(url, path);
|
|
||||||
qDebug() << "file" << path << "was successfully downloaded";
|
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "couldn't save file" << path;
|
//TODO do I need to handle the failure here or it's already being handled in error?
|
||||||
path = "";
|
//emit loadFileError(dwn->messages, path, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<QString>::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) {
|
|
||||||
emit fileLocalPathResponse(*mItr, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
dwn->reply->deleteLater();
|
dwn->reply->deleteLater();
|
||||||
delete dwn;
|
delete dwn;
|
||||||
downloads.erase(itr);
|
downloads.erase(itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::NetworkAccess::startDownload(const QString& messageId, const QString& url)
|
void Core::NetworkAccess::startDownload(const std::list<Shared::MessageInfo>& msgs, const QString& url)
|
||||||
{
|
{
|
||||||
Transfer* dwn = new Transfer({{messageId}, 0, 0, true, "", url, 0});
|
Transfer* dwn = new Transfer({msgs, 0, 0, true, "", url, 0});
|
||||||
QNetworkRequest req(url);
|
QNetworkRequest req(url);
|
||||||
dwn->reply = manager->get(req);
|
dwn->reply = manager->get(req);
|
||||||
connect(dwn->reply, &QNetworkReply::downloadProgress, this, &NetworkAccess::onDownloadProgress);
|
connect(dwn->reply, &QNetworkReply::downloadProgress, this, &NetworkAccess::onDownloadProgress);
|
||||||
@ -341,7 +305,7 @@ void Core::NetworkAccess::startDownload(const QString& messageId, const QString&
|
|||||||
#endif
|
#endif
|
||||||
connect(dwn->reply, &QNetworkReply::finished, this, &NetworkAccess::onDownloadFinished);
|
connect(dwn->reply, &QNetworkReply::finished, this, &NetworkAccess::onDownloadFinished);
|
||||||
downloads.insert(std::make_pair(url, dwn));
|
downloads.insert(std::make_pair(url, dwn));
|
||||||
emit downloadFileProgress(messageId, 0);
|
emit loadFileProgress(dwn->messages, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code)
|
void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code)
|
||||||
@ -350,16 +314,16 @@ void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code)
|
|||||||
QString url = rpl->url().toString();
|
QString url = rpl->url().toString();
|
||||||
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
|
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
|
||||||
if (itr == uploads.end()) {
|
if (itr == uploads.end()) {
|
||||||
qDebug() << "an error uploading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping";
|
qDebug() << "an error uploading" << url << ": the request is reporting an error but there is no record of it being uploading, ignoring";
|
||||||
} else {
|
} else {
|
||||||
QString errorText = getErrorText(code);
|
QString errorText = getErrorText(code);
|
||||||
if (errorText.size() > 0) {
|
if (errorText.size() > 0) {
|
||||||
itr->second->success = false;
|
itr->second->success = false;
|
||||||
Transfer* upl = itr->second;
|
Transfer* upl = itr->second;
|
||||||
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
|
emit loadFileError(upl->messages, errorText, true);
|
||||||
emit uploadFileError(*mItr, errorText);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO deletion?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,17 +333,14 @@ void Core::NetworkAccess::onUploadFinished()
|
|||||||
QString url = rpl->url().toString();
|
QString url = rpl->url().toString();
|
||||||
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
|
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
|
||||||
if (itr == downloads.end()) {
|
if (itr == downloads.end()) {
|
||||||
qDebug() << "an error uploading" << url << ": the request is done but seems like no one is waiting for it, skipping";
|
qDebug() << "an error uploading" << url << ": the request is done there is no record of it being uploading, ignoring";
|
||||||
} else {
|
} else {
|
||||||
Transfer* upl = itr->second;
|
Transfer* upl = itr->second;
|
||||||
if (upl->success) {
|
if (upl->success) {
|
||||||
qDebug() << "upload success for" << url;
|
qDebug() << "upload success for" << url;
|
||||||
files.addRecord(upl->url, upl->path);
|
|
||||||
|
|
||||||
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
|
storage.addFile(upl->messages, upl->url, upl->path);
|
||||||
emit fileLocalPathResponse(*mItr, upl->path);
|
emit uploadFileComplete(upl->messages, upl->url);
|
||||||
emit uploadFileComplete(*mItr, upl->url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upl->reply->deleteLater();
|
upl->reply->deleteLater();
|
||||||
@ -403,94 +364,29 @@ void Core::NetworkAccess::onUploadProgress(qint64 bytesReceived, qint64 bytesTot
|
|||||||
qreal total = bytesTotal;
|
qreal total = bytesTotal;
|
||||||
qreal progress = received/total;
|
qreal progress = received/total;
|
||||||
upl->progress = progress;
|
upl->progress = progress;
|
||||||
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
|
emit loadFileProgress(upl->messages, progress, true);
|
||||||
emit uploadFileProgress(*mItr, progress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::NetworkAccess::startUpload(const QString& messageId, const QString& url, const QString& path)
|
|
||||||
{
|
|
||||||
Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, url, 0});
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
QFile* file = new QFile(path);
|
|
||||||
if (file->open(QIODevice::ReadOnly)) {
|
|
||||||
upl->reply = manager->put(req, file);
|
|
||||||
|
|
||||||
connect(upl->reply, &QNetworkReply::uploadProgress, this, &NetworkAccess::onUploadProgress);
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
|
||||||
connect(upl->reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred), this, &NetworkAccess::onUploadError);
|
|
||||||
#else
|
|
||||||
connect(upl->reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::error), this, &NetworkAccess::onUploadError);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
connect(upl->reply, &QNetworkReply::finished, this, &NetworkAccess::onUploadFinished);
|
|
||||||
uploads.insert(std::make_pair(url, upl));
|
|
||||||
emit downloadFileProgress(messageId, 0);
|
|
||||||
} else {
|
|
||||||
qDebug() << "couldn't upload file" << path;
|
|
||||||
emit uploadFileError(messageId, "Error opening file");
|
|
||||||
delete file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::NetworkAccess::uploadFileRequest(const QString& messageId, const QString& url, const QString& path)
|
|
||||||
{
|
|
||||||
std::map<QString, Transfer*>::iterator itr = uploads.find(url);
|
|
||||||
if (itr != uploads.end()) {
|
|
||||||
Transfer* upl = itr->second;
|
|
||||||
std::set<QString>::const_iterator mItr = upl->messages.find(messageId);
|
|
||||||
if (mItr == upl->messages.end()) {
|
|
||||||
upl->messages.insert(messageId);
|
|
||||||
}
|
|
||||||
emit uploadFileProgress(messageId, upl->progress);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
QString ePath = files.getRecord(url);
|
|
||||||
if (ePath == path) {
|
|
||||||
QFileInfo info(path);
|
|
||||||
if (info.exists() && info.isFile()) {
|
|
||||||
emit fileLocalPathResponse(messageId, path);
|
|
||||||
} else {
|
|
||||||
files.removeRecord(url);
|
|
||||||
startUpload(messageId, url, path);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QFileInfo info(path);
|
|
||||||
if (info.exists() && info.isFile()) {
|
|
||||||
files.changeRecord(url, path);
|
|
||||||
emit fileLocalPathResponse(messageId, path);
|
|
||||||
} else {
|
|
||||||
files.removeRecord(url);
|
|
||||||
startUpload(messageId, url, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const Archive::NotFound& e) {
|
|
||||||
startUpload(messageId, url, path);
|
|
||||||
} catch (const Archive::Unknown& e) {
|
|
||||||
qDebug() << "Error requesting file path on upload:" << e.what();
|
|
||||||
emit uploadFileError(messageId, QString("Database error: ") + e.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Core::NetworkAccess::getFileRemoteUrl(const QString& path)
|
QString Core::NetworkAccess::getFileRemoteUrl(const QString& path)
|
||||||
{
|
{
|
||||||
return ""; //TODO this is a way not to upload some file more then 1 time, here I'm supposed to return that file GET url
|
QString p;
|
||||||
|
|
||||||
|
try {
|
||||||
|
QString p = storage.getUrl(path);
|
||||||
|
} catch (const Archive::NotFound& err) {
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::NetworkAccess::isUploading(const QString& path, const QString& messageId)
|
void Core::NetworkAccess::uploadFile(const Shared::MessageInfo& info, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers)
|
||||||
{
|
|
||||||
return false; //TODO this is a way to avoid parallel uploading of the same files by different chats
|
|
||||||
// message is is supposed to be added to the uploading messageids list
|
|
||||||
// the result should be true if there was an uploading file with this path
|
|
||||||
// message id can be empty, then it's just to check and not to add
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::NetworkAccess::uploadFile(const QString& messageId, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers)
|
|
||||||
{
|
{
|
||||||
QFile* file = new QFile(path);
|
QFile* file = new QFile(path);
|
||||||
Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, get.toString(), file});
|
Transfer* upl = new Transfer({{info}, 0, 0, true, path, get.toString(), file});
|
||||||
QNetworkRequest req(put);
|
QNetworkRequest req(put);
|
||||||
for (QMap<QString, QString>::const_iterator itr = headers.begin(), end = headers.end(); itr != end; itr++) {
|
for (QMap<QString, QString>::const_iterator itr = headers.begin(), end = headers.end(); itr != end; itr++) {
|
||||||
req.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8());
|
req.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8());
|
||||||
@ -506,10 +402,94 @@ void Core::NetworkAccess::uploadFile(const QString& messageId, const QString& pa
|
|||||||
#endif
|
#endif
|
||||||
connect(upl->reply, &QNetworkReply::finished, this, &NetworkAccess::onUploadFinished);
|
connect(upl->reply, &QNetworkReply::finished, this, &NetworkAccess::onUploadFinished);
|
||||||
uploads.insert(std::make_pair(put.toString(), upl));
|
uploads.insert(std::make_pair(put.toString(), upl));
|
||||||
emit downloadFileProgress(messageId, 0);
|
emit loadFileProgress(upl->messages, 0, true);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "couldn't upload file" << path;
|
qDebug() << "couldn't upload file" << path;
|
||||||
emit uploadFileError(messageId, "Error opening file");
|
emit loadFileError(upl->messages, "Error opening file", true);
|
||||||
delete file;
|
delete file;
|
||||||
|
delete upl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::NetworkAccess::registerFile(const QString& url, const QString& account, const QString& jid, const QString& id)
|
||||||
|
{
|
||||||
|
storage.addFile(url, account, jid, id);
|
||||||
|
std::map<QString, Transfer*>::iterator itr = downloads.find(url);
|
||||||
|
if (itr != downloads.end()) {
|
||||||
|
itr->second->messages.emplace_back(account, jid, id); //TODO notification is going to happen the next tick, is that okay?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::NetworkAccess::registerFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id)
|
||||||
|
{
|
||||||
|
storage.addFile(url, path, account, jid, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Core::NetworkAccess::checkAndAddToUploading(const QString& acc, const QString& jid, const QString id, const QString path)
|
||||||
|
{
|
||||||
|
for (const std::pair<const QString, Transfer*>& pair : uploads) {
|
||||||
|
Transfer* info = pair.second;
|
||||||
|
if (pair.second->path == path) {
|
||||||
|
std::list<Shared::MessageInfo>& messages = info->messages;
|
||||||
|
bool dup = false;
|
||||||
|
for (const Shared::MessageInfo& info : messages) {
|
||||||
|
if (info.account == acc && info.jid == jid && info.messageId == id) {
|
||||||
|
dup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dup) {
|
||||||
|
info->messages.emplace_back(acc, jid, id); //TODO notification is going to happen the next tick, is that okay?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Core::NetworkAccess::prepareDirectory(const QString& jid)
|
||||||
|
{
|
||||||
|
QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
||||||
|
path += "/" + QApplication::applicationName();
|
||||||
|
if (jid.size() > 0) {
|
||||||
|
path += "/" + jid;
|
||||||
|
}
|
||||||
|
QDir location(path);
|
||||||
|
|
||||||
|
if (!location.exists()) {
|
||||||
|
bool res = location.mkpath(path);
|
||||||
|
if (!res) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Core::NetworkAccess::checkFileName(const QString& name, const QString& path)
|
||||||
|
{
|
||||||
|
QStringList parts = name.split(".");
|
||||||
|
QString suffix("");
|
||||||
|
QStringList::const_iterator sItr = parts.begin();
|
||||||
|
QString realName = *sItr;
|
||||||
|
++sItr;
|
||||||
|
for (QStringList::const_iterator sEnd = parts.end(); sItr != sEnd; ++sItr) {
|
||||||
|
suffix += "." + (*sItr);
|
||||||
|
}
|
||||||
|
QString postfix("");
|
||||||
|
QFileInfo proposedName(path + realName + suffix);
|
||||||
|
int counter = 0;
|
||||||
|
while (proposedName.exists()) {
|
||||||
|
QString count = QString("(") + std::to_string(++counter).c_str() + ")";
|
||||||
|
proposedName = QFileInfo(path + realName + count + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return proposedName.absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Core::NetworkAccess::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id)
|
||||||
|
{
|
||||||
|
return storage.addMessageAndCheckForPath(url, account, jid, id);
|
||||||
|
}
|
||||||
|
@ -36,6 +36,8 @@ namespace Core {
|
|||||||
/**
|
/**
|
||||||
* @todo write docs
|
* @todo write docs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//TODO Need to describe how to get rid of records when file is no longer reachable;
|
||||||
class NetworkAccess : public QObject
|
class NetworkAccess : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -48,26 +50,26 @@ public:
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
QString getFileRemoteUrl(const QString& path);
|
QString getFileRemoteUrl(const QString& path);
|
||||||
bool isUploading(const QString& path, const QString& messageId = "");
|
QString addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id);
|
||||||
void uploadFile(const QString& messageId, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers);
|
void uploadFile(const Shared::MessageInfo& info, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers);
|
||||||
|
bool checkAndAddToUploading(const QString& acc, const QString& jid, const QString id, const QString path);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fileLocalPathResponse(const QString& messageId, const QString& path);
|
void loadFileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);
|
||||||
void downloadFileProgress(const QString& messageId, qreal value);
|
void loadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& text, bool up);
|
||||||
void downloadFileError(const QString& messageId, const QString& path);
|
void uploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& url);
|
||||||
void uploadFileProgress(const QString& messageId, qreal value);
|
void downloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
|
||||||
void uploadFileError(const QString& messageId, const QString& path);
|
|
||||||
void uploadFileComplete(const QString& messageId, const QString& url);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
void downladFile(const QString& url);
|
||||||
void downladFileRequest(const QString& messageId, const QString& url);
|
void registerFile(const QString& url, const QString& account, const QString& jid, const QString& id);
|
||||||
void uploadFileRequest(const QString& messageId, const QString& url, const QString& path);
|
void registerFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startDownload(const QString& messageId, const QString& url);
|
void startDownload(const std::list<Shared::MessageInfo>& msgs, const QString& url);
|
||||||
void startUpload(const QString& messageId, const QString& url, const QString& path);
|
|
||||||
QString getErrorText(QNetworkReply::NetworkError code);
|
QString getErrorText(QNetworkReply::NetworkError code);
|
||||||
|
QString prepareDirectory(const QString& jid);
|
||||||
|
QString checkFileName(const QString& name, const QString& path);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||||
@ -85,7 +87,7 @@ private:
|
|||||||
std::map<QString, Transfer*> uploads;
|
std::map<QString, Transfer*> uploads;
|
||||||
|
|
||||||
struct Transfer {
|
struct Transfer {
|
||||||
std::set<QString> messages;
|
std::list<Shared::MessageInfo> messages;
|
||||||
qreal progress;
|
qreal progress;
|
||||||
QNetworkReply* reply;
|
QNetworkReply* reply;
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -32,11 +32,10 @@ Core::Squawk::Squawk(QObject* parent):
|
|||||||
,kwallet()
|
,kwallet()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
connect(&network, &NetworkAccess::fileLocalPathResponse, this, &Squawk::onNetworkAccessfileLocalPathResponse);
|
connect(&network, &NetworkAccess::loadFileProgress, this, &Squawk::fileProgress);
|
||||||
connect(&network, &NetworkAccess::downloadFileProgress, this, &Squawk::downloadFileProgress);
|
connect(&network, &NetworkAccess::loadFileError, this, &Squawk::fileError);
|
||||||
connect(&network, &NetworkAccess::downloadFileError, this, &Squawk::downloadFileError);
|
connect(&network, &NetworkAccess::downloadFileComplete, this, &Squawk::fileDownloadComplete);
|
||||||
connect(&network, &NetworkAccess::uploadFileProgress, this, &Squawk::uploadFileProgress);
|
connect(&network, &NetworkAccess::uploadFileComplete, this, &Squawk::fileUploadComplete);
|
||||||
connect(&network, &NetworkAccess::uploadFileError, this, &Squawk::uploadFileError);
|
|
||||||
|
|
||||||
#ifdef WITH_KWALLET
|
#ifdef WITH_KWALLET
|
||||||
if (kwallet.supportState() == PSE::KWallet::success) {
|
if (kwallet.supportState() == PSE::KWallet::success) {
|
||||||
@ -168,7 +167,7 @@ void Core::Squawk::addAccount(
|
|||||||
|
|
||||||
connect(acc, &Account::receivedVCard, this, &Squawk::responseVCard);
|
connect(acc, &Account::receivedVCard, this, &Squawk::responseVCard);
|
||||||
|
|
||||||
connect(acc, &Account::uploadFileError, this, &Squawk::uploadFileError);
|
connect(acc, &Account::uploadFileError, this, &Squawk::onAccountUploadFileError);
|
||||||
|
|
||||||
QMap<QString, QVariant> map = {
|
QMap<QString, QVariant> map = {
|
||||||
{"login", login},
|
{"login", login},
|
||||||
@ -593,14 +592,9 @@ void Core::Squawk::addRoomRequest(const QString& account, const QString& jid, co
|
|||||||
itr->second->addRoomRequest(jid, nick, password, autoJoin);
|
itr->second->addRoomRequest(jid, nick, password, autoJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Squawk::fileLocalPathRequest(const QString& messageId, const QString& url)
|
void Core::Squawk::fileDownloadRequest(const QString& url)
|
||||||
{
|
{
|
||||||
network.fileLocalPathRequest(messageId, url);
|
network.downladFile(url);
|
||||||
}
|
|
||||||
|
|
||||||
void Core::Squawk::downloadFileRequest(const QString& messageId, const QString& url)
|
|
||||||
{
|
|
||||||
network.downladFileRequest(messageId, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName)
|
void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName)
|
||||||
@ -752,7 +746,8 @@ void Core::Squawk::onWalletResponsePassword(const QString& login, const QString&
|
|||||||
accountReady();
|
accountReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Squawk::onNetworkAccessfileLocalPathResponse(const QString& messageId, const QString& path)
|
void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText)
|
||||||
{
|
{
|
||||||
|
Account* acc = static_cast<Account*>(sender());
|
||||||
|
emit fileError({{acc->getName(), jid, id}}, errorText, true);
|
||||||
}
|
}
|
||||||
|
@ -51,30 +51,39 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void quit();
|
void quit();
|
||||||
void ready();
|
void ready();
|
||||||
|
|
||||||
void newAccount(const QMap<QString, QVariant>&);
|
void newAccount(const QMap<QString, QVariant>&);
|
||||||
void changeAccount(const QString& account, const QMap<QString, QVariant>& data);
|
void changeAccount(const QString& account, const QMap<QString, QVariant>& data);
|
||||||
void removeAccount(const QString& account);
|
void removeAccount(const QString& account);
|
||||||
|
|
||||||
void addGroup(const QString& account, const QString& name);
|
void addGroup(const QString& account, const QString& name);
|
||||||
void removeGroup(const QString& account, const QString& name);
|
void removeGroup(const QString& account, const QString& name);
|
||||||
|
|
||||||
void addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data);
|
void addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data);
|
||||||
void removeContact(const QString& account, const QString& jid);
|
void removeContact(const QString& account, const QString& jid);
|
||||||
void removeContact(const QString& account, const QString& jid, const QString& group);
|
void removeContact(const QString& account, const QString& jid, const QString& group);
|
||||||
void changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data);
|
void changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data);
|
||||||
|
|
||||||
void addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removePresence(const QString& account, const QString& jid, const QString& name);
|
void removePresence(const QString& account, const QString& jid, const QString& name);
|
||||||
|
|
||||||
void stateChanged(Shared::Availability state);
|
void stateChanged(Shared::Availability state);
|
||||||
|
|
||||||
void accountMessage(const QString& account, const Shared::Message& data);
|
void accountMessage(const QString& account, const Shared::Message& data);
|
||||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
||||||
|
|
||||||
void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
||||||
void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
||||||
void removeRoom(const QString& account, const QString jid);
|
void removeRoom(const QString& account, const QString jid);
|
||||||
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
||||||
void downloadFileError(const QString& messageId, const QString& error);
|
|
||||||
void downloadFileProgress(const QString& messageId, qreal value);
|
void fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up);
|
||||||
void uploadFileError(const QString& messageId, const QString& error);
|
void fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up);
|
||||||
void uploadFileProgress(const QString& messageId, qreal value);
|
void fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
|
||||||
|
void fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
|
||||||
|
|
||||||
void responseVCard(const QString& jid, const Shared::VCard& card);
|
void responseVCard(const QString& jid, const Shared::VCard& card);
|
||||||
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
||||||
void requestPassword(const QString& account);
|
void requestPassword(const QString& account);
|
||||||
@ -82,14 +91,18 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void newAccountRequest(const QMap<QString, QVariant>& map);
|
void newAccountRequest(const QMap<QString, QVariant>& map);
|
||||||
void modifyAccountRequest(const QString& name, const QMap<QString, QVariant>& map);
|
void modifyAccountRequest(const QString& name, const QMap<QString, QVariant>& map);
|
||||||
void removeAccountRequest(const QString& name);
|
void removeAccountRequest(const QString& name);
|
||||||
void connectAccount(const QString& account);
|
void connectAccount(const QString& account);
|
||||||
void disconnectAccount(const QString& account);
|
void disconnectAccount(const QString& account);
|
||||||
|
|
||||||
void changeState(Shared::Availability state);
|
void changeState(Shared::Availability state);
|
||||||
|
|
||||||
void sendMessage(const QString& account, const Shared::Message& data);
|
void sendMessage(const QString& account, const Shared::Message& data);
|
||||||
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
||||||
|
|
||||||
void subscribeContact(const QString& account, const QString& jid, const QString& reason);
|
void subscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
void addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
void addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
||||||
@ -97,12 +110,14 @@ public slots:
|
|||||||
void removeContactRequest(const QString& account, const QString& jid);
|
void removeContactRequest(const QString& account, const QString& jid);
|
||||||
void renameContactRequest(const QString& account, const QString& jid, const QString& newName);
|
void renameContactRequest(const QString& account, const QString& jid, const QString& newName);
|
||||||
void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet<QString>& groups);
|
void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet<QString>& groups);
|
||||||
|
|
||||||
void setRoomJoined(const QString& account, const QString& jid, bool joined);
|
void setRoomJoined(const QString& account, const QString& jid, bool joined);
|
||||||
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
|
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
|
||||||
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
|
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
|
||||||
void removeRoomRequest(const QString& account, const QString& jid);
|
void removeRoomRequest(const QString& account, const QString& jid);
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
|
||||||
void downloadFileRequest(const QString& messageId, const QString& url);
|
void fileDownloadRequest(const QString& url);
|
||||||
|
|
||||||
void requestVCard(const QString& account, const QString& jid);
|
void requestVCard(const QString& account, const QString& jid);
|
||||||
void uploadVCard(const QString& account, const Shared::VCard& card);
|
void uploadVCard(const QString& account, const Shared::VCard& card);
|
||||||
void responsePassword(const QString& account, const QString& password);
|
void responsePassword(const QString& account, const QString& password);
|
||||||
@ -153,12 +168,12 @@ private slots:
|
|||||||
void onAccountRemoveRoomPresence(const QString& jid, const QString& nick);
|
void onAccountRemoveRoomPresence(const QString& jid, const QString& nick);
|
||||||
void onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
void onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
||||||
|
|
||||||
|
void onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText);
|
||||||
|
|
||||||
void onWalletOpened(bool success);
|
void onWalletOpened(bool success);
|
||||||
void onWalletResponsePassword(const QString& login, const QString& password);
|
void onWalletResponsePassword(const QString& login, const QString& password);
|
||||||
void onWalletRejectPassword(const QString& login);
|
void onWalletRejectPassword(const QString& login);
|
||||||
|
|
||||||
void onNetworkAccessfileLocalPathResponse(const QString& messageId, const QString& path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readSettings();
|
void readSettings();
|
||||||
void accountReady();
|
void accountReady();
|
||||||
|
@ -165,8 +165,7 @@ void Core::UrlStorage::addFile(const QString& url)
|
|||||||
throw Archive::Closed("addFile(no message, no path)", name.toStdString());
|
throw Archive::Closed("addFile(no message, no path)", name.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlInfo info;
|
addToInfo(url, "", "", "");
|
||||||
writeInfo(url, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::UrlStorage::addFile(const QString& url, const QString& path)
|
void Core::UrlStorage::addFile(const QString& url, const QString& path)
|
||||||
@ -175,8 +174,7 @@ void Core::UrlStorage::addFile(const QString& url, const QString& path)
|
|||||||
throw Archive::Closed("addFile(no message, with path)", name.toStdString());
|
throw Archive::Closed("addFile(no message, with path)", name.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlInfo info(path);
|
addToInfo(url, "", "", "", path);
|
||||||
writeInfo(url, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::UrlStorage::addFile(const QString& url, const QString& account, const QString& jid, const QString& id)
|
void Core::UrlStorage::addFile(const QString& url, const QString& account, const QString& jid, const QString& id)
|
||||||
@ -185,9 +183,7 @@ void Core::UrlStorage::addFile(const QString& url, const QString& account, const
|
|||||||
throw Archive::Closed("addFile(with message, no path)", name.toStdString());
|
throw Archive::Closed("addFile(with message, no path)", name.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlInfo info;
|
addToInfo(url, account, jid, id);
|
||||||
info.addMessage(account, jid, id);
|
|
||||||
writeInfo(url, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::UrlStorage::addFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id)
|
void Core::UrlStorage::addFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id)
|
||||||
@ -196,50 +192,74 @@ void Core::UrlStorage::addFile(const QString& url, const QString& path, const QS
|
|||||||
throw Archive::Closed("addFile(with message, with path)", name.toStdString());
|
throw Archive::Closed("addFile(with message, with path)", name.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlInfo info(path);
|
addToInfo(url, account, jid, id, path);
|
||||||
info.addMessage(account, jid, id);
|
}
|
||||||
writeInfo(url, info);
|
|
||||||
|
void Core::UrlStorage::addFile(const std::list<Shared::MessageInfo>& msgs, const QString& url, const QString& path)
|
||||||
|
{
|
||||||
|
if (!opened) {
|
||||||
|
throw Archive::Closed("addFile(with list)", name.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
UrlInfo info (path, msgs);
|
||||||
|
writeInfo(url, info, true);;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Core::UrlStorage::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id)
|
QString Core::UrlStorage::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id)
|
||||||
{
|
{
|
||||||
QString path;
|
if (!opened) {
|
||||||
|
throw Archive::Closed("addMessageAndCheckForPath", name.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return addToInfo(url, account, jid, id).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::UrlStorage::UrlInfo Core::UrlStorage::addToInfo(const QString& url, const QString& account, const QString& jid, const QString& id, const QString& path)
|
||||||
|
{
|
||||||
|
UrlInfo info;
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(environment, NULL, 0, &txn);
|
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||||
UrlInfo info;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
readInfo(url, info, txn);
|
readInfo(url, info, txn);
|
||||||
path = info.getPath();
|
|
||||||
info.addMessage(account, jid, id);
|
|
||||||
try {
|
|
||||||
writeInfo(url, info, txn, true);
|
|
||||||
mdb_txn_commit(txn);
|
|
||||||
} catch (...) {
|
|
||||||
mdb_txn_abort(txn);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
} catch (const Archive::NotFound& e) {
|
} catch (const Archive::NotFound& e) {
|
||||||
info.addMessage(account, jid, id);
|
|
||||||
try {
|
|
||||||
writeInfo(url, info, txn, true);
|
|
||||||
mdb_txn_commit(txn);
|
|
||||||
} catch (...) {
|
|
||||||
mdb_txn_abort(txn);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
bool pathChange = false;
|
||||||
|
bool listChange = false;
|
||||||
|
if (path != "-s") {
|
||||||
|
if (info.getPath() != path) {
|
||||||
|
info.setPath(path);
|
||||||
|
pathChange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.size() > 0 && jid.size() > 0 && id.size() > 0) {
|
||||||
|
listChange = info.addMessage(account, jid, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathChange || listChange) {
|
||||||
|
try {
|
||||||
|
writeInfo(url, info, txn, true);
|
||||||
|
mdb_txn_commit(txn);
|
||||||
|
} catch (...) {
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::setPath(const QString& url, const QString& path)
|
std::list<Shared::MessageInfo> Core::UrlStorage::setPath(const QString& url, const QString& path)
|
||||||
{
|
{
|
||||||
std::list<MessageInfo> list;
|
std::list<Shared::MessageInfo> list;
|
||||||
|
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(environment, NULL, 0, &txn);
|
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||||
@ -247,24 +267,17 @@ std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::setPath(const QString
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
readInfo(url, info, txn);
|
readInfo(url, info, txn);
|
||||||
info.setPath(path);
|
|
||||||
info.getMessages(list);
|
info.getMessages(list);
|
||||||
try {
|
|
||||||
writeInfo(url, info, txn, true);
|
|
||||||
mdb_txn_commit(txn);
|
|
||||||
} catch (...) {
|
|
||||||
mdb_txn_abort(txn);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
} catch (const Archive::NotFound& e) {
|
} catch (const Archive::NotFound& e) {
|
||||||
info.setPath(path);
|
} catch (...) {
|
||||||
try {
|
mdb_txn_abort(txn);
|
||||||
writeInfo(url, info, txn, true);
|
throw;
|
||||||
mdb_txn_commit(txn);
|
}
|
||||||
} catch (...) {
|
|
||||||
mdb_txn_abort(txn);
|
info.setPath(path);
|
||||||
throw;
|
try {
|
||||||
}
|
writeInfo(url, info, txn, true);
|
||||||
|
mdb_txn_commit(txn);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
throw;
|
throw;
|
||||||
@ -273,9 +286,9 @@ std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::setPath(const QString
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::removeFile(const QString& url)
|
std::list<Shared::MessageInfo> Core::UrlStorage::removeFile(const QString& url)
|
||||||
{
|
{
|
||||||
std::list<MessageInfo> list;
|
std::list<Shared::MessageInfo> list;
|
||||||
|
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(environment, NULL, 0, &txn);
|
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||||
@ -313,9 +326,9 @@ std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::removeFile(const QStr
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::deletedFile(const QString& path)
|
std::list<Shared::MessageInfo> Core::UrlStorage::deletedFile(const QString& path)
|
||||||
{
|
{
|
||||||
std::list<MessageInfo> list;
|
std::list<Shared::MessageInfo> list;
|
||||||
|
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(environment, NULL, 0, &txn);
|
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||||
@ -362,6 +375,46 @@ std::list<Core::UrlStorage::MessageInfo> Core::UrlStorage::deletedFile(const QSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString Core::UrlStorage::getUrl(const QString& path)
|
||||||
|
{
|
||||||
|
std::list<Shared::MessageInfo> list;
|
||||||
|
|
||||||
|
MDB_txn *txn;
|
||||||
|
mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
|
||||||
|
|
||||||
|
std::string spath = path.toStdString();
|
||||||
|
|
||||||
|
MDB_val lmdbKey, lmdbData;
|
||||||
|
lmdbKey.mv_size = spath.size();
|
||||||
|
lmdbKey.mv_data = (char*)spath.c_str();
|
||||||
|
|
||||||
|
QString url;
|
||||||
|
int rc = mdb_get(txn, map, &lmdbKey, &lmdbData);
|
||||||
|
|
||||||
|
if (rc == 0) {
|
||||||
|
std::string surl((char*)lmdbData.mv_data, lmdbData.mv_size);
|
||||||
|
url = QString(surl.c_str());
|
||||||
|
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
return url;
|
||||||
|
} else if (rc == MDB_NOTFOUND) {
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
throw Archive::NotFound(spath, name.toStdString());
|
||||||
|
} else {
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QString, std::list<Shared::MessageInfo>> Core::UrlStorage::getPath(const QString& url)
|
||||||
|
{
|
||||||
|
UrlInfo info;
|
||||||
|
readInfo(url, info);
|
||||||
|
std::list<Shared::MessageInfo> container;
|
||||||
|
info.getMessages(container);
|
||||||
|
return std::make_pair(info.getPath(), container);
|
||||||
|
}
|
||||||
|
|
||||||
Core::UrlStorage::UrlInfo::UrlInfo():
|
Core::UrlStorage::UrlInfo::UrlInfo():
|
||||||
localPath(),
|
localPath(),
|
||||||
messages() {}
|
messages() {}
|
||||||
@ -370,19 +423,29 @@ Core::UrlStorage::UrlInfo::UrlInfo(const QString& path):
|
|||||||
localPath(path),
|
localPath(path),
|
||||||
messages() {}
|
messages() {}
|
||||||
|
|
||||||
|
Core::UrlStorage::UrlInfo::UrlInfo(const QString& path, const std::list<Shared::MessageInfo>& msgs):
|
||||||
|
localPath(path),
|
||||||
|
messages(msgs) {}
|
||||||
|
|
||||||
Core::UrlStorage::UrlInfo::~UrlInfo() {}
|
Core::UrlStorage::UrlInfo::~UrlInfo() {}
|
||||||
|
|
||||||
void Core::UrlStorage::UrlInfo::addMessage(const QString& acc, const QString& jid, const QString& id)
|
bool Core::UrlStorage::UrlInfo::addMessage(const QString& acc, const QString& jid, const QString& id)
|
||||||
{
|
{
|
||||||
|
for (const Shared::MessageInfo& info : messages) {
|
||||||
|
if (info.account == acc && info.jid == jid && info.messageId == id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
messages.emplace_back(acc, jid, id);
|
messages.emplace_back(acc, jid, id);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::UrlStorage::UrlInfo::serialize(QDataStream& data) const
|
void Core::UrlStorage::UrlInfo::serialize(QDataStream& data) const
|
||||||
{
|
{
|
||||||
data << localPath;
|
data << localPath;
|
||||||
std::list<MessageInfo>::size_type size = messages.size();
|
std::list<Shared::MessageInfo>::size_type size = messages.size();
|
||||||
data << quint32(size);
|
data << quint32(size);
|
||||||
for (const MessageInfo& info : messages) {
|
for (const Shared::MessageInfo& info : messages) {
|
||||||
data << info.account;
|
data << info.account;
|
||||||
data << info.jid;
|
data << info.jid;
|
||||||
data << info.messageId;
|
data << info.messageId;
|
||||||
@ -396,16 +459,18 @@ void Core::UrlStorage::UrlInfo::deserialize(QDataStream& data)
|
|||||||
data >> size;
|
data >> size;
|
||||||
for (quint32 i = 0; i < size; ++i) {
|
for (quint32 i = 0; i < size; ++i) {
|
||||||
messages.emplace_back();
|
messages.emplace_back();
|
||||||
MessageInfo& info = messages.back();
|
Shared::MessageInfo& info = messages.back();
|
||||||
data >> info.account;
|
data >> info.account;
|
||||||
data >> info.jid;
|
data >> info.jid;
|
||||||
data >> info.messageId;
|
data >> info.messageId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::UrlStorage::UrlInfo::getMessages(std::list<MessageInfo>& container) const
|
void Core::UrlStorage::UrlInfo::getMessages(std::list<Shared::MessageInfo>& container) const
|
||||||
{
|
{
|
||||||
std::copy(messages.begin(), messages.end(), container.end());
|
for (const Shared::MessageInfo& info : messages) {
|
||||||
|
container.emplace_back(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Core::UrlStorage::UrlInfo::getPath() const
|
QString Core::UrlStorage::UrlInfo::getPath() const
|
||||||
@ -423,13 +488,3 @@ void Core::UrlStorage::UrlInfo::setPath(const QString& path)
|
|||||||
{
|
{
|
||||||
localPath = path;
|
localPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::UrlStorage::MessageInfo::MessageInfo():
|
|
||||||
account(),
|
|
||||||
jid(),
|
|
||||||
messageId() {}
|
|
||||||
|
|
||||||
Core::UrlStorage::MessageInfo::MessageInfo(const QString& acc, const QString& j, const QString& id):
|
|
||||||
account(acc),
|
|
||||||
jid(j),
|
|
||||||
messageId(id) {}
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
|
#include <shared/messageinfo.h>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
@ -35,15 +36,6 @@ class UrlStorage
|
|||||||
{
|
{
|
||||||
class UrlInfo;
|
class UrlInfo;
|
||||||
public:
|
public:
|
||||||
struct MessageInfo {
|
|
||||||
MessageInfo();
|
|
||||||
MessageInfo(const QString& acc, const QString& j, const QString& id);
|
|
||||||
|
|
||||||
QString account;
|
|
||||||
QString jid;
|
|
||||||
QString messageId;
|
|
||||||
};
|
|
||||||
|
|
||||||
UrlStorage(const QString& name);
|
UrlStorage(const QString& name);
|
||||||
~UrlStorage();
|
~UrlStorage();
|
||||||
|
|
||||||
@ -54,10 +46,13 @@ public:
|
|||||||
void addFile(const QString& url, const QString& path);
|
void addFile(const QString& url, const QString& path);
|
||||||
void addFile(const QString& url, const QString& account, const QString& jid, const QString& id);
|
void addFile(const QString& url, const QString& account, const QString& jid, const QString& id);
|
||||||
void addFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id);
|
void addFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id);
|
||||||
std::list<MessageInfo> removeFile(const QString& url); //removes entry like it never was in the database, returns affected message infos
|
void addFile(const std::list<Shared::MessageInfo>& msgs, const QString& url, const QString& path); //this one overwrites all that was
|
||||||
std::list<MessageInfo> deletedFile(const QString& path); //empties the localPath of the entry, returns affected message infos
|
std::list<Shared::MessageInfo> removeFile(const QString& url); //removes entry like it never was in the database, returns affected message infos
|
||||||
std::list<MessageInfo> setPath(const QString& url, const QString& path);
|
std::list<Shared::MessageInfo> deletedFile(const QString& path); //empties the localPath of the entry, returns affected message infos
|
||||||
|
std::list<Shared::MessageInfo> setPath(const QString& url, const QString& path);
|
||||||
|
QString getUrl(const QString& path);
|
||||||
QString addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id);
|
QString addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id);
|
||||||
|
std::pair<QString, std::list<Shared::MessageInfo>> getPath(const QString& url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
@ -71,11 +66,13 @@ private:
|
|||||||
void writeInfo(const QString& key, const UrlInfo& info, MDB_txn* txn, bool overwrite = false);
|
void writeInfo(const QString& key, const UrlInfo& info, MDB_txn* txn, bool overwrite = false);
|
||||||
void readInfo(const QString& key, UrlInfo& info);
|
void readInfo(const QString& key, UrlInfo& info);
|
||||||
void readInfo(const QString& key, UrlInfo& info, MDB_txn* txn);
|
void readInfo(const QString& key, UrlInfo& info, MDB_txn* txn);
|
||||||
|
UrlInfo addToInfo(const QString& url, const QString& account, const QString& jid, const QString& id, const QString& path = "-s");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class UrlInfo {
|
class UrlInfo {
|
||||||
public:
|
public:
|
||||||
UrlInfo(const QString& path);
|
UrlInfo(const QString& path);
|
||||||
|
UrlInfo(const QString& path, const std::list<Shared::MessageInfo>& msgs);
|
||||||
UrlInfo();
|
UrlInfo();
|
||||||
~UrlInfo();
|
~UrlInfo();
|
||||||
|
|
||||||
@ -86,12 +83,12 @@ private:
|
|||||||
bool hasPath() const;
|
bool hasPath() const;
|
||||||
void setPath(const QString& path);
|
void setPath(const QString& path);
|
||||||
|
|
||||||
void addMessage(const QString& acc, const QString& jid, const QString& id);
|
bool addMessage(const QString& acc, const QString& jid, const QString& id);
|
||||||
void getMessages(std::list<MessageInfo>& container) const;
|
void getMessages(std::list<Shared::MessageInfo>& container) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString localPath;
|
QString localPath;
|
||||||
std::list<MessageInfo> messages;
|
std::list<Shared::MessageInfo> messages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
15
main.cpp
15
main.cpp
@ -20,6 +20,7 @@
|
|||||||
#include "core/squawk.h"
|
#include "core/squawk.h"
|
||||||
#include "signalcatcher.h"
|
#include "signalcatcher.h"
|
||||||
#include "shared/global.h"
|
#include "shared/global.h"
|
||||||
|
#include "shared/messageinfo.h"
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
@ -31,8 +32,10 @@
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
qRegisterMetaType<Shared::Message>("Shared::Message");
|
qRegisterMetaType<Shared::Message>("Shared::Message");
|
||||||
|
qRegisterMetaType<Shared::MessageInfo>("Shared::MessageInfo");
|
||||||
qRegisterMetaType<Shared::VCard>("Shared::VCard");
|
qRegisterMetaType<Shared::VCard>("Shared::VCard");
|
||||||
qRegisterMetaType<std::list<Shared::Message>>("std::list<Shared::Message>");
|
qRegisterMetaType<std::list<Shared::Message>>("std::list<Shared::Message>");
|
||||||
|
qRegisterMetaType<std::list<Shared::MessageInfo>>("std::list<Shared::MessageInfo>");
|
||||||
qRegisterMetaType<QSet<QString>>("QSet<QString>");
|
qRegisterMetaType<QSet<QString>>("QSet<QString>");
|
||||||
qRegisterMetaType<Shared::ConnectionState>("Shared::ConnectionState");
|
qRegisterMetaType<Shared::ConnectionState>("Shared::ConnectionState");
|
||||||
qRegisterMetaType<Shared::Availability>("Shared::Availability");
|
qRegisterMetaType<Shared::Availability>("Shared::Availability");
|
||||||
@ -106,8 +109,7 @@ int main(int argc, char *argv[])
|
|||||||
QObject::connect(&w, &Squawk::setRoomAutoJoin, squawk, &Core::Squawk::setRoomAutoJoin);
|
QObject::connect(&w, &Squawk::setRoomAutoJoin, squawk, &Core::Squawk::setRoomAutoJoin);
|
||||||
QObject::connect(&w, &Squawk::removeRoomRequest, squawk, &Core::Squawk::removeRoomRequest);
|
QObject::connect(&w, &Squawk::removeRoomRequest, squawk, &Core::Squawk::removeRoomRequest);
|
||||||
QObject::connect(&w, &Squawk::addRoomRequest, squawk, &Core::Squawk::addRoomRequest);
|
QObject::connect(&w, &Squawk::addRoomRequest, squawk, &Core::Squawk::addRoomRequest);
|
||||||
QObject::connect(&w, &Squawk::fileLocalPathRequest, squawk, &Core::Squawk::fileLocalPathRequest);
|
QObject::connect(&w, &Squawk::fileDownloadRequest, squawk, &Core::Squawk::fileDownloadRequest);
|
||||||
QObject::connect(&w, &Squawk::downloadFileRequest, squawk, &Core::Squawk::downloadFileRequest);
|
|
||||||
QObject::connect(&w, &Squawk::addContactToGroupRequest, squawk, &Core::Squawk::addContactToGroupRequest);
|
QObject::connect(&w, &Squawk::addContactToGroupRequest, squawk, &Core::Squawk::addContactToGroupRequest);
|
||||||
QObject::connect(&w, &Squawk::removeContactFromGroupRequest, squawk, &Core::Squawk::removeContactFromGroupRequest);
|
QObject::connect(&w, &Squawk::removeContactFromGroupRequest, squawk, &Core::Squawk::removeContactFromGroupRequest);
|
||||||
QObject::connect(&w, &Squawk::renameContactRequest, squawk, &Core::Squawk::renameContactRequest);
|
QObject::connect(&w, &Squawk::renameContactRequest, squawk, &Core::Squawk::renameContactRequest);
|
||||||
@ -138,11 +140,10 @@ int main(int argc, char *argv[])
|
|||||||
QObject::connect(squawk, &Core::Squawk::addRoomParticipant, &w, &Squawk::addRoomParticipant);
|
QObject::connect(squawk, &Core::Squawk::addRoomParticipant, &w, &Squawk::addRoomParticipant);
|
||||||
QObject::connect(squawk, &Core::Squawk::changeRoomParticipant, &w, &Squawk::changeRoomParticipant);
|
QObject::connect(squawk, &Core::Squawk::changeRoomParticipant, &w, &Squawk::changeRoomParticipant);
|
||||||
QObject::connect(squawk, &Core::Squawk::removeRoomParticipant, &w, &Squawk::removeRoomParticipant);
|
QObject::connect(squawk, &Core::Squawk::removeRoomParticipant, &w, &Squawk::removeRoomParticipant);
|
||||||
QObject::connect(squawk, &Core::Squawk::fileLocalPathResponse, &w, &Squawk::fileLocalPathResponse);
|
QObject::connect(squawk, &Core::Squawk::fileDownloadComplete, &w, &Squawk::fileDownloadComplete);
|
||||||
QObject::connect(squawk, &Core::Squawk::downloadFileProgress, &w, &Squawk::fileProgress);
|
QObject::connect(squawk, &Core::Squawk::fileUploadComplete, &w, &Squawk::fileUploadComplete);
|
||||||
QObject::connect(squawk, &Core::Squawk::downloadFileError, &w, &Squawk::fileError);
|
QObject::connect(squawk, &Core::Squawk::fileProgress, &w, &Squawk::fileProgress);
|
||||||
QObject::connect(squawk, &Core::Squawk::uploadFileProgress, &w, &Squawk::fileProgress);
|
QObject::connect(squawk, &Core::Squawk::fileError, &w, &Squawk::fileError);
|
||||||
QObject::connect(squawk, &Core::Squawk::uploadFileError, &w, &Squawk::fileError);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard);
|
QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard);
|
||||||
QObject::connect(squawk, &Core::Squawk::requestPassword, &w, &Squawk::requestPassword);
|
QObject::connect(squawk, &Core::Squawk::requestPassword, &w, &Squawk::requestPassword);
|
||||||
QObject::connect(squawk, &Core::Squawk::ready, &w, &Squawk::readSettings);
|
QObject::connect(squawk, &Core::Squawk::ready, &w, &Squawk::readSettings);
|
||||||
|
1
shared.h
1
shared.h
@ -25,5 +25,6 @@
|
|||||||
#include "shared/message.h"
|
#include "shared/message.h"
|
||||||
#include "shared/vcard.h"
|
#include "shared/vcard.h"
|
||||||
#include "shared/global.h"
|
#include "shared/global.h"
|
||||||
|
#include "shared/messageinfo.h"
|
||||||
|
|
||||||
#endif // SHARED_H
|
#endif // SHARED_H
|
||||||
|
45
shared/messageinfo.cpp
Normal file
45
shared/messageinfo.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Squawk messenger.
|
||||||
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
*
|
||||||
|
* 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 "messageinfo.h"
|
||||||
|
|
||||||
|
using namespace Shared;
|
||||||
|
|
||||||
|
Shared::MessageInfo::MessageInfo():
|
||||||
|
account(),
|
||||||
|
jid(),
|
||||||
|
messageId() {}
|
||||||
|
|
||||||
|
Shared::MessageInfo::MessageInfo(const QString& acc, const QString& j, const QString& id):
|
||||||
|
account(acc),
|
||||||
|
jid(j),
|
||||||
|
messageId(id) {}
|
||||||
|
|
||||||
|
Shared::MessageInfo::MessageInfo(const Shared::MessageInfo& other):
|
||||||
|
account(other.account),
|
||||||
|
jid(other.jid),
|
||||||
|
messageId(other.messageId) {}
|
||||||
|
|
||||||
|
Shared::MessageInfo & Shared::MessageInfo::operator=(const Shared::MessageInfo& other)
|
||||||
|
{
|
||||||
|
account = other.account;
|
||||||
|
jid = other.jid;
|
||||||
|
messageId = other.messageId;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
43
shared/messageinfo.h
Normal file
43
shared/messageinfo.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Squawk messenger.
|
||||||
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
*
|
||||||
|
* 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 SHARED_MESSAGEINFO_H
|
||||||
|
#define SHARED_MESSAGEINFO_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Shared {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo write docs
|
||||||
|
*/
|
||||||
|
struct MessageInfo {
|
||||||
|
MessageInfo();
|
||||||
|
MessageInfo(const QString& acc, const QString& j, const QString& id);
|
||||||
|
MessageInfo(const MessageInfo& other);
|
||||||
|
|
||||||
|
QString account;
|
||||||
|
QString jid;
|
||||||
|
QString messageId;
|
||||||
|
|
||||||
|
MessageInfo& operator=(const MessageInfo& other);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SHARED_MESSAGEINFO_H
|
@ -30,7 +30,7 @@ Models::Element::Element(Type p_type, const Models::Account* acc, const QString&
|
|||||||
feed(new MessageFeed(this))
|
feed(new MessageFeed(this))
|
||||||
{
|
{
|
||||||
connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive);
|
connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive);
|
||||||
connect(feed, &MessageFeed::fileLocalPathRequest, this, &Element::fileLocalPathRequest);
|
connect(feed, &MessageFeed::fileDownloadRequest, this, &Element::fileDownloadRequest);
|
||||||
|
|
||||||
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
|
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
|
||||||
if (itr != data.end()) {
|
if (itr != data.end()) {
|
||||||
@ -156,8 +156,17 @@ bool Models::Element::isRoom() const
|
|||||||
return type != contact;
|
return type != contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Element::fileProgress(const QString& messageId, qreal value)
|
void Models::Element::fileProgress(const QString& messageId, qreal value, bool up)
|
||||||
{
|
{
|
||||||
feed->fileProgress(messageId, value);
|
feed->fileProgress(messageId, value, up);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Models::Element::fileComplete(const QString& messageId, bool up)
|
||||||
|
{
|
||||||
|
feed->fileComplete(messageId, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Element::fileError(const QString& messageId, const QString& error, bool up)
|
||||||
|
{
|
||||||
|
feed->fileError(messageId, error, up);
|
||||||
|
}
|
||||||
|
@ -43,11 +43,13 @@ public:
|
|||||||
unsigned int getMessagesCount() const;
|
unsigned int getMessagesCount() const;
|
||||||
void responseArchive(const std::list<Shared::Message> list, bool last);
|
void responseArchive(const std::list<Shared::Message> list, bool last);
|
||||||
bool isRoom() const;
|
bool isRoom() const;
|
||||||
void fileProgress(const QString& messageId, qreal value);
|
void fileProgress(const QString& messageId, qreal value, bool up);
|
||||||
|
void fileError(const QString& messageId, const QString& error, bool up);
|
||||||
|
void fileComplete(const QString& messageId, bool up);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestArchive(const QString& before);
|
void requestArchive(const QString& before);
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
void fileDownloadRequest(const QString& url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setJid(const QString& p_jid);
|
void setJid(const QString& p_jid);
|
||||||
|
@ -305,7 +305,7 @@ void Models::MessageFeed::downloadAttachment(const QString& messageId)
|
|||||||
if (progressPair.second) { //Only to take action if we weren't already downloading it
|
if (progressPair.second) { //Only to take action if we weren't already downloading it
|
||||||
Shared::Message* msg = static_cast<Shared::Message*>(ind.internalPointer());
|
Shared::Message* msg = static_cast<Shared::Message*>(ind.internalPointer());
|
||||||
emit dataChanged(ind, ind);
|
emit dataChanged(ind, ind);
|
||||||
emit fileLocalPathRequest(messageId, msg->getOutOfBandUrl());
|
emit fileDownloadRequest(msg->getOutOfBandUrl());
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Attachment download for message with id" << messageId << "is already in progress, skipping";
|
qDebug() << "Attachment download for message with id" << messageId << "is already in progress, skipping";
|
||||||
}
|
}
|
||||||
@ -319,16 +319,34 @@ void Models::MessageFeed::uploadAttachment(const QString& messageId)
|
|||||||
qDebug() << "request to upload attachment of the message" << messageId;
|
qDebug() << "request to upload attachment of the message" << messageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::MessageFeed::fileProgress(const QString& messageId, qreal value)
|
void Models::MessageFeed::fileProgress(const QString& messageId, qreal value, bool up)
|
||||||
{
|
{
|
||||||
Progress::iterator itr = downloads.find(messageId);
|
Progress* pr = 0;
|
||||||
if (itr != downloads.end()) {
|
if (up) {
|
||||||
|
pr = &uploads;
|
||||||
|
} else {
|
||||||
|
pr = &downloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress::iterator itr = pr->find(messageId);
|
||||||
|
if (itr != pr->end()) {
|
||||||
itr->second = value;
|
itr->second = value;
|
||||||
QModelIndex ind = modelIndexById(messageId);
|
QModelIndex ind = modelIndexById(messageId);
|
||||||
emit dataChanged(ind, ind);
|
emit dataChanged(ind, ind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Models::MessageFeed::fileComplete(const QString& messageId, bool up)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::MessageFeed::fileError(const QString& messageId, const QString& error, bool up)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const
|
QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const
|
||||||
{
|
{
|
||||||
StorageById::const_iterator itr = indexById.find(id);
|
StorageById::const_iterator itr = indexById.find(id);
|
||||||
|
@ -59,12 +59,14 @@ public:
|
|||||||
void uploadAttachment(const QString& messageId);
|
void uploadAttachment(const QString& messageId);
|
||||||
|
|
||||||
unsigned int unreadMessagesCount() const;
|
unsigned int unreadMessagesCount() const;
|
||||||
void fileProgress(const QString& messageId, qreal value);
|
void fileProgress(const QString& messageId, qreal value, bool up);
|
||||||
|
void fileError(const QString& messageId, const QString& error, bool up);
|
||||||
|
void fileComplete(const QString& messageId, bool up);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestArchive(const QString& before);
|
void requestArchive(const QString& before);
|
||||||
void requestStateChange(bool requesting);
|
void requestStateChange(bool requesting);
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
void fileDownloadRequest(const QString& url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool sentByMe(const Shared::Message& msg) const;
|
bool sentByMe(const Shared::Message& msg) const;
|
||||||
@ -141,6 +143,8 @@ enum AttachmentType {
|
|||||||
local,
|
local,
|
||||||
downloading,
|
downloading,
|
||||||
uploading,
|
uploading,
|
||||||
|
errorDownload,
|
||||||
|
errorUpload,
|
||||||
ready
|
ready
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ Models::Roster::Roster(QObject* parent):
|
|||||||
root(new Item(Item::root, {{"name", "root"}})),
|
root(new Item(Item::root, {{"name", "root"}})),
|
||||||
accounts(),
|
accounts(),
|
||||||
groups(),
|
groups(),
|
||||||
contacts(),
|
contacts()
|
||||||
requestedFiles()
|
|
||||||
{
|
{
|
||||||
connect(accountsModel, &Accounts::dataChanged, this, &Roster::onAccountDataChanged);
|
connect(accountsModel, &Accounts::dataChanged, this, &Roster::onAccountDataChanged);
|
||||||
connect(root, &Item::childChanged, this, &Roster::onChildChanged);
|
connect(root, &Item::childChanged, this, &Roster::onChildChanged);
|
||||||
@ -448,7 +447,7 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons
|
|||||||
if (itr == contacts.end()) {
|
if (itr == contacts.end()) {
|
||||||
contact = new Contact(acc, jid, data);
|
contact = new Contact(acc, jid, data);
|
||||||
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
|
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
|
||||||
connect(contact, &Contact::fileLocalPathRequest, this, &Roster::onElementFileLocalPathRequest);
|
connect(contact, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
|
||||||
contacts.insert(std::make_pair(id, contact));
|
contacts.insert(std::make_pair(id, contact));
|
||||||
} else {
|
} else {
|
||||||
contact = itr->second;
|
contact = itr->second;
|
||||||
@ -534,35 +533,19 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
|
|||||||
|
|
||||||
void Models::Roster::changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data)
|
void Models::Roster::changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data)
|
||||||
{
|
{
|
||||||
ElId id(account, jid);
|
Element* el = getElement({account, jid});
|
||||||
std::map<ElId, Contact*>::iterator cItr = contacts.find(id);
|
if (el != NULL) {
|
||||||
|
|
||||||
if (cItr != contacts.end()) {
|
|
||||||
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
||||||
cItr->second->update(itr.key(), itr.value());
|
el->update(itr.key(), itr.value());
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::map<ElId, Room*>::iterator rItr = rooms.find(id);
|
|
||||||
if (rItr != rooms.end()) {
|
|
||||||
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
|
||||||
rItr->second->update(itr.key(), itr.value());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
||||||
{
|
{
|
||||||
ElId elid(account, jid);
|
Element* el = getElement({account, jid});
|
||||||
std::map<ElId, Contact*>::iterator cItr = contacts.find(elid);
|
if (el != NULL) {
|
||||||
|
el->changeMessage(id, data);
|
||||||
if (cItr != contacts.end()) {
|
|
||||||
cItr->second->changeMessage(id, data);
|
|
||||||
} else {
|
|
||||||
std::map<ElId, Room*>::iterator rItr = rooms.find(elid);
|
|
||||||
if (rItr != rooms.end()) {
|
|
||||||
rItr->second->changeMessage(id, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +609,6 @@ void Models::Roster::removeContact(const QString& account, const QString& jid, c
|
|||||||
} else {
|
} else {
|
||||||
delete ref;
|
delete ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gr->childCount() == 0) {
|
if (gr->childCount() == 0) {
|
||||||
removeGroup(account, group);
|
removeGroup(account, group);
|
||||||
}
|
}
|
||||||
@ -707,15 +689,9 @@ void Models::Roster::removePresence(const QString& account, const QString& jid,
|
|||||||
|
|
||||||
void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
|
void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
|
||||||
{
|
{
|
||||||
ElId id(account, data.getPenPalJid());
|
Element* el = getElement({account, data.getPenPalJid()});
|
||||||
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
|
if (el != NULL) {
|
||||||
if (itr != contacts.end()) {
|
el->addMessage(data);
|
||||||
itr->second->addMessage(data);
|
|
||||||
} else {
|
|
||||||
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
|
|
||||||
if (rItr != rooms.end()) {
|
|
||||||
rItr->second->addMessage(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +784,7 @@ void Models::Roster::addRoom(const QString& account, const QString jid, const QM
|
|||||||
|
|
||||||
Room* room = new Room(acc, jid, data);
|
Room* room = new Room(acc, jid, data);
|
||||||
connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
|
connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
|
||||||
connect(room, &Contact::fileLocalPathRequest, this, &Roster::onElementFileLocalPathRequest);
|
connect(room, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
|
||||||
rooms.insert(std::make_pair(id, room));
|
rooms.insert(std::make_pair(id, room));
|
||||||
acc->appendChild(room);
|
acc->appendChild(room);
|
||||||
}
|
}
|
||||||
@ -971,51 +947,55 @@ void Models::Roster::onElementRequestArchive(const QString& before)
|
|||||||
void Models::Roster::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last)
|
void Models::Roster::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last)
|
||||||
{
|
{
|
||||||
ElId id(account, jid);
|
ElId id(account, jid);
|
||||||
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
|
Element* el = getElement(id);
|
||||||
if (itr != contacts.end()) {
|
if (el != NULL) {
|
||||||
itr->second->responseArchive(list, last);
|
el->responseArchive(list, last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Roster::fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up)
|
||||||
|
{
|
||||||
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
Element* el = getElement({info.account, info.jid});
|
||||||
|
if (el != NULL) {
|
||||||
|
el->fileProgress(info.messageId, value, up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Roster::fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up)
|
||||||
|
{
|
||||||
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
Element* el = getElement({info.account, info.jid});
|
||||||
|
if (el != NULL) {
|
||||||
|
el->fileComplete(info.messageId, up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Roster::fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up)
|
||||||
|
{
|
||||||
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
|
Element* el = getElement({info.account, info.jid});
|
||||||
|
if (el != NULL) {
|
||||||
|
el->fileError(info.messageId, err, up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Models::Element * Models::Roster::getElement(const Models::Roster::ElId& id)
|
||||||
|
{
|
||||||
|
std::map<ElId, Contact*>::iterator cItr = contacts.find(id);
|
||||||
|
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
return cItr->second;
|
||||||
} else {
|
} else {
|
||||||
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
|
std::map<ElId, Room*>::iterator rItr = rooms.find(id);
|
||||||
if (rItr != rooms.end()) {
|
if (rItr != rooms.end()) {
|
||||||
rItr->second->responseArchive(list, last);
|
return rItr->second;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Models::Roster::onElementFileLocalPathRequest(const QString& messageId, const QString& url)
|
|
||||||
{
|
|
||||||
Element* el = static_cast<Element*>(sender());
|
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
|
|
||||||
bool created = false;
|
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
itr->second.insert(Models::Roster::ElId(el->getAccountName(), el->getJid()));
|
|
||||||
if (created) {
|
|
||||||
emit fileLocalPathRequest(messageId, url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Models::Roster::fileProgress(const QString& messageId, qreal value)
|
|
||||||
{
|
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
|
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
qDebug() << "fileProgress in UI but there is nobody waiting for that id:" << messageId << ", skipping";
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const std::set<Models::Roster::ElId>& convs = itr->second;
|
|
||||||
for (const Models::Roster::ElId& id : convs) {
|
|
||||||
std::map<ElId, Contact*>::const_iterator cItr = contacts.find(id);
|
|
||||||
if (cItr != contacts.end()) {
|
|
||||||
cItr->second->fileProgress(messageId, value);
|
|
||||||
} else {
|
|
||||||
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
|
|
||||||
if (rItr != rooms.end()) {
|
|
||||||
rItr->second->fileProgress(messageId, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "shared/message.h"
|
#include "shared/message.h"
|
||||||
#include "shared/global.h"
|
#include "shared/global.h"
|
||||||
|
#include "shared/messageinfo.h"
|
||||||
#include "accounts.h"
|
#include "accounts.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
@ -81,21 +82,19 @@ public:
|
|||||||
QModelIndex getAccountIndex(const QString& name);
|
QModelIndex getAccountIndex(const QString& name);
|
||||||
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
||||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
||||||
void fileProgress(const QString& messageId, qreal value);
|
|
||||||
|
void fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);
|
||||||
|
void fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up);
|
||||||
|
void fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up);
|
||||||
|
|
||||||
Accounts* accountsModel;
|
Accounts* accountsModel;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestArchive(const QString& account, const QString& jid, const QString& before);
|
void requestArchive(const QString& account, const QString& jid, const QString& before);
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
void fileDownloadRequest(const QString& url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Item* root;
|
Element* getElement(const ElId& id);
|
||||||
std::map<QString, Account*> accounts;
|
|
||||||
std::map<ElId, Group*> groups;
|
|
||||||
std::map<ElId, Contact*> contacts;
|
|
||||||
std::map<ElId, Room*> rooms;
|
|
||||||
std::map<QString, std::set<Models::Roster::ElId>> requestedFiles;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
|
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
|
||||||
@ -107,7 +106,13 @@ private slots:
|
|||||||
void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex);
|
void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex);
|
||||||
void onChildMoved();
|
void onChildMoved();
|
||||||
void onElementRequestArchive(const QString& before);
|
void onElementRequestArchive(const QString& before);
|
||||||
void onElementFileLocalPathRequest(const QString& messageId, const QString& url);
|
|
||||||
|
private:
|
||||||
|
Item* root;
|
||||||
|
std::map<QString, Account*> accounts;
|
||||||
|
std::map<ElId, Group*> groups;
|
||||||
|
std::map<ElId, Contact*> contacts;
|
||||||
|
std::map<ElId, Room*> rooms;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class ElId {
|
class ElId {
|
||||||
|
103
ui/squawk.cpp
103
ui/squawk.cpp
@ -29,7 +29,6 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
conversations(),
|
conversations(),
|
||||||
contextMenu(new QMenu()),
|
contextMenu(new QMenu()),
|
||||||
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
||||||
requestedFiles(),
|
|
||||||
vCards(),
|
vCards(),
|
||||||
requestedAccountsForPasswords(),
|
requestedAccountsForPasswords(),
|
||||||
prompt(0),
|
prompt(0),
|
||||||
@ -62,8 +61,8 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
||||||
|
|
||||||
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
||||||
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onConversationRequestArchive);
|
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive);
|
||||||
connect(&rosterModel, &Models::Roster::fileLocalPathRequest, this, &Squawk::fileLocalPathRequest);
|
connect(&rosterModel, &Models::Roster::fileDownloadRequest, this, &Squawk::fileDownloadRequest);
|
||||||
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
|
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
|
||||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||||
|
|
||||||
@ -389,86 +388,24 @@ void Squawk::onConversationClosed(QObject* parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onConversationDownloadFile(const QString& messageId, const QString& url)
|
void Squawk::fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up)
|
||||||
{
|
{
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
rosterModel.fileProgress(msgs, value, up);
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
|
|
||||||
bool created = false;
|
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
|
|
||||||
if (created) {
|
|
||||||
emit downloadFileRequest(messageId, url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::fileProgress(const QString& messageId, qreal value)
|
void Squawk::fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path)
|
||||||
{
|
{
|
||||||
rosterModel.fileProgress(messageId, value);
|
rosterModel.fileComplete(msgs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::fileError(const QString& messageId, const QString& error)
|
void Squawk::fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up)
|
||||||
{
|
{
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
|
rosterModel.fileError(msgs, error, up);
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
qDebug() << "fileError in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping";
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const std::set<Models::Roster::ElId>& convs = itr->second;
|
|
||||||
for (std::set<Models::Roster::ElId>::const_iterator cItr = convs.begin(), cEnd = convs.end(); cItr != cEnd; ++cItr) {
|
|
||||||
const Models::Roster::ElId& id = *cItr;
|
|
||||||
Conversations::const_iterator c = conversations.find(id);
|
|
||||||
if (c != conversations.end()) {
|
|
||||||
c->second->fileError(messageId, error);
|
|
||||||
}
|
|
||||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
|
||||||
currentConversation->fileError(messageId, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestedFiles.erase(itr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Squawk::fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path)
|
||||||
//TODO! Need to make it look like a standard message change event!
|
|
||||||
void Squawk::fileLocalPathResponse(const QString& messageId, const QString& path)
|
|
||||||
{
|
{
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
|
rosterModel.fileComplete(msgs, true);
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
qDebug() << "fileLocalPathResponse in UI Squawk but there is nobody waiting for that path, skipping";
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const std::set<Models::Roster::ElId>& convs = itr->second;
|
|
||||||
for (std::set<Models::Roster::ElId>::const_iterator cItr = convs.begin(), cEnd = convs.end(); cItr != cEnd; ++cItr) {
|
|
||||||
const Models::Roster::ElId& id = *cItr;
|
|
||||||
Conversations::const_iterator c = conversations.find(id);
|
|
||||||
if (c != conversations.end()) {
|
|
||||||
c->second->responseLocalFile(messageId, path);
|
|
||||||
}
|
|
||||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
|
||||||
currentConversation->responseLocalFile(messageId, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestedFiles.erase(itr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onConversationRequestLocalFile(const QString& messageId, const QString& url)
|
|
||||||
{
|
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
|
|
||||||
bool created = false;
|
|
||||||
if (itr == requestedFiles.end()) {
|
|
||||||
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
|
|
||||||
if (created) {
|
|
||||||
emit fileLocalPathRequest(messageId, url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
||||||
@ -565,23 +502,13 @@ void Squawk::notify(const QString& account, const Shared::Message& msg)
|
|||||||
void Squawk::onConversationMessage(const Shared::Message& msg)
|
void Squawk::onConversationMessage(const Shared::Message& msg)
|
||||||
{
|
{
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
Models::Roster::ElId id = conv->getId();
|
QString acc = conv->getAccount();
|
||||||
|
|
||||||
rosterModel.addMessage(conv->getAccount(), msg);
|
rosterModel.addMessage(acc, msg);
|
||||||
|
emit sendMessage(acc, msg);
|
||||||
QString ap = msg.getAttachPath();
|
|
||||||
QString oob = msg.getOutOfBandUrl();
|
|
||||||
if ((ap.size() > 0 && oob.size() == 0) || (ap.size() == 0 && oob.size() > 0)) {
|
|
||||||
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.insert(std::make_pair(msg.getId(), std::set<Models::Roster::ElId>())).first;
|
|
||||||
itr->second.insert(id);
|
|
||||||
|
|
||||||
//TODO can also start downloading here if someone attached the message with the remote url
|
|
||||||
}
|
|
||||||
|
|
||||||
emit sendMessage(conv->getAccount(), msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onConversationRequestArchive(const QString& account, const QString& jid, const QString& before)
|
void Squawk::onRequestArchive(const QString& account, const QString& jid, const QString& before)
|
||||||
{
|
{
|
||||||
emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
|
emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
|
||||||
}
|
}
|
||||||
@ -1029,8 +956,6 @@ void Squawk::subscribeConversation(Conversation* conv)
|
|||||||
{
|
{
|
||||||
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
||||||
connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage);
|
connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage);
|
||||||
connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile);
|
|
||||||
connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||||
|
15
ui/squawk.h
15
ui/squawk.h
@ -75,8 +75,7 @@ signals:
|
|||||||
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
|
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
|
||||||
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
|
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
|
||||||
void removeRoomRequest(const QString& account, const QString& jid);
|
void removeRoomRequest(const QString& account, const QString& jid);
|
||||||
void fileLocalPathRequest(const QString& messageId, const QString& url);
|
void fileDownloadRequest(const QString& url);
|
||||||
void downloadFileRequest(const QString& messageId, const QString& url);
|
|
||||||
void requestVCard(const QString& account, const QString& jid);
|
void requestVCard(const QString& account, const QString& jid);
|
||||||
void uploadVCard(const QString& account, const Shared::VCard& card);
|
void uploadVCard(const QString& account, const Shared::VCard& card);
|
||||||
void responsePassword(const QString& account, const QString& password);
|
void responsePassword(const QString& account, const QString& password);
|
||||||
@ -103,9 +102,10 @@ public slots:
|
|||||||
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
||||||
void fileLocalPathResponse(const QString& messageId, const QString& path);
|
void fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up);
|
||||||
void fileError(const QString& messageId, const QString& error);
|
void fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up);
|
||||||
void fileProgress(const QString& messageId, qreal value);
|
void fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
|
||||||
|
void fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
|
||||||
void responseVCard(const QString& jid, const Shared::VCard& card);
|
void responseVCard(const QString& jid, const Shared::VCard& card);
|
||||||
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
||||||
void requestPassword(const QString& account);
|
void requestPassword(const QString& account);
|
||||||
@ -119,7 +119,6 @@ private:
|
|||||||
Conversations conversations;
|
Conversations conversations;
|
||||||
QMenu* contextMenu;
|
QMenu* contextMenu;
|
||||||
QDBusInterface dbus;
|
QDBusInterface dbus;
|
||||||
std::map<QString, std::set<Models::Roster::ElId>> requestedFiles;
|
|
||||||
std::map<QString, VCard*> vCards;
|
std::map<QString, VCard*> vCards;
|
||||||
std::deque<QString> requestedAccountsForPasswords;
|
std::deque<QString> requestedAccountsForPasswords;
|
||||||
QInputDialog* prompt;
|
QInputDialog* prompt;
|
||||||
@ -146,10 +145,8 @@ private slots:
|
|||||||
void onComboboxActivated(int index);
|
void onComboboxActivated(int index);
|
||||||
void onRosterItemDoubleClicked(const QModelIndex& item);
|
void onRosterItemDoubleClicked(const QModelIndex& item);
|
||||||
void onConversationMessage(const Shared::Message& msg);
|
void onConversationMessage(const Shared::Message& msg);
|
||||||
void onConversationRequestArchive(const QString& account, const QString& jid, const QString& before);
|
void onRequestArchive(const QString& account, const QString& jid, const QString& before);
|
||||||
void onRosterContextMenu(const QPoint& point);
|
void onRosterContextMenu(const QPoint& point);
|
||||||
void onConversationRequestLocalFile(const QString& messageId, const QString& url);
|
|
||||||
void onConversationDownloadFile(const QString& messageId, const QString& url);
|
|
||||||
void onItemCollepsed(const QModelIndex& index);
|
void onItemCollepsed(const QModelIndex& index);
|
||||||
void onPasswordPromptAccepted();
|
void onPasswordPromptAccepted();
|
||||||
void onPasswordPromptRejected();
|
void onPasswordPromptRejected();
|
||||||
|
Loading…
Reference in New Issue
Block a user