/* This file is part of GNUnet. (C) 2005 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file src/download.c * @brief code for downloading with gnunet-gtk * @author Christian Grothoff */ #include "platform.h" #include "main.h" #include "fs.h" #include "search.h" #include "helper.h" #include typedef struct DL { struct DL * next; struct ECRS_URI * uri; char * filename; GtkTreeRowReference * rr; } DownloadList; static DownloadList * head; static GtkTreeStore * summary; static void initiateDownload(GtkTreeModel *model, GtkTreePath * path, GtkTreeIter * iter, GtkTreeStore * tree) { struct ECRS_URI * uri; struct ECRS_MetaData * meta; char * filename; char * pfx; char * fn; DownloadList * list; GtkTreeIter iiter; char * name; struct stat sbuf; uri = NULL; meta = NULL; name = NULL; gtk_tree_model_get(model, iter, 0, &name, 5, &uri, 6, &meta, -1); if (uri == NULL) { BREAK(); FREENONNULL(name); return; } filename = ECRS_uriToString(uri); if ( (filename == NULL) || (strlen(filename) < strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)) ) { BREAK(); FREENONNULL(name); FREENONNULL(filename); return; } if (name == NULL) name = STRDUP(_("unnamed")); list = MALLOC(sizeof(DownloadList)); list->next = head; list->rr = NULL; if (ECRS_isDirectory(meta)) list->rr = gtk_tree_row_reference_new(model, path); list->uri = ECRS_dupUri(uri); fn = getFileName("FS", "DOWNLOADDIR", _("You must specify a directory in the configuration" " in section '%s' under '%s'.")); mkdirp(fn); pfx = MALLOC(strlen(fn) + 2 + strlen(filename) + strlen(name)); strcpy(pfx, fn); strcat(pfx, DIR_SEPARATOR_STR); strcat(pfx, name); if (0 == STAT(pfx, &sbuf)) { guiMessage(_("File '%s' exists in '%s',\n" "will store download under its GNUnet URI '%s' instead.\n"), name, fn, &filename[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)]); strcpy(pfx, fn); strcat(pfx, DIR_SEPARATOR_STR); strcat(pfx, &filename[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)]); } FREE(fn); list->filename = pfx; head = list; gtk_tree_store_insert(summary, &iiter, NULL, 0); gtk_tree_store_set(summary, &iiter, 0, name, 1, ECRS_fileSize(uri), 2, 0, /* progress */ 3, filename, 4, ECRS_dupUri(uri), 5, list->rr, /* internal: row reference! */ -1); FREE(filename); FREE(name); FSUI_startDownload(ctx, getConfigurationInt("GNUNET-GTK", "ANONYMITY"), /* FIXME: get value from UI! */ uri, pfx); } void on_downloadButton_clicked(GtkWidget * treeview, GtkWidget * downloadButton) { GtkTreeSelection * selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &initiateDownload, NULL); } /** */ void displayDownloadUpdate(const struct ECRS_URI * uri, unsigned long long completed) { GtkTreeIter iter; unsigned int val; unsigned long long total; struct ECRS_URI * u; if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(summary), &iter)) return; do { gtk_tree_model_get(GTK_TREE_MODEL(summary), &iter, 1, &total, 4, &u, -1); if (ECRS_equalsUri(u, uri)) { if (total != 0) val = completed * 100 / total; else val = 100; gtk_tree_store_set(GTK_TREE_STORE(summary), &iter, 2, val, -1); break; } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(summary), &iter)); } /** */ void displayDownloadComplete(const struct ECRS_URI * uri, const char * filename) { char * ren; ren = ECRS_suggestFilename(filename); if (ren == NULL) return; if (0 != strcmp(ren, filename)) { /* fixme: ask user for confirmation? */ /* rename(filename, ren); */ } FREE(ren); /* fixme: also update download model? */ } static int addDownloadView(void * cls, const char * filename, const struct ECRS_URI * uri, unsigned long long filesize, unsigned long long bytesCompleted, int isRecursive, unsigned int anonymityLevel) { GtkTreeIter iiter; int progress; char * uriname; if (filesize != 0) progress = bytesCompleted * 100 / filesize; else progress = 100; uriname = ECRS_uriToString(uri); gtk_tree_store_insert(summary, &iiter, NULL, 0); gtk_tree_store_set(summary, &iiter, 0, filename, 1, filesize, 2, progress, 3, uriname, 4, ECRS_dupUri(uri), 5, NULL, -1); FREE(uriname); return OK; } void fs_download_start() { GtkWidget * downloadList; GtkCellRenderer * renderer; downloadList = glade_xml_get_widget(mainXML, "activeDownloadsList"); summary = gtk_tree_store_new(6, G_TYPE_STRING, /* name */ G_TYPE_UINT64, /* size */ G_TYPE_INT, /* progress */ G_TYPE_STRING, /* uri */ G_TYPE_POINTER, /* url */ G_TYPE_POINTER); /* internal: gtk tree path / NULL */ gtk_tree_view_set_model(GTK_TREE_VIEW(downloadList), GTK_TREE_MODEL(summary)); renderer = gtk_cell_renderer_progress_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList), -1, _("Name"), renderer, "value", 2, "text", 0, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList), -1, _("Size"), renderer, "text", 1, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList), -1, _("URI"), renderer, "text", 3, NULL); FSUI_listDownloads(ctx, &addDownloadView, NULL); } void fs_download_stop() { GtkTreeIter iter; struct ECRS_URI * u; /* free URIs in summary model */ if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(summary), &iter)) return; do { gtk_tree_model_get(GTK_TREE_MODEL(summary), &iter, 4, &u, -1); gtk_tree_store_set(GTK_TREE_STORE(summary), &iter, 4, NULL, -1); ECRS_freeUri(u); } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(summary), &iter)); } /* end of download.c */