PDA

View Full Version : Problem with curl writefunction



januszmk
26th July 2011, 12:47
Hello.
I have little problem.
I have functions:

size_t WriteData(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int MainWindow::progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
{
ui->progressBar->setMaximum(TotalToDownload);
ui->progressBar->setValue(NowDownloaded);
double speed;
curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &speed);
ui->label_2->setText(QString("Prędkość: %0").arg(speed));
return NowDownloaded;
}
bool MainWindow::downloadFile(QString url, QString filename)
{
FILE *fp;
fp = fopen(filename.toStdString().c_str(), "wb");
ui->label->setText(filename);
ui->label_2->setText("Predkosc: 0 KB/s");
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "User-Agent: Mozilla/5.0 (compatible;)");
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookie");
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie");
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_URL, url.toStdString().c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &MainWindow::progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this);
status = curl_easy_perform(curl);
if(status !=0)
qDebug() << QString("curl_easy_perform() error: %0").arg(curl_easy_strerror(status));
curl_easy_cleanup(curl);
fclose(fp);
return true;
}
When I try to download a file, window of my aplication is frozen(?) until downloading is not finished.
Could you suggest what could I do to make this work?
Sory for my bad english
Janusz

mcosta
26th July 2011, 18:00
A solution could be to execute this function in a separate thread.

Why you use CURL and not QtNetwork?

januszmk
26th July 2011, 20:23
Thanks, when I execute function in another thread, it's start working. But progress function is still not working:

int MainWindow::progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
{

int total = (int)TotalToDownload;

ui->progressBar->setMaximum(total);
int now = (int)NowDownloaded;
ui->progressBar->setValue(now);
qDebug() << QString("%0 : %1").arg(now).arg(total);
double speed;
curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &speed);
int speed1 = (int)speed;
ui->label_2->setText(QString("Predkosc: %0 B/s").arg(speed1));
// qDebug() << speed;
return NowDownloaded;
}
now and total always = 0 why?
I am using curl because I have more experience with curl (from php), and in QtNetwork even if I used cookies, websites detect then I have disabled cookies.

mcosta
26th July 2011, 20:31
First of all, these line are wrong



qDebug() << QString("%0 : %1").arg(now).arg(total);
ui->label_2->setText(QString("Predkosc: %0 B/s").arg(speed1));


the placeholder for arg are 1 based so you have to rewrite them as



qDebug() << QString("%1 : %2").arg(now).arg(total);
ui->label_2->setText(QString("Predkosc: %1 B/s").arg(speed1));

januszmk
26th July 2011, 20:39
With arg there are no problem, because speed1 is showing property, but when I update progressbar, then i don't get property value. the value of double variable is something like that: "5.39501e-315" and when I am converting like that:

int var = (int)doublevar;
then I get value 0

Edit:
I tried to do this like that:

int total = 100;
double temp = NowDownloaded/TotalToDownload;
temp = temp*100;
int total = round(temp);
But when I downloading file, then on the start i get 99% and when i get couple of hundred KB (total is 19MB) then I get 100%

januszmk
27th July 2011, 09:17
I make this work by:

double bytesRead;
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &bytesRead);
double totaltoread;
curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &totaltoread);
Thanks for all