working on file upload
This commit is contained in:
parent
100b2e8943
commit
7c32056918
11 changed files with 326 additions and 144 deletions
|
@ -23,7 +23,8 @@ Core::NetworkAccess::NetworkAccess(QObject* parent):
|
|||
running(false),
|
||||
manager(0),
|
||||
files("files"),
|
||||
downloads()
|
||||
downloads(),
|
||||
uploads()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -34,9 +35,9 @@ Core::NetworkAccess::~NetworkAccess()
|
|||
|
||||
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()) {
|
||||
Download* dwn = itr->second;
|
||||
Transfer* dwn = itr->second;
|
||||
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
|
||||
if (mItr == dwn->messages.end()) {
|
||||
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)
|
||||
{
|
||||
std::map<QString, Download*>::iterator itr = downloads.find(url);
|
||||
std::map<QString, Transfer*>::iterator itr = downloads.find(url);
|
||||
if (itr != downloads.end()) {
|
||||
Download* dwn = itr->second;
|
||||
Transfer* dwn = itr->second;
|
||||
std::set<QString>::const_iterator mItr = dwn->messages.find(messageId);
|
||||
if (mItr == dwn->messages.end()) {
|
||||
dwn->messages.insert(messageId);
|
||||
|
@ -85,7 +86,7 @@ void Core::NetworkAccess::downladFileRequest(const QString& messageId, const QSt
|
|||
startDownload(messageId, url);
|
||||
} catch (Archive::Unknown e) {
|
||||
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;
|
||||
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->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());
|
||||
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()) {
|
||||
qDebug() << "an error downloading" << url << ": the request had some progress but seems like noone is waiting for it, skipping";
|
||||
} else {
|
||||
Download* dwn = itr->second;
|
||||
Transfer* dwn = itr->second;
|
||||
qreal received = bytesReceived;
|
||||
qreal total = bytesTotal;
|
||||
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());
|
||||
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()) {
|
||||
qDebug() << "an error downloading" << url << ": the request is reporting an error but seems like noone is waiting for it, skipping";
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
QString errorText = getErrorText(code);
|
||||
if (errorText.size() > 0) {
|
||||
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) {
|
||||
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("");
|
||||
QNetworkReply* rpl = static_cast<QNetworkReply*>(sender());
|
||||
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()) {
|
||||
qDebug() << "an error downloading" << url << ": the request is done but seems like noone is waiting for it, skipping";
|
||||
} else {
|
||||
Download* dwn = itr->second;
|
||||
Transfer* dwn = itr->second;
|
||||
if (dwn->success) {
|
||||
qDebug() << "download success for" << url;
|
||||
QStringList hops = url.split("/");
|
||||
|
@ -320,13 +328,130 @@ void Core::NetworkAccess::onRequestFinished()
|
|||
|
||||
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);
|
||||
dwn->reply = manager->get(req);
|
||||
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(finished()), SLOT(onRequestFinished()));
|
||||
connect(dwn->reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onDownloadError(QNetworkReply::NetworkError)));
|
||||
connect(dwn->reply, SIGNAL(finished()), SLOT(onDownloadFinished()));
|
||||
downloads.insert(std::make_pair(url, dwn));
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue