Changeset 1fdb0a4 for protocols/twitter
- Timestamp:
- 2010-06-05T23:26:07Z (14 years ago)
- Branches:
- master
- Children:
- 4aa0f6b, bc49ec2
- Parents:
- b308cf9 (diff), 3dc6d86 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- protocols/twitter
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
rb308cf9 r1fdb0a4 27 27 #include "twitter_http.h" 28 28 #include "twitter_lib.h" 29 #include "url.h" 29 30 30 31 /** … … 70 71 "http://api.twitter.com/oauth/request_token", 71 72 "http://api.twitter.com/oauth/access_token", 72 "http ://api.twitter.com/oauth/authorize",73 "https://api.twitter.com/oauth/authorize", 73 74 .consumer_key = "xsDNKJuNZYkZyMcu914uEA", 74 75 .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo", … … 160 161 set_t *s; 161 162 163 s = set_add( &acc->set, "base_url", TWITTER_API_URL, NULL, acc ); 164 s->flags |= ACC_SET_OFFLINE_ONLY; 165 162 166 s = set_add( &acc->set, "message_length", "140", set_eval_int, acc ); 163 167 … … 175 179 { 176 180 struct im_connection *ic = imcb_new( acc ); 177 struct twitter_data *td = g_new0( struct twitter_data, 1 );181 struct twitter_data *td; 178 182 char name[strlen(acc->user)+9]; 179 183 url_t url; 184 185 if( !url_set( &url, set_getstr( &ic->acc->set, "base_url" ) ) || 186 ( url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS ) ) 187 { 188 imcb_error( ic, "Incorrect API base URL: %s", set_getstr( &ic->acc->set, "base_url" ) ); 189 imc_logout( ic, FALSE ); 190 return; 191 } 192 180 193 twitter_connections = g_slist_append( twitter_connections, ic ); 194 td = g_new0( struct twitter_data, 1 ); 181 195 ic->proto_data = td; 182 ic->flags |= OPT_DOES_HTML; 196 197 td->url_ssl = url.proto == PROTO_HTTPS; 198 td->url_port = url.port; 199 td->url_host = g_strdup( url.host ); 200 if( strcmp( url.file, "/" ) != 0 ) 201 td->url_path = g_strdup( url.file ); 202 else 203 td->url_path = g_strdup( "" ); 183 204 184 205 td->user = acc->user; 185 if( !set_getbool( &acc->set, "oauth" ) ) 186 td->pass = g_strdup( acc->pass ); 187 else if( strstr( acc->pass, "oauth_token=" ) ) 206 if( strstr( acc->pass, "oauth_token=" ) ) 188 207 td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth ); 189 td->home_timeline_id = 0;190 208 191 209 sprintf( name, "twitter_%s", acc->user ); … … 193 211 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 194 212 195 if( td-> pass || td->oauth_info)213 if( td->oauth_info || !set_getbool( &acc->set, "oauth" ) ) 196 214 twitter_main_loop_start( ic ); 197 215 else … … 268 286 static void twitter_add_buddy( struct im_connection *ic, char *who, char *group ) 269 287 { 288 twitter_friendships_create_destroy(ic, who, 1); 270 289 } 271 290 272 291 static void twitter_remove_buddy( struct im_connection *ic, char *who, char *group ) 273 292 { 293 twitter_friendships_create_destroy(ic, who, 0); 274 294 } 275 295 -
protocols/twitter/twitter.h
rb308cf9 r1fdb0a4 42 42 struct groupchat *home_timeline_gc; 43 43 gint http_fails; 44 45 gboolean url_ssl; 46 int url_port; 47 char *url_host; 48 char *url_path; 44 49 }; 45 50 -
protocols/twitter/twitter_http.c
rb308cf9 r1fdb0a4 41 41 42 42 43 char *twitter_url_append(char *url, char *key, char* value);43 static char *twitter_url_append(char *url, char *key, char* value); 44 44 45 45 /** … … 47 47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c 48 48 */ 49 void *twitter_http( char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, struct oauth_info* oi, char** arguments, int arguments_len)49 void *twitter_http(struct im_connection *ic, char *url_string, http_input_function func, gpointer data, int is_post, char** arguments, int arguments_len) 50 50 { 51 url_t *url = g_new0( url_t, 1 );51 struct twitter_data *td = ic->proto_data; 52 52 char *tmp; 53 char *request;53 GString *request = g_string_new(""); 54 54 void *ret; 55 char *userpass = NULL;56 char *userpass_base64;57 55 char *url_arguments; 58 56 59 // Fill the url structure. 60 if( !url_set( url, url_string ) ) 61 { 62 g_free( url ); 63 return NULL; 64 } 65 66 if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS ) 67 { 68 g_free( url ); 69 return NULL; 70 } 71 72 // Concatenate user and pass 73 if (user && pass) { 74 userpass = g_strdup_printf("%s:%s", user, pass); 75 userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass)); 76 } else { 77 userpass_base64 = NULL; 78 } 79 80 url_arguments = g_malloc(1); 81 url_arguments[0] = '\0'; 57 url_arguments = g_strdup(""); 82 58 83 59 // Construct the url arguments. … … 93 69 } 94 70 95 // Do GET stuff...96 if (!is_post)97 {98 // Find the char-pointer of the end of the string.99 tmp = url->file + strlen(url->file);100 tmp[0] = '?';101 // append the url_arguments to the end of the url->file.102 // TODO GM: Check the length?103 g_stpcpy (tmp+1, url_arguments);104 }105 106 107 71 // Make the request. 108 request = g_strdup_printf( "%s %s HTTP/1.0\r\n" 109 "Host: %s\r\n" 110 "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n", 111 is_post ? "POST" : "GET", url->file, url->host ); 72 g_string_printf(request, "%s %s%s%s%s HTTP/1.0\r\n" 73 "Host: %s\r\n" 74 "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n", 75 is_post ? "POST" : "GET", 76 td->url_path, url_string, 77 is_post ? "" : "?", is_post ? "" : url_arguments, 78 td->url_host); 112 79 113 80 // If a pass and user are given we append them to the request. 114 if ( oi)81 if (td->oauth_info) 115 82 { 116 83 char *full_header; 84 char *full_url; 117 85 118 full_header = oauth_http_header(oi, is_post ? "POST" : "GET", 119 url_string, url_arguments); 86 full_url = g_strconcat(set_getstr(&ic->acc->set, "base_url" ), url_string, NULL); 87 full_header = oauth_http_header(td->oauth_info, is_post ? "POST" : "GET", 88 full_url, url_arguments); 120 89 121 tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); 122 g_free(request); 90 g_string_append_printf(request, "Authorization: %s\r\n", full_header); 123 91 g_free(full_header); 124 request = tmp;92 g_free(full_url); 125 93 } 126 else if (userpass_base64)94 else 127 95 { 128 tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64); 129 g_free(request); 130 request = tmp; 96 char userpass[strlen(ic->acc->user)+2+strlen(ic->acc->pass)]; 97 char *userpass_base64; 98 99 g_snprintf(userpass, sizeof(userpass), "%s:%s", ic->acc->user, ic->acc->pass); 100 userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass)); 101 g_string_append_printf(request, "Authorization: Basic %s\r\n", userpass_base64); 102 g_free( userpass_base64 ); 131 103 } 132 104 … … 135 107 { 136 108 // Append the Content-Type and url-encoded arguments. 137 tmp = g_strdup_printf("%sContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %zd\r\n\r\n%s",138 request, strlen(url_arguments), url_arguments);139 g_free(request);140 request = tmp;109 g_string_append_printf(request, 110 "Content-Type: application/x-www-form-urlencoded\r\n" 111 "Content-Length: %zd\r\n\r\n%s", 112 strlen(url_arguments), url_arguments); 141 113 } else { 142 114 // Append an extra \r\n to end the request... 143 tmp = g_strdup_printf("%s\r\n", request); 144 g_free(request); 145 request = tmp; 115 g_string_append(request, "\r\n"); 146 116 } 147 117 148 ret = http_dorequest( url->host, url->port, url->proto == PROTO_HTTPS, request, func, data);118 ret = http_dorequest(td->url_host, td->url_port, td->url_ssl, request->str, func, data); 149 119 150 g_free( url );151 g_free( userpass );152 g_free( userpass_base64 );153 120 g_free( url_arguments ); 154 g_ free( request);121 g_string_free( request, TRUE ); 155 122 return ret; 156 123 } 157 124 158 char *twitter_url_append(char *url, char *key, char* value)125 static char *twitter_url_append(char *url, char *key, char* value) 159 126 { 160 127 char *key_encoded = g_strndup(key, 3 * strlen(key)); -
protocols/twitter/twitter_http.h
rb308cf9 r1fdb0a4 30 30 struct oauth_info; 31 31 32 void *twitter_http( char *url_string, http_input_function func, gpointer data, int is_post,33 char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len);32 void *twitter_http(struct im_connection *ic, char *url_string, http_input_function func, 33 gpointer data, int is_post, char** arguments, int arguments_len); 34 34 35 35 #endif //_TWITTER_HTTP_H -
protocols/twitter/twitter_lib.c
rb308cf9 r1fdb0a4 117 117 } 118 118 119 /* Warning: May return a malloc()ed value, which will be free()d on the next 120 call. Only for short-term use. */ 121 static char *twitter_parse_error(struct http_request *req) 122 { 123 static char *ret = NULL; 124 struct xt_parser *xp = NULL; 125 struct xt_node *node; 126 127 g_free(ret); 128 ret = NULL; 129 130 if (req->body_size > 0) 131 { 132 xp = xt_new(NULL, NULL); 133 xt_feed(xp, req->reply_body, req->body_size); 134 135 if ((node = xt_find_node(xp->root, "hash")) && 136 (node = xt_find_node(node->children, "error")) && 137 node->text_len > 0) 138 { 139 ret = g_strdup_printf("%s (%s)", req->status_string, node->text); 140 xt_free(xp); 141 return ret; 142 } 143 144 xt_free(xp); 145 } 146 147 return req->status_string; 148 } 149 119 150 static void twitter_http_get_friends_ids(struct http_request *req); 120 151 … … 124 155 void twitter_get_friends_ids(struct im_connection *ic, int next_cursor) 125 156 { 126 struct twitter_data *td = ic->proto_data;127 128 157 // Primitive, but hey! It works... 129 158 char* args[2]; 130 159 args[0] = "cursor"; 131 160 args[1] = g_strdup_printf ("%d", next_cursor); 132 twitter_http( TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2);161 twitter_http(ic, TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, args, 2); 133 162 134 163 g_free(args[1]); … … 196 225 // It didn't go well, output the error and return. 197 226 if (++td->http_fails >= 5) 198 imcb_error(ic, "Could not retrieve friends . HTTP STATUS: %d", req->status_code);227 imcb_error(ic, "Could not retrieve friends: %s", twitter_parse_error(req)); 199 228 200 229 return; … … 396 425 } 397 426 398 twitter_http( TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth_info, args, td->home_timeline_id ? 4 : 2);427 twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, td->home_timeline_id ? 4 : 2); 399 428 400 429 g_free(args[1]); … … 434 463 twitter_add_buddy(ic, status->user->screen_name, status->user->name); 435 464 465 strip_html(status->text); 466 436 467 // Say it! 437 468 if (g_strcasecmp(td->user, status->user->screen_name) == 0) … … 471 502 status = l->data; 472 503 504 strip_html( status->text ); 473 505 if( mode_one ) 474 506 text = g_strdup_printf( "\002<\002%s\002>\002 %s", … … 523 555 // It didn't go well, output the error and return. 524 556 if (++td->http_fails >= 5) 525 imcb_error(ic, "Could not retrieve " TWITTER_HOME_TIMELINE_URL " . HTTP STATUS: %d", req->status_code);557 imcb_error(ic, "Could not retrieve " TWITTER_HOME_TIMELINE_URL ": %s", twitter_parse_error(req)); 526 558 527 559 return; … … 575 607 // It didn't go well, output the error and return. 576 608 if (++td->http_fails >= 5) 577 imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL " HTTP STATUS: %d", req->status_code);609 imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req)); 578 610 579 611 return; … … 614 646 void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor) 615 647 { 616 struct twitter_data *td = ic->proto_data;617 618 648 char* args[2]; 619 649 args[0] = "cursor"; 620 650 args[1] = g_strdup_printf ("%d", next_cursor); 621 651 622 twitter_http( TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2);652 twitter_http(ic, TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, args, 2); 623 653 624 654 g_free(args[1]); … … 626 656 627 657 /** 628 * Callback after sending a new updateto twitter.629 */ 630 static void twitter_http_post _status(struct http_request *req)658 * Callback to use after sending a post request to twitter. 659 */ 660 static void twitter_http_post(struct http_request *req) 631 661 { 632 662 struct im_connection *ic = req->data; … … 639 669 if (req->status_code != 200) { 640 670 // It didn't go well, output the error and return. 641 imcb_error(ic, " Could not post message... HTTP STATUS: %d", req->status_code);671 imcb_error(ic, "HTTP error: %s", twitter_parse_error(req)); 642 672 return; 643 673 } … … 649 679 void twitter_post_status(struct im_connection *ic, char* msg) 650 680 { 651 struct twitter_data *td = ic->proto_data;652 653 681 char* args[2]; 654 682 args[0] = "status"; 655 683 args[1] = msg; 656 twitter_http( TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2);684 twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, args, 2); 657 685 // g_free(args[1]); 658 686 } … … 664 692 void twitter_direct_messages_new(struct im_connection *ic, char *who, char *msg) 665 693 { 666 struct twitter_data *td = ic->proto_data;667 668 694 char* args[4]; 669 695 args[0] = "screen_name"; … … 672 698 args[3] = msg; 673 699 // Use the same callback as for twitter_post_status, since it does basically the same. 674 twitter_http( TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4);700 twitter_http(ic, TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post, ic, 1, args, 4); 675 701 // g_free(args[1]); 676 702 // g_free(args[3]); 677 703 } 704 705 void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create) 706 { 707 char* args[2]; 708 args[0] = "screen_name"; 709 args[1] = who; 710 twitter_http(ic, create ? TWITTER_FRIENDSHIPS_CREATE_URL : TWITTER_FRIENDSHIPS_DESTROY_URL, twitter_http_post, ic, 1, args, 2); 711 } -
protocols/twitter/twitter_lib.h
rb308cf9 r1fdb0a4 32 32 33 33 /* Status URLs */ 34 #define TWITTER_STATUS_UPDATE_URL TWITTER_API_URL"/statuses/update.xml"35 #define TWITTER_STATUS_SHOW_URL TWITTER_API_URL"/statuses/show/"36 #define TWITTER_STATUS_DESTROY_URL TWITTER_API_URL"/statuses/destroy/"34 #define TWITTER_STATUS_UPDATE_URL "/statuses/update.xml" 35 #define TWITTER_STATUS_SHOW_URL "/statuses/show/" 36 #define TWITTER_STATUS_DESTROY_URL "/statuses/destroy/" 37 37 38 38 /* Timeline URLs */ 39 #define TWITTER_PUBLIC_TIMELINE_URL TWITTER_API_URL"/statuses/public_timeline.xml"40 #define TWITTER_FEATURED_USERS_URL TWITTER_API_URL"/statuses/featured.xml"41 #define TWITTER_FRIENDS_TIMELINE_URL TWITTER_API_URL"/statuses/friends_timeline.xml"42 #define TWITTER_HOME_TIMELINE_URL TWITTER_API_URL"/statuses/home_timeline.xml"43 #define TWITTER_MENTIONS_URL TWITTER_API_URL"/statuses/mentions.xml"44 #define TWITTER_USER_TIMELINE_URL TWITTER_API_URL"/statuses/user_timeline.xml"39 #define TWITTER_PUBLIC_TIMELINE_URL "/statuses/public_timeline.xml" 40 #define TWITTER_FEATURED_USERS_URL "/statuses/featured.xml" 41 #define TWITTER_FRIENDS_TIMELINE_URL "/statuses/friends_timeline.xml" 42 #define TWITTER_HOME_TIMELINE_URL "/statuses/home_timeline.xml" 43 #define TWITTER_MENTIONS_URL "/statuses/mentions.xml" 44 #define TWITTER_USER_TIMELINE_URL "/statuses/user_timeline.xml" 45 45 46 46 /* Users URLs */ 47 #define TWITTER_SHOW_USERS_URL TWITTER_API_URL"/users/show.xml"48 #define TWITTER_SHOW_FRIENDS_URL TWITTER_API_URL"/statuses/friends.xml"49 #define TWITTER_SHOW_FOLLOWERS_URL TWITTER_API_URL"/statuses/followers.xml"47 #define TWITTER_SHOW_USERS_URL "/users/show.xml" 48 #define TWITTER_SHOW_FRIENDS_URL "/statuses/friends.xml" 49 #define TWITTER_SHOW_FOLLOWERS_URL "/statuses/followers.xml" 50 50 51 51 /* Direct messages URLs */ 52 #define TWITTER_DIRECT_MESSAGES_URL TWITTER_API_URL"/direct_messages.xml"53 #define TWITTER_DIRECT_MESSAGES_NEW_URL TWITTER_API_URL"/direct_messages/new.xml"54 #define TWITTER_DIRECT_MESSAGES_SENT_URL TWITTER_API_URL"/direct_messages/sent.xml"55 #define TWITTER_DIRECT_MESSAGES_DESTROY_URL TWITTER_API_URL"/direct_messages/destroy/"52 #define TWITTER_DIRECT_MESSAGES_URL "/direct_messages.xml" 53 #define TWITTER_DIRECT_MESSAGES_NEW_URL "/direct_messages/new.xml" 54 #define TWITTER_DIRECT_MESSAGES_SENT_URL "/direct_messages/sent.xml" 55 #define TWITTER_DIRECT_MESSAGES_DESTROY_URL "/direct_messages/destroy/" 56 56 57 57 /* Friendships URLs */ 58 #define TWITTER_FRIENDSHIPS_CREATE_URL TWITTER_API_URL"/friendships/create.xml"59 #define TWITTER_FRIENDSHIPS_DESTROY_URL TWITTER_API_URL"/friendships/destroy.xml"60 #define TWITTER_FRIENDSHIPS_SHOW_URL TWITTER_API_URL"/friendships/show.xml"58 #define TWITTER_FRIENDSHIPS_CREATE_URL "/friendships/create.xml" 59 #define TWITTER_FRIENDSHIPS_DESTROY_URL "/friendships/destroy.xml" 60 #define TWITTER_FRIENDSHIPS_SHOW_URL "/friendships/show.xml" 61 61 62 62 /* Social graphs URLs */ 63 #define TWITTER_FRIENDS_IDS_URL TWITTER_API_URL"/friends/ids.xml"64 #define TWITTER_FOLLOWERS_IDS_URL TWITTER_API_URL"/followers/ids.xml"63 #define TWITTER_FRIENDS_IDS_URL "/friends/ids.xml" 64 #define TWITTER_FOLLOWERS_IDS_URL "/followers/ids.xml" 65 65 66 66 /* Account URLs */ 67 #define TWITTER_ACCOUNT_RATE_LIMIT_URL TWITTER_API_URL"/account/rate_limit_status.xml"67 #define TWITTER_ACCOUNT_RATE_LIMIT_URL "/account/rate_limit_status.xml" 68 68 69 69 /* Favorites URLs */ 70 #define TWITTER_FAVORITES_GET_URL TWITTER_API_URL"/favorites.xml"71 #define TWITTER_FAVORITE_CREATE_URL TWITTER_API_URL"/favorites/create/"72 #define TWITTER_FAVORITE_DESTROY_URL TWITTER_API_URL"/favorites/destroy/"70 #define TWITTER_FAVORITES_GET_URL "/favorites.xml" 71 #define TWITTER_FAVORITE_CREATE_URL "/favorites/create/" 72 #define TWITTER_FAVORITE_DESTROY_URL "/favorites/destroy/" 73 73 74 74 /* Block URLs */ 75 #define TWITTER_BLOCKS_CREATE_URL TWITTER_API_URL"/blocks/create/"76 #define TWITTER_BLOCKS_DESTROY_URL TWITTER_API_URL"/blocks/destroy/"75 #define TWITTER_BLOCKS_CREATE_URL "/blocks/create/" 76 #define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/" 77 77 78 78 void twitter_get_friends_ids(struct im_connection *ic, int next_cursor); … … 82 82 void twitter_post_status(struct im_connection *ic, char *msg); 83 83 void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message); 84 void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create); 84 85 85 86 #endif //_TWITTER_LIB_H
Note: See TracChangeset
for help on using the changeset viewer.