====== Scaricare un file dal web con Curl e Gtk3 ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **// 26/09/2018 - 12:13 //** // //
{{:programmazione:gtk:download_curl_gtk.png|}}
**main.c**
#include
#include
GObject *btStart, *entry ;
gdouble progress;
//Questa funzione aggiorna la GtkProgressbar (viene ripetuta dal timeout)
gboolean updateProgressbar(gpointer data)
{
g_print("UpdateProgressbar...");
if (progress>=0.1 && progress<=1.0)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(data), progress);
}
if (progress>=1.0)
{
gtk_widget_set_sensitive(GTK_WIDGET(btStart), TRUE) ;
gtk_progress_bar_set_text (GTK_PROGRESS_BAR(data),"Scaricamento terminato.");
g_print("\n Stop updateProgressbar .\n");
return FALSE;
}
return TRUE;
}
//Questa callback scrive il file scaricato
size_t writecallback(void *buffer, size_t size, size_t nmemb, void *stream){
int written = fwrite(buffer, size, nmemb, (FILE *)stream);
return written;
}
//Questa callback scrive il progresso sulla variabile "progress"
int progressDownload( void* ptr,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
double percento= d*100/t;
progress=percento/100;
return 0;
}
//Funzione che viene avviata dal thread avvia il download
void *Download(char *url)
{
g_print("Inside thread...\n");
CURL *curl;
CURLcode res;
char errbuf[CURL_ERROR_SIZE];
//long httpFail;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecallback);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressDownload);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
//curl_easy_setopt(curl, CURLOPT_FAILONERROR, httpFail); //gestione errori, da vedere
char *outFile= g_path_get_basename (url);
FILE *f = fopen(outFile,"wb");
if (f == NULL) {
curl_easy_cleanup(curl);
progress=1.0;
}
curl_easy_setopt(curl,CURLOPT_WRITEDATA, f);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
progress=1.0;
size_t len = strlen(errbuf);
if(len)
{
g_print("Errore: %s\n", errbuf);
}
}
//if (httpFail>=400) g_print("Problema http: %ld\n", httpFail);
curl_easy_cleanup(curl);
fclose(f);
}
}
//Callback che crea lancia il thread
void
startThread (GtkWidget *widget, gpointer data)
{
progress=0;
gchar* url =gtk_entry_get_text(GTK_ENTRY(entry));
g_timeout_add(1000, updateProgressbar, data);
GThread *myThread;
myThread= g_thread_new(NULL,(GThreadFunc)Download,url);
gtk_widget_set_sensitive(widget, FALSE) ;
gtk_progress_bar_set_text (GTK_PROGRESS_BAR(data),"Scaricamento in corso...");
}
void on_mainWindow_delete_event(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
void mainWindowInit()
{
GError* error = NULL;
gchar* glade_file = g_build_filename("gui.ui", NULL);
GtkBuilder *xml;
GObject *mainWindow, *progressBar, *lbl ;
xml = gtk_builder_new ();
if (!gtk_builder_add_from_file (xml, glade_file, &error))
{
g_warning ("Couldn\'t load builder file: %s", error->message);
g_error_free (error);
}
mainWindow=gtk_builder_get_object (xml,"mainWindow" );
btStart=gtk_builder_get_object (xml,"btStart" );
progressBar=gtk_builder_get_object(xml,"progressBar");
entry=gtk_builder_get_object(xml,"entry");
lbl=gtk_builder_get_object(xml,"lbl");
g_object_unref( G_OBJECT( xml ) );
g_signal_connect (mainWindow, "destroy", G_CALLBACK (on_mainWindow_delete_event), NULL);
g_signal_connect (btStart, "clicked", G_CALLBACK (startThread),progressBar );
}
int main (int argc, char **argv)
{
gtk_init (&argc, &argv);
mainWindowInit();
gtk_main ();
return 0;
}
**makefile**
all:
gcc main.c -o simple `pkg-config --cflags --libs gtk+-3.0 gthread-2.0 ` `curl-config --cflags --libs`
**gui.ui**