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