diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2012-09-25 01:10:05 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2012-09-25 01:10:05 +0100 | 
| commit | ba8671363c6d3dfbaf54029f35b3455c46cbc7d1 (patch) | |
| tree | 5cb6a5ac8cd447974a3090c212caeb63e1fd6d0f /protocols | |
| parent | 6bef2110ddeb9e1f8e8233a4e61b8917fb939b29 (diff) | |
| parent | 2a6da96544675726c73a60b588dc26e477ce70f5 (diff) | |
More mainline merges.
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/twitter/twitter_lib.c | 147 | 
1 files changed, 64 insertions, 83 deletions
| diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 8e2804a5..4a09cbb1 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -4,7 +4,7 @@  *  Simple module to facilitate twitter functionality.                       *  *                                                                           *  *  Copyright 2009-2010 Geert Mulders <g.c.w.m.mulders@gmail.com>            * -*  Copyright 2010-2011 Wilmer van der Gaast <wilmer@gaast.net>              * +*  Copyright 2010-2012 Wilmer van der Gaast <wilmer@gaast.net>              *  *                                                                           *  *  This library is free software; you can redistribute it and/or            *  *  modify it under the terms of the GNU Lesser General Public               * @@ -187,6 +187,52 @@ char *twitter_parse_error(struct http_request *req)  	return ret ? ret : req->status_string;  } +static struct xt_node *twitter_parse_response(struct im_connection *ic, struct http_request *req) +{ +	gboolean logging_in = !(ic->flags & OPT_LOGGED_IN); +	gboolean periodic; +	struct twitter_data *td = ic->proto_data; +	struct xt_node *ret; +	char path[64] = "", *s; +	 +	if ((s = strchr(req->request, ' '))) { +		path[sizeof(path)-1] = '\0'; +		strncpy(path, s + 1, sizeof(path) - 1); +		if ((s = strchr(path, '?')) || (s = strchr(path, ' '))) +			*s = '\0'; +	} +	 +	/* Kinda nasty. :-( Trying to suppress error messages, but only +	   for periodic (i.e. mentions/timeline) queries. */ +	periodic = strstr(path, "timeline") || strstr(path, "mentions"); +	 +	if (req->status_code == 401 && logging_in) { +		/* IIRC Twitter once had an outage where they were randomly +		   throwing 401s so I'll keep treating this one as fatal +		   only during login. */ +		imcb_error(ic, "Authentication failure"); +		imc_logout(ic, FALSE); +		return NULL; +	} else if (req->status_code != 200) { +		// It didn't go well, output the error and return. +		if (!periodic || logging_in || ++td->http_fails >= 5) +			imcb_error(ic, "Could not retrieve %s: %s", +				   path, twitter_parse_error(req)); +		 +		if (logging_in) +			imc_logout(ic, TRUE); +		return NULL; +	} else { +		td->http_fails = 0; +	} + +	if ((ret = xt_from_string(req->reply_body, req->body_size)) == NULL) { +		imcb_error(ic, "Could not retrieve %s: %s", +			   path, "XML parse error"); +	} +	return ret; +} +  static void twitter_http_get_friends_ids(struct http_request *req);  /** @@ -265,22 +311,6 @@ static void twitter_http_get_friends_ids(struct http_request *req)  	td = ic->proto_data; -	// Check if the HTTP request went well. More strict checks as this is -	// the first request we do in a session. -	if (req->status_code == 401) { -		imcb_error(ic, "Authentication failure"); -		imc_logout(ic, FALSE); -		return; -	} else if (req->status_code != 200) { -		// It didn't go well, output the error and return. -		imcb_error(ic, "Could not retrieve %s: %s", -			   TWITTER_FRIENDS_IDS_URL, twitter_parse_error(req)); -		imc_logout(ic, TRUE); -		return; -	} else { -		td->http_fails = 0; -	} -  	/* Create the room now that we "logged in". */  	if (!td->timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)  		twitter_groupchat_init(ic); @@ -289,7 +319,8 @@ static void twitter_http_get_friends_ids(struct http_request *req)  	txl->list = td->follow_ids;  	// Parse the data. -	parsed = xt_from_string(req->reply_body, req->body_size); +	if (!(parsed = twitter_parse_response(ic, req))) +		return;  	twitter_xt_get_friends_id_list(parsed, txl);  	xt_free_node(parsed); @@ -347,7 +378,6 @@ static void twitter_get_users_lookup(struct im_connection *ic)  static void twitter_http_get_users_lookup(struct http_request *req)  {  	struct im_connection *ic = req->data; -	struct twitter_data *td;  	struct xt_node *parsed;  	struct twitter_xml_list *txl;  	GSList *l = NULL; @@ -357,25 +387,12 @@ static void twitter_http_get_users_lookup(struct http_request *req)  	if (!g_slist_find(twitter_connections, ic))  		return; -	td = ic->proto_data; - -	if (req->status_code != 200) { -		// It didn't go well, output the error and return. -		imcb_error(ic, "Could not retrieve %s: %s", -			   TWITTER_USERS_LOOKUP_URL, twitter_parse_error(req)); -		imc_logout(ic, TRUE); -		return; -	} else { -		td->http_fails = 0; -	} -  	txl = g_new0(struct twitter_xml_list, 1);  	txl->list = NULL; -	// Parse the data. -	parsed = xt_from_string(req->reply_body, req->body_size); -  	// Get the user list from the parsed xml feed. +	if (!(parsed = twitter_parse_response(ic, req))) +		return;  	twitter_xt_get_users(parsed, txl);  	xt_free_node(parsed); @@ -786,6 +803,9 @@ void twitter_flush_timeline(struct im_connection *ic)  			output = g_slist_insert_sorted(output, l->data, twitter_compare_elements);  		}  	} +	 +	if (!(ic->flags & OPT_LOGGED_IN)) +		imcb_connected(ic);  	// 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) @@ -893,26 +913,12 @@ static void twitter_http_get_home_timeline(struct http_request *req)  	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 { -		// 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. -	parsed = xt_from_string(req->reply_body, req->body_size);  	// The root <statuses> node should hold the list of statuses <status> +	if (!(parsed = twitter_parse_response(ic, req))) +		goto end;  	twitter_xt_get_status_list(ic, parsed, txl);  	xt_free_node(parsed); @@ -940,26 +946,12 @@ static void twitter_http_get_mentions(struct http_request *req)  	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 { -		// It didn't go well, output the error and return. -		if (++td->http_fails >= 5) -			imcb_error(ic, "Could not retrieve %s: %s", -				   TWITTER_MENTIONS_URL, twitter_parse_error(req)); - -		goto end; -	} -  	txl = g_new0(struct twitter_xml_list, 1);  	txl->list = NULL; -	// Parse the data. -	parsed = xt_from_string(req->reply_body, req->body_size);  	// The root <statuses> node should hold the list of statuses <status> +	if (!(parsed = twitter_parse_response(ic, req))) +		goto end;  	twitter_xt_get_status_list(ic, parsed, txl);  	xt_free_node(parsed); @@ -979,6 +971,7 @@ static void twitter_http_post(struct http_request *req)  {  	struct im_connection *ic = req->data;  	struct twitter_data *td; +	struct xt_node *parsed, *node;  	// Check if the connection is still active.  	if (!g_slist_find(twitter_connections, ic)) @@ -987,24 +980,12 @@ static void twitter_http_post(struct http_request *req)  	td = ic->proto_data;  	td->last_status_id = 0; -	// Check if the HTTP request went well. -	if (req->status_code != 200) { -		// It didn't go well, output the error and return. -		imcb_error(ic, "HTTP error: %s", twitter_parse_error(req)); +	if (!(parsed = twitter_parse_response(ic, req)))  		return; -	} - -	if (req->body_size > 0) { -		struct xt_node *parsed, *node; - -		parsed = xt_from_string(req->reply_body, req->body_size); - -		if ((node = xt_find_node(parsed, "status")) && -		    (node = xt_find_node(node->children, "id")) && node->text) -			td->last_status_id = g_ascii_strtoull(node->text, NULL, 10); - -		xt_free_node(parsed); -	} +	 +	if ((node = xt_find_node(parsed, "status")) && +	    (node = xt_find_node(node->children, "id")) && node->text) +		td->last_status_id = g_ascii_strtoull(node->text, NULL, 10);  }  /** | 
