my first git commit
[gwget-havlin.git] / src / gwget_data.c
blob9480f34942ec2866684241ba7309d7fb6d6e46e0
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #define _FILE_OFFSET_BITS 64
18 #include <config.h>
19 #include <gio/gio.h>
20 #include <glib.h>
21 #include <glib/gstdio.h>
22 #include <glib/gi18n.h>
23 #include <gtk/gtk.h>
25 #include <fcntl.h>
26 #include <signal.h>
27 #include <stdlib.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include "gwget_data.h"
37 #include "wget-log.h"
38 #include "main_window.h"
39 #include "main_window_cb.h"
40 #include "utils.h"
41 #include "systray.h"
45 static gint gwget_data_process_information (GwgetData *gwgetdata);
46 static void gwget_data_update_statistics_ui(GwgetData *gwgetdata);
47 static void convert_time2str(gchar *buffer, guint32 time);
48 static void gwget_gnotify_finished(GwgetData *gwgetdata);
49 static void gwget_download_finished(GwgetData *gwgetdata);
50 static gboolean gwget_ask_download_playlist(GwgetData *gwgetdata);
51 static void gwget_download_playlist_items(gchar *filename);
53 static void
54 convert_time2str (gchar *buffer, guint32 time)
56 sprintf (buffer, "%02d:%02d:%02d", (gint)(time / 3600),
57 (gint)((time % 3600) / 60), (gint)(time % 60));
60 void
61 gwget_data_set_state_no_sync (GwgetData *gwgetdata, DlState state)
63 gwgetdata->state=state;
64 gwget_data_update_statistics_ui(gwgetdata);
68 void
69 gwget_data_set_state (GwgetData *gwgetdata, DlState state)
71 gwget_data_set_state_no_sync(gwgetdata, state);
72 gwget_remember_downloads();
75 void
76 gwget_data_update_statistics (GwgetData *gwgetdata)
78 guint64 cur_size;
79 time_t cur_time, elapsed_time;
80 struct stat file_stat;
81 gchar buffer[20];
82 guint64 retr_size, remain_size;
83 time_t estimated;
84 gdouble perc;
85 gchar *title;
88 /* Get time and size of the file being retrieved */
89 if (stat (gwgetdata->local_filename, &file_stat) != -1) {
90 cur_size = (guint64) file_stat.st_size;
91 cur_time = file_stat.st_ctime;
92 } else {
93 cur_size = 0;
94 cur_time = 0;
97 gwgetdata->cur_size = cur_size;
98 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
99 STATE_INT_COLUMN,gwgetdata->state,
100 -1);
102 /* Set the total and session time */
103 if ((gwgetdata->state != DL_NOT_STARTED) &&
104 (gwgetdata->state != DL_NOT_RUNNING) &&
105 (gwgetdata->state != DL_NOT_CONNECTED) &&
106 (gwgetdata->state != DL_ERROR) &&
107 (gwgetdata->state != DL_WAITING) &&
108 (gwgetdata->state != DL_COMPLETED))
110 elapsed_time = cur_time - gwgetdata->session_start_time;
111 gwgetdata->total_time += elapsed_time - gwgetdata->session_elapsed;
112 gwgetdata->session_elapsed = elapsed_time;
113 } else {
114 gwgetdata->session_elapsed = 0;
117 convert_time2str (buffer, gwgetdata->session_elapsed);
119 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
120 ELAPSETIME_COLUMN,buffer,
121 -1);
122 convert_time2str (buffer, gwgetdata->total_time);
124 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
125 TOTALTIME_COLUMN, buffer,
126 -1);
128 retr_size = gwgetdata->cur_size - gwgetdata->session_start_size;
129 remain_size = gwgetdata->total_size - gwgetdata->cur_size;
131 /* Total Size */
132 if (gwgetdata->state == DL_NOT_STARTED)
133 strcpy (buffer, "");
134 else
135 sprintf (buffer, "%d kB", (guint32)(gwgetdata->total_size + 512) / 1024);
137 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
138 TOTALSIZE_COLUMN,buffer,
139 -1);
142 /* Update retrieved information */
143 if (gwgetdata->state == DL_NOT_STARTED || gwgetdata->state == DL_COMPLETED)
144 strcpy (buffer, "");
145 else
146 sprintf (buffer, "%d kB",(guint32) (gwgetdata->cur_size + 512) / 1024);
147 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
148 CURRENTSIZE_COLUMN,buffer,
149 -1);
152 /* Update estimated and remain times */
153 if ((gwgetdata->state != DL_NOT_STARTED) &&
154 (gwgetdata->state != DL_NOT_RUNNING) &&
155 (gwgetdata->state != DL_NOT_CONNECTED) &&
156 (gwgetdata->state != DL_ERROR) &&
157 (gwgetdata->state != DL_WAITING) &&
158 (gwgetdata->state != DL_COMPLETED))
160 if (gwgetdata->total_size != 0 && retr_size != 0) {
161 estimated = (((gfloat) (gwgetdata->total_size - gwgetdata->session_start_size)
162 * gwgetdata->session_elapsed) / retr_size)
163 + ((gfloat) (gwgetdata->total_time
164 - gwgetdata->session_elapsed));
165 } else {
166 estimated=0;
168 } else {
169 estimated = 0;
172 if (estimated == 0)
173 strcpy (buffer, "");
174 else
175 convert_time2str (buffer, estimated);
178 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
179 ESTIMATEDTIME_COLUMN,buffer,
180 -1);
182 /* Remain Time */
183 if (estimated == 0) {
184 strcpy (buffer, "");
185 } else {
186 convert_time2str (buffer, estimated - gwgetdata->total_time);
188 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
189 REMAINTIME_COLUMN,buffer,
190 -1);
191 /* Percent column */
192 sprintf(buffer,"%.1f%%", gwgetdata->total_size==0?0:((gfloat)gwgetdata->cur_size*100)/(gfloat)gwgetdata->total_size);
193 perc = gwgetdata->total_size==0?0:((gdouble)gwgetdata->cur_size*100)/(gdouble)gwgetdata->total_size;
194 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
195 PERCENTAGE_COLUMN,(gint)perc,-1);
196 title = g_strdup_printf("%s %d %%", gwgetdata->filename, (gint)perc);
197 /* Speed column */
198 if ((gwgetdata->state != DL_NOT_STARTED) &&
199 (gwgetdata->state != DL_NOT_RUNNING) &&
200 (gwgetdata->state != DL_NOT_CONNECTED) &&
201 (gwgetdata->state != DL_ERROR) &&
202 (gwgetdata->state != DL_WAITING) &&
203 (gwgetdata->state != DL_COMPLETED) &&
204 (gwgetdata->session_elapsed != 0))
206 if (retr_size == 0) {
207 strcpy (buffer, _("stalled"));
208 } else {
209 sprintf (buffer, "%.2f kB/s",
210 ((gfloat) retr_size / gwgetdata->session_elapsed) / 1024);
212 } else {
213 strcpy (buffer, "");
216 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
217 SPEED_COLUMN,buffer,-1);
219 /* Update the filename */
220 gtk_list_store_set(GTK_LIST_STORE(model),
221 &gwgetdata->file_list,
222 FILENAME_COLUMN,
223 gwgetdata->filename,
224 -1);
226 gwget_data_update_statistics_ui(gwgetdata);
227 if (gwgetdata == gwget_data_get_selected() || count_download_in_progress() == 1 ) {
228 gtk_window_set_title(GTK_WINDOW(GTK_WIDGET (gtk_builder_get_object(builder, "main_window"))), title);
232 check_download_in_progress();
235 static void
236 gwget_data_update_statistics_ui(GwgetData *gwgetdata)
238 switch(gwgetdata->state) {
239 case DL_WAITING: gwgetdata->state_str = g_strdup(_("Waiting"));
240 break;
241 case DL_NOT_STARTED: gwgetdata->state_str = g_strdup(_("Not Started"));
242 break;
243 case DL_NOT_RUNNING: gwgetdata->state_str = g_strdup(_("Not Running"));
244 break;
245 case DL_NOT_CONNECTED: gwgetdata->state_str = g_strdup(_("Not Connected"));
246 break;
247 case DL_CONNECTED: gwgetdata->state_str = g_strdup(_("Connected"));
248 break;
249 case DL_RETRIEVING: gwgetdata->state_str = g_strdup(_("Retrieving"));
250 break;
251 case DL_COMPLETED: gwgetdata->state_str=g_strdup(_("Completed"));
252 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
253 PERCENTAGE_COLUMN,100,-1);
254 break;
255 case DL_ERROR: gwgetdata->state_str = g_strdup_printf("%s: %s",_("Error"),gwgetdata->error_msg);
256 break;
261 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
262 STATE_COLUMN,gwgetdata->state_str,
263 -1);
267 static gint
268 gwget_data_process_information (GwgetData *gwgetdata)
270 pid_t child_pid;
271 gint status;
273 /* Process wget_log messages */
274 wget_log_process (gwgetdata);
276 /* Check that wget process is still running */
277 child_pid = waitpid (gwgetdata->wget_pid, &status, WNOHANG | WUNTRACED);
278 if (child_pid == gwgetdata->wget_pid) {
280 * Use any information wget logged and we did not read
282 wget_drain_remaining_log(gwgetdata);
284 /* Wget process stopped so we must register its exit */
285 close (gwgetdata->log_fd);
286 g_free (gwgetdata->line);
287 gwgetdata->line = NULL;
289 /* Set the appropriate state after stopping */
290 if (gwgetdata->error)
291 gwget_data_set_state (gwgetdata, DL_ERROR);
292 else if (WIFEXITED (status)) {
293 if (WEXITSTATUS (status) == 0) {
294 gwget_data_set_state (gwgetdata, DL_COMPLETED);
295 gwget_download_finished(gwgetdata);
296 start_first_waiting_download();
297 if (gwget_pref.open_after_dl) {
298 gwget_data_exec(gwgetdata);
300 } else if (WEXITSTATUS (status) == 255) {
301 /* Only reaches here if wget is not found */
302 gwget_data_set_state (gwgetdata, DL_NOT_RUNNING);
303 g_warning ("couldn't find program wget to exec\n");
304 } else {
305 if (gwgetdata->state!=DL_WAITING) {
306 gwget_data_set_state (gwgetdata, DL_NOT_RUNNING);
309 } else {
310 gwget_data_set_state (gwgetdata, DL_NOT_RUNNING);
312 gwget_data_update_statistics (gwgetdata);
314 /* Decrease the number of current downloads */
315 if (num_of_download > 0)
316 num_of_download--;
318 /* All done this download can be started again */
319 gwgetdata->log_tag = -1;
321 return FALSE;
323 return TRUE;
326 void
327 gwget_data_free(gpointer data)
329 g_free(data);
332 void
333 gwget_data_start_download(GwgetData *gwgetdata)
335 pid_t pid;
336 gint pipe_fd[2];
337 gint number;
338 gchar *user_password;
339 user_password=g_strdup("");
340 /* Control the number of download allowed */
341 number=count_download_in_progress();
343 if (gwget_pref.limit_simultaneousdownloads==TRUE && number>=gwget_pref.max_simultaneousdownloads) {
344 gwget_data_set_state_no_sync(gwgetdata,DL_WAITING);
345 return;
348 /* Put the not connected state before */
349 gwget_data_set_state_no_sync(gwgetdata,DL_NOT_CONNECTED);
350 gwget_data_update_statistics_ui(gwgetdata);
352 /* First check if we are not starting an already started download */
353 if (!gwget_data_run (gwgetdata) && gwgetdata->state != DL_COMPLETED) {
354 if (pipe (pipe_fd) < 0) {
355 g_warning ("couldn't create wget pipe");
356 return;
358 pid = fork ();
359 if (pid == 0) {
360 /* Child process */
361 gint arg;
362 gchar *argv[20];
364 /* Set stderr of child process to one end of the pipe. The father */
365 /* process reads child output throught the pipe */
366 close (pipe_fd[0]);
367 dup2 (pipe_fd[1], 2);
369 /* Set common arguments */
370 argv[0] = "wget";
371 argv[1] = "-v"; /* Verbose */
372 argv[2] = "-P"; /* Use directory prefix */
373 argv[3] = gwgetdata->dir; /* Directory prefix */
374 argv[4] = gwgetdata->url; /* Url to download */
375 argv[5] = "-c"; /* Continue download */
376 argv[6] = "-t"; /* Number of retries */
377 argv[7] = g_strdup_printf ("%d", gwget_pref.num_retries);
379 arg = 8;
380 /* Preferences */
381 if (gwgetdata->recursive) {
382 /* recursive options */
383 argv[arg]="-r";
384 arg++;
385 if (gwgetdata->multimedia) {
386 argv[arg]="-l1";
387 arg++;
388 argv[arg]="-Ajpg";
389 arg++;
390 argv[arg]="-Agif";
391 arg++;
392 argv[arg]="-Ampg";
393 arg++;
394 argv[arg]="-Ampeg";
395 arg++;
396 argv[arg]="-Aavi";
397 arg++;
398 argv[arg]="-Apng";
399 arg++;
400 argv[arg]="-Awmv";
401 arg++;
403 if (gwgetdata->mirror) {
404 argv[arg]="-m";
405 arg++;
408 if (gwget_pref.no_create_directories) {
409 argv[arg]="-nd";
410 arg++;
413 if (!gwgetdata->multimedia && !gwgetdata->mirror){
415 if (gwget_pref.follow_relative) {
416 argv[arg]="-L";
417 arg++;
419 if (gwget_pref.convert_links) {
420 argv[arg]="-k";
421 arg++;
423 if (gwget_pref.dl_page_requisites) {
424 argv[arg]="-p";
425 arg++;
428 argv[arg]="-l";
429 arg++;
430 argv[arg]=g_strdup_printf("%d",gwget_pref.max_depth);
431 arg++;
435 if (gwget_pref.limit_speed) {
436 argv[arg] = g_strdup_printf("--limit-rate=%dk",
437 gwget_pref.max_speed);
438 arg++;
441 if ( strcmp (gwget_pref.network_mode, "manual") == 0 &&
442 gwget_pref.http_proxy )
444 if(gwget_pref.proxy_uses_auth)
446 user_password=g_strdup_printf("%s:%s@",gwget_pref.proxy_user,gwget_pref.proxy_password);
449 setenv("http_proxy", g_strconcat("http://", g_strdup_printf("%s", user_password),g_strdup_printf("%s",gwget_pref.http_proxy),":",g_strdup_printf("%d",gwget_pref.http_proxy_port),NULL), 1);
450 setenv("ftp_proxy", g_strconcat("http://", g_strdup_printf("%s", user_password),g_strdup_printf("%s",gwget_pref.http_proxy),":",g_strdup_printf("%d",gwget_pref.http_proxy_port),NULL), 1);
451 argv[arg]="-Yon";
452 arg++;
455 if ( strcmp (gwget_pref.network_mode, "default" ) == 0 && gwget_pref.gnome_http_proxy && gwget_pref.gnome_use_proxy)
457 if(gwget_pref.gnome_proxy_uses_auth)
459 user_password=g_strdup_printf("%s:%s@",gwget_pref.gnome_proxy_user,gwget_pref.gnome_proxy_password);
462 setenv("http_proxy",g_strconcat("http://", g_strdup_printf("%s", user_password), g_strdup_printf("%s", gwget_pref.gnome_http_proxy),":", g_strdup_printf("%d", gwget_pref.gnome_http_proxy_port),NULL),1);
463 setenv("ftp_proxy",g_strconcat("http://", g_strdup_printf("%s", user_password), g_strdup_printf("%s", gwget_pref.gnome_http_proxy),":", g_strdup_printf("%d", gwget_pref.gnome_http_proxy_port),NULL),1);
464 argv[arg]="-Yon";
465 arg++;
469 argv[arg] = NULL;
471 /* Set Language to C. This must be done or we will not be able */
472 /* to parse the wget output */
473 putenv ("LC_ALL=C");
475 /* Everything ready run wget */
476 execvp ("wget", argv);
478 /* If we get here wget was not found so we return an error 255 */
479 _exit (255);
481 if (pid < 0) {
482 g_warning ("couldn't fork wget");
483 return;
486 gtk_list_store_set(GTK_LIST_STORE(model),&gwgetdata->file_list,
487 PID_COLUMN,pid, -1);
489 close (pipe_fd[1]);
490 gwgetdata->wget_pid = pid;
492 gwgetdata->log_fd = pipe_fd[0];
493 fcntl (gwgetdata->log_fd, F_SETFL, O_NONBLOCK);
494 gwgetdata->log_tag = gtk_timeout_add (1000,
495 (GtkFunction) gwget_data_process_information,
496 gwgetdata);
500 * Update download list in gconf
502 gwget_remember_downloads();
505 void
506 gwget_data_set_total_size (GwgetData *gwgetdata, guint64 total_size)
508 g_return_if_fail (gwgetdata != NULL);
509 gwgetdata->total_size = total_size;
512 GwgetData *
513 gwget_data_new (gchar *url)
516 return gwget_data_create (url, gwget_pref.download_dir);
520 GwgetData *
521 gwget_data_create(gchar *url, gchar *dir)
523 GwgetData *gwgetdata;
524 GFile *file;
525 GFileInfo *info;
526 gint length;
527 GError *err = NULL;
529 g_return_val_if_fail(url != NULL, NULL);
530 g_return_val_if_fail(dir != NULL, NULL);
531 g_return_val_if_fail(gwget_pref.download_dir != NULL, NULL);
533 gwgetdata = g_new0(GwgetData,1);
535 gwgetdata->url = g_strdup(url);
536 gwgetdata->log_tag = -1;
538 /* Figure out a directory to use if none given */
539 length = strlen (dir);
540 if (length == 0) {
541 dir = gwget_pref.download_dir;
544 /* Add a trailing '/' unless already present */
545 length = strlen (dir);
546 if (dir[length - 1] == '/')
547 gwgetdata->dir = g_strdup (dir);
548 else
549 gwgetdata->dir = g_strconcat (dir, "/", NULL);
551 gwget_data_set_filename_from_url(gwgetdata,gwgetdata->url);
553 gwget_data_set_filename(gwgetdata,gwgetdata->filename);
555 file = g_file_new_for_path (gwgetdata->local_filename);
556 info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL, &err);
558 if (err==NULL) {
559 gwgetdata->cur_size = g_file_info_get_size (info);
560 } else {
561 gwgetdata->cur_size = 0;
562 g_error_free (err);
566 gwgetdata->line = NULL;
567 gwgetdata->session_start_time = 0;
568 gwgetdata->session_start_size = 0;
569 gwgetdata->session_elapsed = 0;
570 gwgetdata->state = DL_NOT_STARTED;
571 gwgetdata->total_size = 0;
572 gwgetdata->total_time = 0;
573 gwgetdata->recursive=FALSE;
574 gwgetdata->multimedia=FALSE;
575 gwgetdata->mirror=FALSE;
576 num_of_download++;
577 return gwgetdata;
581 /* Keeps filename and local_filename in sync */
582 void
583 gwget_data_set_filename(GwgetData* gwgetdata,gchar *str)
585 gwgetdata->filename = g_strdup(str);
586 gwgetdata->local_filename = g_strconcat (gwgetdata->dir,
587 str,
588 NULL);
591 /* Return the gwgetdata that is selected in the treeview */
592 GwgetData* gwget_data_get_selected(void)
594 GtkWidget *treev;
595 GtkTreeSelection *select;
596 GtkTreeIter iter;
597 GtkTreeModel *model;
598 GwgetData *gwgetdata;
599 gchar *url;
601 treev=GTK_WIDGET (gtk_builder_get_object(builder,"treeview1"));
602 select=gtk_tree_view_get_selection(GTK_TREE_VIEW(treev));
604 if (gtk_tree_selection_get_selected (select, &model, &iter))
606 gtk_tree_model_get (model, &iter, URL_COLUMN, &url, -1);
607 gwgetdata=g_object_get_data(G_OBJECT(model),url);
608 return gwgetdata;
610 return NULL;
613 void gwget_data_stop_download(GwgetData *data)
615 pid_t child_pid;
616 gint status;
619 if (gwget_data_run(data)) {
620 /* Kill wget process */
621 kill (data->wget_pid, SIGKILL);
623 /* Remove callback that communicates with wget */
624 gtk_timeout_remove (data->log_tag);
626 /* Wait the finish of wget */
627 child_pid = waitpid (data->wget_pid, &status, WUNTRACED);
628 if (child_pid == data->wget_pid) {
629 /* Process the rest of the information that wget process has */
630 gwget_data_process_information (data);
632 /* Register wget exit */
633 close (data->log_fd);
634 g_free (data->line);
635 data->line = NULL;
637 /* Set the appropriate state after stopping */
638 if (WIFEXITED (status) && (WEXITSTATUS (status) == 0)) {
639 gwget_data_set_state (data, DL_COMPLETED);
640 start_first_waiting_download();
641 if (gwget_pref.open_after_dl) {
642 gwget_data_exec(data);
644 } else {
645 gwget_data_set_state (data, DL_NOT_RUNNING);
647 gwget_data_update_statistics (data);
649 /* Decrease the number of current downloads */
650 if (num_of_download > 0)
651 num_of_download--;
653 /* All done this download can be started again */
654 data->log_tag = -1;
659 void
660 gwget_data_set_filename_from_url(GwgetData *gwgetdata,gchar *url)
662 gchar *filename,*filename2;
664 /* Get the filename from the URL */
665 filename = &url[strlen (url)];
666 while (*filename != '/' && filename != url)
667 filename--;
668 filename++;
671 * Figure out if the url it's from the form: http://www.domain.com
672 * If it's in the form: http://www.domain.com/ or
673 * http://www.domain.com/directory/
674 * it's detected in the function on_ok_button_clicked in new_window.c file
676 filename2 = g_strdup_printf("http://%s",filename);
677 if (!strcmp(filename2,url)) {
678 gwgetdata->filename = g_strdup(filename2);
679 } else {
680 gwgetdata->filename = g_strdup(filename);
684 /* Add a gwgetdata to the main window */
685 void
686 gwget_data_add_download(GwgetData *gwgetdata)
688 gint response;
689 gchar *reverse_filename;
690 GtkWidget *radio, *recursive_window;
692 if (check_url_already_exists(gwgetdata->url)) {
693 run_dialog_information(_("Unable to add this download"),
694 _("This download is already added"));
695 return;
698 /* if the url it's not a file drop a dialog to recurse into the url */
699 reverse_filename = g_strdup(gwgetdata->filename);
700 reverse_filename = g_strreverse(reverse_filename);
701 if (!strcmp(gwgetdata->filename,"") || !strcmp(gwgetdata->filename,gwgetdata->url) ||
702 !strncmp(reverse_filename,"lmth",4) || !strncmp(reverse_filename,"mth",3) ||
703 !strncmp(reverse_filename,"php",3) || !strncmp(reverse_filename,"asp",3)) {
704 recursive_window=GTK_WIDGET (gtk_builder_get_object(builder,"dialog2"));
705 response=gtk_dialog_run(GTK_DIALOG(recursive_window));
706 gtk_widget_hide(GTK_WIDGET(recursive_window));
707 if (response==GTK_RESPONSE_OK) {
708 radio=GTK_WIDGET (gtk_builder_get_object(builder,"radio_index"));
709 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) {
710 gwgetdata->recursive=FALSE;
712 radio=GTK_WIDGET (gtk_builder_get_object(builder,"radio_multimedia"));
713 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) {
714 gwgetdata->recursive=TRUE;
715 gwgetdata->multimedia=TRUE;
717 radio=GTK_WIDGET (gtk_builder_get_object(builder,"radio_mirror"));
718 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) {
719 gwgetdata->recursive=TRUE;
720 gwgetdata->mirror=TRUE;
722 radio=GTK_WIDGET (gtk_builder_get_object(builder,"radio_recursive"));
723 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) {
724 gwgetdata->recursive=TRUE;
728 downloads = g_list_append(downloads,gwgetdata);
729 new_download(gwgetdata);
730 gwget_data_set_state(gwgetdata,DL_NOT_CONNECTED);
733 void
734 gwget_data_exec (GwgetData *gwgetdata)
736 gchar *url;
737 GFile *file;
738 GError *err = NULL;
740 file = g_file_new_for_commandline_arg (gwgetdata->local_filename);
741 url = g_file_get_uri (file);
742 g_object_unref (file);
744 if (!gtk_show_uri (NULL, url, GDK_CURRENT_TIME, &err)) {
745 run_dialog_error(_("Error opening file"), _("Couldn't open the file"));
749 void
750 gwget_init_pref(Preferences *pref)
752 pref->trayonly = FALSE;
753 pref->docked = FALSE;
756 static void
757 gwget_gnotify_finished(GwgetData *gwgetdata) {
758 gchar *app_msg, *icon_msg, *fn_msg;
759 int sock;
760 char buf[8];
762 app_msg = g_strdup("APP:Download Finished");
763 icon_msg = g_strdup_printf("ICON:%s", gwgetdata->icon_name);
764 fn_msg = g_strdup_printf("MSG:%s", gwgetdata->filename);
766 sock = socket(AF_INET, SOCK_STREAM, 6);
767 if(sock > 0) {
768 struct sockaddr_in sa;
770 bzero(&sa, sizeof(sa));
771 sa.sin_family = AF_INET;
772 sa.sin_addr.s_addr = inet_addr("127.0.0.1");
773 sa.sin_port = htons(7206);
774 connect(sock, (struct sockaddr *)&sa, sizeof(sa));
775 send(sock, app_msg, strlen(app_msg) + 1, 0);
776 recv(sock, buf, 8, 0);
777 send(sock, icon_msg, strlen(icon_msg) + 1, 0);
778 recv(sock, buf, 8, 0);
779 send(sock, fn_msg, strlen(fn_msg) + 1, 0);
780 close(sock);
783 g_free(app_msg);
784 g_free(icon_msg);
785 g_free(fn_msg);
789 static void
790 gwget_download_finished (GwgetData *gwgetdata)
792 gwget_gnotify_finished(gwgetdata);
793 gwget_tray_notify (_("Download Complete"), gwgetdata->filename, gwgetdata->icon_name);
794 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder, "clear_button")), TRUE);
796 if (gwget_ask_download_playlist(gwgetdata))
797 gwget_download_playlist_items(gwgetdata->local_filename);
800 static gboolean
801 gwget_ask_download_playlist(GwgetData *gwgetdata)
803 gchar *msg;
804 gint response;
806 if (g_str_has_suffix(gwgetdata->filename, ".m3u")
807 || g_str_has_suffix(gwgetdata->filename, ".M3U")) {
808 msg = g_strdup_printf(
809 _("The file %s is an MP3 playlist.\nDownload the files that it contains?"),
810 gwgetdata->filename);
811 response = run_dialog(_("Download files in MP3 playlist?"),
812 _(msg), _("No"), _("Yes"));
813 g_free(msg);
814 if (response == GTK_RESPONSE_OK)
815 return TRUE;
818 return FALSE;
821 static void
822 gwget_download_playlist_items(gchar *filename)
824 FILE *f;
825 gchar line[1024];
826 GwgetData *gwgetdata;
828 f = g_fopen(filename, "r");
829 if (f!=NULL) {
830 while (fgets(line, 1024, f)!=NULL) {
831 if (check_url("http://", line) || check_url("ftp://", line)) {
832 gwgetdata = gwget_data_new (g_strstrip(line));
833 gwget_data_add_download(gwgetdata);
834 gwget_data_start_download(gwgetdata);
837 fclose(f);
841 void
842 gwget_data_set_menus (GwgetData *gwgetdata)
845 if (gwgetdata!=NULL) {
846 if (gwget_data_run(gwgetdata)) {
847 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_menuitem")),TRUE);
848 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_menuitem")),FALSE);
849 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_menuitem")),TRUE);
850 } else {
851 if (gwgetdata->state==DL_COMPLETED) {
852 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_menuitem")),FALSE);
853 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_menuitem")),FALSE);
854 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_menuitem")),FALSE);
855 } else {
856 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_menuitem")),TRUE);
857 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_menuitem")),FALSE);
860 } else {
861 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_menuitem")),FALSE);
862 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_menuitem")),FALSE);
863 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_menuitem")),FALSE);
867 void
868 gwget_data_set_popupmenu (GwgetData *gwgetdata)
870 if (gwgetdata!=NULL) {
871 if (gwget_data_run(gwgetdata)) {
872 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_download")),TRUE);
873 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_download")),FALSE);
874 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_download")),TRUE);
875 } else {
876 if (gwgetdata->state==DL_COMPLETED) {
877 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_download")),FALSE);
878 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_download")),FALSE);
879 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_download")),FALSE);
880 } else {
881 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_download")),TRUE);
882 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_download")),FALSE);
885 } else {
886 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"continue_download")),FALSE);
887 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"pause_download")),FALSE);
888 gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder,"cancel_download")),FALSE);