/soc/2015/jgeboski/facebook: 53cb588d8760: facebook: implemented...

James Geboski jgeboski at gmail.com
Sun Jul 5 14:44:24 EDT 2015


Changeset: 53cb588d876050e10ed633096f10c5e0234f5ec8
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-07-05 14:44 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/53cb588d8760

Description:

facebook: implemented kicking/leaving group chats

diffstat:

 libpurple/protocols/facebook/api.c      |   48 +++++++++++-
 libpurple/protocols/facebook/api.h      |    3 +
 libpurple/protocols/facebook/facebook.c |  127 ++++++++++++++++++++++++++++++-
 libpurple/protocols/facebook/json.c     |   24 ++++-
 libpurple/protocols/facebook/util.c     |   62 +++++++++++++++
 libpurple/protocols/facebook/util.h     |   16 ++++
 6 files changed, 266 insertions(+), 14 deletions(-)

diffs (truncated from 431 to 300 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -1219,6 +1219,7 @@ fb_api_cb_threads(PurpleHttpConnection *
 	FbApiPrivate *priv = api->priv;
 	FbApiThread thrd;
 	FbApiUser user;
+	gboolean haself;
 	gchar *str;
 	GError *err = NULL;
 	GList *elms = NULL;
@@ -1258,7 +1259,7 @@ fb_api_cb_threads(PurpleHttpConnection *
 		FB_API_ERROR_CHK(api, err, goto finish);
 		elms2 = json_array_get_elements(arr2);
 
-		for (m = elms2; m != NULL; m = m->next) {
+		for (haself = FALSE, m = elms2; m != NULL; m = m->next) {
 			node2 = m->data;
 			fb_api_user_reset(&user, FALSE);
 
@@ -1268,6 +1269,7 @@ fb_api_cb_threads(PurpleHttpConnection *
 			g_free(str);
 
 			if (user.uid == priv->uid) {
+				haself = TRUE;
 				continue;
 			}
 
@@ -1289,8 +1291,12 @@ fb_api_cb_threads(PurpleHttpConnection *
 			continue;
 		}
 
-		mptr = fb_api_thread_dup(&thrd, FALSE);
-		thrds = g_slist_prepend(thrds, mptr);
+		if (haself) {
+			mptr = fb_api_thread_dup(&thrd, FALSE);
+			thrds = g_slist_prepend(thrds, mptr);
+		} else {
+			fb_api_thread_reset(&thrd, TRUE);
+		}
 	}
 
 	ret = g_slist_reverse(thrds);
@@ -1428,6 +1434,42 @@ fb_api_thread_list(FbApi *api)
 }
 
 void
+fb_api_thread_remove(FbApi *api, FbId tid, FbId uid)
+{
+	FbApiPrivate *priv;
+	FbHttpParams *prms;
+	gchar *json;
+	JsonBuilder *bldr;
+
+	static const FbApiHttpInfo info = {
+		fb_api_cb_http_bool,
+		"com.facebook.orca.protocol.a",
+		"removeMembers",
+		"DELETE"
+	};
+
+	g_return_if_fail(api != NULL);
+	priv = api->priv;
+
+	prms = fb_http_params_new();
+	fb_http_params_set_strf(prms, "id", "t_id.%" FB_ID_FORMAT, tid);
+
+	if (uid == 0) {
+		uid = priv->uid;
+	}
+
+	if (uid != priv->uid) {
+		bldr = fb_json_bldr_new(JSON_NODE_ARRAY);
+		fb_json_bldr_add_strf(bldr, NULL, "%" FB_ID_FORMAT, uid);
+		json = fb_json_bldr_close(bldr, JSON_NODE_ARRAY, NULL);
+		fb_http_params_set_str(prms, "to", json);
+		g_free(json);
+	}
+
+	fb_api_http_req(api, &info, prms, FB_API_URL_PARTS);
+}
+
+void
 fb_api_thread_topic(FbApi *api, FbId tid, const gchar *topic)
 {
 	FbHttpParams *prms;
diff --git a/libpurple/protocols/facebook/api.h b/libpurple/protocols/facebook/api.h
--- a/libpurple/protocols/facebook/api.h
+++ b/libpurple/protocols/facebook/api.h
@@ -191,6 +191,9 @@ void
 fb_api_thread_list(FbApi *api);
 
 void
+fb_api_thread_remove(FbApi *api, FbId tid, FbId uid);
+
+void
 fb_api_thread_topic(FbApi *api, FbId tid, const gchar *topic);
 
 void
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -30,11 +30,13 @@
 #include "version.h"
 
 #include "api.h"
+#include "cmds.h"
 #include "data.h"
 #include "facebook.h"
 #include "util.h"
 
-static PurpleProtocol *my_protocol = NULL;
+static GSList *fb_cmds = NULL;
+static PurpleProtocol *fb_protocol = NULL;
 
 static void
 fb_cb_api_error(FbApi *api, GError *error, gpointer data);
@@ -739,6 +741,79 @@ fb_roomlist_cancel(PurpleRoomlist *list)
 	g_object_unref(list);
 }
 
+static PurpleCmdRet
+fb_cmd_kick(PurpleConversation *conv, const gchar *cmd, gchar **args,
+            gchar **error, gpointer data)
+{
+	const gchar *name;
+	FbApi *api;
+	FbData *fata;
+	FbId tid;
+	FbId uid;
+	GError *err = NULL;
+	PurpleAccount *acct;
+	PurpleBuddy *bdy;
+	PurpleConnection *gc;
+	PurpleChatConversation *chat;
+
+	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(conv),
+	                     PURPLE_CMD_RET_FAILED);
+
+	gc = purple_conversation_get_connection(conv);
+	acct = purple_connection_get_account(gc);
+	chat = PURPLE_CHAT_CONVERSATION(conv);
+	bdy = fb_util_account_find_buddy(acct, chat, args[0], &err);
+
+	if (err != NULL) {
+		*error = g_strdup_printf(_("%s."), err->message);
+		g_error_free(err);
+		return PURPLE_CMD_RET_FAILED;
+	}
+
+	fata = purple_connection_get_protocol_data(gc);
+	api = fb_data_get_api(fata);
+
+	name = purple_conversation_get_name(conv);
+	tid = FB_ID_FROM_STR(name);
+
+	name = purple_buddy_get_name(bdy);
+	uid = FB_ID_FROM_STR(name);
+
+	purple_chat_conversation_remove_user(chat, name, NULL);
+	fb_api_thread_remove(api, tid, uid);
+	return PURPLE_CMD_RET_OK;
+}
+
+static PurpleCmdRet
+fb_cmd_leave(PurpleConversation *conv, const gchar *cmd, gchar **args,
+             gchar **error, gpointer data)
+{
+	const gchar *name;
+	FbApi *api;
+	FbData *fata;
+	FbId tid;
+	gint id;
+	PurpleConnection *gc;
+	PurpleChatConversation *chat;
+
+	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(conv),
+	                     PURPLE_CMD_RET_FAILED);
+
+	gc = purple_conversation_get_connection(conv);
+	fata = purple_connection_get_protocol_data(gc);
+	api = fb_data_get_api(fata);
+
+	chat = PURPLE_CHAT_CONVERSATION(conv);
+	id = purple_chat_conversation_get_id(chat);
+
+	name = purple_conversation_get_name(conv);
+	tid = FB_ID_FROM_STR(name);
+
+	purple_serv_got_chat_left(gc, id);
+	fb_api_thread_remove(api, tid, 0);
+	return PURPLE_CMD_RET_OK;
+}
+
 static void
 facebook_protocol_init(PurpleProtocol *protocol)
 {
@@ -814,6 +889,43 @@ PURPLE_DEFINE_TYPE_EXTENDED(
 	                                  facebook_protocol_roomlist_iface_init)
 );
 
+static void
+fb_cmds_register(void)
+{
+	PurpleCmdId id;
+
+	static PurpleCmdFlag cflags =
+		PURPLE_CMD_FLAG_CHAT |
+		PURPLE_CMD_FLAG_PROTOCOL_ONLY;
+
+	g_return_if_fail(fb_cmds == NULL);
+
+	id = purple_cmd_register("kick", "s", PURPLE_CMD_P_PROTOCOL, cflags,
+				 fb_protocol->id, fb_cmd_kick,
+				 _("kick: Kick someone from the chat"),
+				 NULL);
+	fb_cmds = g_slist_prepend(fb_cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("leave", "", PURPLE_CMD_P_PROTOCOL, cflags,
+				 fb_protocol->id, fb_cmd_leave,
+				 _("leave: Leave the chat"),
+				 NULL);
+	fb_cmds = g_slist_prepend(fb_cmds, GUINT_TO_POINTER(id));
+}
+
+static void
+fb_cmds_unregister_free(gpointer data)
+{
+	PurpleCmdId id = GPOINTER_TO_UINT(data);
+	purple_cmd_unregister(id);
+}
+
+static void
+fb_cmds_unregister(void)
+{
+	g_slist_free_full(fb_cmds, fb_cmds_unregister_free);
+}
+
 static PurplePluginInfo *
 plugin_query(GError **error)
 {
@@ -836,14 +948,21 @@ static gboolean
 plugin_load(PurplePlugin *plugin, GError **error)
 {
 	facebook_protocol_register_type(plugin);
-	my_protocol = purple_protocols_add(FACEBOOK_TYPE_PROTOCOL, error);
-	return my_protocol != NULL;
+	fb_protocol = purple_protocols_add(FACEBOOK_TYPE_PROTOCOL, error);
+
+	if (fb_protocol == NULL) {
+		return FALSE;
+	}
+
+	fb_cmds_register();
+	return TRUE;
 }
 
 static gboolean
 plugin_unload(PurplePlugin *plugin, GError **error)
 {
-	return purple_protocols_remove(my_protocol, error);
+	fb_cmds_unregister();
+	return purple_protocols_remove(fb_protocol, error);
 }
 
 PURPLE_PLUGIN_INIT(facebook, plugin_query, plugin_load, plugin_unload);
diff --git a/libpurple/protocols/facebook/json.c b/libpurple/protocols/facebook/json.c
--- a/libpurple/protocols/facebook/json.c
+++ b/libpurple/protocols/facebook/json.c
@@ -128,28 +128,40 @@ fb_json_bldr_obj_end(JsonBuilder *bldr)
 void
 fb_json_bldr_add_bool(JsonBuilder *bldr, const gchar *name, gboolean value)
 {
-	json_builder_set_member_name(bldr, name);
+	if (name != NULL) {
+		json_builder_set_member_name(bldr, name);
+	}
+
 	json_builder_add_boolean_value(bldr, value);
 }
 
 void
 fb_json_bldr_add_dbl(JsonBuilder *bldr, const gchar *name, gdouble value)
 {
-	json_builder_set_member_name(bldr, name);
+	if (name != NULL) {
+		json_builder_set_member_name(bldr, name);
+	}
+
 	json_builder_add_double_value(bldr, value);
 }
 
 void
 fb_json_bldr_add_int(JsonBuilder *bldr, const gchar *name, gint64 value)
 {
-	json_builder_set_member_name(bldr, name);
+	if (name != NULL) {
+		json_builder_set_member_name(bldr, name);
+	}
+



More information about the Commits mailing list