diff options
author | jgeboski <jgeboski@gmail.com> | 2015-01-15 22:11:16 -0500 |
---|---|---|
committer | jgeboski <jgeboski@gmail.com> | 2015-01-15 22:59:28 -0500 |
commit | 8d8c6cce403106f418505cb0691a864d61313bb2 (patch) | |
tree | 9294b505c7f0aef9f4941b7ca7d868bd2e6dee07 | |
parent | a2cdeab81cb287063f8ed4be01263c284d4d94d6 (diff) | |
download | bitlbee-facebook-8d8c6cce403106f418505cb0691a864d61313bb2.tar.gz bitlbee-facebook-8d8c6cce403106f418505cb0691a864d61313bb2.tar.bz2 bitlbee-facebook-8d8c6cce403106f418505cb0691a864d61313bb2.tar.xz |
Migrated to numeric facebook user identifiers
-rw-r--r-- | facebook/facebook-api.c | 237 | ||||
-rw-r--r-- | facebook/facebook-api.h | 49 | ||||
-rw-r--r-- | facebook/facebook-id.h | 57 | ||||
-rw-r--r-- | facebook/facebook.c | 39 |
4 files changed, 151 insertions, 231 deletions
diff --git a/facebook/facebook-api.c b/facebook/facebook-api.c index 39db434..92dcc96 100644 --- a/facebook/facebook-api.c +++ b/facebook/facebook-api.c @@ -199,7 +199,7 @@ static void fb_api_cb_mqtt_open(fb_mqtt_t *mqtt, gpointer data) FB_MQTT_CONNECT_FLAG_CLR; msg = g_strdup_printf("{" - "\"u\":\"%s\"," + "\"u\":\"%" FB_ID_FORMAT "\"," "\"a\":\"" FB_API_AGENT "\"," "\"mqtt_sid\":%s," "\"d\":\"%s\"," @@ -351,7 +351,7 @@ static void fb_api_cb_mqtt_connack(fb_mqtt_t *mqtt, gpointer data) static void fb_api_cb_publish_tn(fb_api_t *api, const GByteArray *pload) { json_value *json; - fb_api_typing_t *typg; + fb_api_typing_t typg; const gchar *str; gint64 uid; gint64 state; @@ -374,10 +374,9 @@ static void fb_api_cb_publish_tn(fb_api_t *api, const GByteArray *pload) goto finish; } - typg = fb_api_typing_new(NULL, state != 0); - typg->uid = g_strdup_printf("%" G_GINT64_FORMAT, uid); - FB_API_FUNC(api, typing, typg); - fb_api_typing_free(typg); + typg.uid = uid; + typg.state = state; + FB_API_FUNC(api, typing, &typg); finish: json_value_free(json); @@ -426,7 +425,7 @@ finish: static void fb_api_cb_publish_ms(fb_api_t *api, const GByteArray *pload) { GSList *msgs; - fb_api_msg_t *msg; + fb_api_msg_t msg; json_value *json; json_value *jv; json_value *jx; @@ -434,12 +433,10 @@ static void fb_api_cb_publish_ms(fb_api_t *api, const GByteArray *pload) json_value *jz; const gchar *str; gint64 in; - gint64 auid; guint i; /* Start at 1 to skip the NULL byte */ json = fb_api_json_new(api, (gchar*) pload->data + 1, pload->len - 1); - auid = g_ascii_strtoll(api->uid, NULL, 10); msgs = NULL; if (json == NULL) @@ -461,23 +458,23 @@ static void fb_api_cb_publish_ms(fb_api_t *api, const GByteArray *pload) if (!fb_json_val_chk(jx, "deltaNewMessage", json_object, &jy) || !fb_json_val_chk(jy, "messageMetadata", json_object, &jz) || !fb_json_int_chk(jz, "actorFbId", &in) || - (in == auid)) + (in == api->uid)) { continue; } + msg.uid = in; + if (fb_json_str_chk(jy, "body", &str)) { - msg = fb_api_msg_new(NULL, str); - msg->uid = g_strdup_printf("%" G_GINT64_FORMAT, in); - msgs = g_slist_prepend(msgs, msg); + msg.text = str; + msgs = g_slist_prepend(msgs, g_memdup(&msg, sizeof msg)); } if (fb_json_val_chk(jy, "attachments", json_array, &jy) && (jy->u.array.length > 0)) { - msg = fb_api_msg_new(NULL, "* Non-Displayable Attachments *"); - msg->uid = g_strdup_printf("%" G_GINT64_FORMAT, in); - msgs = g_slist_prepend(msgs, msg); + msg.text = "* Non-Displayable Attachments *"; + msgs = g_slist_prepend(msgs, g_memdup(&msg, sizeof msg)); } } @@ -485,7 +482,7 @@ static void fb_api_cb_publish_ms(fb_api_t *api, const GByteArray *pload) FB_API_FUNC(api, message, msgs); finish: - g_slist_free_full(msgs, (GDestroyNotify) fb_api_msg_free); + g_slist_free_full(msgs, g_free); json_value_free(json); } @@ -499,7 +496,7 @@ static void fb_api_cb_publish_p(fb_api_t *api, const GByteArray *pload) { fb_thrift_t *thft; fb_thrift_type_t type; - fb_api_pres_t *pres; + fb_api_pres_t pres; GSList *press; gint64 i64; gint32 i32; @@ -534,11 +531,10 @@ static void fb_api_cb_publish_p(fb_api_t *api, const GByteArray *pload) g_warn_if_fail(type == FB_THRIFT_TYPE_I32); fb_thrift_read_i32(thft, &i32); - pres = fb_api_pres_new(NULL, i32 != 0); - pres->uid = g_strdup_printf("%" G_GINT64_FORMAT, i64); - press = g_slist_prepend(press, pres); - - FB_UTIL_DEBUGLN("Presence: %s (%d)", pres->uid, pres->active); + pres.uid = i64; + pres.active = i32 != 0; + press = g_slist_prepend(press, g_memdup(&pres, sizeof pres)); + FB_UTIL_DEBUGLN("Presence: %" FB_ID_FORMAT " (%d)", i64, i32 != 0); /* Skip the last active timestamp field */ if (!fb_thrift_read_field(thft, &type, NULL)) @@ -571,7 +567,7 @@ static void fb_api_cb_publish_p(fb_api_t *api, const GByteArray *pload) press = g_slist_reverse(press); FB_API_FUNC(api, presence, press); - g_slist_free_full(press, (GDestroyNotify) fb_api_pres_free); + g_slist_free_full(press, g_free); } /** @@ -706,7 +702,6 @@ void fb_api_free(fb_api_t *api) g_free(api->cid); g_free(api->stoken); g_free(api->token); - g_free(api->uid); g_free(api); } @@ -766,11 +761,10 @@ static void fb_api_cb_auth(fb_http_req_t *req, gpointer data) goto finish; } - g_free(api->uid); - api->uid = g_strdup_printf("%" G_GINT64_FORMAT, in); - g_free(api->token); api->token = g_strdup(str); + + api->uid = in; FB_API_FUNC(api, auth); finish: @@ -815,7 +809,7 @@ static void fb_api_cb_contacts(fb_http_req_t *req, gpointer data) { fb_api_t *api = data; GSList *users; - fb_api_user_t *user; + fb_api_user_t user; json_value *json; json_value *jv; json_value *jx; @@ -844,34 +838,39 @@ static void fb_api_cb_contacts(fb_http_req_t *req, gpointer data) jx = jv->u.array.values[i]; /* Scattered values lead to a gnarly conditional... */ - if (fb_json_val_chk(jx, "represented_profile", json_object, &jy) && + if (!fb_json_val_chk(jx, "represented_profile", json_object, &jy) || /* Check the contact type is "user" */ - fb_json_val_chk(jy, "__type__", json_object, &jz) && - fb_json_str_chk(jz, "name", &str) && - (g_ascii_strcasecmp(str, "user") == 0) && + !fb_json_val_chk(jy, "__type__", json_object, &jz) || + !fb_json_str_chk(jz, "name", &str) || + (g_ascii_strcasecmp(str, "user") != 0) || /* Check the contact is a friend */ - fb_json_str_chk(jy, "friendship_status", &str) && - (g_ascii_strcasecmp(str, "ARE_FRIENDS") == 0) && + !fb_json_str_chk(jy, "friendship_status", &str) || + (g_ascii_strcasecmp(str, "ARE_FRIENDS") != 0) || /* Obtain the contact user identifier */ - fb_json_str_chk(jy, "id", &uid) && - (g_strcmp0(uid, api->uid) != 0) && + !fb_json_str_chk(jy, "id", &uid) || /* Obtain the name of the user */ - fb_json_val_chk(jx, "structured_name", json_object, &jy) && - fb_json_str_chk(jy, "text", &name)) + !fb_json_val_chk(jx, "structured_name", json_object, &jy) || + !fb_json_str_chk(jy, "text", &name)) { - user = fb_api_user_new(uid, name); - users = g_slist_prepend(users, user); + continue; + } + + user.uid = FB_ID_FROM_STR(uid); + + if (user.uid != api->uid) { + user.name = name; + users = g_slist_prepend(users, g_memdup(&user, sizeof user)); } } FB_API_FUNC(api, contacts, users); finish: - g_slist_free_full(users, (GDestroyNotify) fb_api_user_free); + g_slist_free_full(users, g_free); json_value_free(json); } @@ -932,24 +931,23 @@ void fb_api_disconnect(fb_api_t *api) * Sends a message to a user. * * @param api The #fb_api. - * @param uid The target user identifier. + * @param uid The #fb_id of the user. * @param msg The message. **/ -void fb_api_message(fb_api_t *api, const gchar *uid, const gchar *msg) +void fb_api_message(fb_api_t *api, fb_id_t uid, const gchar *msg) { guint64 msgid; gchar *rmsg; g_return_if_fail(api != NULL); - g_return_if_fail(uid != NULL); g_return_if_fail(msg != NULL); msgid = FB_API_MSGID(g_get_real_time() / 1000, g_random_int()); rmsg = g_strdup_printf("{" "\"body\":\"%s\"," - "\"to\":\"%s\"," - "\"sender_fbid\":\"%s\"," + "\"to\":\"%" FB_ID_FORMAT "\"," + "\"sender_fbid\":\"%" FB_ID_FORMAT "\"," "\"msgid\":%" G_GUINT64_FORMAT "}", msg, uid, api->uid, msgid); @@ -997,154 +995,15 @@ void fb_api_publish(fb_api_t *api, const gchar *topic, const gchar *fmt, ...) * Sends a typing state to a user. * * @param api The #fb_api. - * @param uid The target user identifier. + * @param uid The #fb_id. * @param state TRUE if the user is typing, otherwise FALSE. **/ -void fb_api_typing(fb_api_t *api, const gchar *uid, gboolean state) +void fb_api_typing(fb_api_t *api, fb_id_t uid, gboolean state) { g_return_if_fail(api != NULL); - g_return_if_fail(uid != NULL); fb_api_publish(api, "/typing", "{" - "\"to\":\"%s\"," + "\"to\":\"%" FB_ID_FORMAT "\"," "\"state\":%d" "}", uid, state != 0); } - -/** - * Creates a new #fb_api_msg. The returned #fb_api_msg should be freed - * with #fb_api_msg_free() when no longer needed. - * - * @param uid The user identifier. - * @param text The message text. - * - * @return The #fb_api_msg or NULL on error. - **/ -fb_api_msg_t *fb_api_msg_new(const gchar *uid, const gchar *text) -{ - fb_api_msg_t *msg; - - msg = g_new0(fb_api_msg_t, 1); - msg->uid = g_strdup(uid); - msg->text = g_strdup(text); - - return msg; -} - -/** - * Frees all memory used by a #fb_api_msg. - * - * @param msg The #fb_api_msg. - **/ -void fb_api_msg_free(fb_api_msg_t *msg) -{ - if (G_UNLIKELY(msg == NULL)) - return; - - g_free(msg->text); - g_free(msg->uid); - g_free(msg); -} - -/** - * Creates a new #fb_api_pres. The returned #fb_api_pres should be - * freed with #fb_api_pres_free() when no longer needed. - * - * @param uid The user identifier. - * @param active TRUE if the user is active, otherwise FALSE. - * - * @return The #fb_api_pres or NULL on error. - **/ -fb_api_pres_t *fb_api_pres_new(const gchar *uid, gboolean active) -{ - fb_api_pres_t *pres; - - pres = g_new0(fb_api_pres_t, 1); - pres->uid = g_strdup(uid); - pres->active = active; - - return pres; -} - -/** - * Frees all memory used by a #fb_api_pres. - * - * @param pres The #fb_api_pres. - **/ -void fb_api_pres_free(fb_api_pres_t *pres) -{ - if (G_UNLIKELY(pres == NULL)) - return; - - g_free(pres->uid); - g_free(pres); -} - -/** - * Creates a new #fb_api_typing. The returned #fb_api_typing should be - * freed with #fb_api_typing_free() when no longer needed. - * - * @param uid The user identifier. - * @param state TRUE if the user is typing, otherwise FALSE. - * - * @return The #fb_api_typing or NULL on error. - **/ -fb_api_typing_t *fb_api_typing_new(const gchar *uid, gboolean state) -{ - fb_api_typing_t *typg; - - typg = g_new0(fb_api_typing_t, 1); - typg->uid = g_strdup(uid); - typg->state = state; - - return typg; -} - -/** - * Frees all memory used by a #fb_api_typing. - * - * @param typg The #fb_api_typing. - **/ -void fb_api_typing_free(fb_api_typing_t *typg) -{ - if (G_UNLIKELY(typg == NULL)) - return; - - g_free(typg->uid); - g_free(typg); -} - -/** - * Creates a new #fb_api_user. The returned #fb_api_user should be - * freed with #fb_api_user_free() when no longer needed. - * - * @param uid The user identifier. - * @param name The name of the user. - * - * @return The #fb_api_user or NULL on error. - **/ -fb_api_user_t *fb_api_user_new(const gchar *uid, const gchar *name) -{ - fb_api_user_t *user; - - user = g_new0(fb_api_user_t, 1); - user->uid = g_strdup(uid); - user->name = g_strdup(name); - - return user; -} - -/** - * Frees all memory used by a #fb_api_user. - * - * @param user The #fb_api_user. - **/ -void fb_api_user_free(fb_api_user_t *user) -{ - if (G_UNLIKELY(user == NULL)) - return; - - g_free(user->name); - g_free(user->uid); - g_free(user); -} diff --git a/facebook/facebook-api.h b/facebook/facebook-api.h index 2caace2..d6433c2 100644 --- a/facebook/facebook-api.h +++ b/facebook/facebook-api.h @@ -23,6 +23,7 @@ #include <bitlbee.h> #include "facebook-http.h" +#include "facebook-id.h" #include "facebook-json.h" #include "facebook-mqtt.h" @@ -187,12 +188,12 @@ struct fb_api GError *err; /** The #GError or NULL. **/ GQueue *msgs; /** The #GQueue of raw messages. **/ - gchar *uid; /** The user identifier. **/ - gchar *token; /** The session token. **/ - gchar *stoken; /** The sync token. **/ - gchar *cid; /** The client identifier. **/ - gchar *mid; /** The MQTT identifier. **/ - gchar *cuid; /** The client unique identifier. **/ + fb_id_t uid; /** The The #fb_id of the user. **/ + gchar *token; /** The session token. **/ + gchar *stoken; /** The sync token. **/ + gchar *cid; /** The client identifier. **/ + gchar *mid; /** The MQTT identifier. **/ + gchar *cuid; /** The client unique identifier. **/ }; /** @@ -200,8 +201,8 @@ struct fb_api **/ struct fb_api_msg { - gchar *uid; /** The user identifier. **/ - gchar *text; /** The message text. **/ + fb_id_t uid; /** The #fb_id of the user. **/ + const gchar *text; /** The message text. **/ }; /** @@ -209,8 +210,8 @@ struct fb_api_msg **/ struct fb_api_pres { - gchar *uid; /** The user identifier. **/ - gboolean active; /** TRUE if the user is active. **/ + fb_id_t uid; /** The #fb_id of the user. **/ + gboolean active; /** TRUE if the user is active. **/ }; /** @@ -218,8 +219,8 @@ struct fb_api_pres **/ struct fb_api_typing { - gchar *uid; /** The user identifier. **/ - gboolean state; /** TRUE if the user is typing. **/ + fb_id_t uid; /** The #fb_id of the user. **/ + gboolean state; /** TRUE if the user is typing. **/ }; /** @@ -227,8 +228,8 @@ struct fb_api_typing **/ struct fb_api_user { - gchar *uid; /** The user identifier. **/ - gchar *name; /** The name of the user. **/ + fb_id_t uid; /** The #fb_id of the user. **/ + const gchar *name; /** The name of the user. **/ }; @@ -252,26 +253,10 @@ void fb_api_connect(fb_api_t *api); void fb_api_disconnect(fb_api_t *api); -void fb_api_message(fb_api_t *api, const gchar *uid, const gchar *msg); +void fb_api_message(fb_api_t *api, fb_id_t uid, const gchar *msg); void fb_api_publish(fb_api_t *api, const gchar *topic, const gchar *fmt, ...); -void fb_api_typing(fb_api_t *api, const gchar *uid, gboolean state); - -fb_api_msg_t *fb_api_msg_new(const gchar *uid, const gchar *text); - -void fb_api_msg_free(fb_api_msg_t *msg); - -fb_api_pres_t *fb_api_pres_new(const gchar *uid, gboolean online); - -void fb_api_pres_free(fb_api_pres_t *pres); - -fb_api_typing_t *fb_api_typing_new(const gchar *uid, gboolean state); - -void fb_api_typing_free(fb_api_typing_t *typg); - -fb_api_user_t *fb_api_user_new(const gchar *uid, const gchar *name); - -void fb_api_user_free(fb_api_user_t *user); +void fb_api_typing(fb_api_t *api, fb_id_t uid, gboolean state); #endif /* _FACEBOOK_API_H */ diff --git a/facebook/facebook-id.h b/facebook/facebook-id.h new file mode 100644 index 0000000..f435930 --- /dev/null +++ b/facebook/facebook-id.h @@ -0,0 +1,57 @@ +/* + * Copyright 2014 James Geboski <jgeboski@gmail.com> + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +/** @file **/ + +#ifndef _FACEBOOK_ID_H +#define _FACEBOOK_ID_H + +#include <glib.h> +#include <glib/gprintf.h> + +#define FB_ID_CONSTANT(v) G_GINT64_CONSTANT(v) +#define FB_ID_FORMAT G_GINT64_FORMAT +#define FB_ID_MODIFIER G_GINT64_MODIFIER +#define FB_ID_STRMAX 21 +#define fb_id_hash g_int64_hash +#define fb_id_equal g_int64_equal + +/** + * Converts a string to a #fb_id. + * + * @param s The string. + * + * @return The resulting #fb_id. + **/ +#define FB_ID_FROM_STR(s) \ + g_ascii_strtoll(s, NULL, 10) + +/** + * Converts a #f_uid to a string. The buffer should be at least + * #FB_ID_STRMAX in length. + * + * @param i The #fb_id. + * @param s The string buffer. + **/ +#define FB_ID_TO_STR(i, s) \ + g_sprintf(s, "%" FB_ID_FORMAT, (fb_id_t) i) + + +/** The 64-bit Facebook identifier. **/ +typedef gint64 fb_id_t; + +#endif /* _FACEBOOK_ID_H */ diff --git a/facebook/facebook.c b/facebook/facebook.c index 6ab46a3..ab9427b 100644 --- a/facebook/facebook.c +++ b/facebook/facebook.c @@ -44,8 +44,10 @@ static void fb_cb_api_auth(fb_api_t *api, gpointer data) { fb_data_t *fata = data; account_t *acc = fata->ic->acc; + gchar uid[FB_ID_STRMAX]; - set_setstr(&acc->set, "uid", api->uid); + FB_ID_TO_STR(api->uid, uid); + set_setstr(&acc->set, "uid", uid); set_setstr(&acc->set, "token", api->token); imcb_log(fata->ic, "Authentication finished"); @@ -81,12 +83,14 @@ static void fb_cb_api_contacts(fb_api_t *api, const GSList *users, fb_data_t *fata = data; fb_api_user_t *user; const GSList *l; + gchar uid[FB_ID_STRMAX]; for (l = users; l != NULL; l = l->next) { user = l->data; - imcb_add_buddy(fata->ic, user->uid, NULL); - imcb_buddy_nick_hint(fata->ic, user->uid, user->name); - imcb_rename_buddy(fata->ic, user->uid, user->name); + FB_ID_TO_STR(user->uid, uid); + imcb_add_buddy(fata->ic, uid, NULL); + imcb_buddy_nick_hint(fata->ic, uid, user->name); + imcb_rename_buddy(fata->ic, uid, user->name); } imcb_log(fata->ic, "Establishing connection"); @@ -105,10 +109,12 @@ static void fb_cb_api_message(fb_api_t *api, const GSList *msgs, gpointer data) fb_data_t *fata = data; fb_api_msg_t *msg; const GSList *l; + gchar uid[FB_ID_STRMAX]; for (l = msgs; l != NULL; l = l->next) { msg = l->data; - imcb_buddy_msg(fata->ic, msg->uid, (gchar*) msg->text, 0, 0); + FB_ID_TO_STR(msg->uid, uid); + imcb_buddy_msg(fata->ic, uid, (gchar*) msg->text, 0, 0); } } @@ -126,6 +132,7 @@ static void fb_cb_api_presence(fb_api_t *api, const GSList *press, fb_api_pres_t *pres; const GSList *l; guint flags; + gchar uid[FB_ID_STRMAX]; for (l = press; l != NULL; l = l->next) { pres = l->data; @@ -134,7 +141,8 @@ static void fb_cb_api_presence(fb_api_t *api, const GSList *press, if (pres->active) flags |= OPT_LOGGED_IN; - imcb_buddy_status(fata->ic, pres->uid, flags, NULL, NULL); + FB_ID_TO_STR(pres->uid, uid); + imcb_buddy_status(fata->ic, uid, flags, NULL, NULL); } } @@ -150,9 +158,11 @@ static void fb_cb_api_typing(fb_api_t *api, fb_api_typing_t *typg, { fb_data_t *fata = data; guint32 flags; + gchar uid[FB_ID_STRMAX]; + FB_ID_TO_STR(typg->uid, uid); flags = typg->state ? OPT_TYPING : 0; - imcb_buddy_typing(fata->ic, typg->uid, flags); + imcb_buddy_typing(fata->ic, uid, flags); } /** @@ -166,6 +176,7 @@ static void fb_cb_api_typing(fb_api_t *api, fb_api_typing_t *typg, fb_data_t *fb_data_new(account_t *acc) { fb_data_t *fata; + gchar *uid; static const fb_api_funcs_t funcs = { .error = fb_cb_api_error, @@ -185,7 +196,11 @@ fb_data_t *fb_data_new(account_t *acc) fata->ic = imcb_new(acc); fata->ic->proto_data = fata; - fata->api->uid = g_strdup(set_getstr(&acc->set, "uid")); + uid = set_getstr(&acc->set, "uid"); + + if (uid != NULL) + fata->api->uid = FB_ID_FROM_STR(uid); + fata->api->token = g_strdup(set_getstr(&acc->set, "token")); fata->api->stoken = g_strdup(set_getstr(&acc->set, "stoken")); fata->api->cid = g_strdup(set_getstr(&acc->set, "cid")); @@ -292,8 +307,10 @@ static int fb_buddy_msg(struct im_connection *ic, char *to, char *message, int flags) { fb_data_t *fata = ic->proto_data; + fb_id_t uid; - fb_api_message(fata->api, to, message); + uid = FB_ID_FROM_STR(to); + fb_api_message(fata->api, uid, message); return 0; } @@ -309,10 +326,12 @@ static int fb_buddy_msg(struct im_connection *ic, char *to, char *message, static int fb_send_typing(struct im_connection *ic, char *who, int flags) { fb_data_t *fata = ic->proto_data; + fb_id_t uid; gboolean state; + uid = FB_ID_FROM_STR(who); state = (flags & OPT_TYPING) != 0; - fb_api_typing(fata->api, who, state); + fb_api_typing(fata->api, uid, state); return 0; } |