/soc/2015/jgeboski/facebook: 291b6e1acc24: facebook: implemented...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 291b6e1acc24290c4f43d6d9b04ede4a3b2a99d4 Author: James Geboski <[email protected]> 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; +