summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Alan F <ajf@eth0.org.uk>2014-02-19 08:54:10 +0000
committerGravatar Alan F <ajf@eth0.org.uk>2014-02-19 08:54:10 +0000
commit1d6f77d4c4fafd0a9cafddd2797249557e601dba (patch)
tree33dee51882a0475aff63ec6c6d9095c92c9ac5d4 /src
parentadf06453574270bf467b5f37e632c04c153ee90a (diff)
refactor the torrent upload code (it's called from a few places so is probably worth it), and make it easier to use a HTTP response as the input.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/requests.c17
-rw-r--r--src/requests.h5
-rw-r--r--src/trg-client.c18
-rw-r--r--src/trg-files-tree-view.c2
-rw-r--r--src/trg-main-window.c75
-rw-r--r--src/trg-main-window.h3
-rw-r--r--src/trg-rss-model.c94
-rw-r--r--src/trg-rss-model.h2
-rw-r--r--src/trg-rss-window.c68
-rw-r--r--src/trg-torrent-add-dialog.c143
-rw-r--r--src/trg-torrent-add-dialog.h16
-rw-r--r--src/trg-torrent-add-url-dialog.c2
-rw-r--r--src/trg-torrent-move-dialog.c2
-rw-r--r--src/trg-torrent-props-dialog.c2
-rw-r--r--src/trg-trackers-tree-view.c2
-rw-r--r--src/upload.c62
-rw-r--r--src/upload.h25
18 files changed, 317 insertions, 222 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f82a7f5..bb11db2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -107,6 +107,7 @@ transmission_remote_gtk_SOURCES = \
main.c \
trg-rss-window.c \
trg-rss-model.c \
+ upload.c \
$(NULL)
transmission_remote_gtk_LDFLAGS = -lm $(jsonglib_LIBS) $(gtk_LIBS) $(gthread_LIBS) $(GEOIP_LIBS) $(gio_LIBS) $(notify_LIBS) $(libproxy_LIBS) $(libcurl_LIBS) $(libappindicator_LIBS) $(rssglib_LIBS)
diff --git a/src/requests.c b/src/requests.c
index 95be1d7..43a8561 100644
--- a/src/requests.c
+++ b/src/requests.c
@@ -227,7 +227,22 @@ JsonNode *torrent_add_url(const gchar * url, gboolean paused)
return root;
}
-JsonNode *torrent_add(gchar * target, gint flags)
+JsonNode *torrent_add_from_response(trg_response *response, gint flags) {
+ JsonNode *root = base_request(METHOD_TORRENT_ADD);
+ JsonObject *args = node_get_arguments(root);
+ gchar *encoded = g_base64_encode((guchar *)response->raw, response->size);
+
+ json_object_set_string_member(args, PARAM_METAINFO,
+ encoded);
+ g_free(encoded);
+
+ json_object_set_boolean_member(args, PARAM_PAUSED,
+ (flags & TORRENT_ADD_FLAG_PAUSED));
+
+ return root;
+}
+
+JsonNode *torrent_add_from_file(gchar * target, gint flags)
{
JsonNode *root;
JsonObject *args;
diff --git a/src/requests.h b/src/requests.h
index 5ea9b2a..7430fda 100644
--- a/src/requests.h
+++ b/src/requests.h
@@ -23,6 +23,8 @@
#include <glib-object.h>
#include <json-glib/json-glib.h>
+#include "trg-client.h"
+
JsonNode *generic_request(gchar * method, JsonArray * array);
JsonNode *session_set(void);
@@ -34,7 +36,8 @@ JsonNode *torrent_start(JsonArray * array);
JsonNode *torrent_verify(JsonArray * array);
JsonNode *torrent_reannounce(JsonArray * array);
JsonNode *torrent_remove(JsonArray * array, int removeData);
-JsonNode *torrent_add(gchar * filename, gint flags);
+JsonNode *torrent_add_from_response(trg_response *response, gint flags);
+JsonNode *torrent_add_from_file(gchar * filename, gint flags);
JsonNode *torrent_add_url(const gchar * url, gboolean paused);
JsonNode *torrent_set_location(JsonArray * array, gchar * location,
gboolean move);
diff --git a/src/trg-client.c b/src/trg-client.c
index 6f33b36..8ab2afd 100644
--- a/src/trg-client.c
+++ b/src/trg-client.c
@@ -442,11 +442,15 @@ void trg_client_configunlock(TrgClient * tc)
void trg_response_free(trg_response * response)
{
- if (response->obj)
- json_object_unref(response->obj);
- if (response->raw)
- g_free(response->raw);
- g_free(response);
+ if (response) {
+ if (response->obj)
+ json_object_unref(response->obj);
+
+ if (response->raw)
+ g_free(response->raw);
+
+ g_free(response);
+ }
}
static size_t
@@ -559,10 +563,6 @@ static CURL* get_curl(TrgClient *tc, guint http_class)
priv->http_class = http_class;
}
- if (http_class == HTTP_CLASS_TRANSMISSION) {
- curl_easy_setopt(curl, CURLOPT_URL, trg_client_get_url(tc));
- }
-
curl_easy_setopt(curl, CURLOPT_TIMEOUT,
(long) trg_prefs_get_int(prefs, TRG_PREFS_KEY_TIMEOUT,
TRG_PREFS_CONNECTION));
diff --git a/src/trg-files-tree-view.c b/src/trg-files-tree-view.c
index 1c93ad6..ae9e071 100644
--- a/src/trg-files-tree-view.c
+++ b/src/trg-files-tree-view.c
@@ -93,7 +93,7 @@ static gboolean on_files_update(gpointer data)
response->cb_data = priv->win;
- return on_generic_interactive_action(data);
+ return on_generic_interactive_action_response(data);
}
static void send_updated_file_prefs(TrgFilesTreeView * tv)
diff --git a/src/trg-main-window.c b/src/trg-main-window.c
index f4e479c..3066c4d 100644
--- a/src/trg-main-window.c
+++ b/src/trg-main-window.c
@@ -76,6 +76,7 @@
#include "trg-rss-window.h"
#include "trg-remote-prefs-dialog.h"
#include "trg-preferences-dialog.h"
+#include "upload.h"
/* The rather large main window class, which glues everything together. */
@@ -480,7 +481,7 @@ static void pause_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_pause(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void pause_all_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -489,7 +490,7 @@ static void pause_all_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
if (trg_client_is_connected(priv->client))
dispatch_async(priv->client, torrent_pause(NULL),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
gint trg_add_from_filename(TrgMainWindow * win, gchar ** uris)
@@ -505,10 +506,14 @@ gint trg_add_from_filename(TrgMainWindow * win, gchar ** uris)
return EXIT_SUCCESS;
}
- if (uris)
- for (i = 0; uris[i]; i++)
- if (uris[i])
+ if (uris) {
+ for (i = 0; uris[i]; i++) {
+ if (is_minimised_arg(uris[i]))
+ g_free(uris[i]);
+ else if (uris[i])
filesList = g_slist_append(filesList, uris[i]);
+ }
+ }
g_free(uris);
@@ -518,20 +523,20 @@ gint trg_add_from_filename(TrgMainWindow * win, gchar ** uris)
if (trg_prefs_get_bool(prefs, TRG_PREFS_KEY_ADD_OPTIONS_DIALOG,
TRG_PREFS_GLOBAL)) {
TrgTorrentAddDialog *dialog =
- trg_torrent_add_dialog_new(win, client,
+ trg_torrent_add_dialog_new_from_filenames(win, client,
filesList);
gtk_widget_show_all(GTK_WIDGET(dialog));
} else {
- struct add_torrent_threadfunc_args *args =
- g_new0(struct add_torrent_threadfunc_args, 1);
- args->list = filesList;
- args->cb_data = win;
- args->client = client;
- args->extraArgs = FALSE;
- args->flags = trg_prefs_get_add_flags(prefs);
-
- launch_add_thread(args);
+ trg_upload *upload = g_new0(trg_upload, 1);
+
+ upload->list = filesList;
+ upload->main_window = win;
+ upload->client = client;
+ upload->extra_args = FALSE;
+ upload->flags = trg_prefs_get_add_flags(prefs);
+
+ trg_do_upload(upload);
}
return EXIT_SUCCESS;
@@ -543,7 +548,7 @@ static void resume_all_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
if (trg_client_is_connected(priv->client))
dispatch_async(priv->client, torrent_start(NULL),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void resume_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -554,7 +559,7 @@ static void resume_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_start(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void disconnect_cb(GtkWidget * w G_GNUC_UNUSED, gpointer data)
@@ -713,7 +718,7 @@ static void reannounce_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_reannounce(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void verify_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -724,7 +729,7 @@ static void verify_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_verify(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void start_now_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -735,7 +740,7 @@ static void start_now_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_start_now(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void up_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -746,7 +751,7 @@ static void up_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_queue_move_up(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void top_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -757,7 +762,7 @@ static void top_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_queue_move_top(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void
@@ -769,7 +774,7 @@ bottom_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_queue_move_bottom(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static void down_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
@@ -780,7 +785,7 @@ static void down_queue_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
dispatch_async(priv->client,
torrent_queue_move_down(build_json_id_array
(priv->torrentTreeView)),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
}
static gint
@@ -882,7 +887,7 @@ static void remove_cb(GtkWidget * w G_GNUC_UNUSED, TrgMainWindow * win)
_("<big><b>Remove %d torrents?</b></big>"),
GTK_STOCK_REMOVE) == GTK_RESPONSE_ACCEPT)
dispatch_async(priv->client, torrent_remove(ids, FALSE),
- on_generic_interactive_action, win);
+ on_generic_interactive_action_response, win);
else
json_array_unref(ids);
}
@@ -1584,13 +1589,10 @@ gboolean on_delete_complete(gpointer data)
trg_client_update_session(priv->client, on_session_get,
response->cb_data);
- return on_generic_interactive_action(data);
+ return on_generic_interactive_action_response(data);
}
-gboolean on_generic_interactive_action(gpointer data)
-{
- trg_response *response = (trg_response *) data;
- TrgMainWindow *win = TRG_MAIN_WINDOW(response->cb_data);
+void on_generic_interactive_action(TrgMainWindow *win, trg_response *response) {
TrgMainWindowPrivate *priv = win->priv;
TrgClient *tc = priv->client;
@@ -1610,6 +1612,15 @@ gboolean on_generic_interactive_action(gpointer data)
}
trg_response_free(response);
+}
+
+gboolean on_generic_interactive_action_response(gpointer data)
+{
+ trg_response *response = (trg_response *) data;
+ TrgMainWindow *win = TRG_MAIN_WINDOW(response->cb_data);
+
+ on_generic_interactive_action(win, response);
+
return FALSE;
}
@@ -1944,7 +1955,7 @@ static void set_limit_cb(GtkWidget * w, TrgMainWindow * win)
json_object_set_boolean_member(args, enabledKey, speed >= 0);
if (limitIds)
- dispatch_async(priv->client, req, on_generic_interactive_action,
+ dispatch_async(priv->client, req, on_generic_interactive_action_response,
win);
else
dispatch_async(priv->client, req, on_session_set, win);
@@ -1969,7 +1980,7 @@ static void set_priority_cb(GtkWidget * w, TrgMainWindow * win)
json_object_set_int_member(args, FIELD_BANDWIDTH_PRIORITY, priority);
- dispatch_async(priv->client, req, on_generic_interactive_action, win);
+ dispatch_async(priv->client, req, on_generic_interactive_action_response, win);
}
static GtkWidget *limit_item_new(TrgMainWindow * win, GtkWidget * menu,
diff --git a/src/trg-main-window.h b/src/trg-main-window.h
index 3c6ace5..3fb69af 100644
--- a/src/trg-main-window.h
+++ b/src/trg-main-window.h
@@ -63,7 +63,8 @@ GType trg_main_window_get_type(void);
gint trg_add_from_filename(TrgMainWindow * win, gchar ** uris);
gboolean on_session_set(gpointer data);
gboolean on_delete_complete(gpointer data);
-gboolean on_generic_interactive_action(gpointer data);
+void on_generic_interactive_action(TrgMainWindow *win, trg_response *response);
+gboolean on_generic_interactive_action_response(gpointer data);
void auto_connect_if_required(TrgMainWindow * win);
void trg_main_window_set_start_args(TrgMainWindow * win, gchar ** args);
TrgMainWindow *trg_main_window_new(TrgClient * tc, gboolean minonstart);
diff --git a/src/trg-rss-model.c b/src/trg-rss-model.c
index bc43ef7..12b2d2b 100644
--- a/src/trg-rss-model.c
+++ b/src/trg-rss-model.c
@@ -45,10 +45,8 @@ typedef struct {
TrgRssModel *model;
gchar *feed_id;
gchar *feed_url;
- gint status;
- RssParser *parser;
- gboolean success;
GError *error;
+ trg_response *response;
} feed_update;
static void feed_update_free(feed_update *update) {
@@ -58,61 +56,52 @@ static void feed_update_free(feed_update *update) {
g_free(update->feed_id);
g_free(update->feed_url);
- if (update->parser)
- g_object_unref(update->parser);
-
g_free(update);
}
-static gboolean on_rss_receive_idle(gpointer data) {
- feed_update *update = (feed_update*) data;
- TrgRssModel *model = update->model;
- TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(model);
-
- if (update->success) {
- RssDocument *doc = rss_parser_get_document(update->parser);
- GtkTreeIter iter;
- GList *list, *tmp;
- gchar *title;
-
- list = rss_document_get_items(doc);
-
- for (tmp = list; tmp != NULL; tmp = tmp->next) {
- RssItem *item = (RssItem*) tmp->data;
- const gchar *guid = rss_item_get_guid(item);
- if (g_hash_table_lookup(priv->table, guid) != (void*) 1) {
- gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- gtk_list_store_set(GTK_LIST_STORE(model), &iter, RSSCOL_ID,
- guid, RSSCOL_TITLE, rss_item_get_title(item),
- RSSCOL_LINK, rss_item_get_link(item), -1);
- g_hash_table_insert(priv->table, g_strdup(guid), (void*) 1);
- }
- }
-
- g_list_free(list);
- g_object_unref(doc);
- }
-
- feed_update_free(update);
-
- return FALSE;
-}
-
static gboolean on_rss_receive(gpointer data) {
trg_response *response = (trg_response *) data;
feed_update *update = (feed_update*) response->cb_data;
-
- update->status = response->status;
+ TrgRssModel *model = update->model;
+ TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(model);
if (response->status == CURLE_OK) {
- update->parser = rss_parser_new();
- update->success = rss_parser_load_from_data(update->parser,
- response->raw, response->size, &(update->error));
- }
+ RssParser* parser = rss_parser_new();
+ GError *error = NULL;
+ if (rss_parser_load_from_data(parser, response->raw,
+ response->size, &error)) {
+ RssDocument *doc = rss_parser_get_document(parser);
+ GtkTreeIter iter;
+ GList *list, *tmp;
+ gchar *title;
+
+ list = rss_document_get_items(doc);
+
+ for (tmp = list; tmp != NULL; tmp = tmp->next) {
+ RssItem *item = (RssItem*) tmp->data;
+ const gchar *guid = rss_item_get_guid(item);
+ if (g_hash_table_lookup(priv->table, guid) != (void*) 1) {
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, RSSCOL_ID,
+ guid, RSSCOL_TITLE, rss_item_get_title(item),
+ RSSCOL_LINK, rss_item_get_link(item), RSSCOL_FEED,
+ update->feed_id, RSSCOL_PUBDATE,
+ rss_item_get_pub_date(item), -1);
+ g_hash_table_insert(priv->table, g_strdup(guid), (void*) 1);
+ }
+ }
- g_idle_add(on_rss_receive_idle, update);
+ g_list_free(list);
+ g_object_unref(doc);
+ g_object_unref(parser);
+ } else {
+ g_error_free(error);
+ g_message("parse error?");
+ }
+ }
trg_response_free(response);
+ feed_update_free(update);
return FALSE;
}
@@ -126,7 +115,8 @@ void trg_rss_model_update(TrgRssModel * model) {
if (!feeds)
return;
- for (li = json_array_get_elements(feeds); li != NULL; li = g_list_next(li)) {
+ for (li = json_array_get_elements(feeds); li != NULL;
+ li = g_list_next(li)) {
JsonObject *feed = json_node_get_object((JsonNode *) li->data);
const gchar *url = json_object_get_string_member(feed, "url");
const gchar *id = json_object_get_string_member(feed, "id");
@@ -174,11 +164,10 @@ static GObject *trg_rss_model_constructor(GType type,
return obj;
}
-static void trg_rss_model_dispose(GObject * object)
-{
+static void trg_rss_model_dispose(GObject * object) {
TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(object);
g_hash_table_destroy(priv->table);
- G_OBJECT_CLASS(trg_rss_model_parent_class)->dispose(object);
+ G_OBJECT_CLASS(trg_rss_model_parent_class)->dispose(object);
}
static void trg_rss_model_class_init(TrgRssModelClass * klass) {
@@ -199,12 +188,13 @@ static void trg_rss_model_class_init(TrgRssModelClass * klass) {
}
static void trg_rss_model_init(TrgRssModel * self) {
- //TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(self);
GType column_types[RSSCOL_COLUMNS];
column_types[RSSCOL_ID] = G_TYPE_STRING;
column_types[RSSCOL_TITLE] = G_TYPE_STRING;
column_types[RSSCOL_LINK] = G_TYPE_STRING;
+ column_types[RSSCOL_FEED] = G_TYPE_STRING;
+ column_types[RSSCOL_PUBDATE] = G_TYPE_STRING;
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 9befa48..799629a 100644
--- a/src/trg-rss-model.h
+++ b/src/trg-rss-model.h
@@ -57,6 +57,8 @@ enum {
RSSCOL_ID,
RSSCOL_TITLE,
RSSCOL_LINK,
+ RSSCOL_FEED,
+ RSSCOL_PUBDATE,
RSSCOL_COLUMNS
};
diff --git a/src/trg-rss-window.c b/src/trg-rss-window.c
index 52a096f..942dddc 100644
--- a/src/trg-rss-window.c
+++ b/src/trg-rss-window.c
@@ -23,7 +23,9 @@
#include "trg-rss-window.h"
#include "trg-rss-model.h"
+#include "trg-torrent-add-dialog.h"
#include "trg-client.h"
+#include "upload.h"
#include "util.h"
G_DEFINE_TYPE(TrgRssWindow, trg_rss_window,
@@ -84,15 +86,59 @@ trg_rss_window_set_property(GObject * object,
}
}
+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);
+ TrgClient *client = priv->client;
+ TrgPrefs *prefs = trg_client_get_prefs(client);
+ TrgMainWindow *main_win = priv->parent;
+
+ 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));*/
+ } 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);
+ }
+ } else {
+ trg_error_dialog(GTK_WINDOW(win), response);
+ trg_response_free(response);
+ }
+
+ return FALSE;
+}
+
static void
-trg_rss_window_response_cb(GtkDialog * dlg, gint res_id,
- gpointer data G_GNUC_UNUSED)
+rss_item_activated(GtkTreeView * treeview,
+ GtkTreePath * path,
+ GtkTreeViewColumn *
+ col G_GNUC_UNUSED, gpointer userdata)
{
- TrgRssWindowPrivate *priv =
- TRG_RSS_WINDOW_GET_PRIVATE(dlg);
+ TrgRssWindow *win = TRG_RSS_WINDOW(userdata);
+ TrgRssWindowPrivate *priv = TRG_RSS_WINDOW_GET_PRIVATE(win);
+ GtkTreeModel *model = gtk_tree_view_get_model(treeview);
+ GtkTreeIter iter;
+ gchar *link;
+
+ gtk_tree_model_get_iter(model, &iter, path);
+
+ gtk_tree_model_get(model, &iter, RSSCOL_LINK, &link, -1);
+
+ async_http_request(priv->client, link, on_torrent_receive, userdata);
- gtk_widget_destroy(GTK_WIDGET(dlg));
- instance = NULL;
+ g_free(link);
}
static GObject *trg_rss_window_constructor(GType type,
@@ -105,7 +151,7 @@ static GObject *trg_rss_window_constructor(GType type,
TrgRssWindowPrivate *priv;
TrgRssModel *model;
GtkTreeView *view;
- GtkWidget *vbox, *toolbar, *contentbox;
+ GtkWidget *vbox, *toolbar;
GtkToolItem *item;
object = G_OBJECT_CLASS
@@ -120,10 +166,14 @@ static GObject *trg_rss_window_constructor(GType type,
view = GTK_TREE_VIEW(gtk_tree_view_new());
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_window_set_title(GTK_WINDOW(object), _("RSS Viewer"));
+ g_signal_connect(view, "row-activated",
+ G_CALLBACK(rss_item_activated), object);
- //contentbox = gtk_dialog_get_content_area(GTK_DIALOG(object));
+ gtk_window_set_title(GTK_WINDOW(object), _("RSS Feeds"));
toolbar = gtk_toolbar_new();
diff --git a/src/trg-torrent-add-dialog.c b/src/trg-torrent-add-dialog.c
index 517797e..702efd4 100644
--- a/src/trg-torrent-add-dialog.c
+++ b/src/trg-torrent-add-dialog.c
@@ -45,9 +45,10 @@
#include "torrent.h"
#include "json.h"
#include "protocol-constants.h"
+#include "upload.h"
enum {
- PROP_0, PROP_FILENAME, PROP_PARENT, PROP_CLIENT
+ PROP_0, PROP_FILENAME, PROP_PARENT, PROP_CLIENT, PROP_RESPONSE
};
enum {
@@ -63,6 +64,7 @@ struct _TrgTorrentAddDialogPrivate {
TrgClient *client;
TrgMainWindow *parent;
GSList *filenames;
+ trg_response *response;
GtkWidget *source_chooser;
GtkWidget *dest_combo;
GtkWidget *priority_combo;
@@ -115,65 +117,6 @@ trg_torrent_add_dialog_get_property(GObject * object,
}
}
-static void
-add_set_common_args(JsonObject * args, gint priority, gchar * dir)
-{
- json_object_set_string_member(args, FIELD_FILE_DOWNLOAD_DIR, dir);
- json_object_set_int_member(args, FIELD_BANDWIDTH_PRIORITY,
- (gint64) priority);
-}
-
-static gpointer add_files_threadfunc(gpointer data)
-{
- struct add_torrent_threadfunc_args *files_thread_data =
- (struct add_torrent_threadfunc_args *) data;
-
- GSList *li;
-
- for (li = files_thread_data->list; li; li = g_slist_next(li)) {
- gchar *fileName = (gchar *) li->data;
- JsonNode *request =
- torrent_add(fileName, files_thread_data->flags);
- JsonObject *args;
- trg_response *response;
-
- if (!request)
- continue;
-
- args = node_get_arguments(request);
-
- if (files_thread_data->extraArgs)
- add_set_common_args(args, files_thread_data->priority,
- files_thread_data->dir);
-
- response = dispatch(files_thread_data->client, request);
- response->cb_data = files_thread_data->cb_data;
- g_idle_add(on_generic_interactive_action, response);
- }
-
- g_str_slist_free(files_thread_data->list);
-
- if (files_thread_data->extraArgs)
- g_free(files_thread_data->dir);
-
- g_free(files_thread_data);
-
- return NULL;
-}
-
-void launch_add_thread(struct add_torrent_threadfunc_args *args)
-{
- GError *error = NULL;
- g_thread_create(add_files_threadfunc, args, FALSE, &error);
-
- if (error) {
- g_error("thread creation error: %s", error->message);
- g_error_free(error);
- g_str_slist_free(args->list);
- g_free(args);
- }
-}
-
static gboolean
add_file_indexes_foreachfunc(GtkTreeModel * model,
GtkTreePath *
@@ -226,32 +169,17 @@ trg_torrent_add_response_cb(GtkDialog * dlg, gint res_id, gpointer data)
trg_destination_combo_get_dir(TRG_DESTINATION_COMBO
(priv->dest_combo));
- if (g_slist_length(priv->filenames) == 1) {
- JsonNode *req =
- torrent_add((gchar *) priv->filenames->data, flags);
- if (req) {
- JsonObject *args = node_get_arguments(req);
- gtk_tree_model_foreach(GTK_TREE_MODEL(priv->store),
- add_file_indexes_foreachfunc, args);
- add_set_common_args(args, priority, dir);
- dispatch_async(priv->client, req,
- on_generic_interactive_action,
- priv->parent);
- }
- g_str_slist_free(priv->filenames);
- } else {
- struct add_torrent_threadfunc_args *args =
- g_new(struct add_torrent_threadfunc_args, 1);
- args->list = priv->filenames;
- args->cb_data = priv->parent;
- args->client = priv->client;
- args->dir = g_strdup(dir);
- args->priority = priority;
- args->flags = flags;
- args->extraArgs = TRUE;
-
- launch_add_thread(args);
- }
+ trg_upload *upload = g_new0(trg_upload, 1);
+
+ upload->list = priv->filenames;
+ upload->main_window = priv->parent;
+ upload->client = priv->client;
+ upload->dir = dir;
+ upload->priority = priority;
+ upload->flags = flags;
+ upload->extra_args = TRUE;
+
+ trg_do_upload(upload);
trg_destination_combo_save_selection(TRG_DESTINATION_COMBO
(priv->dest_combo));
@@ -868,6 +796,21 @@ 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",
+ G_PARAM_READWRITE
+ |
+ G_PARAM_CONSTRUCT_ONLY
+ |
+ G_PARAM_STATIC_NAME
+ |
+ G_PARAM_STATIC_NICK
+ |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property(object_class,
PROP_CLIENT,
g_param_spec_pointer("client",
"client",
@@ -902,7 +845,7 @@ static void trg_torrent_add_dialog_init(TrgTorrentAddDialog * self)
{
}
-TrgTorrentAddDialog *trg_torrent_add_dialog_new(TrgMainWindow * parent,
+TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_filenames(TrgMainWindow * parent,
TrgClient * client,
GSList * filenames)
{
@@ -911,6 +854,15 @@ TrgTorrentAddDialog *trg_torrent_add_dialog_new(TrgMainWindow * parent,
NULL);
}
+TrgTorrentAddDialog *trg_torrent_add_dialog_new_from_response(TrgMainWindow * parent,
+ TrgClient * client,
+ trg_response *response)
+{
+ return g_object_new(TRG_TYPE_TORRENT_ADD_DIALOG, "response",
+ response, "parent", parent, "client", client,
+ NULL);
+}
+
void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client)
{
GtkWidget *w;
@@ -937,22 +889,21 @@ void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client)
prefs);
if (showOptions) {
- TrgTorrentAddDialog *dialog = trg_torrent_add_dialog_new(win,
+ TrgTorrentAddDialog *dialog = trg_torrent_add_dialog_new_from_filenames(win,
client,
l);
gtk_widget_show_all(GTK_WIDGET(dialog));
} else {
- struct add_torrent_threadfunc_args *args =
- g_new0(struct add_torrent_threadfunc_args, 1);
+ trg_upload *upload = g_new0(trg_upload, 1);
- args->list = l;
- args->cb_data = win;
- args->client = client;
- args->extraArgs = FALSE;
- args->flags = trg_prefs_get_add_flags(prefs);
+ upload->list = l;
+ upload->main_window = win;
+ upload->client = client;
+ upload->extra_args = FALSE;
+ upload->flags = trg_prefs_get_add_flags(prefs);
- launch_add_thread(args);
+ trg_do_upload(upload);
}
}
diff --git a/src/trg-torrent-add-dialog.h b/src/trg-torrent-add-dialog.h
index 0f45e2c..ab6721e 100644
--- a/src/trg-torrent-add-dialog.h
+++ b/src/trg-torrent-add-dialog.h
@@ -46,28 +46,12 @@ typedef struct {
GtkDialogClass parent_class;
} TrgTorrentAddDialogClass;
-/* Use synchronous dispatch() in our dedicated thread function.
- * This means torrents are added in sequence, instead of dispatch_async()
- * working concurrently for each upload.
- */
-
-struct add_torrent_threadfunc_args {
- GSList *list;
- TrgClient *client;
- gpointer cb_data;
- guint flags;
- gchar *dir;
- gint priority;
- gboolean extraArgs;
-};
-
GType trg_torrent_add_dialog_get_type(void);
TrgTorrentAddDialog *trg_torrent_add_dialog_new(TrgMainWindow * win,
TrgClient * client,
GSList * filenames);
void trg_torrent_add_dialog(TrgMainWindow * win, TrgClient * client);
-void launch_add_thread(struct add_torrent_threadfunc_args *args);
G_END_DECLS
#endif /* TRG_TORRENT_ADD_DIALOG_H_ */
diff --git a/src/trg-torrent-add-url-dialog.c b/src/trg-torrent-add-url-dialog.c
index 7f6335e..8ed15d8 100644
--- a/src/trg-torrent-add-url-dialog.c
+++ b/src/trg-torrent-add-url-dialog.c
@@ -90,7 +90,7 @@ trg_torrent_add_url_response_cb(TrgTorrentAddUrlDialog * dlg, gint res_id,
gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON(priv->startCheck)));
dispatch_async(priv->client, request,
- on_generic_interactive_action, data);
+ on_generic_interactive_action_response, data);
}
gtk_widget_destroy(GTK_WIDGET(dlg));
diff --git a/src/trg-torrent-move-dialog.c b/src/trg-torrent-move-dialog.c
index 7669545..99a11fb 100644
--- a/src/trg-torrent-move-dialog.c
+++ b/src/trg-torrent-move-dialog.c
@@ -69,7 +69,7 @@ trg_torrent_move_response_cb(GtkDialog * dlg, gint res_id, gpointer data)
trg_destination_combo_save_selection(TRG_DESTINATION_COMBO
(priv->location_combo));
dispatch_async(priv->client, request,
- on_generic_interactive_action, data);
+ on_generic_interactive_action_response, data);
} else {
json_array_unref(priv->ids);
}
diff --git a/src/trg-torrent-props-dialog.c b/src/trg-torrent-props-dialog.c
index 90ef4e3..71a9c71 100644
--- a/src/trg-torrent-props-dialog.c
+++ b/src/trg-torrent-props-dialog.c
@@ -172,7 +172,7 @@ static void trg_torrent_props_response_cb(GtkDialog * dialog, gint res_id,
trg_json_widgets_save(priv->widgets, args);
trg_json_widget_desc_list_free(priv->widgets);
- dispatch_async(priv->client, request, on_generic_interactive_action,
+ dispatch_async(priv->client, request, on_generic_interactive_action_response,
priv->parent);
}
diff --git a/src/trg-trackers-tree-view.c b/src/trg-trackers-tree-view.c
index 7ce05b7..54948f3 100644
--- a/src/trg-trackers-tree-view.c
+++ b/src/trg-trackers-tree-view.c
@@ -66,7 +66,7 @@ static gboolean on_trackers_update(gpointer data)
trg_trackers_model_set_accept(TRG_TRACKERS_MODEL(model), TRUE);
response->cb_data = priv->win;
- return on_generic_interactive_action(data);
+ return on_generic_interactive_action_response(data);
}
void
diff --git a/src/upload.c b/src/upload.c
new file mode 100644
index 0000000..5bac869
--- /dev/null
+++ b/src/upload.c
@@ -0,0 +1,62 @@
+#include "protocol-constants.h"
+#include "requests.h"
+#include "trg-client.h"
+#include "upload.h"
+#include "util.h"
+#include "trg-main-window.h"
+
+static gboolean upload_complete_callback(gpointer data);
+static void next_upload(trg_upload *upload);
+
+static void
+add_set_common_args(JsonObject * args, gint priority, gchar * dir)
+{
+ json_object_set_string_member(args, FIELD_FILE_DOWNLOAD_DIR, dir);
+ json_object_set_int_member(args, FIELD_BANDWIDTH_PRIORITY,
+ (gint64) priority);
+}
+
+void trg_upload_free(trg_upload *upload) {
+ g_str_slist_free(upload->list);
+ g_free(upload->dir);
+ trg_response_free(upload->upload_response);
+ g_free(upload);
+}
+
+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 =
+ 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);
+ upload->progress_index++;
+ dispatch_async(upload->client, req, upload_complete_callback, upload);
+ } else {
+ trg_upload_free(upload);
+ }
+}
+
+static gboolean upload_complete_callback(gpointer data) {
+ trg_response *response = (trg_response*)data;
+ trg_upload *upload = (trg_upload*)response->cb_data;
+
+ next_upload(upload);
+
+ /* 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 */
+ trg_response_free(response);
+
+ return FALSE;
+}
+
+void trg_do_upload(trg_upload *upload)
+{
+ next_upload(upload);
+}
diff --git a/src/upload.h b/src/upload.h
new file mode 100644
index 0000000..9f3f719
--- /dev/null
+++ b/src/upload.h
@@ -0,0 +1,25 @@
+#ifndef UPLOAD_H_
+#define UPLOAD_H_
+
+#include <glib.h>
+
+#include "trg-client.h"
+#include "trg-main-window.h"
+
+typedef struct {
+ GSList *list; // list of filenames
+ trg_response *upload_response; // OR: a HTTP response containing a torrent
+ TrgClient *client;
+ gpointer cb_data;
+ TrgMainWindow *main_window; // a parent window to attach any error dialogs to
+ guint flags;
+ gchar *dir;
+ gint priority;
+ gboolean extra_args;
+ guint progress_index;
+
+} trg_upload;
+
+void trg_do_upload(trg_upload *upload);
+
+#endif