Switch to uploader thread for log file uploads.
This commit is contained in:
+2
-4
@@ -209,8 +209,7 @@ HEADERS += src/engine/game.h \
|
|||||||
src/gui/qt/gametable/mycashlabel.h \
|
src/gui/qt/gametable/mycashlabel.h \
|
||||||
src/gui/qt/sound/soundevents.h \
|
src/gui/qt/sound/soundevents.h \
|
||||||
src/gui/qt/mymessagebox/mymessagebox.h \
|
src/gui/qt/mymessagebox/mymessagebox.h \
|
||||||
src/gui/qt/logfiledialog/logfiledialog.h \
|
src/gui/qt/logfiledialog/logfiledialog.h
|
||||||
src/gui/qt/logfiledialog/callback.h
|
|
||||||
|
|
||||||
!gui_800x480 {
|
!gui_800x480 {
|
||||||
FORMS += src/gui/qt/gametable.ui \
|
FORMS += src/gui/qt/gametable.ui \
|
||||||
@@ -287,8 +286,7 @@ SOURCES += src/pokerth.cpp \
|
|||||||
src/gui/qt/gametable/mycashlabel.cpp \
|
src/gui/qt/gametable/mycashlabel.cpp \
|
||||||
src/gui/qt/sound/soundevents.cpp \
|
src/gui/qt/sound/soundevents.cpp \
|
||||||
src/gui/qt/mymessagebox/mymessagebox.cpp \
|
src/gui/qt/mymessagebox/mymessagebox.cpp \
|
||||||
src/gui/qt/logfiledialog/logfiledialog.cpp \
|
src/gui/qt/logfiledialog/logfiledialog.cpp
|
||||||
src/gui/qt/logfiledialog/callback.cpp
|
|
||||||
|
|
||||||
TRANSLATIONS = ts/pokerth_af.ts \
|
TRANSLATIONS = ts/pokerth_af.ts \
|
||||||
ts/pokerth_bg.ts \
|
ts/pokerth_bg.ts \
|
||||||
|
|||||||
+4
-2
@@ -129,7 +129,8 @@ HEADERS += \
|
|||||||
src/gui/generic/serverguiwrapper.h \
|
src/gui/generic/serverguiwrapper.h \
|
||||||
src/net/receivebuffer.h \
|
src/net/receivebuffer.h \
|
||||||
src/net/sendbuffer.h \
|
src/net/sendbuffer.h \
|
||||||
src/net/servermanagerfactory.h
|
src/net/servermanagerfactory.h \
|
||||||
|
src/net/uploadcallback.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/engine/game.cpp \
|
src/engine/game.cpp \
|
||||||
@@ -202,7 +203,8 @@ SOURCES += \
|
|||||||
src/gui/generic/serverguiwrapper.cpp \
|
src/gui/generic/serverguiwrapper.cpp \
|
||||||
src/gui/qttoolsinterface.cpp \
|
src/gui/qttoolsinterface.cpp \
|
||||||
src/net/common/sendbuffer.cpp \
|
src/net/common/sendbuffer.cpp \
|
||||||
src/net/common/receivebuffer.cpp
|
src/net/common/receivebuffer.cpp \
|
||||||
|
src/net/common/uploadcallback.cpp
|
||||||
|
|
||||||
!android:!android_test{
|
!android:!android_test{
|
||||||
SOURCES += src/engine/local_engine/tools.cpp
|
SOURCES += src/engine/local_engine/tools.cpp
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
#include "callback.h"
|
|
||||||
|
|
||||||
Callback::Callback()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t
|
|
||||||
Callback::writeCallback(char* buf, size_t size, size_t nmemb, void* up)
|
|
||||||
{
|
|
||||||
data = "";
|
|
||||||
|
|
||||||
for (int c = 0; c<size*nmemb; c++)
|
|
||||||
{
|
|
||||||
data.push_back(buf[c]);
|
|
||||||
}
|
|
||||||
return size*nmemb;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef CALLBACK_H
|
|
||||||
#define CALLBACK_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
class Callback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Callback();
|
|
||||||
|
|
||||||
size_t writeCallback(char* buf, size_t size, size_t nmemb, void* up);
|
|
||||||
|
|
||||||
std::string getData() { return data; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CALLBACK_H
|
|
||||||
@@ -27,8 +27,7 @@
|
|||||||
#include "guilog.h"
|
#include "guilog.h"
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
#include "mymessagebox.h"
|
#include "mymessagebox.h"
|
||||||
#include "callback.h"
|
#include <net/uploaderthread.h>
|
||||||
#include "curl/curl.h"
|
|
||||||
|
|
||||||
LogFileDialog::LogFileDialog(QWidget *parent, ConfigFile *c) :
|
LogFileDialog::LogFileDialog(QWidget *parent, ConfigFile *c) :
|
||||||
QDialog(parent), myConfig(c),
|
QDialog(parent), myConfig(c),
|
||||||
@@ -46,7 +45,10 @@ ui(new Ui::LogFileDialog)
|
|||||||
connect( ui->treeWidget_logFiles, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(showLogFilePreviewInit()));
|
connect( ui->treeWidget_logFiles, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(showLogFilePreviewInit()));
|
||||||
connect( ui->pushButton_analyseLogfile, SIGNAL(clicked()), this, SLOT (uploadFile()));
|
connect( ui->pushButton_analyseLogfile, SIGNAL(clicked()), this, SLOT (uploadFile()));
|
||||||
connect( ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showLogFilePreviewSelected()));
|
connect( ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showLogFilePreviewSelected()));
|
||||||
|
connect( this, SIGNAL(signalUploadCompleted(QString,QString)), this, SLOT(showLogAnalysis(QString,QString)));
|
||||||
|
connect( this, SIGNAL(signalUploadError(QString,QString)), this, SLOT(showUploadError(QString,QString)));
|
||||||
|
|
||||||
|
uploader.reset(new UploaderThread(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
LogFileDialog::~LogFileDialog()
|
LogFileDialog::~LogFileDialog()
|
||||||
@@ -56,8 +58,21 @@ LogFileDialog::~LogFileDialog()
|
|||||||
|
|
||||||
void LogFileDialog::exec()
|
void LogFileDialog::exec()
|
||||||
{
|
{
|
||||||
|
uploader->Run();
|
||||||
refreshLogFileList();
|
refreshLogFileList();
|
||||||
QDialog::exec();
|
QDialog::exec();
|
||||||
|
uploader->SignalTermination();
|
||||||
|
uploader->Join(THREAD_WAIT_INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogFileDialog::UploadCompleted(const std::string &filename, const std::string &returnMessage)
|
||||||
|
{
|
||||||
|
signalUploadCompleted(QString::fromStdString(filename), QString::fromStdString(returnMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogFileDialog::UploadError(const std::string &filename, const std::string &errorMessage)
|
||||||
|
{
|
||||||
|
signalUploadError(QString::fromStdString(filename), QString::fromStdString(errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFileDialog::refreshLogFileList()
|
void LogFileDialog::refreshLogFileList()
|
||||||
@@ -109,7 +124,7 @@ void LogFileDialog::deleteLogFile()
|
|||||||
if(selectedItemsList.at(i)->data(0, Qt::UserRole+1).toString() != "current") {
|
if(selectedItemsList.at(i)->data(0, Qt::UserRole+1).toString() != "current") {
|
||||||
|
|
||||||
if(!QFile::remove(selectedItemsList.at(i)->data(0, Qt::UserRole).toString())) {
|
if(!QFile::remove(selectedItemsList.at(i)->data(0, Qt::UserRole).toString())) {
|
||||||
MyMessageBox::warning(this, "Remove log file", "PokerTH cannot remove this log file, please verify that you have write access to this file!", QMessageBox::Close );
|
MyMessageBox::warning(this, tr("Remove log file"), tr("PokerTH cannot remove this log file, please verify that you have write access to this file!"), QMessageBox::Close );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,71 +214,28 @@ void LogFileDialog::keyPressEvent ( QKeyEvent * event )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Callback* curl_writedata = new Callback();
|
|
||||||
void writeCallback(char* buf, size_t size, size_t nmemb, void* up)
|
|
||||||
{
|
|
||||||
curl_writedata->writeCallback(buf, size, nmemb, up);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFileDialog::uploadFile()
|
void LogFileDialog::uploadFile()
|
||||||
{
|
{
|
||||||
const QString buttonText(tr("Upload in progress"));
|
|
||||||
const QString errorMessage(tr("Upload failed. Please check your internet connection!\nUploading log files may fail if you are using an http proxy."));
|
|
||||||
const QString processMessage(tr("Processing of the log file on the web server failed.\nPlease verify that you are uploading a valid PokerTH log file."));
|
|
||||||
const QString reasonMessage(tr("Failure reason: "));
|
|
||||||
QTreeWidgetItem* selectedItem = ui->treeWidget_logFiles->currentItem();
|
QTreeWidgetItem* selectedItem = ui->treeWidget_logFiles->currentItem();
|
||||||
|
|
||||||
if(selectedItem) {
|
if(selectedItem) {
|
||||||
file.setFileName(selectedItem->data(0, Qt::UserRole).toString());
|
file.setFileName(selectedItem->data(0, Qt::UserRole).toString());
|
||||||
|
|
||||||
CURL *curl;
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
struct curl_httppost* post = NULL;
|
|
||||||
struct curl_httppost* last = NULL;
|
|
||||||
|
|
||||||
curl = curl_easy_init();
|
|
||||||
|
|
||||||
if(curl) {
|
|
||||||
|
|
||||||
curl_formadd(&post, &last,
|
|
||||||
CURLFORM_COPYNAME, "pdb_file",
|
|
||||||
CURLFORM_FILE, file.fileName().toStdString().c_str(),
|
|
||||||
CURLFORM_END);
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, "http://pokerth.net/floty_upload/upload.php");
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
|
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
qDebug() << "curl_easy_perform failed: " << res << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = QString(curl_writedata->getData().data()).trimmed();
|
|
||||||
|
|
||||||
curl_formfree(post);
|
|
||||||
|
|
||||||
if(id.length() == 40 && !id.contains("ERROR")) {
|
|
||||||
|
|
||||||
qDebug() << id << endl;
|
|
||||||
QDesktopServices::openUrl(QUrl("http://logfile-analysis.pokerth.net/?ID="+id));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
qDebug() << QString::fromStdString(curl_writedata->getData()) << endl;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "curl_easy_init failed\n" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uploadInProgressAnimationStart();
|
||||||
|
uploader->QueueUpload(
|
||||||
|
"http://pokerth.nett/floty_upload/upload.php",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
file.fileName().toStdString(),
|
||||||
|
file.size(),
|
||||||
|
"pdb_file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFileDialog::uploadInProgressAnimationStart()
|
void LogFileDialog::uploadInProgressAnimationStart()
|
||||||
{
|
{
|
||||||
ui->pushButton_analyseLogfile->setDisabled(TRUE);
|
//const QString buttonText(tr("Upload in progress"));
|
||||||
|
ui->pushButton_analyseLogfile->setDisabled(TRUE);
|
||||||
|
|
||||||
QMovie *movie = new QMovie(":/gfx/loader.gif");
|
QMovie *movie = new QMovie(":/gfx/loader.gif");
|
||||||
ui->label_animation->setMovie(movie);
|
ui->label_animation->setMovie(movie);
|
||||||
@@ -281,3 +253,36 @@ void LogFileDialog::uploadInProgressAnimationStop()
|
|||||||
ui->horizontalLayout_animation->setSpacing(0);
|
ui->horizontalLayout_animation->setSpacing(0);
|
||||||
ui->label_animation->setGeometry(0,0,0,0);
|
ui->label_animation->setGeometry(0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogFileDialog::showLogAnalysis(QString /*filename*/, QString returnMessage)
|
||||||
|
{
|
||||||
|
uploadInProgressAnimationStop();
|
||||||
|
|
||||||
|
QString id = returnMessage.trimmed();
|
||||||
|
|
||||||
|
if(id.length() == 40 && !id.contains("ERROR")) {
|
||||||
|
|
||||||
|
qDebug() << id << endl;
|
||||||
|
QDesktopServices::openUrl(QUrl("http://logfile-analysis.pokerth.net/?ID="+id));
|
||||||
|
} else {
|
||||||
|
qDebug() << returnMessage << endl;
|
||||||
|
QString serverMsg(tr("Processing of the log file on the web server failed.\nPlease verify that you are uploading a valid PokerTH log file."));
|
||||||
|
// if there is a readable message, display it.
|
||||||
|
if (!returnMessage.isEmpty() && returnMessage.size() < 128) {
|
||||||
|
serverMsg += "\n" + tr("Failure reason: ") + returnMessage;
|
||||||
|
}
|
||||||
|
MyMessageBox::warning(
|
||||||
|
this, tr("Uploading log file"), serverMsg, QMessageBox::Close );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogFileDialog::showUploadError(QString /*filename*/, QString errorMessage)
|
||||||
|
{
|
||||||
|
uploadInProgressAnimationStop();
|
||||||
|
|
||||||
|
QString uploadMsg(tr("Upload failed. Please check your internet connection!\nUploading log files may fail if you are using an http proxy."));
|
||||||
|
uploadMsg += "\n" + tr("Failure reason: ") + errorMessage;
|
||||||
|
MyMessageBox::warning(
|
||||||
|
this, tr("Uploading log file"), uploadMsg, QMessageBox::Close );
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <net/uploadcallback.h>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
class UploaderThread;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class LogFileDialog;
|
class LogFileDialog;
|
||||||
@@ -32,7 +36,7 @@ class guiLog;
|
|||||||
class ConfigFile;
|
class ConfigFile;
|
||||||
class Callback;
|
class Callback;
|
||||||
|
|
||||||
class LogFileDialog : public QDialog
|
class LogFileDialog : public QDialog, public UploadCallback
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -43,6 +47,13 @@ public:
|
|||||||
void setGuiLog(guiLog *g) { myGuiLog = g; }
|
void setGuiLog(guiLog *g) { myGuiLog = g; }
|
||||||
void exec();
|
void exec();
|
||||||
|
|
||||||
|
virtual void UploadCompleted(const std::string &filename, const std::string &returnMessage);
|
||||||
|
virtual void UploadError(const std::string &filename, const std::string &errorMessage);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void signalUploadCompleted(QString filename, QString returnMessage);
|
||||||
|
void signalUploadError(QString filename, QString errorMessage);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void refreshLogFileList();
|
void refreshLogFileList();
|
||||||
void deleteLogFile();
|
void deleteLogFile();
|
||||||
@@ -57,6 +68,9 @@ public slots:
|
|||||||
void uploadInProgressAnimationStart();
|
void uploadInProgressAnimationStart();
|
||||||
void uploadInProgressAnimationStop();
|
void uploadInProgressAnimationStop();
|
||||||
|
|
||||||
|
void showLogAnalysis(QString filename, QString returnMessage);
|
||||||
|
void showUploadError(QString filename, QString errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigFile *myConfig;
|
ConfigFile *myConfig;
|
||||||
guiLog *myGuiLog;
|
guiLog *myGuiLog;
|
||||||
@@ -64,7 +78,7 @@ private:
|
|||||||
int writer(char *data, size_t size, size_t nmemb,std::string *buffer);
|
int writer(char *data, size_t size, size_t nmemb,std::string *buffer);
|
||||||
QFile file;
|
QFile file;
|
||||||
QString id;
|
QString id;
|
||||||
|
boost::shared_ptr<UploaderThread> uploader;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOGFILEDIALOG_H
|
#endif // LOGFILEDIALOG_H
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ DownloadHelper::~DownloadHelper()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DownloadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &/*user*/, const string &/*password*/, size_t /*filesize*/)
|
DownloadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &/*user*/, const string &/*password*/, size_t /*filesize*/, const string &/*httpPost*/)
|
||||||
{
|
{
|
||||||
// Open target file for writing.
|
// Open target file for writing.
|
||||||
GetData()->targetFile = fopen(targetFileName.c_str(), "wb");
|
GetData()->targetFile = fopen(targetFileName.c_str(), "wb");
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ using namespace std;
|
|||||||
TransferHelper::TransferHelper()
|
TransferHelper::TransferHelper()
|
||||||
{
|
{
|
||||||
m_data.reset(new TransferData);
|
m_data.reset(new TransferData);
|
||||||
m_data->curlHandle = NULL;
|
|
||||||
m_data->curlMultiHandle = NULL;
|
|
||||||
m_data->targetFile = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferHelper::~TransferHelper()
|
TransferHelper::~TransferHelper()
|
||||||
@@ -42,8 +39,11 @@ TransferHelper::~TransferHelper()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TransferHelper::Init(const string &url, const string &targetFileName, const string &user, const string &password, size_t filesize)
|
TransferHelper::Init(const string &url, const string &targetFileName, const string &user, const string &password, size_t filesize, const string &httpPost)
|
||||||
{
|
{
|
||||||
|
// Cleanup data.
|
||||||
|
Cleanup();
|
||||||
|
m_data->returnMessage.clear();
|
||||||
// Initialise curl.
|
// Initialise curl.
|
||||||
m_data->curlHandle = curl_easy_init();
|
m_data->curlHandle = curl_easy_init();
|
||||||
if (!m_data->curlHandle)
|
if (!m_data->curlHandle)
|
||||||
@@ -57,7 +57,7 @@ TransferHelper::Init(const string &url, const string &targetFileName, const stri
|
|||||||
if (curl_easy_setopt(m_data->curlHandle, CURLOPT_URL, m_data->curlUrl.c_str()) != CURLE_OK)
|
if (curl_easy_setopt(m_data->curlHandle, CURLOPT_URL, m_data->curlUrl.c_str()) != CURLE_OK)
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INVALID_URL, 0);
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INVALID_URL, 0);
|
||||||
|
|
||||||
InternalInit(url, targetFileName, user, password, filesize);
|
InternalInit(url, targetFileName, user, password, filesize, httpPost);
|
||||||
|
|
||||||
// Use the multi interface for better abort handling.
|
// Use the multi interface for better abort handling.
|
||||||
if (curl_multi_add_handle(m_data->curlMultiHandle, m_data->curlHandle) != CURLM_OK)
|
if (curl_multi_add_handle(m_data->curlMultiHandle, m_data->curlHandle) != CURLM_OK)
|
||||||
@@ -128,6 +128,10 @@ TransferHelper::Process()
|
|||||||
void
|
void
|
||||||
TransferHelper::Cleanup()
|
TransferHelper::Cleanup()
|
||||||
{
|
{
|
||||||
|
if (m_data->post) {
|
||||||
|
curl_formfree(m_data->post);
|
||||||
|
m_data->post = NULL;
|
||||||
|
}
|
||||||
if (m_data->curlMultiHandle) {
|
if (m_data->curlMultiHandle) {
|
||||||
curl_multi_cleanup(m_data->curlMultiHandle);
|
curl_multi_cleanup(m_data->curlMultiHandle);
|
||||||
m_data->curlMultiHandle = NULL;
|
m_data->curlMultiHandle = NULL;
|
||||||
@@ -143,6 +147,14 @@ TransferHelper::Cleanup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
TransferHelper::ResetLastMessage()
|
||||||
|
{
|
||||||
|
string retVal(m_data->returnMessage);
|
||||||
|
m_data->returnMessage.clear();
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TransferData>
|
boost::shared_ptr<TransferData>
|
||||||
TransferHelper::GetData()
|
TransferHelper::GetData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* PokerTH - The open source texas holdem engine *
|
||||||
|
* Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Affero General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <net/uploadcallback.h>
|
||||||
|
|
||||||
|
|
||||||
|
UploadCallback::~UploadCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <net/uploaderthread.h>
|
#include <net/uploaderthread.h>
|
||||||
#include <net/uploadhelper.h>
|
#include <net/uploadhelper.h>
|
||||||
|
#include <net/uploadcallback.h>
|
||||||
#include <net/netexception.h>
|
#include <net/netexception.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <core/loghelper.h>
|
#include <core/loghelper.h>
|
||||||
@@ -28,8 +29,8 @@ using namespace std;
|
|||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
|
|
||||||
UploaderThread::UploaderThread()
|
UploaderThread::UploaderThread(UploadCallback *callback)
|
||||||
: m_uploadInProgress(false)
|
: m_uploadInProgress(false), m_callback(callback)
|
||||||
{
|
{
|
||||||
m_uploadHelper.reset(new UploadHelper());
|
m_uploadHelper.reset(new UploadHelper());
|
||||||
}
|
}
|
||||||
@@ -39,15 +40,16 @@ UploaderThread::~UploaderThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UploaderThread::QueueUpload(const string &url, const string &user, const string &pwd, const string &filename, size_t filesize)
|
UploaderThread::QueueUpload(const string &url, const string &user, const string &pwd, const string &filename, size_t filesize, const string &httpPost)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
||||||
m_uploadQueue.push(UploadData(url, user, pwd, filename, filesize));
|
m_uploadQueue.push(UploadData(url, user, pwd, filename, filesize, httpPost));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UploaderThread::Main()
|
UploaderThread::Main()
|
||||||
{
|
{
|
||||||
|
string lastfile;
|
||||||
while (!ShouldTerminate()) {
|
while (!ShouldTerminate()) {
|
||||||
try {
|
try {
|
||||||
if (m_uploadInProgress) {
|
if (m_uploadInProgress) {
|
||||||
@@ -55,29 +57,40 @@ UploaderThread::Main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_uploadInProgress) {
|
if (!m_uploadInProgress) {
|
||||||
|
string lastMsg(m_uploadHelper->ResetLastMessage());
|
||||||
|
if (!lastMsg.empty() && m_callback) {
|
||||||
|
m_callback->UploadCompleted(lastfile, lastMsg);
|
||||||
|
}
|
||||||
Msleep(UPLOAD_DELAY_MSEC);
|
Msleep(UPLOAD_DELAY_MSEC);
|
||||||
// The upload needs only local state, as no value needs to be returned.
|
|
||||||
UploadData data;
|
UploadData data;
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
||||||
if (!m_uploadQueue.empty()) {
|
if (!m_uploadQueue.empty()) {
|
||||||
data = m_uploadQueue.front();
|
data = m_uploadQueue.front();
|
||||||
|
lastfile = data.filename;
|
||||||
m_uploadQueue.pop();
|
m_uploadQueue.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!data.filename.empty() && data.filesize > 0) {
|
if (!data.filename.empty() && data.filesize > 0) {
|
||||||
path filepath(data.filename);
|
path filepath(data.filename);
|
||||||
|
string url(data.address);
|
||||||
|
if (data.httpPost.empty()) {
|
||||||
#if BOOST_FILESYSTEM_VERSION != 3
|
#if BOOST_FILESYSTEM_VERSION != 3
|
||||||
m_uploadHelper->Init(data.address + filepath.leaf(), filepath.file_string(), data.user, data.pwd, data.filesize);
|
url += filepath.leaf();
|
||||||
#else
|
#else
|
||||||
m_uploadHelper->Init(data.address + filepath.filename().string(), filepath.file_string(), data.user, data.pwd, data.filesize);
|
url += filepath.filename().string();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
m_uploadHelper->Init(url, filepath.file_string(), data.user, data.pwd, data.filesize, data.httpPost);
|
||||||
m_uploadInProgress = true;
|
m_uploadInProgress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const NetException &e) {
|
} catch (const NetException &e) {
|
||||||
LOG_ERROR("Upload failed: " << e.what());
|
LOG_ERROR("Upload failed: " << e.what());
|
||||||
m_uploadInProgress = false;
|
m_uploadInProgress = false;
|
||||||
|
if (m_callback) {
|
||||||
|
m_callback->UploadError(lastfile, e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ readFunction(char *bufptr, size_t size, size_t nitems, void *userp)
|
|||||||
return fread(bufptr, size, nitems, (FILE *)userp);
|
return fread(bufptr, size, nitems, (FILE *)userp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
writeFunction(char *bufptr, size_t size, size_t nitems, void *userp)
|
||||||
|
{
|
||||||
|
string msgPart(bufptr, size * nitems);
|
||||||
|
((string *)userp)->append(msgPart);
|
||||||
|
return size * nitems;
|
||||||
|
}
|
||||||
|
|
||||||
UploadHelper::UploadHelper()
|
UploadHelper::UploadHelper()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -43,22 +51,35 @@ UploadHelper::~UploadHelper()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UploadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &user, const string &password, size_t filesize)
|
UploadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &user, const string &password, size_t filesize, const string &httpPost)
|
||||||
{
|
{
|
||||||
// Open target file for reading.
|
|
||||||
GetData()->targetFile = fopen(targetFileName.c_str(), "rb");
|
|
||||||
if (!GetData()->targetFile)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_OPEN_FAILED, 0);
|
|
||||||
|
|
||||||
GetData()->userCredentials = user + ":" + password;
|
|
||||||
// Assume that the following calls never fail.
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READFUNCTION, readFunction);
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READDATA, GetData()->targetFile);
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_INFILESIZE, filesize);
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_USERPWD, GetData()->userCredentials.c_str());
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_UPLOAD, 1L);
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_PUT, 1L);
|
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_SSL_VERIFYPEER, 0L);
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
curl_easy_setopt(GetData()->curlHandle, CURLOPT_SSL_VERIFYHOST, 0L);
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
|
||||||
|
if (!user.empty() || !password.empty()) {
|
||||||
|
GetData()->userCredentials = user + ":" + password;
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_USERPWD, GetData()->userCredentials.c_str());
|
||||||
|
}
|
||||||
|
if (httpPost.empty()) {
|
||||||
|
// Open target file for reading.
|
||||||
|
GetData()->targetFile = fopen(targetFileName.c_str(), "rb");
|
||||||
|
if (!GetData()->targetFile)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_OPEN_FAILED, 0);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READFUNCTION, readFunction);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READDATA, GetData()->targetFile);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_PUT, 1L);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_UPLOAD, 1L);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_INFILESIZE, filesize);
|
||||||
|
} else {
|
||||||
|
// Curl will handle file I/O.
|
||||||
|
struct curl_httppost *last = NULL;
|
||||||
|
curl_formadd(&GetData()->post, &last,
|
||||||
|
CURLFORM_COPYNAME, httpPost.c_str(),
|
||||||
|
CURLFORM_FILE, targetFileName.c_str(),
|
||||||
|
CURLFORM_END);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_HTTPPOST, GetData()->post);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_WRITEFUNCTION, writeFunction);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_WRITEDATA, &GetData()->returnMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
const std::string &user, const std::string &password, size_t filesize);
|
const std::string &user, const std::string &password,
|
||||||
|
size_t filesize, const std::string &httpPost);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -25,11 +25,14 @@
|
|||||||
|
|
||||||
|
|
||||||
struct TransferData {
|
struct TransferData {
|
||||||
|
TransferData() : curlHandle(NULL), curlMultiHandle(NULL), targetFile(NULL), post(NULL) {}
|
||||||
CURL *curlHandle;
|
CURL *curlHandle;
|
||||||
CURLM *curlMultiHandle;
|
CURLM *curlMultiHandle;
|
||||||
FILE *targetFile;
|
FILE *targetFile;
|
||||||
std::string curlUrl;
|
std::string curlUrl;
|
||||||
std::string userCredentials;
|
std::string userCredentials;
|
||||||
|
struct curl_httppost *post;
|
||||||
|
std::string returnMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ public:
|
|||||||
// Set the parameters. Does not do any error checking.
|
// Set the parameters. Does not do any error checking.
|
||||||
// Throws an exception on failure.
|
// Throws an exception on failure.
|
||||||
void Init(const std::string &url, const std::string &targetFileName,
|
void Init(const std::string &url, const std::string &targetFileName,
|
||||||
const std::string &user = "", const std::string &password = "", size_t filesize = 0);
|
const std::string &user = "", const std::string &password = "",
|
||||||
|
size_t filesize = 0, const std::string &httpPost = "");
|
||||||
|
|
||||||
// Returns true when done, false should call again.
|
// Returns true when done, false should call again.
|
||||||
// Throws an exception on error.
|
// Throws an exception on error.
|
||||||
@@ -44,11 +45,15 @@ public:
|
|||||||
// Close all handles.
|
// Close all handles.
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
|
// Get and reset the last (error) message.
|
||||||
|
std::string ResetLastMessage();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boost::shared_ptr<TransferData> GetData();
|
boost::shared_ptr<TransferData> GetData();
|
||||||
|
|
||||||
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
const std::string &user, const std::string &password, size_t filesize) = 0;
|
const std::string &user, const std::string &password,
|
||||||
|
size_t filesize, const std::string &httpPost) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* PokerTH - The open source texas holdem engine *
|
||||||
|
* Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Affero General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
*****************************************************************************/
|
||||||
|
/* Network file upload callback. */
|
||||||
|
|
||||||
|
#ifndef _UPLOADCALLBACK_H_
|
||||||
|
#define _UPLOADCALLBACK_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class UploadCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~UploadCallback();
|
||||||
|
|
||||||
|
virtual void UploadCompleted(const std::string &filename, const std::string &returnMessage) = 0;
|
||||||
|
virtual void UploadError(const std::string &filename, const std::string &errorMessage) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _UPLOADCALLBACK_H_
|
||||||
@@ -27,27 +27,29 @@
|
|||||||
|
|
||||||
#define UPLOADER_THREAD_TERMINATE_TIMEOUT THREAD_WAIT_INFINITE
|
#define UPLOADER_THREAD_TERMINATE_TIMEOUT THREAD_WAIT_INFINITE
|
||||||
class UploadHelper;
|
class UploadHelper;
|
||||||
|
class UploadCallback;
|
||||||
|
|
||||||
class UploaderThread : public Thread
|
class UploaderThread : public Thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UploaderThread();
|
UploaderThread(UploadCallback *callback = NULL);
|
||||||
virtual ~UploaderThread();
|
virtual ~UploaderThread();
|
||||||
|
|
||||||
void QueueUpload(const std::string &url, const std::string &user, const std::string &pwd, const std::string &filename, size_t filesize);
|
void QueueUpload(const std::string &url, const std::string &user, const std::string &pwd, const std::string &filename, size_t filesize, const std::string &httpPost = "");
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct UploadData {
|
struct UploadData {
|
||||||
UploadData() : filesize(0) {}
|
UploadData() : filesize(0) {}
|
||||||
UploadData(const std::string &a, const std::string &u, const std::string &p, const std::string &f, size_t s)
|
UploadData(const std::string &a, const std::string &u, const std::string &p, const std::string &f, size_t s, const std::string &h)
|
||||||
: address(a), user(u), pwd(p), filename(f), filesize(s) {}
|
: address(a), user(u), pwd(p), filename(f), filesize(s), httpPost(h) {}
|
||||||
|
|
||||||
std::string address;
|
std::string address;
|
||||||
std::string user;
|
std::string user;
|
||||||
std::string pwd;
|
std::string pwd;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
size_t filesize;
|
size_t filesize;
|
||||||
|
std::string httpPost;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::queue<UploadData> UploadDataQueue;
|
typedef std::queue<UploadData> UploadDataQueue;
|
||||||
@@ -62,6 +64,7 @@ private:
|
|||||||
|
|
||||||
boost::shared_ptr<UploadHelper> m_uploadHelper;
|
boost::shared_ptr<UploadHelper> m_uploadHelper;
|
||||||
bool m_uploadInProgress;
|
bool m_uploadInProgress;
|
||||||
|
UploadCallback *m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
const std::string &user, const std::string &password, size_t filesize);
|
const std::string &user, const std::string &password,
|
||||||
|
size_t filesize, const std::string &httpPost);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user