/soc/2015/jgeboski/facebook: 291b6e1acc24: facebook: implemented...

James Geboski jgeboski at gmail.com
Thu Jun 11 01:33:57 EDT 2015


Changeset: 291b6e1acc24290c4f43d6d9b04ede4a3b2a99d4
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-06-11 01:33 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/291b6e1acc24

Description:

facebook: implemented group chat support

This is a fairly comprehensive implementation of the group chats which
are provided by the Messenger protocol. However, this does leave some
features out, such as removing users from a chat, as well as removing
oneself from a chat. This also does not support the inviting of users
which are not in the friend list of the user.

diffstat:

 libpurple/protocols/facebook/Makefile.am    |    2 +
 libpurple/protocols/facebook/Makefile.mingw |    1 +
 libpurple/protocols/facebook/api.c          |   15 +-
 libpurple/protocols/facebook/api.h          |    2 +-
 libpurple/protocols/facebook/data.c         |  245 ++++++++++++
 libpurple/protocols/facebook/data.h         |   81 ++++
 libpurple/protocols/facebook/facebook.c     |  545 ++++++++++++++++++++-------
 libpurple/protocols/facebook/id.h           |    5 +
 libpurple/protocols/facebook/util.c         |  132 ++++++
 libpurple/protocols/facebook/util.h         |   13 +
 10 files changed, 887 insertions(+), 154 deletions(-)

diffs (truncated from 1389 to 300 lines):

diff --git a/libpurple/protocols/facebook/Makefile.am b/libpurple/protocols/facebook/Makefile.am
--- a/libpurple/protocols/facebook/Makefile.am
+++ b/libpurple/protocols/facebook/Makefile.am
@@ -9,6 +9,8 @@ FACEBOOKSOURCES = \
 	marshal.h \
 	api.c \
 	api.h \
+	data.c \
+	data.h \
 	facebook.h \
 	facebook.c \
 	http.c \
diff --git a/libpurple/protocols/facebook/Makefile.mingw b/libpurple/protocols/facebook/Makefile.mingw
--- a/libpurple/protocols/facebook/Makefile.mingw
+++ b/libpurple/protocols/facebook/Makefile.mingw
@@ -43,6 +43,7 @@ LIB_PATHS +=		-L$(GTK_TOP)/lib \
 ##
 C_SRC =	\
 			api.c \
+			data.c \
 			facebook.c \
 			http.c \
 			json.c \
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
@@ -1180,7 +1180,7 @@ fb_api_thread_create(FbApi *api, GSList 
 	};
 
 	g_return_if_fail(FB_IS_API(api));
-	g_warn_if_fail((uids != NULL) && (uids->next != NULL));
+	g_warn_if_fail(g_slist_length(uids) > 1);
 	priv = api->priv;
 
 	bldr = fb_json_bldr_new(JSON_NODE_ARRAY);
@@ -1200,7 +1200,7 @@ fb_api_thread_create(FbApi *api, GSList 
 	json = fb_json_bldr_close(bldr, JSON_NODE_ARRAY, NULL);
 	prms = fb_http_params_new();
 	fb_http_params_set_str(prms, "to", json);
-	fb_api_http_req(api, &info, prms, FB_API_URL_FQL);
+	fb_api_http_req(api, &info, prms, FB_API_URL_THRDS);
 	g_free(json);
 }
 
@@ -1404,6 +1404,11 @@ fb_api_cb_thread_list(PurpleHttpConnecti
 		g_list_free(elms2);
 		elms2 = NULL;
 
+		if (g_slist_length(thrd.users) < 2) {
+			g_slist_free_full(thrd.users, g_free);
+			continue;
+		}
+
 		mptr = g_memdup(&thrd, sizeof thrd);
 		thrds = g_slist_prepend(thrds, mptr);
 	}
@@ -1419,7 +1424,7 @@ finish:
 }
 
 void
-fb_api_thread_list(FbApi *api, guint limit)
+fb_api_thread_list(FbApi *api)
 {
 	FbHttpParams *prms;
 	gchar *json;
@@ -1437,9 +1442,7 @@ fb_api_thread_list(FbApi *api, guint lim
 		"SELECT thread_fbid, participants, name "
 			"FROM unified_thread "
 			"WHERE folder='inbox' "
-			"ORDER BY timestamp DESC "
-			"LIMIT %u",
-		limit);
+			"ORDER BY timestamp DESC");
 	json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL);
 
 	prms = fb_http_params_new();
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
@@ -189,7 +189,7 @@ void
 fb_api_thread_invite(FbApi *api, FbId tid, FbId uid);
 
 void
-fb_api_thread_list(FbApi *api, guint limit);
+fb_api_thread_list(FbApi *api);
 
 void
 fb_api_thread_topic(FbApi *api, FbId tid, const gchar *topic);
diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/facebook/data.c
@@ -0,0 +1,245 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include <string.h>
+
+#include "api.h"
+#include "data.h"
+
+struct _FbDataPrivate
+{
+	FbApi *api;
+	PurpleConnection *gc;
+	PurpleRoomlist *roomlist;
+	gint chatid;
+};
+
+static const gchar *fb_props_strs[] = {
+	"cid",
+	"did",
+	"stoken",
+	"token"
+};
+
+G_DEFINE_TYPE(FbData, fb_data, G_TYPE_OBJECT);
+
+static void
+fb_data_dispose(GObject *obj)
+{
+	FbDataPrivate *priv = FB_DATA(obj)->priv;
+
+	if (G_LIKELY(priv->api != NULL)) {
+		g_object_unref(priv->api);
+	}
+
+	if (priv->roomlist != NULL) {
+		g_object_unref(priv->roomlist);
+	}
+}
+
+static void
+fb_data_class_init(FbDataClass *klass)
+{
+	GObjectClass *gklass = G_OBJECT_CLASS(klass);
+
+	gklass->dispose = fb_data_dispose;
+	g_type_class_add_private(klass, sizeof (FbDataPrivate));
+}
+
+static void
+fb_data_init(FbData *fata)
+{
+	FbDataPrivate *priv;
+
+	priv = G_TYPE_INSTANCE_GET_PRIVATE(fata, FB_TYPE_DATA, FbDataPrivate);
+	fata->priv = priv;
+}
+
+FbData *
+fb_data_new(PurpleConnection *gc)
+{
+	FbData *fata;
+	FbDataPrivate *priv;
+
+	fata = g_object_new(FB_TYPE_DATA, NULL);
+	priv = fata->priv;
+
+	priv->api = fb_api_new(gc);
+	priv->gc = gc;
+
+	return fata;
+}
+
+gboolean
+fb_data_load(FbData *fata)
+{
+	const gchar *str;
+	FbDataPrivate *priv;
+	FbId id;
+	gboolean ret = TRUE;
+	guint i;
+	guint64 uint;
+	GValue val = G_VALUE_INIT;
+	PurpleAccount *acct;
+
+	g_return_val_if_fail(FB_IS_DATA(fata), FALSE);
+	priv = fata->priv;
+	acct = purple_connection_get_account(priv->gc);
+
+	for (i = 0; i < G_N_ELEMENTS(fb_props_strs); i++) {
+		str = purple_account_get_string(acct, fb_props_strs[i], NULL);
+
+		if (str == NULL) {
+			ret = FALSE;
+		}
+
+		g_value_init(&val, G_TYPE_STRING);
+		g_value_set_string(&val, str);
+		g_object_set_property(G_OBJECT(priv->api), fb_props_strs[i],
+		                      &val);
+		g_value_unset(&val);
+	}
+
+	str = purple_account_get_string(acct, "mid", NULL);
+
+	if (str != NULL) {
+		uint = g_ascii_strtoull(str, NULL, 10);
+		g_value_init(&val, G_TYPE_UINT64);
+		g_value_set_uint64(&val, uint);
+		g_object_set_property(G_OBJECT(priv->api), "mid", &val);
+		g_value_unset(&val);
+	} else {
+		ret = FALSE;
+	}
+
+	str = purple_account_get_string(acct, "uid", NULL);
+
+	if (str != NULL) {
+		id = FB_ID_FROM_STR(str);
+		g_value_init(&val, FB_TYPE_ID);
+		g_value_set_int64(&val, id);
+		g_object_set_property(G_OBJECT(priv->api), "uid", &val);
+		g_value_unset(&val);
+	} else {
+		ret = FALSE;
+	}
+
+	fb_api_rehash(priv->api);
+	return ret;
+}
+
+void
+fb_data_save(FbData *fata)
+{
+	const gchar *str;
+	FbDataPrivate *priv;
+	gchar *dup;
+	guint i;
+	guint64 uint;
+	GValue val = G_VALUE_INIT;
+	PurpleAccount *acct;
+
+	g_return_if_fail(FB_IS_DATA(fata));
+	priv = fata->priv;
+	acct = purple_connection_get_account(priv->gc);
+
+	for (i = 0; i < G_N_ELEMENTS(fb_props_strs); i++) {
+		g_value_init(&val, G_TYPE_STRING);
+		g_object_get_property(G_OBJECT(priv->api), fb_props_strs[i],
+		                      &val);
+		str = g_value_get_string(&val);
+		purple_account_set_string(acct, fb_props_strs[i], str);
+		g_value_unset(&val);
+	}
+
+	g_value_init(&val, G_TYPE_UINT64);
+	g_object_get_property(G_OBJECT(priv->api), "mid", &val);
+	uint = g_value_get_uint64(&val);
+	g_value_unset(&val);
+
+	dup = g_strdup_printf("%" G_GINT64_FORMAT, uint);
+	purple_account_set_string(acct, "mid", dup);
+	g_free(dup);
+
+	g_value_init(&val, G_TYPE_INT64);
+	g_object_get_property(G_OBJECT(priv->api), "uid", &val);
+	uint = g_value_get_int64(&val);
+	g_value_unset(&val);
+
+	dup = g_strdup_printf("%" FB_ID_FORMAT, uint);
+	purple_account_set_string(acct, "uid", dup);
+	g_free(dup);
+}
+
+FbApi *
+fb_data_get_api(FbData *fata)
+{
+	FbDataPrivate *priv;
+
+	g_return_val_if_fail(FB_IS_DATA(fata), NULL);
+	priv = fata->priv;
+
+	return priv->api;
+}
+
+gint
+fb_data_get_chatid(FbData *fata)
+{
+	FbDataPrivate *priv;
+



More information about the Commits mailing list