Browse Source

- GTSOUL, wtf you're doing??? Committing back the new downloadThread.h

adaptive-webui-19844
Christophe Dumez 18 years ago
parent
commit
a74dc5ee35
  1. 1
      TODO
  2. 132
      src/downloadThread.h

1
TODO

@ -43,6 +43,7 @@
- Complete documentation and english translation - Complete documentation and english translation
* beta3 * beta3
- Windows port (Chris - GTSoul - Peerkoel) - Windows port (Chris - GTSoul - Peerkoel)
- Translations update
* beta2 * beta2
- Display rss streams icons (+ code cleanup) -> GTSoul - Display rss streams icons (+ code cleanup) -> GTSoul
- Wait for some bug fixes in libtorrent : - Wait for some bug fixes in libtorrent :

132
src/downloadThread.h

@ -28,11 +28,15 @@
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QWaitCondition> #include <QWaitCondition>
#include <curl/curl.h>
#include <iostream> #include <iostream>
#include <cc++/common.h>
#include "misc.h" #include "misc.h"
#ifdef CCXX_NAMESPACES
using namespace std;
using namespace ost;
#endif
class downloadThread : public QThread { class downloadThread : public QThread {
Q_OBJECT Q_OBJECT
@ -41,9 +45,11 @@ class downloadThread : public QThread {
QMutex mutex; QMutex mutex;
QWaitCondition condition; QWaitCondition condition;
bool abort; bool abort;
URLStream url_stream;
signals: signals:
void downloadFinished(const QString& url, const QString& file_path, int return_code, const QString& errorBuffer); void downloadFinished(const QString& url, const QString& file_path);
void downloadFailure(const QString& url, const QString& reason);
public: public:
downloadThread(QObject* parent) : QThread(parent){ downloadThread(QObject* parent) : QThread(parent){
@ -73,6 +79,33 @@ class downloadThread : public QThread {
} }
} }
QString errorCodeToString(URLStream::Error status){
switch(status){
case URLStream::errUnreachable:
return tr("Host is unreachable");
case URLStream::errMissing:
return tr("File was not found (404)");
case URLStream::errDenied:
return tr("Connection was denied");
case URLStream::errInvalid:
return tr("Url is invalid");
case URLStream::errForbidden:
return tr("Connection forbidden (403)");
case URLStream::errUnauthorized:
return tr("Connection was not authorized (401)");
case URLStream::errRelocated:
return tr("Content has moved (301)");
case URLStream::errFailure:
return tr("Connection failure");
case URLStream::errTimeout:
return tr("Connection was timed out");
case URLStream::errInterface:
return tr("Incorrect network interface");
default:
return tr("Unknown error");
}
}
protected: protected:
void run(){ void run(){
forever{ forever{
@ -84,80 +117,41 @@ class downloadThread : public QThread {
QString url = url_list.takeFirst(); QString url = url_list.takeFirst();
mutex.unlock(); mutex.unlock();
qDebug("In Download thread RUN, mutex unlocked (got url)"); qDebug("In Download thread RUN, mutex unlocked (got url)");
CURL *curl;
QString filePath;
int return_code, response;
// XXX: Trick to get a unique filename // XXX: Trick to get a unique filename
QTemporaryFile *tmpfile = new QTemporaryFile; QString filePath;
QTemporaryFile *tmpfile = new QTemporaryFile();
if (tmpfile->open()) { if (tmpfile->open()) {
filePath = tmpfile->fileName(); filePath = tmpfile->fileName();
} }
delete tmpfile; delete tmpfile;
if(abort) QFile dest_file(filePath);
return; if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){
FILE *file = fopen((const char*)filePath.toUtf8(), "w"); std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n';
if(!file){ continue;
std::cerr << "Error: could not open temporary file...\n";
return;
} }
// Initilization required by libcurl URLStream::Error status = url_stream.get((const char*)url.toUtf8());
curl = curl_easy_init(); if(status){
if(!curl){ // Failure
std::cerr << "Error: Failed to init curl...\n"; QString error_msg = QString(misc::toString(status).c_str());
fclose(file); qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8());
return; url_stream.close();
emit downloadFailure(url, errorCodeToString(status));
continue;
} }
// Set url to download qDebug("Downloading %s...", (const char*)url.toUtf8());
curl_easy_setopt(curl, CURLOPT_URL, url.toLocal8Bit().constData()); char cbuf[1024];
qDebug("Url: %s", url.toLocal8Bit().constData()); int len;
// Define our callback to get called when there's data to be written while(!url_stream.eof()) {
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, misc::my_fwrite); url_stream.read(cbuf, sizeof(cbuf));
// Set destination file len = url_stream.gcount();
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); if(len > 0){
// Some SSL mambo jambo dest_file.write(cbuf, len);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); }
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// Disable progress meter
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
// Any kind of authentication
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
// Auto referrer
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
// Follow redirections
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
// Enable cookies
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
// We want error message:
char errorBuffer[CURL_ERROR_SIZE];
errorBuffer[0]=0; /* prevent junk from being output */
return_code = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
if(return_code){
std::cerr << "Error: failed to set error buffer in curl\n";
fclose(file);
QFile::remove(filePath);
return;
} }
unsigned short retries = 0; dest_file.close();
bool to_many_users = false; url_stream.close();
do{ emit downloadFinished(url, filePath);
// Perform Download qDebug("In Download thread RUN, signal emitted");
return_code = curl_easy_perform(curl);
// We want HTTP response code
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
qDebug("HTTP response code: %d", response);
if(response/100 == 5){
to_many_users = true;
++retries;
SleeperThread::msleep(1000);
}
}while(to_many_users && retries < 10 && response!=0);
// Cleanup
curl_easy_cleanup(curl);
// Close tmp file
fclose(file);
emit downloadFinished(url, filePath, return_code, QString(errorBuffer));
qDebug("In Download thread RUN, signal emitted, ErrorBuffer: %s", errorBuffer);
}else{ }else{
qDebug("In Download thread RUN, mutex still locked (no urls) -> sleeping"); qDebug("In Download thread RUN, mutex still locked (no urls) -> sleeping");
condition.wait(&mutex); condition.wait(&mutex);

Loading…
Cancel
Save