From 2322a9f38a2f6c9bf86eb62c2cd68fd3848b694f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 25 Aug 2011 20:08:07 +0200 Subject: Merging Twitter-mentions patch from meh. Bug #663. --- protocols/twitter/twitter_lib.c | 302 ++++++++++++++++++++++++++++++++-------- 1 file changed, 247 insertions(+), 55 deletions(-) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 14e98c53..805ff5aa 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -77,17 +77,20 @@ static void txu_free(struct twitter_xml_user *txu) { if (txu == NULL) return; + g_free(txu->name); g_free(txu->screen_name); g_free(txu); } - /** * Frees a twitter_xml_status struct. */ static void txs_free(struct twitter_xml_status *txs) { + if (txs == NULL) + return; + g_free(txs->text); txu_free(txs->user); g_free(txs); @@ -102,19 +105,40 @@ static void txl_free(struct twitter_xml_list *txl) GSList *l; if (txl == NULL) return; - for (l = txl->list; l; l = g_slist_next(l)) - if (txl->type == TXL_STATUS) + + for (l = txl->list; l; l = g_slist_next(l)) { + if (txl->type == TXL_STATUS) { txs_free((struct twitter_xml_status *) l->data); - else if (txl->type == TXL_ID) + } else if (txl->type == TXL_ID) { g_free(l->data); - else if (txl->type == TXL_USER) + } else if (txl->type == TXL_USER) { txu_free(l->data); + } + } + g_slist_free(txl->list); g_free(txl); } /** - * Add a buddy if it is not allready added, set the status to logged in. + * Compare status elements + */ +static gint twitter_compare_elements(gconstpointer a, gconstpointer b) +{ + struct twitter_xml_status *a_status = (struct twitter_xml_status *) a; + struct twitter_xml_status *b_status = (struct twitter_xml_status *) b; + + if (a_status->created_at < b_status->created_at) { + return -1; + } else if (a_status->created_at > b_status->created_at) { + return 1; + } else { + return 0; + } +} + +/** + * Add a buddy if it is not already added, set the status to logged in. */ static void twitter_add_buddy(struct im_connection *ic, char *name, const char *fullname) { @@ -131,7 +155,7 @@ static void twitter_add_buddy(struct im_connection *ic, char *name, const char * /* Necessary so that nicks always get translated to the exact Twitter username. */ imcb_buddy_nick_hint(ic, name, name); - imcb_chat_add_buddy(td->home_timeline_gc, name); + imcb_chat_add_buddy(td->timeline_gc, name); } else if (g_strcasecmp(mode, "many") == 0) imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL); } @@ -259,7 +283,7 @@ static void twitter_http_get_friends_ids(struct http_request *req) } /* Create the room now that we "logged in". */ - if (!td->home_timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) + if (!td->timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) twitter_groupchat_init(ic); txl = g_new0(struct twitter_xml_list, 1); @@ -521,32 +545,6 @@ static xt_status twitter_xt_get_status_list(struct im_connection *ic, struct xt_ return XT_HANDLED; } -static void twitter_http_get_home_timeline(struct http_request *req); - -/** - * Get the timeline. - */ -void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) -{ - struct twitter_data *td = ic->proto_data; - - char *args[4]; - args[0] = "cursor"; - args[1] = g_strdup_printf("%lld", (long long) next_cursor); - if (td->home_timeline_id) { - args[2] = "since_id"; - args[3] = g_strdup_printf("%llu", (long long unsigned int) td->home_timeline_id); - } - - twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, - td->home_timeline_id ? 4 : 2); - - g_free(args[1]); - if (td->home_timeline_id) { - g_free(args[3]); - } -} - static char *twitter_msg_add_id(struct im_connection *ic, struct twitter_xml_status *txs, const char *prefix) { @@ -585,7 +583,7 @@ static void twitter_groupchat_init(struct im_connection *ic) struct twitter_data *td = ic->proto_data; GSList *l; - td->home_timeline_gc = gc = imcb_chat_new(ic, "home/timeline"); + td->timeline_gc = gc = imcb_chat_new(ic, "twitter/timeline"); name_hint = g_strdup_printf("%s_%s", td->prefix, ic->acc->user); imcb_chat_name_hint(gc, name_hint); @@ -594,7 +592,7 @@ static void twitter_groupchat_init(struct im_connection *ic) for (l = ic->bee->users; l; l = l->next) { bee_user_t *bu = l->data; if (bu->ic == ic) - imcb_chat_add_buddy(td->home_timeline_gc, bu->handle); + imcb_chat_add_buddy(td->timeline_gc, bu->handle); } } @@ -607,12 +605,13 @@ static void twitter_groupchat(struct im_connection *ic, GSList * list) GSList *l = NULL; struct twitter_xml_status *status; struct groupchat *gc; + guint64 last_id = 0; // Create a new groupchat if it does not exsist. - if (!td->home_timeline_gc) + if (!td->timeline_gc) twitter_groupchat_init(ic); - gc = td->home_timeline_gc; + gc = td->timeline_gc; if (!gc->joined) imcb_chat_add_buddy(gc, ic->acc->user); @@ -620,26 +619,30 @@ static void twitter_groupchat(struct im_connection *ic, GSList * list) char *msg; status = l->data; - if (status->user == NULL || status->text == NULL) + if (status->user == NULL || status->text == NULL || last_id == status->id) continue; - twitter_add_buddy(ic, status->user->screen_name, status->user->name); + last_id = status->id; strip_html(status->text); + msg = twitter_msg_add_id(ic, status, ""); // Say it! - if (g_strcasecmp(td->user, status->user->screen_name) == 0) + if (g_strcasecmp(td->user, status->user->screen_name) == 0) { imcb_chat_log(gc, "You: %s", msg ? msg : status->text); - else + } else { + twitter_add_buddy(ic, status->user->screen_name, status->user->name); + imcb_chat_msg(gc, status->user->screen_name, msg ? msg : status->text, 0, status->created_at); + } g_free(msg); - // Update the home_timeline_id to hold the highest id, so that by the next request + // Update the timeline_id to hold the highest id, so that by the next request // we won't pick up the updates already in the list. - td->home_timeline_id = MAX(td->home_timeline_id, status->id); + td->timeline_id = MAX(td->timeline_id, status->id); } } @@ -653,6 +656,7 @@ static void twitter_private_message_chat(struct im_connection *ic, GSList * list struct twitter_xml_status *status; char from[MAX_STRING]; gboolean mode_one; + guint64 last_id = 0; mode_one = g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "one") == 0; @@ -665,6 +669,10 @@ static void twitter_private_message_chat(struct im_connection *ic, GSList * list char *prefix = NULL, *text = NULL; status = l->data; + if (status->user == NULL || status->text == NULL || last_id == status->id) + continue; + + last_id = status->id; strip_html(status->text); if (mode_one) @@ -679,15 +687,150 @@ static void twitter_private_message_chat(struct im_connection *ic, GSList * list mode_one ? from : status->user->screen_name, text ? text : status->text, 0, status->created_at); - // Update the home_timeline_id to hold the highest id, so that by the next request + // Update the timeline_id to hold the highest id, so that by the next request // we won't pick up the updates already in the list. - td->home_timeline_id = MAX(td->home_timeline_id, status->id); + td->timeline_id = MAX(td->timeline_id, status->id); g_free(text); g_free(prefix); } } +static void twitter_http_get_home_timeline(struct http_request *req); +static void twitter_http_get_mentions(struct http_request *req); + +/** + * Get the timeline with optionally mentions + */ +void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor) +{ + struct twitter_data *td = ic->proto_data; + gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions"); + + if (td->flags & TWITTER_DOING_TIMELINE) { + return; + } + + td->flags |= TWITTER_DOING_TIMELINE; + + twitter_get_home_timeline(ic, next_cursor); + + if (include_mentions) { + twitter_get_mentions(ic, next_cursor); + } +} + +/** + * Call this one after receiving timeline/mentions. Show to user once we have + * both. + */ +void twitter_flush_timeline(struct im_connection *ic) +{ + struct twitter_data *td = ic->proto_data; + gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions"); + gboolean show_old_mentions = set_getbool(&ic->acc->set, "show_old_mentions"); + struct twitter_xml_list *home_timeline = td->home_timeline_obj; + struct twitter_xml_list *mentions = td->mentions_obj; + GSList *output = NULL; + GSList *l; + + if (!(td->flags & TWITTER_GOT_TIMELINE)) { + return; + } + + if (include_mentions && !(td->flags & TWITTER_GOT_MENTIONS)) { + return; + } + + if (home_timeline && home_timeline->list) { + for (l = home_timeline->list; l; l = g_slist_next(l)) { + output = g_slist_insert_sorted(output, l->data, twitter_compare_elements); + } + } + + if (include_mentions && mentions && mentions->list) { + for (l = mentions->list; l; l = g_slist_next(l)) { + if (!show_old_mentions && output && twitter_compare_elements(l->data, output->data) < 0) { + continue; + } + + output = g_slist_insert_sorted(output, l->data, twitter_compare_elements); + } + } + + // See if the user wants to see the messages in a groupchat window or as private messages. + if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) + twitter_groupchat(ic, output); + else + twitter_private_message_chat(ic, output); + + g_slist_free(output); + + if (home_timeline && home_timeline->list) { + txl_free(home_timeline); + } + + if (mentions && mentions->list) { + txl_free(mentions); + } + + td->flags &= ~(TWITTER_DOING_TIMELINE | TWITTER_GOT_TIMELINE | TWITTER_GOT_MENTIONS); +} + +/** + * Get the timeline. + */ +void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) +{ + struct twitter_data *td = ic->proto_data; + + td->home_timeline_obj = NULL; + td->flags &= ~TWITTER_GOT_TIMELINE; + + char *args[4]; + args[0] = "cursor"; + args[1] = g_strdup_printf("%lld", (long long) next_cursor); + if (td->timeline_id) { + args[2] = "since_id"; + args[3] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); + } + + twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, + td->timeline_id ? 4 : 2); + + g_free(args[1]); + if (td->timeline_id) { + g_free(args[3]); + } +} + +/** + * Get mentions. + */ +void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor) +{ + struct twitter_data *td = ic->proto_data; + + td->mentions_obj = NULL; + td->flags &= ~TWITTER_GOT_MENTIONS; + + char *args[4]; + args[0] = "cursor"; + args[1] = g_strdup_printf("%lld", (long long) next_cursor); + if (td->timeline_id) { + args[2] = "since_id"; + args[3] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); + } + + twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, ic, 0, args, + td->timeline_id ? 4 : 2); + + g_free(args[1]); + if (td->timeline_id) { + g_free(args[3]); + } +} + /** * Callback for getting the home timeline. */ @@ -712,14 +855,66 @@ static void twitter_http_get_home_timeline(struct http_request *req) } else if (req->status_code == 401) { imcb_error(ic, "Authentication failure"); imc_logout(ic, FALSE); - return; + goto end; } else { // It didn't go well, output the error and return. if (++td->http_fails >= 5) imcb_error(ic, "Could not retrieve %s: %s", TWITTER_HOME_TIMELINE_URL, twitter_parse_error(req)); + goto end; + } + + txl = g_new0(struct twitter_xml_list, 1); + txl->list = NULL; + + // Parse the data. + parser = xt_new(NULL, txl); + xt_feed(parser, req->reply_body, req->body_size); + // The root node should hold the list of statuses + twitter_xt_get_status_list(ic, parser->root, txl); + xt_free(parser); + + td->home_timeline_obj = txl; + + end: + td->flags |= TWITTER_GOT_TIMELINE; + + twitter_flush_timeline(ic); +} + +/** + * Callback for getting mentions. + */ +static void twitter_http_get_mentions(struct http_request *req) +{ + struct im_connection *ic = req->data; + struct twitter_data *td; + struct xt_parser *parser; + struct twitter_xml_list *txl; + + // Check if the connection is still active. + if (!g_slist_find(twitter_connections, ic)) return; + + td = ic->proto_data; + + // Check if the HTTP request went well. + if (req->status_code == 200) { + td->http_fails = 0; + if (!(ic->flags & OPT_LOGGED_IN)) + imcb_connected(ic); + } else if (req->status_code == 401) { + imcb_error(ic, "Authentication failure"); + imc_logout(ic, FALSE); + goto end; + } else { + // It didn't go well, output the error and return. + if (++td->http_fails >= 5) + imcb_error(ic, "Could not retrieve " TWITTER_MENTIONS_URL ": %s", + twitter_parse_error(req)); + + goto end; } txl = g_new0(struct twitter_xml_list, 1); @@ -732,15 +927,12 @@ static void twitter_http_get_home_timeline(struct http_request *req) twitter_xt_get_status_list(ic, parser->root, txl); xt_free(parser); - // See if the user wants to see the messages in a groupchat window or as private messages. - if (txl->list == NULL); - else if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) - twitter_groupchat(ic, txl->list); - else - twitter_private_message_chat(ic, txl->list); + td->mentions_obj = txl; - // Free the structure. - txl_free(txl); + end: + td->flags |= TWITTER_GOT_MENTIONS; + + twitter_flush_timeline(ic); } /** -- cgit v1.2.3 From 429a9b17fb256e5fc750104f4c5ffb2dc7fba74b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 26 Aug 2011 22:16:17 +0200 Subject: Since t.co is all over Twitter now, start parsing and showing entity information. I'm going for this way of rendering even though full URLs are also available to me because A) it puts me on the safe side wrt Twitter ToS and B) some full URLS may really be very long. Noticed some problem with truncated RT statuses not getting fixed but this seems to be unrelated. (This is a truncated RT status without the "truncated" property set.) Bug #821. --- protocols/twitter/twitter_lib.c | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 805ff5aa..7f2fb811 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -498,6 +498,27 @@ static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_ g_free(txs->text); txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text); txs_free(rtxs); + } else { + struct xt_node *urls, *url; + + urls = xt_find_path(node, "entities/urls"); + for (url = urls ? urls->children : NULL; url; url = url->next) { + /* "short" is a reserved word. :-P */ + struct xt_node *kort = xt_find_node(url->children, "url"); + struct xt_node *disp = xt_find_node(url->children, "display_url"); + char *pos, *new; + + if (!kort || !kort->text || !disp || !disp->text || + !(pos = strstr(txs->text, kort->text))) + continue; + + *pos = '\0'; + new = g_strdup_printf("%s%s <%s>%s", txs->text, kort->text, + disp->text, pos + strlen(kort->text)); + + g_free(txs->text); + txs->text = new; + } } return XT_HANDLED; @@ -787,20 +808,22 @@ void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) td->home_timeline_obj = NULL; td->flags &= ~TWITTER_GOT_TIMELINE; - char *args[4]; + char *args[6]; args[0] = "cursor"; args[1] = g_strdup_printf("%lld", (long long) next_cursor); + args[2] = "include_entities"; + args[3] = "true"; if (td->timeline_id) { - args[2] = "since_id"; - args[3] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); + args[4] = "since_id"; + args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); } twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, - td->timeline_id ? 4 : 2); + td->timeline_id ? 6 : 4); g_free(args[1]); if (td->timeline_id) { - g_free(args[3]); + g_free(args[5]); } } @@ -814,20 +837,22 @@ void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor) td->mentions_obj = NULL; td->flags &= ~TWITTER_GOT_MENTIONS; - char *args[4]; + char *args[6]; args[0] = "cursor"; args[1] = g_strdup_printf("%lld", (long long) next_cursor); + args[2] = "include_entities"; + args[3] = "true"; if (td->timeline_id) { - args[2] = "since_id"; - args[3] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); + args[4] = "since_id"; + args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); } twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, ic, 0, args, - td->timeline_id ? 4 : 2); + td->timeline_id ? 6 : 4); g_free(args[1]); if (td->timeline_id) { - g_free(args[3]); + g_free(args[5]); } } -- cgit v1.2.3 From 0fff0b22db8860d3e6165f381028b441f26a31fe Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 27 Aug 2011 12:18:45 +0200 Subject: Just reconstruct all retweets instead of just the ones marked as truncated. --- protocols/twitter/twitter_lib.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 7f2fb811..4c680930 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -459,14 +459,11 @@ static xt_status twitter_xt_get_users(struct xt_node *node, struct twitter_xml_l static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_status *txs) { struct xt_node *child, *rt = NULL; - gboolean truncated = FALSE; // Walk over the nodes children. for (child = node->children; child; child = child->next) { if (g_strcasecmp("text", child->name) == 0) { txs->text = g_memdup(child->text, child->text_len + 1); - } else if (g_strcasecmp("truncated", child->name) == 0 && child->text) { - truncated = bool2int(child->text); } else if (g_strcasecmp("retweeted_status", child->name) == 0) { rt = child; } else if (g_strcasecmp("created_at", child->name) == 0) { @@ -487,8 +484,9 @@ static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_ } } - /* If it's a truncated retweet, get the original because dots suck. */ - if (truncated && rt) { + /* If it's a (truncated) retweet, get the original. Even if the API claims it + wasn't truncated because it may be lying. */ + if (rt) { struct twitter_xml_status *rtxs = g_new0(struct twitter_xml_status, 1); if (twitter_xt_get_status(rt, rtxs) != XT_HANDLED) { txs_free(rtxs); -- cgit v1.2.3 From 733f607bfaa34aa949df2602aec3b46aa2c3a46f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 17 Oct 2011 23:58:14 -0400 Subject: Stupid work-around for bug #838. The troublesome condition is known, I just don't know exactly how BitlBee gets into it. Any more info from people who see this problem often would be useful. --- protocols/twitter/twitter_lib.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 4c680930..dd9c3ac6 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -726,6 +726,13 @@ void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor) struct twitter_data *td = ic->proto_data; gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions"); + if ((td->flags & 0xf0000) == (TWITTER_DOING_TIMELINE | TWITTER_DOING_TIMELINE_SLOW)) { + imcb_log(ic, "Connection seems to have stalled again.\n" + "This is a known bug, if you see this happen a lot " + "please generate some traffic dumps."); + td->flags &= ~0xf0000; + } + if (td->flags & TWITTER_DOING_TIMELINE) { return; } -- cgit v1.2.3 From 32bea82d26872395634862204f551644233454ae Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 19 Oct 2011 22:59:57 -0400 Subject: changeset:devel,814 was silly and incomplete. This should fix that. Full workaround for Twitter "hang" problem. --- protocols/twitter/twitter_lib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index dd9c3ac6..00e3a2ee 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -734,6 +734,10 @@ void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor) } if (td->flags & TWITTER_DOING_TIMELINE) { + /* This shouldn't normally happen at all but I'm currently hunting a bug + where it does. Instead of having users suffer under it, have a work- + around with a warning. */ + td->flags |= TWITTER_DOING_TIMELINE_SLOW; return; } -- cgit v1.2.3 From 90fc864b79ba673623ce96e3e89866e48bc32d7f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 24 Nov 2011 08:18:04 +0000 Subject: Hopefully this fixed #838. Patch from Artem Savkov, thanks! The problem was HTTP failures caused by (most likely) DNS resolution problems. Yes, ignoring return values is still bad, kids! --- protocols/twitter/twitter_lib.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'protocols/twitter/twitter_lib.c') diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 00e3a2ee..d52c29ff 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -726,18 +726,7 @@ void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor) struct twitter_data *td = ic->proto_data; gboolean include_mentions = set_getbool(&ic->acc->set, "fetch_mentions"); - if ((td->flags & 0xf0000) == (TWITTER_DOING_TIMELINE | TWITTER_DOING_TIMELINE_SLOW)) { - imcb_log(ic, "Connection seems to have stalled again.\n" - "This is a known bug, if you see this happen a lot " - "please generate some traffic dumps."); - td->flags &= ~0xf0000; - } - if (td->flags & TWITTER_DOING_TIMELINE) { - /* This shouldn't normally happen at all but I'm currently hunting a bug - where it does. Instead of having users suffer under it, have a work- - around with a warning. */ - td->flags |= TWITTER_DOING_TIMELINE_SLOW; return; } @@ -827,8 +816,14 @@ void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor) args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); } - twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, - td->timeline_id ? 6 : 4); + if (twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, + td->timeline_id ? 6 : 4) == NULL) { + if (++td->http_fails >= 5) + imcb_error(ic, "Could not retrieve %s: %s", + TWITTER_HOME_TIMELINE_URL, "connection failed"); + td->flags |= TWITTER_GOT_TIMELINE; + twitter_flush_timeline(ic); + } g_free(args[1]); if (td->timeline_id) { @@ -856,8 +851,14 @@ void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor) args[5] = g_strdup_printf("%llu", (long long unsigned int) td->timeline_id); } - twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, ic, 0, args, - td->timeline_id ? 6 : 4); + if (twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, ic, 0, args, + td->timeline_id ? 6 : 4) == NULL) { + if (++td->http_fails >= 5) + imcb_error(ic, "Could not retrieve %s: %s", + TWITTER_MENTIONS_URL, "connection failed"); + td->flags |= TWITTER_GOT_MENTIONS; + twitter_flush_timeline(ic); + } g_free(args[1]); if (td->timeline_id) { @@ -945,8 +946,8 @@ static void twitter_http_get_mentions(struct http_request *req) } else { // It didn't go well, output the error and return. if (++td->http_fails >= 5) - imcb_error(ic, "Could not retrieve " TWITTER_MENTIONS_URL ": %s", - twitter_parse_error(req)); + imcb_error(ic, "Could not retrieve %s: %s", + TWITTER_MENTIONS_URL, twitter_parse_error(req)); goto end; } -- cgit v1.2.3