Barra laterale

programmazione:gtk:scaricare_file_dal_web

Scaricare un file dal web con Curl e Gtk3

Autore: Fabio Di Matteo
Ultima revisione: 26/09/2018 - 12:13

main.c

#include <gtk/gtk.h>
#include <curl/curl.h>
 
 
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

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="mainWindow">
    <property name="width_request">406</property>
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="has_resize_grip">True</property>
    <signal name="delete-event" handler="on_mainWindow_delete_event()" swapped="no"/>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkEntry" id="entry">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <object class="GtkProgressBar" id="progressBar">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="text" translatable="yes">Progresso</property>
            <property name="show_text">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
    <child type="titlebar">
      <object class="GtkHeaderBar">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="title">Scarica un file dal web</property>
        <property name="subtitle">Usa lib curl per scaricare un file dal web.</property>
        <property name="show_close_button">True</property>
        <child>
          <object class="GtkBox">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkButton" id="btStart">
                <property name="label">gtk-execute</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

programmazione/gtk/scaricare_file_dal_web.txt · Ultima modifica: 26/09/2018 - 12:18 da Fabio Di Matteo