adium.1-3: a00ecf89: pidgin-facebookchat at r678 (1.61+).
zacw at adiumx.com
zacw at adiumx.com
Fri Oct 16 10:30:32 EDT 2009
-----------------------------------------------------------------
Revision: a00ecf891b108bb09796d7770835216b7ce73e4f
Ancestor: 9166882a2852f0b4eb1e5e2a279baaf35c0212b2
Author: zacw at adiumx.com
Date: 2009-10-16T14:24:43
Branch: im.pidgin.adium.1-3
URL: http://d.pidgin.im/viewmtn/revision/info/a00ecf891b108bb09796d7770835216b7ce73e4f
Modified files:
libpurple/protocols/facebook/facebook.nsi
libpurple/protocols/facebook/fb_blist.c
libpurple/protocols/facebook/fb_connection.c
libpurple/protocols/facebook/fb_conversation.c
libpurple/protocols/facebook/fb_friendlist.c
libpurple/protocols/facebook/fb_messages.c
libpurple/protocols/facebook/fb_util.c
libpurple/protocols/facebook/fb_util.h
libpurple/protocols/facebook/libfacebook.c
libpurple/protocols/facebook/libfacebook.h
libpurple/protocols/facebook/pidgin-facebookchat.rc
libpurple/protocols/facebook/rss.xml
ChangeLog:
pidgin-facebookchat at r678 (1.61+).
-------------- next part --------------
============================================================
--- libpurple/protocols/facebook/facebook.nsi 0ea82a12c41c433fc30f2431d1d6a0c9f53d1329
+++ libpurple/protocols/facebook/facebook.nsi 27b05643b15daeeac1bff1585817edcc4e63db91
@@ -6,7 +6,7 @@ SetCompress off
; todo: SetBrandingImage
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "pidgin-facebookchat"
-!define PRODUCT_VERSION "1.60"
+!define PRODUCT_VERSION "1.61"
!define PRODUCT_PUBLISHER "Eion Robb"
!define PRODUCT_WEB_SITE "http://pidgin-facebookchat.googlecode.com/"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
============================================================
--- libpurple/protocols/facebook/fb_blist.c 13096220516c9de76237d53a5a0b21d9663f6bd5
+++ libpurple/protocols/facebook/fb_blist.c 55a589254403723cac7bc7e62531ef9a5241e2a4
@@ -110,64 +110,6 @@ static GList *get_buddies(FacebookAccoun
return buddies;
}
-static gboolean process_buddy_status(FacebookAccount *fba, PurpleBuddy *buddy,
- JsonObject *userInfo)
-{
- FacebookBuddy *fbuddy;
- gboolean status_changed;
-
- status_changed = FALSE;
- fbuddy = buddy->proto_data;
-
- if (json_object_has_member(userInfo, "status"))
- {
- gchar *status_text;
- const gchar *status_time_text;
-
- status_time_text = json_node_get_string(
- json_object_get_member(userInfo, "statusTimeRel"));
- status_text = fb_strdup_withhtml(json_node_get_string(
- json_object_get_member(userInfo, "status")));
-
- /* set our last known status so that we don't re-set it */
- if (!fba->last_status_message &&
- atoll(buddy->name) == fba->uid) {
- fba->last_status_message = g_strdup(status_text);
- }
-
- if (strlen(status_time_text) == 0) {
- status_time_text = NULL;
- }
-
- g_free(fbuddy->status_rel_time);
- if (status_time_text != NULL) {
- fbuddy->status_rel_time =
- fb_strdup_withhtml(status_time_text);
- } else {
- fbuddy->status_rel_time = NULL;
- }
-
- /* if the buddy status has changed, update the contact list */
- if (fbuddy->status == NULL ||
- !g_str_equal(fbuddy->status, status_text))
- {
- g_free(fbuddy->status);
- fbuddy->status = g_strdup(status_text);
- status_changed = TRUE;
- }
-
- g_free(status_text);
- } else {
- if (fbuddy->status != NULL) {
- g_free(fbuddy->status);
- fbuddy->status = NULL;
- status_changed = TRUE;
- }
- }
-
- return status_changed;
-}
-
static void process_buddy_icon(FacebookAccount *fba, PurpleBuddy *buddy,
JsonObject *userInfo)
{
@@ -260,12 +202,10 @@ static void process_buddies(FacebookAcco
for (cur = buddies; cur != NULL; cur = cur->next)
{
PurpleBuddy *buddy;
- gboolean status_changed;
buddy = (PurpleBuddy *)cur->data;
process_buddy_icon(fba, buddy, userInfo);
- status_changed = process_buddy_status(fba, buddy, userInfo);
purple_presence_set_idle(purple_buddy_get_presence(buddy),
idle, 0);
@@ -279,7 +219,6 @@ static void process_buddies(FacebookAcco
// conditions before doing this, because if we set it always
// Pidgin has a bug where the logs go nuts with "x is online".
if (!PURPLE_BUDDY_IS_ONLINE(buddy) ||
- status_changed ||
idle != purple_presence_is_idle(
purple_buddy_get_presence(buddy)))
{
@@ -320,6 +259,118 @@ static void process_notifications(Facebo
}
}
+static void got_status_stream_cb(FacebookAccount *fba, gchar *data,
+ gsize data_len, gpointer userdata)
+{
+ gchar *error = NULL;
+ JsonParser *parser;
+ JsonObject *objnode;
+ gint new_latest;
+ const gchar *html;
+ gchar **messages;
+ gchar *message;
+ gint i;
+ gchar *uid_string;
+ gchar *message_string;
+ gsize uid_length;
+ FacebookBuddy *fbuddy;
+ PurpleBuddy *buddy;
+
+ purple_debug_info("facebook", "parsing status message stream\n");
+
+ if (fba == NULL)
+ return;
+
+ parser = fb_get_parser(data, data_len);
+ if (parser == NULL) {
+ return;
+ }
+
+ //purple_debug_misc("facebook", "status message stream\n%s\n", data);
+
+ objnode = fb_get_json_object(parser, &error);
+
+ if (error || !json_object_has_member(objnode, "payload")) {
+ json_parser_free(parser);
+ return;
+ }
+
+ objnode = json_node_get_object(json_object_get_member(
+ objnode, "payload"));
+
+ new_latest = json_node_get_int(json_object_get_member(
+ objnode, "newestStoryTime"));
+
+ if (!new_latest)
+ {
+ json_parser_free(parser);
+ return;
+ }
+
+ fba->last_status_timestamp = new_latest;
+
+ html = json_node_get_string(json_object_get_member(
+ objnode, "html"));
+ //purple_debug_misc("facebook", "html data\n%s\n", html);
+
+ messages = g_strsplit(html, "/h3>", -1);
+ for(i = 0; messages[i]; i++)
+ {
+ message = messages[i];
+ uid_length = 0;
+
+ //find uid:
+ //start with aid_ ... "
+ uid_string = strstr(message, "aid_");
+ if (!uid_string)
+ continue;
+ uid_string += 4;
+ while (uid_string[uid_length] >= '0' &&
+ uid_string[uid_length] <= '9')
+ {
+ uid_length++;
+ }
+ uid_string = g_strndup(uid_string, uid_length);
+
+ //find message:
+ //class="UIStory_Message"> ... </span>
+ message_string = strstr(message, "UIStory_Message");
+ if (!message_string)
+ {
+ g_free(uid_string);
+ continue;
+ }
+ message_string = strchr(message_string, '>');
+ if (!message_string)
+ {
+ g_free(uid_string);
+ continue;
+ }
+ message_string += 1;
+ message_string = g_strndup(message_string, strstr(message_string, "</span>")-message_string);
+
+ buddy = purple_find_buddy(fba->account, uid_string);
+ if (buddy && buddy->proto_data)
+ {
+ fbuddy = buddy->proto_data;
+ g_free(fbuddy->status);
+
+ fbuddy->status = purple_markup_strip_html(message_string);
+
+ purple_prpl_got_user_status(fba->account, buddy->name,
+ purple_primitive_get_id_from_type(
+ purple_presence_is_idle(purple_buddy_get_presence(buddy)) ? PURPLE_STATUS_AWAY :
+ PURPLE_STATUS_AVAILABLE), "message", fbuddy->status, NULL);
+ }
+
+ g_free(uid_string);
+ g_free(message_string);
+ }
+ g_strfreev(messages);
+
+ json_parser_free(parser);
+}
+
static void got_buddy_list_cb(FacebookAccount *fba, gchar *data,
gsize data_len, gpointer userdata)
{
@@ -335,9 +386,12 @@ static void got_buddy_list_cb(FacebookAc
JsonParser *parser = fb_get_parser(data, data_len);
if (parser == NULL) {
- purple_connection_error_reason(fba->pc,
+ if (fba->bad_buddy_list_count++ == 3)
+ {
+ purple_connection_error_reason(fba->pc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Could not retrieve buddy list"));
+ }
return;
}
@@ -346,12 +400,16 @@ static void got_buddy_list_cb(FacebookAc
gchar *error = NULL;
JsonObject *objnode = fb_get_json_object(parser, &error);
if (error) {
- purple_connection_error_reason(
+ if (fba->bad_buddy_list_count++ == 3)
+ {
+ purple_connection_error_reason(
fba->pc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
error);
- json_parser_free(parser);
- return;
+ }
+ json_parser_free(parser);
+
+ return;
}
/* look for "userInfos":{ ... }, */
@@ -375,6 +433,9 @@ static void got_buddy_list_cb(FacebookAc
return;
}
+ //Reset invalid buddy list counter
+ fba->bad_buddy_list_count = 0;
+
if (purple_account_get_bool(fba->account, "facebook_use_groups", TRUE))
{
//Only process if we have the setting
@@ -439,9 +500,15 @@ gboolean fb_get_buddy_list(gpointer data
postdata = g_strdup_printf(
"user=%" G_GINT64_FORMAT "&popped_out=true&force_render=true&buddy_list=1¬ifications=1",
fba->uid);
- fb_post_or_get(fba, FB_METHOD_POST, NULL, "/ajax/presence/update.php",
+ fb_post_or_get(fba, FB_METHOD_POST, NULL, "/ajax/chat/buddy_list.php",
postdata, got_buddy_list_cb, NULL, FALSE);
g_free(postdata);
+
+ postdata = g_strdup_printf("/ajax/intent.php?filter=app_2915120374&request_type=1&__a=1&newest=%d&ignore_self=true",
+ fba->last_status_timestamp);
+ fb_post_or_get(fba, FB_METHOD_GET, NULL, postdata,
+ NULL, got_status_stream_cb, NULL, FALSE);
+ g_free(postdata);
return TRUE;
}
============================================================
--- libpurple/protocols/facebook/fb_connection.c df49a2d2b12155149fe59498282cc0a17adbe6f9
+++ libpurple/protocols/facebook/fb_connection.c 33973e7de9483646796ea2e4c476ccc886ce0df6
@@ -560,7 +560,7 @@ void fb_post_or_get(FacebookAccount *fba
* the TTL returned by the DNS server. We should expire things
* from the cache after some amount of time.
*/
- if (!is_proxy)
+ if (!is_proxy && !(method & FB_METHOD_SSL))
{
/* Don't do this for proxy connections, since proxies do the DNS lookup */
gchar *host_ip;
============================================================
--- libpurple/protocols/facebook/fb_conversation.c 8c4a8888a113ce29b70b943c33512e4f54983d97
+++ libpurple/protocols/facebook/fb_conversation.c 20f34f5ff69959ab8ca5cc9e0d3eab7a485cfedc
@@ -140,9 +140,9 @@ static void fb_history_fetch_cb(Facebook
gchar *to;
JsonObject *text_obj;
- from = g_strdup_printf("%" G_GINT64_FORMAT, json_node_get_int(
+ from = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(
json_object_get_member(message_obj, "from")));
- to = g_strdup_printf("%" G_GINT64_FORMAT, json_node_get_int(
+ to = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(
json_object_get_member(message_obj, "to")));
text_obj = json_node_get_object(
============================================================
--- libpurple/protocols/facebook/fb_friendlist.c 06b923d6224e80cb54759ba438f657d897bd4d3a
+++ libpurple/protocols/facebook/fb_friendlist.c 66a6aeac0aba11a6919cf7a0a09db77e79a80d56
@@ -322,7 +322,7 @@ gboolean fb_process_friend_lists(Faceboo
"got friend list %s with id %s\n",
name, id);
g_hash_table_insert(fba->friend_lists,
- g_strdup(id), g_utf8_strdown(name, -1));
+ g_strdup(id), g_strdup(name));
g_hash_table_insert(fba->friend_lists_reverse,
g_utf8_strdown(name, -1), g_strdup(id));
}
============================================================
--- libpurple/protocols/facebook/fb_messages.c 5e169ad1f7317b6d6d259a02cae23575f5600247
+++ libpurple/protocols/facebook/fb_messages.c 1b4165576e00b956a05890547ccc44abf85528a7
@@ -31,7 +31,7 @@ struct _FacebookOutgoingMessage {
struct _FacebookOutgoingMessage {
FacebookAccount *fba;
gchar *who;
- time_t time;
+ GTimeVal time;
gchar *message;
gint msg_id;
guint retry_count;
@@ -98,12 +98,13 @@ static void parse_new_messages(PurpleCon
for (i = 0; i < json_array_get_length(messages); i++) {
const gchar *type;
gchar *from, *to;
+
JsonObject *object = json_node_get_object(json_array_get_element(messages, i));
type = json_node_get_string(json_object_get_member(object, "type"));
- from = g_strdup_printf("%" G_GINT64_FORMAT, json_node_get_int(json_object_get_member(object, "from")));
- to = g_strdup_printf("%" G_GINT64_FORMAT, json_node_get_int(json_object_get_member(object, "to")));
+ from = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(object, "from")));
+ to = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(object, "to")));
/* Use the in-line buddy name if the buddy list hasn't been downloaded yet */
buddy = purple_find_buddy(pc->account, from);
@@ -337,7 +338,7 @@ static void fb_send_im_cb(FacebookAccoun
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
fba->account, msg->who);
purple_conversation_write(conv, NULL, error,
- PURPLE_MESSAGE_ERROR, msg->time);
+ PURPLE_MESSAGE_ERROR, msg->time.tv_sec);
}
g_hash_table_remove(fba->sent_messages_hash, msg->message);
@@ -351,13 +352,16 @@ static gboolean fb_send_im_fom(FacebookO
{
gchar *encoded_message;
gchar *postdata;
+ gchar *jstime;
+
+ jstime = g_strdup_printf("%ld%ld", msg->time.tv_sec, (msg->time.tv_usec/1000));
encoded_message = g_strdup(purple_url_encode(msg->message));
- postdata = g_strdup_printf("msg_text=%s&msg_id=%d&to=%s&client_time=%lu&post_form_id=%s",
- encoded_message, msg->msg_id, msg->who,
- (gulong) msg->time,
+ postdata = g_strdup_printf("msg_text=%s&msg_id=%d&to=%s&client_time=%s&post_form_id=%s",
+ encoded_message, msg->msg_id, msg->who, jstime,
msg->fba->post_form_id ? msg->fba->post_form_id : "0");
g_free(encoded_message);
+ g_free(jstime);
fb_post_or_get(msg->fba, FB_METHOD_POST, NULL, "/ajax/chat/send.php", postdata, fb_send_im_cb, msg, FALSE);
g_free(postdata);
@@ -389,7 +393,7 @@ int fb_send_im(PurpleConnection *pc, con
msg->msg_id = g_random_int();
msg->who = g_strdup(who);
- msg->time = time(NULL);
+ g_get_current_time(&msg->time);
msg->retry_count = 0;
//save that we're sending the message
============================================================
--- libpurple/protocols/facebook/fb_util.c 8ddff7af209527eb1c9a4c04c27ddccf0d3a01b0
+++ libpurple/protocols/facebook/fb_util.c db25bbe26ed405a613ac050b45a0567df3ee5aa8
@@ -112,9 +112,46 @@ gchar *fb_strdup_withhtml(const gchar *s
return dest;
}
-gint64 fb_time_kludge(gint initial_time)
+static gboolean is_json_64bit_safe()
{
+ //Cache the result to try make this function quick
+ static gint result = -1;
+ gint64 largeint = G_MAXINT64;
+
+ if (result == 1)
+ return TRUE;
+ if (result == 0)
+ return FALSE;
+
if (sizeof(gint) >= sizeof(gint64))
+ {
+ result = 1;
+ return TRUE;
+ }
+
+#ifndef USE_JSONC
+ JsonNode *node;
+
+ node = json_node_new(JSON_NODE_VALUE);
+ json_node_set_int(node, largeint);
+ if(json_node_get_int(node) == largeint)
+ {
+ result = 1;
+ } else {
+ result = 0;
+ }
+ json_node_free(node);
+ return result ? TRUE : FALSE;
+
+#endif /* !USE_JSONC */
+
+ result = 0;
+ return FALSE;
+}
+
+gint64 fb_time_kludge(gint64 initial_time)
+{
+ if (is_json_64bit_safe())
return initial_time;
gint64 now_millis = (gint64) time(NULL);
============================================================
--- libpurple/protocols/facebook/fb_util.h 9020d025525bf359be4dd1dc66478bf14a9250c7
+++ libpurple/protocols/facebook/fb_util.h 97d1d52c6ee49b764654ac3ae448284bfa071c81
@@ -30,7 +30,7 @@ gchar *fb_convert_unicode(const gchar *i
gchar *fb_replace_styled_text(const gchar *text);
gchar *fb_strdup_withhtml(const gchar *src);
gchar *fb_convert_unicode(const gchar *input);
-gint64 fb_time_kludge(int initial_time);
+gint64 fb_time_kludge(gint64 initial_time);
#endif /* FACEBOOK_UTIL_H */
============================================================
--- libpurple/protocols/facebook/libfacebook.c 447422b0f0485ea215b57f80293182de67dfcc2e
+++ libpurple/protocols/facebook/libfacebook.c c79f5931a33700bcd827cbf76b222bef530e0a31
@@ -32,6 +32,7 @@ static void fb_close(PurpleConnection *p
static void fb_login_cb(FacebookAccount *fba, gchar *response, gsize len,
gpointer userdata);
static void fb_close(PurpleConnection *pc);
+static void fb_buddy_free(PurpleBuddy *buddy);
/******************************************************************************/
/* PRPL functions */
@@ -68,12 +69,6 @@ static void fb_tooltip_text(PurpleBuddy
purple_notify_user_info_add_pair(userinfo,
_("Status"), status);
g_free(status);
- if (fbuddy->status_rel_time && *fbuddy->status_rel_time)
- {
- purple_notify_user_info_add_pair(userinfo,
- _("Status changed"),
- fbuddy->status_rel_time);
- }
}
}
@@ -85,17 +80,13 @@ static GList *fb_statuses(PurpleAccount
/* Online people have a status message and also a date when it was set */
status = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
NULL, _("Online"), FALSE, TRUE, FALSE, "message",
- _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "message_date", _("Message changed"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
/* Cave into feature requests and allow people to set themselves to be idle */
status = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
NULL, _("Idle"), FALSE, TRUE, FALSE, "message",
- _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- "message_date", _("Message changed"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
+ _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
/* Offline people dont have messages */
@@ -118,52 +109,117 @@ static gboolean fb_get_messages_failsafe
return TRUE;
}
+void fb_login_captcha_cancel_cb(PurpleConnection *pc, PurpleRequestFields *fields)
+{
+ purple_connection_error_reason(pc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Could not authenticate captcha. Logging into the Facebook website may fix this.");
+}
+
void fb_login_captcha_ok_cb(PurpleConnection *pc, PurpleRequestFields *fields)
{
- gint birthday_year, birthday_month, birthday_day;
+ const gchar *captcha_response;
gchar *postdata, *encoded_username, *encoded_password, *encoded_charset_test,
- *encoded_auth_token, *encoded_persist_data;
- const gchar* const *languages;
- const gchar *locale;
+ *encoded_persist_data, *encoded_response, *encoded_extra_challenge,
+ *encoded_session;
FacebookAccount *fba = pc->proto_data;
- birthday_year = purple_request_fields_get_integer(fields, "birthday_year");
- birthday_month = purple_request_fields_get_integer(fields, "birthday_month");
- birthday_day = purple_request_fields_get_integer(fields, "birthday_day");
-
+ captcha_response = purple_request_fields_get_string(fields, "captcha_response");
+
+ encoded_response = g_strdup(purple_url_encode(captcha_response));
encoded_username = g_strdup(purple_url_encode(
purple_account_get_username(fba->account)));
encoded_password = g_strdup(purple_url_encode(
purple_account_get_password(fba->account)));
- encoded_auth_token = g_strdup(purple_url_encode(
- fba->auth_token));
+ encoded_extra_challenge = g_strdup(purple_url_encode(
+ fba->extra_challenge));
encoded_persist_data = g_strdup(purple_url_encode(
fba->persist_data));
+ encoded_session = g_strdup(purple_url_encode(
+ fba->captcha_session));
encoded_charset_test = g_strdup(purple_url_encode("EUR,?,EUR,?,?,?,?"));
- languages = g_get_language_names();
- locale = languages[0];
- if (locale == NULL || g_str_equal(locale, "C"))
- locale = "en_US";
- postdata = g_strdup_printf(
- "charset_test=%s&locale=%s&email=%s&pass=%s&persistent=1&login=Login&charset_test=%s&version=1.0&return_session=0&t_auth_token=%s&answered_captcha=1&captcha_persist_data=%s&birthday_captcha_day=%d&birthday_captcha_month=%d&birthday_captcha_year=%d",
- encoded_charset_test, locale, encoded_username, encoded_password, encoded_charset_test, encoded_auth_token, encoded_persist_data, birthday_day, birthday_month, birthday_year);
+ postdata = g_strdup_printf("charset_test=%s&"
+ "version=1.0&"
+ "return_session=0&"
+ "charset_test=%s&"
+ "answered_captcha=1&"
+ "captcha_persist_data=%s&"
+ "captcha_session=%s&"
+ "extra_challenge_params=%s&"
+ "captcha_response=%s&"
+ "email=%s&pass=%s&"
+ "persistent=1",
+ encoded_charset_test, encoded_charset_test,
+ encoded_persist_data, encoded_session,
+ encoded_extra_challenge, encoded_response,
+ encoded_username, encoded_password);
g_free(encoded_username);
g_free(encoded_password);
g_free(encoded_charset_test);
- g_free(encoded_auth_token);
+ g_free(encoded_extra_challenge);
g_free(encoded_persist_data);
+ g_free(encoded_response);
+ g_free(encoded_session);
fb_post_or_get(fba, FB_METHOD_POST | FB_METHOD_SSL, "login.facebook.com",
- "/login.php?login_attempt=1", postdata, fb_login_cb, NULL, FALSE);
+ "/login.php?login_attempt=1&_fb_noscript=1", postdata, fb_login_cb, NULL, FALSE);
g_free(postdata);
- g_free(fba->auth_token);
+ g_free(fba->extra_challenge);
g_free(fba->persist_data);
- fba->auth_token = NULL;
+ g_free(fba->captcha_session);
+ fba->extra_challenge = NULL;
fba->persist_data = NULL;
+ fba->captcha_session = NULL;
}
+static void fb_login_captcha_image_cb(FacebookAccount *fba, gchar *response,
+ gsize len, gpointer userdata)
+{
+ PurpleRequestFields *fields;
+ PurpleRequestFieldGroup *group;
+ PurpleRequestField *field;
+
+ fields = purple_request_fields_new();
+ group = purple_request_field_group_new(NULL);
+ purple_request_fields_add_group(fields, group);
+
+ field = purple_request_field_image_new("captcha_image", "", response, len);
+ purple_request_field_group_add_field(group, field);
+
+ field = purple_request_field_string_new("captcha_response", "", "", FALSE);
+ purple_request_field_group_add_field(group, field);
+
+ purple_request_fields(fba->pc,
+ _("Facebook Captcha"), _("Facebook Captcha"),
+ _("Enter both words below, separated by a space"),
+ fields,
+ _("OK"), G_CALLBACK(fb_login_captcha_ok_cb),
+ _("Logout"), G_CALLBACK(fb_login_captcha_cancel_cb),
+ fba->account, NULL, NULL, fba->pc
+ );
+}
+
+static void fb_login_captcha_cb(FacebookAccount *fba, gchar *response,
+ gsize len, gpointer userdata)
+{
+ const gchar *challenge_start = "challenge : '";
+ gchar *challenge;
+ gchar *image_url;
+
+ challenge = g_strstr_len(response, len, challenge_start);
+ if (challenge)
+ {
+ challenge += strlen(challenge_start);
+ challenge = g_strndup(challenge, strchr(challenge, '\'') - challenge);
+
+ image_url = g_strdup_printf("/image?c=%s", challenge);
+
+ fb_post_or_get(fba, FB_METHOD_GET | FB_METHOD_SSL, "api-secure.recaptcha.net",
+ image_url, NULL, fb_login_captcha_image_cb, NULL, FALSE);
+ }
+}
+
static void fb_login_cb(FacebookAccount *fba, gchar *response, gsize len,
gpointer userdata)
{
@@ -173,7 +229,7 @@ static void fb_login_cb(FacebookAccount
{
purple_connection_update_progress(fba->pc, _("Handling Captcha"), 2, 4);
- const gchar *persist_data_start = "<input type=\"hidden\" name=\"captcha_persist_data\" value=\"";
+ const gchar *persist_data_start = "<input type=\"hidden\" id=\"captcha_persist_data\" name=\"captcha_persist_data\" value=\"";
gchar *persist_data = g_strstr_len(response, len, persist_data_start);
if (persist_data)
{
@@ -181,38 +237,47 @@ static void fb_login_cb(FacebookAccount
fba->persist_data = g_strndup(persist_data, strchr(persist_data, '"') - persist_data);
}
- const gchar *auth_token_start = "<input type=\"hidden\" name=\"t_auth_token\" value=\"";
- gchar *auth_token = g_strstr_len(response, len, auth_token_start);
- if (auth_token)
+ const gchar *session_start = "<input type=\"hidden\" id=\"captcha_session\" name=\"captcha_session\" value=\"";
+ gchar *session = g_strstr_len(response, len, session_start);
+ if (session)
{
- auth_token += strlen(auth_token);
- fba->auth_token = g_strndup(auth_token, strchr(auth_token, '"') - auth_token);
+ session += strlen(session_start);
+ fba->captcha_session = g_strndup(session, strchr(session, '"') - session);
}
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
+ gchar *captcha_url;
+ const gchar *extra_challenge_params = "<input type=\"hidden\" id=\"extra_challenge_params\" name=\"extra_challenge_params\" value=\"";
+ gchar *extra_challenge = g_strstr_len(response, len, extra_challenge_params);
+ if (extra_challenge)
+ {
+ extra_challenge += strlen(extra_challenge_params);
+ fba->extra_challenge = g_strndup(extra_challenge, strchr(extra_challenge, '"') - extra_challenge);
+ extra_challenge = purple_unescape_html(fba->extra_challenge);
+ g_free(fba->extra_challenge);
+ fba->extra_challenge = extra_challenge;
+ }
- fields = purple_request_fields_new();
- group = purple_request_field_group_new(NULL);
- purple_request_fields_add_group(fields, group);
+ if (!fba->extra_challenge || !fba->persist_data || !fba->captcha_session)
+ {
+ g_free(fba->extra_challenge);
+ g_free(fba->persist_data);
+ g_free(fba->captcha_session);
+ fba->extra_challenge = NULL;
+ fba->persist_data = NULL;
+ fba->captcha_session = NULL;
+ purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Could not authenticate captcha. Logging into the Facebook website may fix this.");
+ return;
+ }
- field = purple_request_field_int_new("birthday_year", _("Year"), 0);
- purple_request_field_group_add_field(group, field);
- field = purple_request_field_int_new("birthday_month", _("Month"), 0);
- purple_request_field_group_add_field(group, field);
- field = purple_request_field_int_new("birthday_day", _("Day"), 0);
- purple_request_field_group_add_field(group, field);
+ captcha_url = g_strdup_printf("/challenge?k=" FACEBOOK_CAPTCHA_SITE "&%s",
+ fba->extra_challenge?fba->extra_challenge:"");
- purple_request_fields(fba->pc,
- _("Facebook Captcha"), _("Facebook Captcha"),
- _("Facebook thinks you're not you. To prove you are, please enter your date of birth"),
- fields,
- _("OK"), G_CALLBACK(fb_login_captcha_ok_cb),
- _("Logout"), G_CALLBACK(fb_close),
- fba->account, NULL, NULL, fba->pc
- );
+ fb_post_or_get(fba, FB_METHOD_GET | FB_METHOD_SSL, "api-secure.recaptcha.net",
+ captcha_url, NULL, fb_login_captcha_cb, NULL, FALSE);
+ g_free(captcha_url);
+
return;
}
@@ -325,7 +390,7 @@ static void fb_login(PurpleAccount *acco
g_free(encoded_charset_test);
fb_post_or_get(fba, FB_METHOD_POST | FB_METHOD_SSL, "login.facebook.com",
- "/login.php?login_attempt=1", postdata, fb_login_cb, NULL, FALSE);
+ "/login.php?login_attempt=1&_fb_noscript=1", postdata, fb_login_cb, NULL, FALSE);
g_free(postdata);
}
@@ -333,6 +398,7 @@ static void fb_close(PurpleConnection *p
{
FacebookAccount *fba;
gchar *postdata;
+ GSList *buddies;
purple_debug_info("facebook", "disconnecting account\n");
@@ -349,6 +415,13 @@ static void fb_close(PurpleConnection *p
/* destroy conversation subsystem */
fb_conversation_destroy(fba);
+ buddies = purple_find_buddies(fba->account, NULL);
+ while(buddies) {
+ PurpleBuddy *b = buddies->data;
+ fb_buddy_free(b);
+ buddies = g_slist_delete_link(buddies, buddies);
+ }
+
/* Tell Facebook that we've logged out. */
/*
* TODO
@@ -417,7 +490,8 @@ static void fb_close(PurpleConnection *p
g_free(fba->post_form_id);
g_free(fba->channel_number);
g_free(fba->last_status_message);
- g_free(fba->auth_token);
+ g_free(fba->extra_challenge);
+ g_free(fba->captcha_session);
g_free(fba->persist_data);
g_free(fba);
}
@@ -530,7 +604,6 @@ static void fb_buddy_free(PurpleBuddy *b
g_free(fbuddy->name);
g_free(fbuddy->status);
- g_free(fbuddy->status_rel_time);
g_free(fbuddy->thumb_url);
g_free(fbuddy);
}
============================================================
--- libpurple/protocols/facebook/libfacebook.h b7634eccfe4ac79928e153d73436504d5c15b020
+++ libpurple/protocols/facebook/libfacebook.h 320fb4a16727ec862f67f3087ace1a23f7ea1ef2
@@ -21,8 +21,9 @@
#ifndef LIBFACEBOOK_H
#define LIBFACEBOOK_H
-#define FACEBOOK_PLUGIN_VERSION "1.60"
+#define FACEBOOK_PLUGIN_VERSION "1.61"
#define FACEBOOK_PLUGIN_ID "prpl-bigbrownchunx-facebookim"
+#define FACEBOOK_CAPTCHA_SITE "6LezHAAAAAAAADqVjseQ3ctG3ocfQs2Elo1FTa_a"
#include <glib.h>
@@ -104,8 +105,11 @@ struct _FacebookAccount {
gboolean is_idle;
GHashTable *sent_messages_hash;
gint last_inbox_count;
- gchar *auth_token;
+ gchar *extra_challenge;
gchar *persist_data;
+ gchar *captcha_session;
+ gint last_status_timestamp;
+ guint bad_buddy_list_count;
};
struct _FacebookBuddy {
@@ -114,7 +118,6 @@ struct _FacebookBuddy {
gint64 uid;
gchar *name;
gchar *status;
- gchar *status_rel_time;
gchar *thumb_url;
};
============================================================
--- libpurple/protocols/facebook/pidgin-facebookchat.rc 78abadafda8864721a2d0249a7710578eaba4cc2
+++ libpurple/protocols/facebook/pidgin-facebookchat.rc df1d296b5f3e4af608710ac1adbc8bbe5d0bae04
@@ -1,7 +1,7 @@ 1 VERSIONINFO
1 VERSIONINFO
-FILEVERSION 1,60,0,0
-PRODUCTVERSION 1,60,0,0
+FILEVERSION 1,61,0,0
+PRODUCTVERSION 1,61,0,0
FILEOS 0x40004 // VOS_NT_WINDOWS32
FILETYPE 0x2 // VFT_DLL
{
@@ -12,8 +12,8 @@ BLOCK "StringFileInfo"
VALUE "CompanyName", "Eion Robb\0"
VALUE "FileDescription", "Facebook Chat plugin for Pidgin\0"
VALUE "ProductName", "pidgin-facebookchat\0"
- VALUE "FileVersion", "1.60\0"
- VALUE "ProductVersion", "1.60\0"
+ VALUE "FileVersion", "1.61\0"
+ VALUE "ProductVersion", "1.61\0"
VALUE "InternalName", "pidgin-facebookchat\0"
VALUE "OriginalFilename", "libfacebook.dll\0"
VALUE "Comments", "http://pidgin-facebookchat.googlecode.com/\0"
============================================================
--- libpurple/protocols/facebook/rss.xml 40100d174f1ed87fdc64698421454ee9d4991879
+++ libpurple/protocols/facebook/rss.xml 5307d58e8af5e6e4481d89e241d46b35b5baefde
@@ -13,6 +13,17 @@
<width>48</width><height>48</height>
</image>
<item>
+ <title>Version 1.61</title>
+ <link>http://code.google.com/p/pidgin-facebookchat/issues/detail?id=24#c49</link>
+ <description><![CDATA[Against all odds, I've just put out a new version 1.61 of the plugin. It should fix up the problems with messages arriving from weird numbers, but it also now requires version 0.7.6 of json-glib to work. It might or might not also have the option to disable friends lists, depending on who you ask :)<br/><br/>
+ Changelog:<br/>
+ <a href="http://code.google.com/p/pidgin-facebookchat/wiki/Changelog">http://code.google.com/p/pidgin-facebookchat/wiki/Changelog</a><br/>
+ Download:<br/>
+ <a href="http://code.google.com/p/pidgin-facebookchat/downloads/list">http://code.google.com/p/pidgin-facebookchat/downloads/list</a><br/>]]></description>
+ <pubDate>Tue, 8 September 2009 17:38:16 +1200</pubDate>
+ <guid isPermaLink="true">http://code.google.com/p/pidgin-facebookchat/issues/detail?id=24#c49</guid>
+ </item>
+ <item>
<title>Version 1.60</title>
<link>http://code.google.com/p/pidgin-facebookchat/issues/detail?id=24#c48</link>
<description><![CDATA[Hi all, sorry for the recent weirdness with the plugin. v1.60 is out which addresses the major bit of these problems.<br/>
More information about the Commits
mailing list