1
0
forked from blue/squawk

working on file upload

This commit is contained in:
Blue 2019-09-23 15:09:15 +03:00
parent 100b2e8943
commit 7c32056918
11 changed files with 326 additions and 144 deletions

View File

@ -30,6 +30,7 @@
#include <QXmppClient.h> #include <QXmppClient.h>
#include <QXmppBookmarkManager.h> #include <QXmppBookmarkManager.h>
#include <QXmppBookmarkSet.h> #include <QXmppBookmarkSet.h>
#include <QXmppHttpUploadIq.h>
#include "../global.h" #include "../global.h"
#include "contact.h" #include "contact.h"
#include "conference.h" #include "conference.h"

View File

@ -23,7 +23,8 @@ Core::NetworkAccess::NetworkAccess(QObject* parent):
running(false), running(false),
manager(0), manager(0),
files("files"), files("files"),
downloads() downloads(),
uploads()
{ {
} }
@ -34,9 +35,9 @@ Core::NetworkAccess::~NetworkAccess()
void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const QString& url) void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const QString& url)
{ {
std::map<QString, Download*>::iterator itr = downloads.find(url); std::map<QString, Transfer*>::iterator itr = downloads.find(url);
if (itr != downloads.end()) { if (itr != downloads.end()) {
Download* dwn = itr->second; Transfer* dwn = itr->second;
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId); std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
if (mItr == dwn->messages.end()) { if (mItr == dwn->messages.end()) {
dwn->messages.insert(messageId); dwn->messages.insert(messageId);
@ -63,9 +64,9 @@ void Core::NetworkAccess::fileLocalPathRequest(const QString& messageId, const Q
void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QString& url) void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QString& url)
{ {
std::map<QString, Download*>::iterator itr = downloads.find(url); std::map<QString, Transfer*>::iterator itr = downloads.find(url);
if (itr != downloads.end()) { if (itr != downloads.end()) {
Download* dwn = itr->second; Transfer* dwn = itr->second;
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId); std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
if (mItr == dwn->messages.end()) { if (mItr == dwn->messages.end()) {
dwn->messages.insert(messageId); dwn->messages.insert(messageId);
@ -85,7 +86,7 @@ void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QSt
startDownload(messageId, url); startDownload(messageId, url);
} catch (Archive::Unknown e) { } catch (Archive::Unknown e) {
qDebug() << "Error requesting file path:" << e.what(); qDebug() << "Error requesting file path:" << e.what();
startDownload(messageId, url); emit downloadFileError(messageId, QString("Database error: ") + e.what());
} }
} }
} }
@ -107,7 +108,7 @@ void Core::NetworkAccess::stop()
manager = 0; manager = 0;
running = false; running = false;
for (std::map<QString, Download*>::const_iterator itr = downloads.begin(), end = downloads.end(); itr != end; ++itr) { for (std::map<QString, Transfer*>::const_iterator itr = downloads.begin(), end = downloads.end(); itr != end; ++itr) {
itr->second->success = false; itr->second->success = false;
itr->second->reply->abort(); //assuming it's gonna call onRequestFinished slot itr->second->reply->abort(); //assuming it's gonna call onRequestFinished slot
} }
@ -118,11 +119,11 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT
{ {
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, Download*>::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 had some progress but seems like noone is waiting for it, skipping"; qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping";
} else { } else {
Download* dwn = itr->second; Transfer* dwn = itr->second;
qreal received = bytesReceived; qreal received = bytesReceived;
qreal total = bytesTotal; qreal total = bytesTotal;
qreal progress = received/total; qreal progress = received/total;
@ -133,132 +134,18 @@ void Core::NetworkAccess::onDownloadProgress(qint64 bytesReceived, qint64 bytesT
} }
} }
void Core::NetworkAccess::onRequestError(QNetworkReply::NetworkError code) void Core::NetworkAccess::onDownloadError(QNetworkReply::NetworkError code)
{ {
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, Download*>::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 reporting an error but seems like noone is waiting for it, skipping"; qDebug() << "an error downloading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping";
} else { } else {
QString errorText; QString errorText = getErrorText(code);
switch (code) {
case QNetworkReply::NoError:
//this never is supposed to happen
break;
// network layer errors [relating to the destination server] (1-99):
case QNetworkReply::ConnectionRefusedError:
errorText = "Connection refused";
break;
case QNetworkReply::RemoteHostClosedError:
errorText = "Remote server closed the connection";
break;
case QNetworkReply::HostNotFoundError:
errorText = "Remote host is not found";
break;
case QNetworkReply::TimeoutError:
errorText = "Connection was closed because it timed out";
break;
case QNetworkReply::OperationCanceledError:
//this means I closed it myself by abort() or close(), don't think I need to notify here
break;
case QNetworkReply::SslHandshakeFailedError:
errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here
break;
case QNetworkReply::TemporaryNetworkFailureError:
//this means the connection is lost by opened route, but it's going to be resumed, not sure I need to notify
break;
case QNetworkReply::NetworkSessionFailedError:
errorText = "Outgoing connection problem";
break;
case QNetworkReply::BackgroundRequestNotAllowedError:
errorText = "Background request is not allowed";
break;
case QNetworkReply::TooManyRedirectsError:
errorText = "The request was redirected too many times";
break;
case QNetworkReply::InsecureRedirectError:
errorText = "The request was redirected to insecure connection";
break;
case QNetworkReply::UnknownNetworkError:
errorText = "Unknown network error";
break;
// proxy errors (101-199):
case QNetworkReply::ProxyConnectionRefusedError:
errorText = "The connection to the proxy server was refused";
break;
case QNetworkReply::ProxyConnectionClosedError:
errorText = "Proxy server closed the connection";
break;
case QNetworkReply::ProxyNotFoundError:
errorText = "Proxy host was not found";
break;
case QNetworkReply::ProxyTimeoutError:
errorText = "Connection to the proxy server was closed because it timed out";
break;
case QNetworkReply::ProxyAuthenticationRequiredError:
errorText = "Couldn't connect to proxy server, authentication is required";
break;
case QNetworkReply::UnknownProxyError:
errorText = "Unknown proxy error";
break;
// content errors (201-299):
case QNetworkReply::ContentAccessDenied:
errorText = "The access to file is denied";
break;
case QNetworkReply::ContentOperationNotPermittedError:
errorText = "The operation over requesting file is not permitted";
break;
case QNetworkReply::ContentNotFoundError:
errorText = "The file was not found";
break;
case QNetworkReply::AuthenticationRequiredError:
errorText = "Couldn't access the file, authentication is required";
break;
case QNetworkReply::ContentReSendError:
errorText = "Sending error, one more attempt will probably solve this problem";
break;
case QNetworkReply::ContentConflictError:
errorText = "The request could not be completed due to a conflict with the current state of the resource";
break;
case QNetworkReply::ContentGoneError:
errorText = "The requested resource is no longer available at the server";
break;
case QNetworkReply::UnknownContentError:
errorText = "Unknown content error";
break;
// protocol errors
case QNetworkReply::ProtocolUnknownError:
errorText = "Unknown protocol error";
break;
case QNetworkReply::ProtocolInvalidOperationError:
errorText = "Requested operation is not permitted in this protocol";
break;
case QNetworkReply::ProtocolFailure:
errorText = "Low level protocol error";
break;
// Server side errors (401-499)
case QNetworkReply::InternalServerError:
errorText = "Internal server error";
break;
case QNetworkReply::OperationNotImplementedError:
errorText = "Server doesn't support requested operation";
break;
case QNetworkReply::ServiceUnavailableError:
errorText = "The server is not available for this operation right now";
break;
case QNetworkReply::UnknownServerError:
errorText = "Unknown server error";
break;
}
if (errorText.size() > 0) { if (errorText.size() > 0) {
itr->second->success = false; itr->second->success = false;
Download* dwn = itr->second; Transfer* dwn = itr->second;
for (std::set<QString>::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) { for (std::set<QString>::const_iterator mItr = dwn->messages.begin(), end = dwn->messages.end(); mItr != end; ++mItr) {
emit downloadFileError(*mItr, errorText); emit downloadFileError(*mItr, errorText);
} }
@ -266,16 +153,137 @@ void Core::NetworkAccess::onRequestError(QNetworkReply::NetworkError code)
} }
} }
void Core::NetworkAccess::onRequestFinished() QString Core::NetworkAccess::getErrorText(QNetworkReply::NetworkError code)
{
QString errorText("");
switch (code) {
case QNetworkReply::NoError:
//this never is supposed to happen
break;
// network layer errors [relating to the destination server] (1-99):
case QNetworkReply::ConnectionRefusedError:
errorText = "Connection refused";
break;
case QNetworkReply::RemoteHostClosedError:
errorText = "Remote server closed the connection";
break;
case QNetworkReply::HostNotFoundError:
errorText = "Remote host is not found";
break;
case QNetworkReply::TimeoutError:
errorText = "Connection was closed because it timed out";
break;
case QNetworkReply::OperationCanceledError:
//this means I closed it myself by abort() or close(), don't think I need to notify here
break;
case QNetworkReply::SslHandshakeFailedError:
errorText = "Security error"; //TODO need to handle sslErrors signal to get a better description here
break;
case QNetworkReply::TemporaryNetworkFailureError:
//this means the connection is lost by opened route, but it's going to be resumed, not sure I need to notify
break;
case QNetworkReply::NetworkSessionFailedError:
errorText = "Outgoing connection problem";
break;
case QNetworkReply::BackgroundRequestNotAllowedError:
errorText = "Background request is not allowed";
break;
case QNetworkReply::TooManyRedirectsError:
errorText = "The request was redirected too many times";
break;
case QNetworkReply::InsecureRedirectError:
errorText = "The request was redirected to insecure connection";
break;
case QNetworkReply::UnknownNetworkError:
errorText = "Unknown network error";
break;
// proxy errors (101-199):
case QNetworkReply::ProxyConnectionRefusedError:
errorText = "The connection to the proxy server was refused";
break;
case QNetworkReply::ProxyConnectionClosedError:
errorText = "Proxy server closed the connection";
break;
case QNetworkReply::ProxyNotFoundError:
errorText = "Proxy host was not found";
break;
case QNetworkReply::ProxyTimeoutError:
errorText = "Connection to the proxy server was closed because it timed out";
break;
case QNetworkReply::ProxyAuthenticationRequiredError:
errorText = "Couldn't connect to proxy server, authentication is required";
break;
case QNetworkReply::UnknownProxyError:
errorText = "Unknown proxy error";
break;
// content errors (201-299):
case QNetworkReply::ContentAccessDenied:
errorText = "The access to file is denied";
break;
case QNetworkReply::ContentOperationNotPermittedError:
errorText = "The operation over requesting file is not permitted";
break;
case QNetworkReply::ContentNotFoundError:
errorText = "The file was not found";
break;
case QNetworkReply::AuthenticationRequiredError:
errorText = "Couldn't access the file, authentication is required";
break;
case QNetworkReply::ContentReSendError:
errorText = "Sending error, one more attempt will probably solve this problem";
break;
case QNetworkReply::ContentConflictError:
errorText = "The request could not be completed due to a conflict with the current state of the resource";
break;
case QNetworkReply::ContentGoneError:
errorText = "The requested resource is no longer available at the server";
break;
case QNetworkReply::UnknownContentError:
errorText = "Unknown content error";
break;
// protocol errors
case QNetworkReply::ProtocolUnknownError:
errorText = "Unknown protocol error";
break;
case QNetworkReply::ProtocolInvalidOperationError:
errorText = "Requested operation is not permitted in this protocol";
break;
case QNetworkReply::ProtocolFailure:
errorText = "Low level protocol error";
break;
// Server side errors (401-499)
case QNetworkReply::InternalServerError:
errorText = "Internal server error";
break;
case QNetworkReply::OperationNotImplementedError:
errorText = "Server doesn't support requested operation";
break;
case QNetworkReply::ServiceUnavailableError:
errorText = "The server is not available for this operation right now";
break;
case QNetworkReply::UnknownServerError:
errorText = "Unknown server error";
break;
}
return errorText;
}
void Core::NetworkAccess::onDownloadFinished()
{ {
QString path(""); 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, Download*>::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 seems like noone is waiting for it, skipping";
} else { } else {
Download* 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("/");
@ -320,13 +328,130 @@ void Core::NetworkAccess::onRequestFinished()
void Core::NetworkAccess::startDownload(const QString& messageId, const QString& url) void Core::NetworkAccess::startDownload(const QString& messageId, const QString& url)
{ {
Download* dwn = new Download({{messageId}, 0, 0, true}); Transfer* dwn = new Transfer({{messageId}, 0, 0, true, "", 0});
QNetworkRequest req(url); QNetworkRequest req(url);
dwn->reply = manager->get(req); dwn->reply = manager->get(req);
connect(dwn->reply, SIGNAL(downloadProgress(qint64, qint64)), SLOT(onDownloadProgress(qint64, qint64))); connect(dwn->reply, SIGNAL(downloadProgress(qint64, qint64)), SLOT(onDownloadProgress(qint64, qint64)));
connect(dwn->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onRequestError(QNetworkReply::NetworkError))); connect(dwn->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onDownloadError(QNetworkReply::NetworkError)));
connect(dwn->reply, SIGNAL(finished()), SLOT(onRequestFinished())); connect(dwn->reply, SIGNAL(finished()), SLOT(onDownloadFinished()));
downloads.insert(std::make_pair(url, dwn)); downloads.insert(std::make_pair(url, dwn));
emit downloadFileProgress(messageId, 0); emit downloadFileProgress(messageId, 0);
} }
void Core::NetworkAccess::onUploadError(QNetworkReply::NetworkError code)
{
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
if (itr == uploads.end()) {
qDebug() << "an error uploading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping";
} else {
QString errorText = getErrorText(code);
if (errorText.size() > 0) {
itr->second->success = false;
Transfer* upl = itr->second;
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
emit uploadFileError(*mItr, errorText);
}
}
}
}
void Core::NetworkAccess::onUploadFinished()
{
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
if (itr == downloads.end()) {
qDebug() << "an error uploading" << url << ": the request is done but seems like noone is waiting for it, skipping";
} else {
Transfer* upl = itr->second;
if (upl->success) {
qDebug() << "upload success for" << url;
files.addRecord(url, upl->path);
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
emit fileLocalPathResponse(*mItr, upl->path);
}
}
upl->reply->deleteLater();
upl->file->close();
upl->file->deleteLater();
delete upl;
uploads.erase(itr);
}
}
void Core::NetworkAccess::onUploadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
QString url = rpl->url().toString();
std::map<QString, Transfer*>::const_iterator itr = uploads.find(url);
if (itr == uploads.end()) {
qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping";
} else {
Transfer* upl = itr->second;
qreal received = bytesReceived;
qreal total = bytesTotal;
qreal progress = received/total;
upl->progress = progress;
for (std::set<QString>::const_iterator mItr = upl->messages.begin(), end = upl->messages.end(); mItr != end; ++mItr) {
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, 0});
QNetworkRequest req(url);
QFile* file = new QFile(path);
if (file->open(QIODevice::ReadOnly)) {
upl->reply = manager->put(req, file);
connect(upl->reply, SIGNAL(uploadProgress(qint64, qint64)), SLOT(onUploadProgress(qint64, qint64)));
connect(upl->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onUploadError(QNetworkReply::NetworkError)));
connect(upl->reply, SIGNAL(finished()), SLOT(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) {
emit fileLocalPathResponse(messageId, path);
} else {
files.changeRecord(url, path);
}
QFileInfo info(path);
if (info.exists() && info.isFile()) {
emit fileLocalPathResponse(messageId, path);
} else {
files.removeRecord(url);
startDownload(messageId, url);
}
} catch (Archive::NotFound e) {
startUpload(messageId, url, path);
} catch (Archive::Unknown e) {
qDebug() << "Error requesting file path on upload:" << e.what();
emit uploadFileError(messageId, QString("Database error: ") + e.what());
}
}
}

View File

@ -39,7 +39,7 @@ namespace Core {
class NetworkAccess : public QObject class NetworkAccess : public QObject
{ {
Q_OBJECT Q_OBJECT
struct Download; struct Transfer;
public: public:
NetworkAccess(QObject* parent = nullptr); NetworkAccess(QObject* parent = nullptr);
virtual ~NetworkAccess(); virtual ~NetworkAccess();
@ -51,30 +51,41 @@ signals:
void fileLocalPathResponse(const QString& messageId, const QString& path); void fileLocalPathResponse(const QString& messageId, const QString& path);
void downloadFileProgress(const QString& messageId, qreal value); void downloadFileProgress(const QString& messageId, qreal value);
void downloadFileError(const QString& messageId, const QString& path); void downloadFileError(const QString& messageId, const QString& path);
void uploadFileProgress(const QString& messageId, qreal value);
void uploadFileError(const QString& messageId, const QString& path);
public slots: public slots:
void fileLocalPathRequest(const QString& messageId, const QString& url); void fileLocalPathRequest(const QString& messageId, const QString& url);
void downladFileRequest(const QString& messageId, const QString& url); void downladFileRequest(const QString& messageId, const QString& url);
void uploadFileRequest(const QString& messageId, const QString& url, const QString& path);
private: private:
void startDownload(const QString& messageId, const QString& url); void startDownload(const QString& messageId, const QString& url);
void startUpload(const QString& messageId, const QString& url, const QString& path);
QString getErrorText(QNetworkReply::NetworkError code);
private slots: private slots:
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onRequestError(QNetworkReply::NetworkError code); void onDownloadError(QNetworkReply::NetworkError code);
void onRequestFinished(); void onDownloadFinished();
void onUploadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onUploadError(QNetworkReply::NetworkError code);
void onUploadFinished();
private: private:
bool running; bool running;
QNetworkAccessManager* manager; QNetworkAccessManager* manager;
Storage files; Storage files;
std::map<QString, Download*> downloads; std::map<QString, Transfer*> downloads;
std::map<QString, Transfer*> uploads;
struct Download { struct Transfer {
std::set<QString> messages; std::set<QString> messages;
qreal progress; qreal progress;
QNetworkReply* reply; QNetworkReply* reply;
bool success; bool success;
QString path;
QFile* file;
}; };
}; };

View File

@ -31,6 +31,8 @@ Core::Squawk::Squawk(QObject* parent):
connect(&network, SIGNAL(fileLocalPathResponse(const QString&, const QString&)), this, SIGNAL(fileLocalPathResponse(const QString&, const QString&))); connect(&network, SIGNAL(fileLocalPathResponse(const QString&, const QString&)), this, SIGNAL(fileLocalPathResponse(const QString&, const QString&)));
connect(&network, SIGNAL(downloadFileProgress(const QString&, qreal)), this, SIGNAL(downloadFileProgress(const QString&, qreal))); connect(&network, SIGNAL(downloadFileProgress(const QString&, qreal)), this, SIGNAL(downloadFileProgress(const QString&, qreal)));
connect(&network, SIGNAL(downloadFileError(const QString&, const QString&)), this, SIGNAL(downloadFileError(const QString&, const QString&))); connect(&network, SIGNAL(downloadFileError(const QString&, const QString&)), this, SIGNAL(downloadFileError(const QString&, const QString&)));
connect(&network, SIGNAL(uploadFileProgress(const QString&, qreal)), this, SIGNAL(uploadFileProgress(const QString&, qreal)));
connect(&network, SIGNAL(uploadFileError(const QString&, const QString&)), this, SIGNAL(uploadFileError(const QString&, const QString&)));
} }
Core::Squawk::~Squawk() Core::Squawk::~Squawk()
@ -276,6 +278,11 @@ void Core::Squawk::sendMessage(const QString& account, const Shared::Message& da
itr->second->sendMessage(data); itr->second->sendMessage(data);
} }
void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data, const QString& path)
{
}
void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before) void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before)
{ {
AccountsMap::const_iterator itr = amap.find(account); AccountsMap::const_iterator itr = amap.find(account);
@ -368,7 +375,6 @@ void Core::Squawk::removeAccountRequest(const QString& name)
acc->deleteLater(); acc->deleteLater();
} }
void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason) void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason)
{ {
AccountsMap::const_iterator itr = amap.find(account); AccountsMap::const_iterator itr = amap.find(account);

View File

@ -65,6 +65,8 @@ signals:
void fileLocalPathResponse(const QString& messageId, const QString& path); void fileLocalPathResponse(const QString& messageId, const QString& path);
void downloadFileError(const QString& messageId, const QString& error); void downloadFileError(const QString& messageId, const QString& error);
void downloadFileProgress(const QString& messageId, qreal value); void downloadFileProgress(const QString& messageId, qreal value);
void uploadFileError(const QString& messageId, const QString& error);
void uploadFileProgress(const QString& messageId, qreal value);
public slots: public slots:
void start(); void start();
@ -76,6 +78,7 @@ public slots:
void disconnectAccount(const QString& account); void disconnectAccount(const QString& account);
void changeState(int state); void changeState(int state);
void sendMessage(const QString& account, const Shared::Message& data); void sendMessage(const QString& account, const Shared::Message& data);
void sendMessage(const QString& account, const Shared::Message& data, const QString& path);
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);

View File

@ -73,7 +73,7 @@ void Core::Storage::close()
void Core::Storage::addRecord(const QString& key, const QString& value) void Core::Storage::addRecord(const QString& key, const QString& value)
{ {
if (!opened) { if (!opened) {
throw Archive::Closed("addElement", name.toStdString()); throw Archive::Closed("addRecord", name.toStdString());
} }
const std::string& id = key.toStdString(); const std::string& id = key.toStdString();
const std::string& val = value.toStdString(); const std::string& val = value.toStdString();
@ -99,6 +99,33 @@ void Core::Storage::addRecord(const QString& key, const QString& value)
} }
} }
void Core::Storage::changeRecord(const QString& key, const QString& value)
{
if (!opened) {
throw Archive::Closed("changeRecord", name.toStdString());
}
const std::string& id = key.toStdString();
const std::string& val = value.toStdString();
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
lmdbData.mv_size = val.size();
lmdbData.mv_data = (char*)val.c_str();
MDB_txn *txn;
mdb_txn_begin(environment, NULL, 0, &txn);
int rc;
rc = mdb_put(txn, base, &lmdbKey, &lmdbData, 0);
if (rc != 0) {
mdb_txn_abort(txn);
if (rc) {
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));
}
} else {
mdb_txn_commit(txn);
}
}
QString Core::Storage::getRecord(const QString& key) const QString Core::Storage::getRecord(const QString& key) const
{ {
if (!opened) { if (!opened) {

View File

@ -39,6 +39,7 @@ public:
void close(); void close();
void addRecord(const QString& key, const QString& value); void addRecord(const QString& key, const QString& value);
void changeRecord(const QString& key, const QString& value);
void removeRecord(const QString& key); void removeRecord(const QString& key);
QString getRecord(const QString& key) const; QString getRecord(const QString& key) const;

View File

@ -70,6 +70,8 @@ int main(int argc, char *argv[])
QObject::connect(&w, SIGNAL(disconnectAccount(const QString&)), squawk, SLOT(disconnectAccount(const QString&))); QObject::connect(&w, SIGNAL(disconnectAccount(const QString&)), squawk, SLOT(disconnectAccount(const QString&)));
QObject::connect(&w, SIGNAL(changeState(int)), squawk, SLOT(changeState(int))); QObject::connect(&w, SIGNAL(changeState(int)), squawk, SLOT(changeState(int)));
QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&))); QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&)));
QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&, const QString&)),
squawk, SLOT(sendMessage(const QString&, const Shared::Message&, const QString&)));
QObject::connect(&w, SIGNAL(requestArchive(const QString&, const QString&, int, const QString&)), QObject::connect(&w, SIGNAL(requestArchive(const QString&, const QString&, int, const QString&)),
squawk, SLOT(requestArchive(const QString&, const QString&, int, const QString&))); squawk, SLOT(requestArchive(const QString&, const QString&, int, const QString&)));
QObject::connect(&w, SIGNAL(subscribeContact(const QString&, const QString&, const QString&)), QObject::connect(&w, SIGNAL(subscribeContact(const QString&, const QString&, const QString&)),
@ -125,9 +127,6 @@ int main(int argc, char *argv[])
QObject::connect(squawk, SIGNAL(downloadFileProgress(const QString&, qreal)), &w, SLOT(downloadFileProgress(const QString&, qreal))); QObject::connect(squawk, SIGNAL(downloadFileProgress(const QString&, qreal)), &w, SLOT(downloadFileProgress(const QString&, qreal)));
QObject::connect(squawk, SIGNAL(downloadFileError(const QString&, const QString&)), &w, SLOT(downloadFileError(const QString&, const QString&))); QObject::connect(squawk, SIGNAL(downloadFileError(const QString&, const QString&)), &w, SLOT(downloadFileError(const QString&, const QString&)));
//qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
coreThread->start(); coreThread->start();
int result = app.exec(); int result = app.exec();

View File

@ -285,6 +285,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*))); connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&))); connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&, const QString&)), this, SLOT(onConversationMessage(const Shared::Message&, const QString&)));
connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&))); connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
connect(conv, SIGNAL(requestLocalFile(const QString&, const QString&)), this, SLOT(onConversationRequestLocalFile(const QString&, const QString&))); connect(conv, SIGNAL(requestLocalFile(const QString&, const QString&)), this, SLOT(onConversationRequestLocalFile(const QString&, const QString&)));
connect(conv, SIGNAL(downloadFile(const QString&, const QString&)), this, SLOT(onConversationDownloadFile(const QString&, const QString&))); connect(conv, SIGNAL(downloadFile(const QString&, const QString&)), this, SLOT(onConversationDownloadFile(const QString&, const QString&)));
@ -468,10 +469,15 @@ 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());
emit sendMessage(conv->getAccount(), msg); emit sendMessage(conv->getAccount(), msg);
} }
void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path)
{
Conversation* conv = static_cast<Conversation*>(sender());
emit sendMessage(conv->getAccount(), msg, path);
}
void Squawk::onConversationRequestArchive(const QString& before) void Squawk::onConversationRequestArchive(const QString& before)
{ {
Conversation* conv = static_cast<Conversation*>(sender()); Conversation* conv = static_cast<Conversation*>(sender());

View File

@ -57,6 +57,7 @@ signals:
void disconnectAccount(const QString&); void disconnectAccount(const QString&);
void changeState(int state); void changeState(int state);
void sendMessage(const QString& account, const Shared::Message& data); void sendMessage(const QString& account, const Shared::Message& data);
void sendMessage(const QString& account, const Shared::Message& data, const QString& path);
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);
@ -121,6 +122,7 @@ 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 onConversationMessage(const Shared::Message& msg, const QString& path);
void onConversationRequestArchive(const QString& before); void onConversationRequestArchive(const QString& before);
void onRosterContextMenu(const QPoint& point); void onRosterContextMenu(const QPoint& point);
void onConversationShown(); void onConversationShown();

View File

@ -80,6 +80,7 @@ public:
signals: signals:
void sendMessage(const Shared::Message& message); void sendMessage(const Shared::Message& message);
void sendMessage(const Shared::Message& message, const QString& path);
void requestArchive(const QString& before); void requestArchive(const QString& before);
void shown(); void shown();
void requestLocalFile(const QString& messageId, const QString& url); void requestLocalFile(const QString& messageId, const QString& url);