/soc/2013/bhaskar/plugins-window: e607be6b11ac: Added JSON_CFLAG...

Bhaskar Kandiyal bkandiyal at gmail.com
Thu Aug 22 15:40:46 EDT 2013


Changeset: e607be6b11ac59e1780f52e4411c8ae9cf575eb4
Author:	 Bhaskar Kandiyal <bkandiyal at gmail.com>
Date:	 2013-08-23 01:08 +0530
Branch:	 soc.2013.plugins_window
URL: https://hg.pidgin.im/soc/2013/bhaskar/plugins-window/rev/e607be6b11ac

Description:

Added JSON_CFLAGS to pidgin/Makefile.am. Also implemented basic auto-updation of plugins from the plugins window

diffstat:

 pidgin/Makefile.am |    3 +-
 pidgin/gtkplugin.c |  232 ++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 206 insertions(+), 29 deletions(-)

diffs (truncated from 411 to 300 lines):

diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
--- a/pidgin/Makefile.am
+++ b/pidgin/Makefile.am
@@ -208,6 +208,7 @@ AM_CPPFLAGS = \
 	$(GTKSPELL_CFLAGS) \
 	$(LIBXML_CFLAGS) \
 	$(WEBKIT_CFLAGS) \
-	$(INTGG_CFLAGS)
+	$(INTGG_CFLAGS) \
+	$(JSON_CFLAGS)
 endif  # ENABLE_GTK
 
diff --git a/pidgin/gtkplugin.c b/pidgin/gtkplugin.c
--- a/pidgin/gtkplugin.c
+++ b/pidgin/gtkplugin.c
@@ -33,11 +33,13 @@
 #include "request.h"
 #include "pidgintooltip.h"
 #include "gtkwebview.h"
+#include "libpurple/http.h"
 
 #include <string.h>
+#include <json-glib/json-glib.h>
+#include <sys/utsname.h>
 
 #include "gtk3compat.h"
-
 #define PIDGIN_RESPONSE_CONFIGURE 98121
 
 typedef enum {
@@ -51,7 +53,8 @@ typedef enum {
 	PLUGIN_FILTER_ALL_PLUGINS = 3,
 } PluginFilter;
 
-static const gchar* DEFAULT_URI = "http://bhaskar-kandiyal.rhcloud.com/";
+/*static const gchar* DEFAULT_URI = "http://bhaskar-kandiyal.rhcloud.com";*/
+static const gchar* DEFAULT_URI = "http://127.0.0.1:8000"; /* For local debugging only */
 static gint FIRST_LOAD = TRUE;
 
 static void plugin_toggled_stage_two(PurplePlugin *plug, GtkTreeModel *model,
@@ -176,15 +179,18 @@ update_plugin_list(void *data)
 
 static void plugin_loading_common(PurplePlugin *plugin, GtkTreeView *view, gboolean loaded)
 {
+	GtkTreeIter iter_filter;
 	GtkTreeIter iter;
-	GtkTreeModel *model = gtk_tree_view_get_model(view);
+	GtkTreeModel *model_filter = gtk_tree_view_get_model(view);
+	GtkTreeModel *model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model_filter));
 	gchar *buf;
 
-	if (gtk_tree_model_get_iter_first(model, &iter)) {
+	if (gtk_tree_model_get_iter_first(model_filter, &iter_filter)) {
 		do {
 			PurplePlugin *plug;
 			GtkTreeSelection *sel;
 
+			gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model_filter), &iter, &iter_filter);
 			gtk_tree_model_get(model, &iter, 2, &plug, -1);
 
 			if (plug != plugin)
@@ -212,7 +218,7 @@ static void plugin_loading_common(Purple
 			}
 
 			break;
-		} while (gtk_tree_model_iter_next(model, &iter));
+		} while (gtk_tree_model_iter_next(model_filter, &iter_filter));
 	}
 }
 
@@ -262,9 +268,11 @@ static void plugin_unload_confirm_cb(gpo
 
 static void plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer data)
 {
-	GtkTreeModel *model = (GtkTreeModel *)data;
+	GtkTreeModelFilter *model_filter = (GtkTreeModelFilter *)data;
+	GtkTreeModel *model = gtk_tree_model_filter_get_model(model_filter);
 	GtkTreeIter *iter = g_new(GtkTreeIter, 1);
-	GtkTreePath *path = gtk_tree_path_new_from_string(pth);
+	GtkTreePath *path_filter = gtk_tree_path_new_from_string(pth);
+	GtkTreePath *path = gtk_tree_model_filter_convert_path_to_child_path(model_filter, path_filter);
 	PurplePlugin *plug;
 	GtkWidget *dialog = NULL;
 
@@ -571,6 +579,7 @@ static void plugin_dialog_response_cb(Gt
 static void
 plugin_tab_change_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
 {
+	gchar *uri;
 	switch (page_num) {
 	case PLUGINS_TAB_DOWNLOAD_PLUGINS:
 
@@ -579,8 +588,11 @@ plugin_tab_change_cb(GtkNotebook *notebo
 		 * TODO: Any other way to do this?
 		 * */
 		if (FIRST_LOAD) {
-			webkit_web_view_load_uri(WEBKIT_WEB_VIEW(download_plugins), DEFAULT_URI);
+			uri = g_strdup_printf("%s/?platform=detect", DEFAULT_URI);
+			purple_debug_info("plugins", "Loading %s", uri);
+			webkit_web_view_load_uri(WEBKIT_WEB_VIEW(download_plugins), uri);
 			FIRST_LOAD = FALSE;
+			g_free(uri);
 		}
 
 	break;
@@ -671,13 +683,12 @@ static void
 plugin_details_button_click_cb(WebKitDOMNode *element, WebKitDOMEvent *dom_event, void *context)
 {
 	GtkTreeSelection *sel;
-	GtkTreeIter iter;
+	GtkTreeIter iter, iter_filter;
 	PurplePlugin *plugin;
-	GtkTreeModel *model;
+	GtkTreeModel *model, *model_filter;
 	gchar *id;
 	GtkWidget *dialog;
 	gint result;
-	GtkListStore *ls;
 	gboolean ret;
 
 	g_object_get(element, "id", &id, NULL);
@@ -687,9 +698,11 @@ plugin_details_button_click_cb(WebKitDOM
 
 		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(event_view));
 
-		if (!gtk_tree_selection_get_selected(sel, &model, &iter))
+		if (!gtk_tree_selection_get_selected(sel, &model_filter, &iter_filter))
 			return;
 
+		model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model_filter));
+		gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model_filter), &iter, &iter_filter);
 		gtk_tree_model_get(model, &iter, 2, &plugin, -1);
 
 		if (!purple_plugin_is_loaded(plugin))
@@ -702,9 +715,11 @@ plugin_details_button_click_cb(WebKitDOM
 	{
 		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(event_view));
 
-		if (!gtk_tree_selection_get_selected(sel, &model, &iter))
+		if (!gtk_tree_selection_get_selected(sel, &model_filter, &iter_filter))
 			return;
 
+		model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model_filter));
+		gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model_filter), &iter, &iter_filter);
 		gtk_tree_model_get(model, &iter, 2, &plugin, -1);
 
 		dialog = gtk_message_dialog_new(GTK_WINDOW(plugin_dialog), GTK_DIALOG_MODAL,
@@ -716,14 +731,14 @@ plugin_details_button_click_cb(WebKitDOM
 		case GTK_RESPONSE_YES:
 			ret = purple_plugin_remove(plugin);
 			if (ret) {
-				ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(event_view)));
-				g_object_ref(G_OBJECT(ls));
+				/*ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(event_view)));
+				g_object_ref(G_OBJECT(ls));*/
 
 				gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), NULL);
-				update_plugin_list(ls);
-				gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), GTK_TREE_MODEL(ls));
+				update_plugin_list(model);
+				gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), GTK_TREE_MODEL(model_filter));
 
-				g_object_unref(G_OBJECT(ls));
+				/* g_object_unref(G_OBJECT(ls)); */
 			}
 			else {
 				dialog = gtk_message_dialog_new(GTK_WINDOW(plugin_dialog), GTK_DIALOG_MODAL,
@@ -742,7 +757,7 @@ static gboolean
 webview_download_status(gpointer data)
 {
 	GtkWidget *dialog;
-	GtkListStore *ls;
+	GtkTreeModel *model, *model_filter;
 	WebKitDownloadStatus status = webkit_download_get_status(WEBKIT_DOWNLOAD(data));
 
 	switch(status)
@@ -756,12 +771,11 @@ webview_download_status(gpointer data)
 		gtk_widget_destroy(dialog);
 
 		/* Refresh the plugins list */
-		ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(event_view)));
-		g_object_ref(G_OBJECT(ls));
+		model_filter = gtk_tree_view_get_model(GTK_TREE_VIEW(event_view));
+		model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model_filter));
 		gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), NULL);
-		update_plugin_list(ls);
-		gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), GTK_TREE_MODEL(ls));
-		g_object_unref(G_OBJECT(ls));
+		update_plugin_list(model);
+		gtk_tree_view_set_model(GTK_TREE_VIEW(event_view), GTK_TREE_MODEL(model_filter));
 
 		return FALSE;
 	break;
@@ -835,7 +849,6 @@ static void
 plugin_details_view_load_status_cb(WebKitWebView *webview, GParamSpec *spec, void *context)
 {
 	WebKitLoadStatus status = webkit_web_view_get_load_status(webview);
-	purple_debug_info("plugins", "Load status called\n");
 	switch (status) {
 	case WEBKIT_LOAD_FINISHED:
 		setup_webview_input_event_handlers(webview);
@@ -894,6 +907,166 @@ plugin_filter_function(GtkTreeModel *mod
 	return FALSE;
 }
 
+static void
+download_plugin_cb(PurpleHttpConnection *con, PurpleHttpResponse *response, gpointer user_data)
+{
+	gchar *id = (gchar*) user_data;
+	gssize size;
+	const gchar *data, *header;
+	gchar *path, *filename;
+	GRegex *regex;
+	GMatchInfo *minfo;
+
+	if(purple_http_response_is_successfull(response))
+	{
+		data = purple_http_response_get_data(response, &size);
+		header = purple_http_response_get_header(response, "Content-Disposition");
+		regex = g_regex_new("attachment; filename=\"(?<filename>.*)\"", G_REGEX_OPTIMIZE, 0, NULL);
+		if(g_regex_match(regex, header, 0, &minfo))
+		{
+			filename = g_match_info_fetch_named(minfo, "filename");
+			if(filename == NULL)
+			{
+				purple_debug_info("plugins", "Error: Cannot parse filename from header!");
+				return;
+			}
+			else
+			{
+				path = g_build_filename(purple_user_dir(), "plugins", filename, NULL);
+				purple_debug_info("plugins", "Downloading finished, saving to: %s\n", path);
+				if(!g_file_set_contents(path, data, size, NULL))
+				{
+					purple_debug_info("plugins", "Error downloading plugin %s\n", id);
+				}
+			}
+		}
+		g_match_info_free(minfo);
+		g_regex_unref(regex);
+	}
+	else {
+		purple_debug_info("plugins", "Error cannot download plugin %s\n", id);
+	}
+}
+
+static void
+download_plugin(gchar *plugin_id)
+{
+	struct utsname u_name;
+	gchar *url;
+	uname(&u_name);
+
+	url = g_strdup_printf("%s/plugin/download?id=%s&platform=%s&arch=%s", DEFAULT_URI,
+			plugin_id, u_name.sysname, u_name.machine);
+	purple_debug_info("plugins", "Starting download of: %s\n", url);
+	purple_http_get(NULL, url, download_plugin_cb, plugin_id);
+}
+
+static void
+check_updates_request_cb(PurpleHttpConnection *con, PurpleHttpResponse *response, gpointer user_data)
+{
+	JsonParser *parser;
+	JsonReader *reader;
+	const gchar *data;
+	gchar **list, **ptr;
+	const gchar *ver;
+	PurplePlugin *plug;
+
+	if(!purple_http_response_is_successfull(response))
+	{
+		purple_debug_info("plugins", "Error: Cannot check for updates\n");
+		return;
+	}
+
+	parser = json_parser_new();
+	data = purple_http_response_get_data(response, NULL);
+
+	json_parser_load_from_data(parser, data, -1, NULL);
+	reader = json_reader_new(json_parser_get_root(parser));
+
+	json_reader_read_member(reader, "plugins");
+
+	list = json_reader_list_members(reader);
+	for(ptr = list; *ptr != NULL; ptr++)
+	{
+		purple_debug_info("plugins", "At: %s", *ptr);
+		if(json_reader_read_member(reader, *ptr))
+		{
+			plug = purple_plugins_find_with_id(*ptr);
+			ver = json_reader_get_string_value(reader);
+			/*
+			 * If plug and ver are not NULL and current version is not equal to the version
+			 * on the server, we can update the plugin
+			 */
+			if(plug != NULL && ver != NULL && g_strcmp0(purple_plugin_get_version(plug), ver) != 0) {
+				purple_debug_info("plugins", "%s: %s\n", *ptr, ver);
+				download_plugin(*ptr);
+			}
+			else {



More information about the Commits mailing list