soc.2010.detachablepurple: 25b821b7: Added client side of the GetBuddyList db...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Mon Aug 9 23:58:28 EDT 2010


----------------------------------------------------------------------
Revision: 25b821b75a6179fee0aa580f3e725a95fba7062a
Parent:   d4c871b2bf423d139c723623878d4b4e4379acd7
Author:   gillux at soc.pidgin.im
Date:     08/09/10 23:39:05
Branch:   im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/25b821b75a6179fee0aa580f3e725a95fba7062a

Changelog: 

Added client side of the GetBuddyList dbus method. Clients can now load their
buddy list from the daemon rather than their local blist.xml.

Changes against parent d4c871b2bf423d139c723623878d4b4e4379acd7

  patched  libpurple/blist.c
  patched  libpurple/dbus/blist.c
  patched  libpurple/dbus/blist.h

-------------- next part --------------
============================================================
--- libpurple/blist.c	0c7cecf3a031d32d341c9fc305964ff0f733a35c
+++ libpurple/blist.c	537960f896237f9b9d5291c36d4ec69ad01394a6
@@ -390,6 +390,10 @@ purple_blist_load()
 
 	PURPLE_BLIST->blist_loaded = TRUE;
 
+	/* In remote mode, get the buddy list from the daemon instead. */
+	if (purple_core_is_remote_mode())
+		return purple_blist_load_RPC();
+
 	purple = purple_util_read_xml_from_file("blist.xml", _("buddy list"));
 
 	if (purple == NULL)
============================================================
--- libpurple/dbus/blist.c	3417d644ac5ddd558678b881be6c2ba7d4f616c3
+++ libpurple/dbus/blist.c	db185f5825734e45ed1cea5fddbcc1cb310f5093
@@ -417,3 +417,244 @@ set_blist_setting(GValueArray* box, GHas
 	g_value_unset(&val);
 	g_value_unset(value);
 }
+
+static void
+set_blist_settings(PurpleBlistNode *node, GPtrArray *settings)
+{
+	g_ptr_array_foreach(settings, (GFunc)set_blist_setting,
+	                     purple_blist_node_get_settings(node));
+}
+
+static void
+unpack_groups_cb(GValueArray* box)
+{
+	GValue val = {0, };
+	PurpleGroup *group;
+	PurpleRunningMode mode;
+	gboolean ok;
+	char *group_path = NULL;
+	char *group_name = NULL;
+	GPtrArray *settings = NULL;
+
+	/* Each group consists of a DBUS_PURPLE_GROUP_PACK */
+	g_value_init(&val, DBUS_PURPLE_GROUP_PACK);
+	g_value_set_boxed(&val, box);
+	ok = dbus_g_type_struct_get(&val,
+	                            0, &group_path,
+	                            1, &group_name,
+	                            2, &settings, G_MAXUINT);
+	
+	if (ok && group_path[0] && group_name[0]) {
+		/* Temporarly go in mirror mode and create a local group. */
+		mode = purple_core_get_running_mode();
+		purple_core_set_running_mode(PURPLE_RUN_MIRROR_MODE);
+		group = purple_group_new(group_name);
+		purple_object_install_dbus_infos(PURPLE_OBJECT(group),
+		                             DBUS_GROUP_INTERFACE, group_path);
+		set_blist_settings(PURPLE_BLIST_NODE(group), settings);
+		purple_core_set_running_mode(mode);
+	} else {
+		purple_debug_warning("dbus", "GetBuddyList: received an invalid group\n");
+	}
+
+	g_free(group_path);
+	g_free(group_name);
+	g_ptr_array_foreach(settings, (GFunc)g_value_array_free, NULL);
+	g_ptr_array_free(settings, TRUE);
+	g_value_unset(&val);
+	g_value_array_free(box);
+}
+
+
+static void
+unpack_contacts_cb(GValueArray* box)
+{
+	GValue val = {0, };
+	PurpleContact *contact;
+	PurpleRunningMode mode;
+	gboolean ok;
+	GObject *parent;
+	char *contact_path = NULL;
+	char *alias = NULL;
+	char *parent_path = NULL;
+	GPtrArray *settings = NULL;
+
+	/* Each contact consists of a DBUS_PURPLE_CONTACT_PACK */
+	g_value_init(&val, DBUS_PURPLE_CONTACT_PACK);
+	g_value_set_boxed(&val, box);
+	ok = dbus_g_type_struct_get(&val,
+	                            0, &contact_path,
+	                            1, &alias,
+	                            2, &parent_path,
+	                            3, &settings, G_MAXUINT);
+
+	if (ok && contact_path[0]) {
+		/* Temporarly go in mirror mode, and create a local contact. */
+		mode = purple_core_get_running_mode();
+		purple_core_set_running_mode(PURPLE_RUN_MIRROR_MODE);
+		contact = purple_contact_new();
+		purple_object_install_dbus_infos(PURPLE_OBJECT(contact),
+		                         DBUS_CONTACT_INTERFACE, contact_path);
+		parent = purple_dbus_get_gobject_by_path(parent_path);
+		if (parent)
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(parent),
+			                            PURPLE_BLIST_NODE(contact));
+		if (alias[0])
+			purple_blist_alias_contact(contact, alias);
+		set_blist_settings(PURPLE_BLIST_NODE(contact), settings);
+		purple_core_set_running_mode(mode);
+	} else {
+		purple_debug_warning("dbus", "GetBuddyList: received an invalid contact\n");
+	}
+
+	g_free(contact_path);
+	g_free(alias);
+	g_free(parent_path);
+	g_ptr_array_foreach(settings, (GFunc)g_value_array_free, NULL);
+	g_ptr_array_free(settings, TRUE);
+	g_value_unset(&val);
+	g_value_array_free(box);
+}
+
+static void
+unpack_buddies_cb(GValueArray* box)
+{
+	GValue val = {0, };
+	PurpleBuddy *buddy;
+	PurpleRunningMode mode;
+	gboolean ok;
+	GObject *parent;
+	GObject *account;
+	char *buddy_path = NULL;
+	char *account_path = NULL;
+	char *name = NULL;
+	char *alias = NULL;
+	char *parent_path = NULL;
+	GPtrArray *settings = NULL;
+
+	/* Each buddy consists of a DBUS_PURPLE_BUDDY_PACK */
+	g_value_init(&val, DBUS_PURPLE_BUDDY_PACK);
+	g_value_set_boxed(&val, box);
+	ok = dbus_g_type_struct_get(&val,
+	                            0, &buddy_path,
+	                            1, &account_path,
+	                            2, &name,
+	                            3, &alias,
+	                            4, &parent_path,
+	                            5, &settings, G_MAXUINT);
+
+	if (ok && account_path[0])
+		account = purple_dbus_get_gobject_by_path(account_path);
+	if (ok && buddy_path[0] && PURPLE_IS_ACCOUNT(account)) {
+		/* Temporarly go in mirror mode, and create a local buddy. */
+		mode = purple_core_get_running_mode();
+		purple_core_set_running_mode(PURPLE_RUN_MIRROR_MODE);
+		parent = purple_dbus_get_gobject_by_path(parent_path);
+		buddy = purple_buddy_new(PURPLE_ACCOUNT(account), name, alias,
+		                         PURPLE_BLIST_NODE(parent));
+		purple_object_install_dbus_infos(PURPLE_OBJECT(buddy),
+		                         DBUS_BUDDY_INTERFACE, buddy_path);
+		purple_core_set_running_mode(mode);
+		set_blist_settings(PURPLE_BLIST_NODE(buddy), settings);
+	} else {
+		purple_debug_warning("dbus", "GetBuddyList: received an invalid buddy\n");
+	}
+
+	g_free(buddy_path);
+	g_free(account_path);
+	g_free(name);
+	g_free(alias);
+	g_free(parent_path);
+	g_ptr_array_foreach(settings, (GFunc)g_value_array_free, NULL);
+	g_ptr_array_free(settings, TRUE);
+	g_value_unset(&val);
+	g_value_array_free(box);
+}
+
+static void
+unpack_chats_cb(GValueArray* box)
+{
+	GValue val = {0, };
+	PurpleChat *chat;
+	PurpleRunningMode mode;
+	gboolean ok;
+	GObject *parent;
+	GObject *account;
+	char *chat_path = NULL;
+	char *account_path = NULL;
+	char *alias = NULL;
+	GHashTable *components = NULL;
+	char *parent_path = NULL;
+	GPtrArray *settings = NULL;
+
+	/* Each chat consists of a DBUS_PURPLE_CHAT_PACK */
+	g_value_init(&val, DBUS_PURPLE_CHAT_PACK);
+	g_value_set_boxed(&val, box);
+	ok = dbus_g_type_struct_get(&val,
+	                            0, &chat_path,
+	                            1, &account_path,
+	                            2, &alias,
+	                            3, &components,
+	                            4, &parent_path,
+	                            5, &settings, G_MAXUINT);
+
+	if (ok && account_path[0])
+		account = purple_dbus_get_gobject_by_path(account_path);
+	if (ok && chat_path[0] && PURPLE_IS_ACCOUNT(account) && components) {
+		/* Temporarly go in mirror mode, and create a local chat. */
+		mode = purple_core_get_running_mode();
+		purple_core_set_running_mode(PURPLE_RUN_MIRROR_MODE);
+		parent = purple_dbus_get_gobject_by_path(parent_path);
+		chat = purple_chat_new(PURPLE_ACCOUNT(account), alias,
+		                       components);
+		purple_object_install_dbus_infos(PURPLE_OBJECT(chat),
+		                         DBUS_CHAT_INTERFACE, chat_path);
+		if (parent)
+			purple_blist_node_add_child(PURPLE_BLIST_NODE(parent),
+			                            PURPLE_BLIST_NODE(chat));
+		purple_core_set_running_mode(mode);
+		set_blist_settings(PURPLE_BLIST_NODE(chat), settings);
+	} else {
+		purple_debug_warning("dbus", "GetChatList: received an invalid chat\n");
+	}
+
+	g_free(chat_path);
+	g_free(account_path);
+	g_free(alias);
+	g_hash_table_destroy(components);
+	g_free(parent_path);
+	g_ptr_array_foreach(settings, (GFunc)g_value_array_free, NULL);
+	g_ptr_array_free(settings, TRUE);
+	g_value_unset(&val);
+	g_value_array_free(box);
+}
+
+void
+purple_blist_load_RPC(void)
+{
+	PurpleBListDBus *blist = purple_blist_dbus_get_instance();
+	DBusGProxy *proxy = purple_object_get_dbus_obj_proxy(PURPLE_OBJECT(blist));
+	GError *error = NULL;
+	GPtrArray *groups;
+	GPtrArray *contacts;
+	GPtrArray *buddies;
+	GPtrArray *chats;
+
+	/* In remote mode the buddy list is already loaded by the daemon.
+	 * We need get it here.
+	 */
+	if(!im_pidgin_purple_blist_get_buddy_list(proxy, &groups, &contacts,
+	                                          &buddies, &chats, &error)) {
+		PURPLE_RPC_FAILED(purple_blist_load, error);
+		return;
+	}
+
+	g_ptr_array_foreach(groups,   (GFunc)unpack_groups_cb,   NULL);
+	g_ptr_array_foreach(contacts, (GFunc)unpack_contacts_cb, NULL);
+	g_ptr_array_foreach(buddies,  (GFunc)unpack_buddies_cb,  NULL);
+	g_ptr_array_foreach(chats,    (GFunc)unpack_chats_cb,    NULL);
+	g_ptr_array_free(groups,   TRUE);
+	g_ptr_array_free(contacts, TRUE);
+	g_ptr_array_free(buddies,  TRUE);
+	g_ptr_array_free(chats,    TRUE);
+}
============================================================
--- libpurple/dbus/blist.h	afaa5c56288ed2ee77903ce3b53b6e2658b2e411
+++ libpurple/dbus/blist.h	f45b9c6593b22783be373941cc61e2138bbd84f8
@@ -33,9 +33,15 @@ void purple_blist_uninit_dbus(void);
  */
 void purple_blist_uninit_dbus(void);
 
+/**
+ * Calls the GetBuddyList dbus method and loads the received buddy list.
+ */
+void purple_blist_load_RPC(void);
+
 #else /* !HAVE_DBUS */
 
 #define purple_blist_init_dbus()                                 ((void)0)
 #define purple_blist_uninit_dbus()                               ((void)0)
+#define purple_blist_get_buddy_list_RPC()                        ((void)0)
 
 #endif /* HAVE_DBUS */


More information about the Commits mailing list