From 56a60210894a344d66ec3c77f807c2867491f45d Mon Sep 17 00:00:00 2001 From: Alan F Date: Sun, 9 Mar 2014 17:25:32 +0000 Subject: hacking to support the options dialog from rss feeds --- src/trg-client.c | 4 +- src/trg-destination-combo.c | 2 +- src/trg-file-parser.c | 56 +++++++++-------- src/trg-main-window.c | 1 + src/trg-preferences-dialog.c | 8 ++- src/trg-preferences-dialog.h | 1 + src/trg-rss-cell-renderer.c | 29 ++++++--- src/trg-rss-model.c | 3 +- src/trg-rss-model.h | 2 +- src/trg-rss-window.c | 141 +++++++++++++++++++++++++++++-------------- src/trg-torrent-add-dialog.c | 99 ++++++++++++++++++++---------- src/trg-torrent-add-dialog.h | 6 +- src/upload.c | 63 +++++++++++++++---- src/upload.h | 7 ++- 14 files changed, 296 insertions(+), 126 deletions(-) (limited to 'src') diff --git a/src/trg-client.c b/src/trg-client.c index 7e1a784..f03e893 100644 --- a/src/trg-client.c +++ b/src/trg-client.c @@ -532,7 +532,7 @@ static CURL* get_curl(TrgClient *tc, guint http_class) curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE_NAME); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &http_receive_callback); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); if (http_class == HTTP_CLASS_TRANSMISSION) { curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *) tc); @@ -633,7 +633,7 @@ trg_response *dispatch(TrgClient * tc, JsonNode * req) json_node_free(req); #ifdef DEBUG if (g_getenv("TRG_SHOW_OUTGOING")) - g_debug("=>(OUTgoing)=>: %s", serialized); + g_message("=>(OUTgoing)=>: %s", serialized); #endif return dispatch_str(tc, serialized); } diff --git a/src/trg-destination-combo.c b/src/trg-destination-combo.c index 099b6a5..f7fc2f0 100644 --- a/src/trg-destination-combo.c +++ b/src/trg-destination-combo.c @@ -397,7 +397,7 @@ gchar *trg_destination_combo_get_dir(TrgDestinationCombo * combo) if (type == DEST_LABEL) { gtk_tree_model_get(model, &iter, DEST_COLUMN_DIR, &value, -1); - return value; + return g_strdup(value); } } diff --git a/src/trg-file-parser.c b/src/trg-file-parser.c index fbfb6aa..ff4ac62 100644 --- a/src/trg-file-parser.c +++ b/src/trg-file-parser.c @@ -134,32 +134,11 @@ static trg_files_tree_node *trg_parse_torrent_file_nodes(be_node * return top_node; } -trg_torrent_file *trg_parse_torrent_file(const gchar * filename) -{ - GError *error = NULL; - GMappedFile *mf; - be_node *top_node, *info_node, *name_node; - trg_torrent_file *ret = NULL; - - if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { - g_message("%s does not exist", filename); - return NULL; - } - - mf = g_mapped_file_new(filename, FALSE, &error); +trg_torrent_file *trg_parse_torrent_data(const gchar *data, gsize length) { + trg_torrent_file *ret = NULL; + be_node *top_node, *info_node, *name_node; - if (error) { - g_error("%s", error->message); - g_error_free(error); - g_mapped_file_unref(mf); - return NULL; - } else { - top_node = - be_decoden(g_mapped_file_get_contents(mf), - g_mapped_file_get_length(mf)); - } - - g_mapped_file_unref(mf); + top_node = be_decoden(data, length); if (!top_node) { return NULL; @@ -199,3 +178,30 @@ trg_torrent_file *trg_parse_torrent_file(const gchar * filename) be_free(top_node); return ret; } + +trg_torrent_file *trg_parse_torrent_file(const gchar * filename) +{ + GError *error = NULL; + trg_torrent_file *ret = NULL; + GMappedFile *mf; + + if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { + g_message("%s does not exist", filename); + return NULL; + } + + mf = g_mapped_file_new(filename, FALSE, &error); + + if (error) { + g_error("%s", error->message); + g_error_free(error); + g_mapped_file_unref(mf); + return NULL; + } else { + ret = trg_parse_torrent_data(g_mapped_file_get_contents(mf), g_mapped_file_get_length(mf)); + } + + g_mapped_file_unref(mf); + + return ret; +} diff --git a/src/trg-main-window.c b/src/trg-main-window.c index 32212f6..4cf6047 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -941,6 +941,7 @@ static void view_rss_toggled_cb(GtkWidget * w, gpointer data) trg_rss_window_get_instance(TRG_MAIN_WINDOW(data), priv->client); gtk_widget_show_all(GTK_WIDGET(rss)); + gtk_window_present(GTK_WINDOW(rss)); } } #endif diff --git a/src/trg-preferences-dialog.c b/src/trg-preferences-dialog.c index e7434d3..53e4fe9 100644 --- a/src/trg-preferences-dialog.c +++ b/src/trg-preferences-dialog.c @@ -58,6 +58,7 @@ struct _TrgPreferencesDialogPrivate { GtkWidget *profileNameEntry; GtkWidget *fullUpdateCheck; GList *widgets; + GtkWidget *notebook; }; static GObject *instance = NULL; @@ -928,7 +929,7 @@ static GObject *trg_preferences_dialog_constructor(GType type, g_signal_connect(G_OBJECT(object), "response", G_CALLBACK(trg_preferences_response_cb), NULL); - notebook = gtk_notebook_new(); + notebook = priv->notebook = gtk_notebook_new(); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), trg_prefs_serverPage(TRG_PREFERENCES_DIALOG @@ -969,6 +970,11 @@ static GObject *trg_preferences_dialog_constructor(GType type, return object; } +void trg_preferences_dialog_set_page(TrgPreferencesDialog *pref_dlg, guint page) { + TrgPreferencesDialogPrivate *priv = TRG_PREFERENCES_DIALOG_GET_PRIVATE(pref_dlg); + gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->notebook), page); +} + static void trg_preferences_dialog_init(TrgPreferencesDialog * pref_dlg) { } diff --git a/src/trg-preferences-dialog.h b/src/trg-preferences-dialog.h index f5e9825..e163964 100644 --- a/src/trg-preferences-dialog.h +++ b/src/trg-preferences-dialog.h @@ -60,6 +60,7 @@ GtkWidget *trg_preferences_dialog_get_instance(TrgMainWindow * win, TrgClient * client); trg_pref_widget_desc *trg_pref_widget_desc_new(GtkWidget * w, gchar * key, int flags); +void trg_preferences_dialog_set_page(TrgPreferencesDialog *pref_dlg, guint page); G_END_DECLS #endif /* TRG_PREFERENCES_WINDOW_H_ */ diff --git a/src/trg-rss-cell-renderer.c b/src/trg-rss-cell-renderer.c index 5cae5c7..4765f2c 100644 --- a/src/trg-rss-cell-renderer.c +++ b/src/trg-rss-cell-renderer.c @@ -14,7 +14,8 @@ enum { PROP_TITLE = 1, PROP_FEED, - PROP_PUBLISHED + PROP_PUBLISHED, + PROP_UPLOADED }; #define SMALL_SCALE 0.9 @@ -34,6 +35,7 @@ struct TrgRssCellRendererPrivate { gchar *title; gchar *published; gchar *feed; + gboolean uploaded; }; static void @@ -75,6 +77,9 @@ static void trg_rss_cell_renderer_set_property(GObject * object, g_free(p->feed); p->feed = g_value_dup_string(v); break; + case PROP_UPLOADED: + p->uploaded = g_value_get_boolean(v); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -243,6 +248,19 @@ trg_rss_cell_renderer_class_init(TrgRssCellRendererClass * klass) | G_PARAM_STATIC_BLURB)); + g_object_class_install_property(gobject_class, + PROP_UPLOADED, + g_param_spec_boolean("uploaded", + "uploaded", + "Uploaded", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME + | + G_PARAM_STATIC_NICK + | + G_PARAM_STATIC_BLURB)); + /*g_object_class_install_property(gobject_class, P_BAR_HEIGHT, g_param_spec_int("bar-height", NULL, "Bar Height", @@ -281,15 +299,12 @@ static void get_text_color(TrgRssCellRenderer * r, GtkWidget * widget, GtrColor * setme) { - /*struct TrgRssCellRendererPrivate *p = r->priv; - static const GdkRGBA red = { 1.0, 0, 0, 0 }; + struct TrgRssCellRendererPrivate *p = r->priv; - if (p->error) - *setme = red; - else if (p->flags & TORRENT_FLAG_PAUSED) + if (p->uploaded) gtk_style_context_get_color(gtk_widget_get_style_context(widget), GTK_STATE_FLAG_INSENSITIVE, setme); - else*/ + else gtk_style_context_get_color(gtk_widget_get_style_context(widget), GTK_STATE_FLAG_NORMAL, setme); } diff --git a/src/trg-rss-model.c b/src/trg-rss-model.c index b6ee229..f898f34 100644 --- a/src/trg-rss-model.c +++ b/src/trg-rss-model.c @@ -49,6 +49,7 @@ typedef struct _TrgRssModelPrivate TrgRssModelPrivate; struct _TrgRssModelPrivate { TrgClient *client; GHashTable *table; + guint index; }; typedef struct { @@ -245,7 +246,7 @@ static void trg_rss_model_init(TrgRssModel * self) { column_types[RSSCOL_LINK] = G_TYPE_STRING; column_types[RSSCOL_FEED] = G_TYPE_STRING; column_types[RSSCOL_PUBDATE] = G_TYPE_STRING; - column_types[RSSCOL_SENSITIVE] = G_TYPE_BOOLEAN; + column_types[RSSCOL_UPLOADED] = G_TYPE_BOOLEAN; gtk_list_store_set_column_types(GTK_LIST_STORE(self), RSSCOL_COLUMNS, column_types); diff --git a/src/trg-rss-model.h b/src/trg-rss-model.h index 8ddddd4..206ee41 100644 --- a/src/trg-rss-model.h +++ b/src/trg-rss-model.h @@ -77,7 +77,7 @@ enum { RSSCOL_LINK, RSSCOL_FEED, RSSCOL_PUBDATE, - RSSCOL_SENSITIVE, + RSSCOL_UPLOADED, RSSCOL_COLUMNS }; diff --git a/src/trg-rss-window.c b/src/trg-rss-window.c index c4091a5..64c1452 100644 --- a/src/trg-rss-window.c +++ b/src/trg-rss-window.c @@ -29,6 +29,7 @@ #include "trg-rss-model.h" #include "trg-rss-cell-renderer.h" #include "trg-torrent-add-dialog.h" +#include "trg-preferences-dialog.h" #include "trg-client.h" #include "upload.h" #include "util.h" @@ -46,6 +47,8 @@ typedef struct _TrgRssWindowPrivate TrgRssWindowPrivate; struct _TrgRssWindowPrivate { TrgMainWindow *parent; TrgClient *client; + GtkTreeView *tree_view; + TrgRssModel *tree_model; }; static GObject *instance = NULL; @@ -91,35 +94,57 @@ trg_rss_window_set_property(GObject * object, } } +static gboolean upload_complete_searchfunc(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) { + trg_upload *upload = (trg_upload*)data; + gchar *item_guid = NULL; + + gtk_tree_model_get(model, iter, RSSCOL_ID, &item_guid, -1); + + if (!g_strcmp0(item_guid, upload->uid)) { + gtk_list_store_set(GTK_LIST_STORE(model), iter, RSSCOL_UPLOADED, TRUE, -1); + return TRUE; + } + + return FALSE; +} + +static gboolean on_upload_complete(gpointer data) { + trg_response *response = (trg_response*)data; + trg_upload *upload = (trg_upload*)response->cb_data; + TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(upload->cb_data); + + if (response->status == CURLE_OK) + gtk_tree_model_foreach(GTK_TREE_MODEL(priv->tree_model), upload_complete_searchfunc, upload); + + return FALSE; +} + static gboolean on_torrent_receive(gpointer data) { trg_response *response = (trg_response *) data; - TrgRssWindow *win = TRG_RSS_WINDOW(response->cb_data); - TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(response->cb_data); + trg_upload *upload = (trg_upload*)response->cb_data; + TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(upload->cb_data); TrgClient *client = priv->client; TrgPrefs *prefs = trg_client_get_prefs(client); TrgMainWindow *main_win = priv->parent; + upload->upload_response = response; + if (response->status == CURLE_OK) { if (trg_prefs_get_bool(prefs, TRG_PREFS_KEY_ADD_OPTIONS_DIALOG, TRG_PREFS_GLOBAL)) { - /*TrgTorrentAddDialog *dialog = - trg_torrent_add_dialog_new_from_filenames(main_win, client, - filesList); - gtk_widget_show_all(GTK_WIDGET(dialog));*/ + TrgTorrentAddDialog *dialog = + trg_torrent_add_dialog_new_from_upload(main_win, client, + upload); + gtk_widget_show_all(GTK_WIDGET(dialog)); } else { - trg_upload *upload = g_new0(trg_upload, 1); - - upload->upload_response = response; - upload->main_window = main_win; - upload->client = client; - upload->extra_args = FALSE; - upload->flags = trg_prefs_get_add_flags(prefs); - - trg_do_upload(upload); + trg_do_upload(upload); } } else { - trg_error_dialog(GTK_WINDOW(win), response); - trg_response_free(response); + trg_error_dialog(GTK_WINDOW(main_win), response); + trg_upload_free(upload); } return FALSE; @@ -133,15 +158,28 @@ rss_item_activated(GtkTreeView * treeview, { TrgRssWindow *win = TRG_RSS_WINDOW(userdata); TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(win); + TrgClient *client = priv->client; + TrgPrefs *prefs = trg_client_get_prefs(client); GtkTreeModel *model = gtk_tree_view_get_model(treeview); + trg_upload *upload = g_new0(trg_upload, 1); GtkTreeIter iter; - gchar *link; + gchar *link, *uid; + + //upload->upload_response = response; + upload->main_window = priv->parent; + upload->client = client; + upload->extra_args = FALSE; + upload->flags = trg_prefs_get_add_flags(prefs); + upload->callback = on_upload_complete; + upload->cb_data = win; gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, RSSCOL_LINK, &link, -1); + gtk_tree_model_get(model, &iter, RSSCOL_LINK, &link, RSSCOL_ID, &uid, -1); + + upload->uid = uid; - async_http_request(priv->client, link, on_torrent_receive, userdata); + async_http_request(priv->client, link, on_torrent_receive, upload); g_free(link); } @@ -179,6 +217,18 @@ static void trg_rss_on_parse_error(TrgRssModel *model, rss_parse_error *error, g gtk_widget_destroy(dialog); } +static void on_configure(GtkWidget *widget, gpointer data) { + TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(data); + GtkWidget *dlg = trg_preferences_dialog_get_instance(priv->parent, priv->client); + gtk_widget_show_all(dlg); + trg_preferences_dialog_set_page(TRG_PREFERENCES_DIALOG(dlg), 5); +} + +static void on_refresh(GtkWidget *widget, gpointer data) { + TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(data); + trg_rss_model_update(priv->tree_model); +} + static GObject *trg_rss_window_constructor(GType type, guint n_construct_properties, @@ -187,10 +237,9 @@ static GObject *trg_rss_window_constructor(GType type, { GObject *object; TrgRssWindowPrivate *priv; - TrgRssModel *model; - GtkTreeView *view; GtkWidget *vbox; - //GtkToolItem *item; + GtkToolItem *item; + GtkWidget *toolbar; object = G_OBJECT_CLASS (trg_rss_window_parent_class)->constructor(type, @@ -198,41 +247,45 @@ static GObject *trg_rss_window_constructor(GType type, construct_params); priv = TRG_RSS_WINDOW_GET_PRIVATE(object); - model = trg_rss_model_new(priv->client); + priv->tree_model = trg_rss_model_new(priv->client); - g_signal_connect(model, "get-error", - G_CALLBACK(trg_rss_on_get_error), NULL); - g_signal_connect(model, "parse-error", - G_CALLBACK(trg_rss_on_parse_error), NULL); + g_signal_connect(priv->tree_model, "get-error", + G_CALLBACK(trg_rss_on_get_error), object); + g_signal_connect(priv->tree_model, "parse-error", + G_CALLBACK(trg_rss_on_parse_error), object); - trg_rss_model_update(model); + trg_rss_model_update(priv->tree_model); - view = GTK_TREE_VIEW(gtk_tree_view_new()); - gtk_tree_view_set_headers_visible(view, FALSE); - gtk_tree_view_set_model(view, GTK_TREE_MODEL(model)); - /*gtk_tree_view_insert_column_with_attributes(view, -1, "Title", gtk_cell_renderer_text_new(), "text", RSSCOL_TITLE, NULL); - gtk_tree_view_insert_column_with_attributes(view, -1, "Feed", gtk_cell_renderer_text_new(), "text", RSSCOL_FEED, NULL); - gtk_tree_view_insert_column_with_attributes(view, -1, "Published", gtk_cell_renderer_text_new(), "text", RSSCOL_PUBDATE, NULL); - gtk_tree_view_insert_column_with_attributes(view, -1, "URL", gtk_cell_renderer_text_new(), "text", RSSCOL_LINK, NULL);*/ - gtk_tree_view_insert_column_with_attributes(view, -1, NULL, trg_rss_cell_renderer_new(), "title", RSSCOL_TITLE, "feed", RSSCOL_FEED, "published", RSSCOL_PUBDATE, NULL); + priv->tree_view = GTK_TREE_VIEW(gtk_tree_view_new()); + gtk_tree_view_set_headers_visible(priv->tree_view, FALSE); + gtk_tree_view_set_model(priv->tree_view, GTK_TREE_MODEL(priv->tree_model)); - g_signal_connect(view, "row-activated", + gtk_tree_view_insert_column_with_attributes(priv->tree_view, -1, NULL, trg_rss_cell_renderer_new(), "title", RSSCOL_TITLE, "feed", RSSCOL_FEED, "published", RSSCOL_PUBDATE, "uploaded", RSSCOL_UPLOADED, NULL); + + g_signal_connect(priv->tree_view, "row-activated", G_CALLBACK(rss_item_activated), object); gtk_window_set_title(GTK_WINDOW(object), _("RSS Feeds")); - /*toolbar = gtk_toolbar_new(); + toolbar = gtk_toolbar_new(); + + item = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH); + gtk_widget_set_sensitive(GTK_WIDGET(item), TRUE); + gtk_tool_item_set_tooltip_text(item, "Refresh"); + g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(on_refresh), object); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, 0); item = gtk_tool_button_new_from_stock(GTK_STOCK_PREFERENCES); gtk_widget_set_sensitive(GTK_WIDGET(item), TRUE); - gtk_tool_item_set_tooltip_text(item, "Configure"); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, 0);*/ + gtk_tool_item_set_tooltip_text(item, "Configure Feeds"); + g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(on_configure), object); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, 0); vbox = trg_vbox_new(FALSE, 0); - /*gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(toolbar), - FALSE, FALSE, 0);*/ - gtk_box_pack_start(GTK_BOX(vbox), my_scrolledwin_new(GTK_WIDGET(view)), + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(toolbar), + FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), my_scrolledwin_new(GTK_WIDGET(priv->tree_view)), TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(object), vbox); diff --git a/src/trg-torrent-add-dialog.c b/src/trg-torrent-add-dialog.c index 702efd4..aa63166 100644 --- a/src/trg-torrent-add-dialog.c +++ b/src/trg-torrent-add-dialog.c @@ -48,7 +48,7 @@ #include "upload.h" enum { - PROP_0, PROP_FILENAME, PROP_PARENT, PROP_CLIENT, PROP_RESPONSE + PROP_0, PROP_FILENAME, PROP_PARENT, PROP_CLIENT, PROP_UPLOAD }; enum { @@ -64,7 +64,7 @@ struct _TrgTorrentAddDialogPrivate { TrgClient *client; TrgMainWindow *parent; GSList *filenames; - trg_response *response; + trg_upload *upload; GtkWidget *source_chooser; GtkWidget *dest_combo; GtkWidget *priority_combo; @@ -72,6 +72,7 @@ struct _TrgTorrentAddDialogPrivate { GtkTreeStore *store; GtkWidget *paused_check; GtkWidget *delete_check; + guint n_files; }; #define MAGNET_MAX_LINK_WIDTH 75 @@ -92,6 +93,9 @@ static void trg_torrent_add_dialog_set_property(GObject * object, case PROP_PARENT: priv->parent = g_value_get_object(value); break; + case PROP_UPLOAD: + priv->upload = g_value_get_pointer(value); + break; case PROP_CLIENT: priv->client = g_value_get_pointer(value); break; @@ -123,7 +127,7 @@ add_file_indexes_foreachfunc(GtkTreeModel * model, path G_GNUC_UNUSED, GtkTreeIter * iter, gpointer data) { - JsonObject *args = (JsonObject *) data; + trg_upload *upload = (trg_upload *) data; gint priority, index, wanted; gtk_tree_model_get(model, iter, FC_PRIORITY, &priority, FC_ENABLED, @@ -132,17 +136,8 @@ add_file_indexes_foreachfunc(GtkTreeModel * model, if (gtk_tree_model_iter_has_child(model, iter) || index < 0) return FALSE; - if (wanted) - add_file_id_to_array(args, FIELD_FILES_WANTED, index); - else - add_file_id_to_array(args, FIELD_FILES_UNWANTED, index); - - if (priority == TR_PRI_LOW) - add_file_id_to_array(args, FIELD_FILES_PRIORITY_LOW, index); - else if (priority == TR_PRI_HIGH) - add_file_id_to_array(args, FIELD_FILES_PRIORITY_HIGH, index); - else - add_file_id_to_array(args, FIELD_FILES_PRIORITY_NORMAL, index); + upload->file_wanted[index] = wanted; + upload->file_priorities[index] = priority; return FALSE; } @@ -168,10 +163,15 @@ trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, gpointer data) gchar *dir = trg_destination_combo_get_dir(TRG_DESTINATION_COMBO (priv->dest_combo)); + trg_upload *upload; - trg_upload *upload = g_new0(trg_upload, 1); + if (priv->upload) { + upload = priv->upload; + } else { + upload = g_new0(trg_upload, 1); + upload->list = priv->filenames; + } - upload->list = priv->filenames; upload->main_window = priv->parent; upload->client = priv->client; upload->dir = dir; @@ -179,12 +179,17 @@ trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, gpointer data) upload->flags = flags; upload->extra_args = TRUE; + upload->n_files = priv->n_files; + upload->file_priorities = g_new0(gint, priv->n_files); + upload->file_wanted = g_new0(gint, priv->n_files); + + gtk_tree_model_foreach(GTK_TREE_MODEL(priv->store), + add_file_indexes_foreachfunc, upload); + trg_do_upload(upload); trg_destination_combo_save_selection(TRG_DESTINATION_COMBO (priv->dest_combo)); - - g_free(dir); } else { g_str_slist_free(priv->filenames); } @@ -393,7 +398,7 @@ static void addTorrentFilters(GtkFileChooser * chooser) static void store_add_node(GtkTreeStore * store, GtkTreeIter * parent, - trg_files_tree_node * node) + trg_files_tree_node * node, guint *n_files) { GtkTreeIter child; GList *li; @@ -404,11 +409,12 @@ store_add_node(GtkTreeStore * store, GtkTreeIter * parent, 1, FC_INDEX, node->index, FC_PRIORITY, TR_PRI_NORMAL, FC_SIZE, node->length, -1); + *n_files = *n_files + 1; } for (li = node->children; li; li = g_list_next(li)) store_add_node(store, node->name ? &child : NULL, - (trg_files_tree_node *) li->data); + (trg_files_tree_node *) li->data, n_files); } static void torrent_not_parsed_warning(GtkWindow * parent) @@ -438,6 +444,28 @@ static void torrent_not_found_error(GtkWindow * parent, gchar * file) gtk_widget_destroy(dialog); } +static void +trg_torrent_add_dialog_set_upload(TrgTorrentAddDialog *d, trg_upload *upload) { + TrgTorrentAddDialogPrivate *priv = + TRG_TORRENT_ADD_DIALOG_GET_PRIVATE(d); + GtkButton *chooser = GTK_BUTTON(priv->source_chooser); + trg_torrent_file *tor_data = NULL; + + if (upload->uid) + gtk_button_set_label(chooser, upload->uid); + + tor_data = trg_parse_torrent_data(upload->upload_response->raw, upload->upload_response->size); + + if (!tor_data) { + torrent_not_parsed_warning(GTK_WINDOW(priv->parent)); + } else { + store_add_node(priv->store, NULL, tor_data->top_node, &priv->n_files); + trg_torrent_file_free(tor_data); + } + + gtk_widget_set_sensitive(priv->file_list, tor_data != NULL); +} + static void trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, GSList * filenames) @@ -449,6 +477,11 @@ trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, gtk_tree_store_clear(priv->store); + if (priv->upload) { + trg_upload_free(priv->upload); + priv->upload = NULL; + } + if (nfiles == 1) { gchar *file_name = (gchar *) filenames->data; if (is_url(file_name) || is_magnet(file_name)) { @@ -484,7 +517,7 @@ trg_torrent_add_dialog_set_filenames(TrgTorrentAddDialog * d, if (!tor_data) { torrent_not_parsed_warning(GTK_WINDOW(priv->parent)); } else { - store_add_node(priv->store, NULL, tor_data->top_node); + store_add_node(priv->store, NULL, tor_data->top_node, &priv->n_files); trg_torrent_file_free(tor_data); } } else { @@ -712,8 +745,12 @@ static GObject *trg_torrent_add_dialog_constructor(GType type, priv->source_chooser = gtk_button_new(); gtk_button_set_alignment(GTK_BUTTON(priv->source_chooser), 0.0f, 0.5f); - trg_torrent_add_dialog_set_filenames(TRG_TORRENT_ADD_DIALOG(obj), - priv->filenames); + + if (priv->filenames) + trg_torrent_add_dialog_set_filenames(TRG_TORRENT_ADD_DIALOG(obj), + priv->filenames); + else if (priv->upload) + trg_torrent_add_dialog_set_upload(TRG_TORRENT_ADD_DIALOG(obj), priv->upload); gtk_table_attach(GTK_TABLE(t), priv->source_chooser, 1, 2, 0, 1, ~0, 0, 0, 0); @@ -796,10 +833,10 @@ trg_torrent_add_dialog_class_init(TrgTorrentAddDialogClass * klass) G_PARAM_STATIC_BLURB)); g_object_class_install_property(object_class, - PROP_RESPONSE, - g_param_spec_pointer("response", - "response", - "response", + PROP_UPLOAD, + g_param_spec_pointer("upload", + "upload", + "upload", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY @@ -854,12 +891,12 @@ TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_filenames(TrgMainWindow * p NULL); } -TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_response(TrgMainWindow * parent, +TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_upload(TrgMainWindow * parent, TrgClient * client, - trg_response *response) + trg_upload *upload) { - return g_object_new(TRG_TYPE_TORRENT_ADD_DIALOG, "response", - response, "parent", parent, "client", client, + return g_object_new(TRG_TYPE_TORRENT_ADD_DIALOG, "upload", + upload, "parent", parent, "client", client, NULL); } diff --git a/src/trg-torrent-add-dialog.h b/src/trg-torrent-add-dialog.h index ab6721e..eebea45 100644 --- a/src/trg-torrent-add-dialog.h +++ b/src/trg-torrent-add-dialog.h @@ -24,6 +24,7 @@ #include #include "trg-client.h" +#include "upload.h" #include "trg-main-window.h" G_BEGIN_DECLS @@ -48,9 +49,12 @@ typedef struct { GType trg_torrent_add_dialog_get_type(void); -TrgTorrentAddDialog *trg_torrent_add_dialog_new(TrgMainWindow * win, +TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_filenames(TrgMainWindow * parent, TrgClient * client, GSList * filenames); +TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_upload(TrgMainWindow * parent, + TrgClient * client, + trg_upload *upload); void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client); G_END_DECLS diff --git a/src/upload.c b/src/upload.c index 5bac869..2f16c51 100644 --- a/src/upload.c +++ b/src/upload.c @@ -1,9 +1,10 @@ #include "protocol-constants.h" #include "requests.h" #include "trg-client.h" -#include "upload.h" #include "util.h" #include "trg-main-window.h" +#include "json.h" +#include "upload.h" static gboolean upload_complete_callback(gpointer data); static void next_upload(trg_upload *upload); @@ -19,20 +20,57 @@ add_set_common_args(JsonObject * args, gint priority, gchar * dir) void trg_upload_free(trg_upload *upload) { g_str_slist_free(upload->list); g_free(upload->dir); + g_free(upload->uid); + g_free(upload->file_wanted); + g_free(upload->file_priorities); trg_response_free(upload->upload_response); g_free(upload); } +static void add_priorities(JsonObject *args, gint* priorities, gint n_files) +{ + gint i; + for (i = 0; i < n_files; i++) { + gint priority = priorities[i]; + if (priority == TR_PRI_LOW) + add_file_id_to_array(args, FIELD_FILES_PRIORITY_LOW, i); + else if (priority == TR_PRI_HIGH) + add_file_id_to_array(args, FIELD_FILES_PRIORITY_HIGH, i); + else + add_file_id_to_array(args, FIELD_FILES_PRIORITY_NORMAL, i); + } +} + +static void add_wanteds(JsonObject *args, gint* wanteds, gint n_files) { + gint i; + for (i = 0; i < n_files; i++) { + if (wanteds[i]) + add_file_id_to_array(args, FIELD_FILES_WANTED, i); + else + add_file_id_to_array(args, FIELD_FILES_UNWANTED, i); + } +} + static void next_upload(trg_upload *upload) { - if (upload->upload_response && upload->progress_index < 1) { - JsonNode *req = torrent_add_from_response(upload->upload_response, 0); - /*JsonObject *args = + JsonNode *req = NULL; + + if (upload->upload_response && upload->progress_index < 1) + req = torrent_add_from_response(upload->upload_response, upload->flags); + else if (upload->list && upload->progress_index < g_slist_length(upload->list)) + req = torrent_add_from_file((gchar*)g_slist_nth_data(upload->list, upload->progress_index), upload->flags); + + if (req) { + JsonObject *args = node_get_arguments(req); + if (upload->extra_args) - add_set_common_args()*/ - upload->progress_index++; - dispatch_async(upload->client, req, upload_complete_callback, upload); - } else if (upload->list && upload->progress_index < g_slist_length(upload->list)) { - JsonNode *req = torrent_add_from_file((gchar*)g_slist_nth_data(upload->list, upload->progress_index), 0); + add_set_common_args(args, upload->priority, upload->dir); + + if (upload->file_wanted) + add_wanteds(args, upload->file_wanted, upload->n_files); + + if (upload->file_priorities) + add_priorities(args, upload->file_priorities, upload->n_files); + upload->progress_index++; dispatch_async(upload->client, req, upload_complete_callback, upload); } else { @@ -44,15 +82,18 @@ static gboolean upload_complete_callback(gpointer data) { trg_response *response = (trg_response*)data; trg_upload *upload = (trg_upload*)response->cb_data; - next_upload(upload); + if (upload->callback) + upload->callback(data); /* the callback we're delegating to will destroy the response */ if (upload->main_window) on_generic_interactive_action(upload->main_window, response); - else /* otherwise need to do it here */ + else trg_response_free(response); + next_upload(upload); + return FALSE; } diff --git a/src/upload.h b/src/upload.h index 9f3f719..5dc17e2 100644 --- a/src/upload.h +++ b/src/upload.h @@ -15,11 +15,16 @@ typedef struct { guint flags; gchar *dir; gint priority; + gint* file_priorities; + gint* file_wanted; + guint n_files; gboolean extra_args; guint progress_index; - + GSourceFunc callback; + gchar *uid; } trg_upload; +void trg_upload_free(trg_upload *upload); void trg_do_upload(trg_upload *upload); #endif -- cgit v1.2.3