/soc/2015/jgeboski/facebook: 168a859417f6: facebook: implemented...
James Geboski
jgeboski at gmail.com
Sun Jul 26 14:56:26 EDT 2015
Changeset: 168a859417f69f54f4338583586c6916669c622b
Author: James Geboski <jgeboski at gmail.com>
Date: 2015-07-26 14:56 -0400
Branch: facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/168a859417f6
Description:
facebook: implemented marking threads as read
diffstat:
libpurple/protocols/facebook/api.c | 77 ++++++++++++++++++++++++++++----
libpurple/protocols/facebook/api.h | 3 +
libpurple/protocols/facebook/facebook.c | 18 +++++++
3 files changed, 87 insertions(+), 11 deletions(-)
diffs (222 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
@@ -50,6 +50,7 @@ struct _FbApiPrivate
FbMqtt *mqtt;
FbId uid;
+ gint64 sid;
guint64 mid;
gchar *cid;
gchar *did;
@@ -551,7 +552,6 @@ fb_api_cb_seqid(PurpleHttpConnection *co
gchar *json;
gchar *str;
GError *err = NULL;
- gint64 nid;
JsonBuilder *bldr;
JsonNode *root;
@@ -565,7 +565,7 @@ fb_api_cb_seqid(PurpleHttpConnection *co
str = fb_json_node_get_str(root, expr, &err);
json_node_free(root);
FB_API_ERROR_CHK(api, err, return);
- nid = g_ascii_strtoll(str, NULL, 10);
+ priv->sid = g_ascii_strtoll(str, NULL, 10);
g_free(str);
bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
@@ -575,7 +575,8 @@ fb_api_cb_seqid(PurpleHttpConnection *co
fb_json_bldr_add_str(bldr, "encoding", "JSON");
if (priv->stoken == NULL) {
- fb_json_bldr_add_int(bldr, "initial_titan_sequence_id", nid);
+ fb_json_bldr_add_int(bldr, "initial_titan_sequence_id",
+ priv->sid);
fb_json_bldr_add_str(bldr, "device_id", priv->did);
fb_json_bldr_obj_begin(bldr, "device_params");
fb_json_bldr_obj_end(bldr);
@@ -587,7 +588,7 @@ fb_api_cb_seqid(PurpleHttpConnection *co
return;
}
- fb_json_bldr_add_int(bldr, "last_seq_id", nid);
+ fb_json_bldr_add_int(bldr, "last_seq_id", priv->sid);
fb_json_bldr_add_str(bldr, "sync_token", priv->stoken);
json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL);
@@ -643,7 +644,25 @@ fb_api_cb_mqtt_connect(FbMqtt *mqtt, gpo
}
static void
-fb_api_cb_publish_tn(FbApi *api, const GByteArray *pload)
+fb_api_cb_publish_mark(FbApi *api, const GByteArray *pload)
+{
+ gboolean res;
+ JsonNode *root;
+
+ if (!fb_api_json_chk(api, pload->data, pload->len, &root)) {
+ return;
+ }
+
+ if (fb_json_node_chk_bool(root, "$.succeeded", &res) && !res) {
+ fb_api_error(api, FB_API_ERROR_GENERAL,
+ _("Failed to mark thread as read"));
+ }
+
+ json_node_free(root);
+}
+
+static void
+fb_api_cb_publish_typing(FbApi *api, const GByteArray *pload)
{
FbApiTyping typg;
gboolean res;
@@ -712,6 +731,8 @@ fb_api_cb_publish_ms(FbApi *api, const G
goto finish;
}
+ fb_json_node_chk_int(root, "$.lastIssuedSeqId", &priv->sid);
+
arr = fb_json_node_get_arr(root, "$.deltas", &err);
FB_API_ERROR_CHK(api, err, goto finish);
elms = json_array_get_elements(arr);
@@ -863,6 +884,17 @@ fb_api_cb_mqtt_publish(FbMqtt *mqtt, con
FbApi *api = data;
gboolean comp;
GByteArray *bytes;
+ guint i;
+
+ static const struct {
+ const gchar *topic;
+ void (*func) (FbApi *api, const GByteArray *pload);
+ } parsers[] = {
+ {"/mark_thread_response", fb_api_cb_publish_mark},
+ {"/orca_typing_notifications", fb_api_cb_publish_typing},
+ {"/t_ms", fb_api_cb_publish_ms},
+ {"/t_p", fb_api_cb_publish_p}
+ };
comp = fb_util_zcompressed(pload);
@@ -882,12 +914,11 @@ fb_api_cb_mqtt_publish(FbMqtt *mqtt, con
"Reading message (topic: %s)",
topic);
- if (g_ascii_strcasecmp(topic, "/orca_typing_notifications") == 0) {
- fb_api_cb_publish_tn(api, bytes);
- } else if (g_ascii_strcasecmp(topic, "/t_ms") == 0) {
- fb_api_cb_publish_ms(api, bytes);
- } else if (g_ascii_strcasecmp(topic, "/t_p") == 0) {
- fb_api_cb_publish_p(api, bytes);
+ for (i = 0; i < G_N_ELEMENTS(parsers); i++) {
+ if (g_ascii_strcasecmp(topic, parsers[i].topic) == 0) {
+ parsers[i].func(api, bytes);
+ break;
+ }
}
if (G_LIKELY(comp)) {
@@ -1242,6 +1273,30 @@ fb_api_publish(FbApi *api, const gchar *
g_byte_array_free(bytes, TRUE);
}
+void
+fb_api_read(FbApi *api, FbId id, gboolean thread)
+{
+ const gchar *key;
+ FbApiPrivate *priv;
+ gchar *json;
+ JsonBuilder *bldr;
+
+ g_return_if_fail(FB_IS_API(api));
+ priv = api->priv;
+
+ bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
+ fb_json_bldr_add_bool(bldr, "state", TRUE);
+ fb_json_bldr_add_int(bldr, "syncSeqId", priv->sid);
+ fb_json_bldr_add_str(bldr, "mark", "read");
+
+ key = thread ? "threadFbId" : "otherUserFbId";
+ fb_json_bldr_add_strf(bldr, key, "%" FB_ID_FORMAT, id);
+
+ json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL);
+ fb_api_publish(api, "/mark_thread", "%s", json);
+ g_free(json);
+}
+
static void
fb_api_cb_thread_create(PurpleHttpConnection *con, PurpleHttpResponse *res,
gpointer data)
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
@@ -183,6 +183,9 @@ fb_api_publish(FbApi *api, const gchar *
G_GNUC_PRINTF(3, 4);
void
+fb_api_read(FbApi *api, FbId id, gboolean thread);
+
+void
fb_api_thread_create(FbApi *api, GSList *uids);
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
@@ -194,6 +194,7 @@ fb_cb_api_message(FbApi *api, GSList *ms
{
FbApiMessage *msg;
FbData *fata = data;
+ gboolean mark;
gchar *html;
gchar tid[FB_ID_STRMAX];
gchar uid[FB_ID_STRMAX];
@@ -205,6 +206,7 @@ fb_cb_api_message(FbApi *api, GSList *ms
gc = fb_data_get_connection(fata);
acct = purple_connection_get_account(gc);
+ mark = purple_account_get_bool(acct, "mark-read", TRUE);
for (l = msgs; l != NULL; l = l->next) {
msg = l->data;
@@ -214,6 +216,10 @@ fb_cb_api_message(FbApi *api, GSList *ms
FB_ID_TO_STR(msg->uid, uid);
if (msg->tid == 0) {
+ if (mark) {
+ fb_api_read(api, msg->uid, TRUE);
+ }
+
purple_serv_got_im(gc, uid, html,
PURPLE_MESSAGE_RECV,
time(NULL));
@@ -225,6 +231,10 @@ fb_cb_api_message(FbApi *api, GSList *ms
chat = purple_conversations_find_chat_with_account(tid, acct);
if (chat != NULL) {
+ if (mark) {
+ fb_api_read(api, msg->tid, TRUE);
+ }
+
id = purple_chat_conversation_get_id(chat);
purple_serv_got_chat_in(gc, id, uid,
PURPLE_MESSAGE_RECV,
@@ -901,9 +911,17 @@ fb_cmd_leave(PurpleConversation *conv, c
static void
facebook_protocol_init(PurpleProtocol *protocol)
{
+ GList *opts = NULL;
+ PurpleAccountOption *opt;
+
protocol->id = "prpl-facebook";
protocol->name = "Facebook";
protocol->options = OPT_PROTO_CHAT_TOPIC;
+
+ opt = purple_account_option_bool_new(_("Mark messages as read"),
+ "mark-read", TRUE);
+ opts = g_list_prepend(opts, opt);
+ protocol->account_options = g_list_reverse(opts);
}
static void
More information about the Commits
mailing list