Changeset f924563 for protocols/twitter
- Timestamp:
- 2010-05-03T00:52:08Z (15 years ago)
- Branches:
- master
- Children:
- 1a3ba05
- Parents:
- 6a9d068 (diff), 6824fb3 (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:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
r6a9d068 rf924563 23 23 24 24 #include "nogaim.h" 25 #include "oauth.h" 25 26 #include "twitter.h" 26 27 #include "twitter_http.h" 27 28 #include "twitter_lib.h" 28 29 29 30 30 /** 31 31 * Main loop function … … 41 41 // If the user uses multiple private message windows we need to get the 42 42 // users buddies. 43 if ( !set_getbool( &ic->acc->set, "use_groupchat" ))43 if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "many") == 0) 44 44 twitter_get_statuses_friends(ic, -1); 45 45 … … 51 51 } 52 52 53 54 static void twitter_init( account_t *acc ) 55 { 56 set_t *s; 57 s = set_add( &acc->set, "use_groupchat", "false", set_eval_bool, acc ); 58 s->flags |= ACC_SET_OFFLINE_ONLY; 59 } 60 61 /** 62 * Login method. Since the twitter API works with seperate HTTP request we 63 * only save the user and pass to the twitter_data object. 64 */ 65 static void twitter_login( account_t *acc ) 66 { 67 struct im_connection *ic = imcb_new( acc ); 68 struct twitter_data *td = g_new0( struct twitter_data, 1 ); 69 70 twitter_connections = g_slist_append( twitter_connections, ic ); 71 72 td->user = acc->user; 73 td->pass = acc->pass; 74 td->home_timeline_id = 0; 75 76 ic->proto_data = td; 77 53 static void twitter_main_loop_start( struct im_connection *ic ) 54 { 55 struct twitter_data *td = ic->proto_data; 56 78 57 imcb_log( ic, "Connecting to Twitter" ); 79 58 … … 86 65 } 87 66 67 68 static const struct oauth_service twitter_oauth = 69 { 70 "http://api.twitter.com/oauth/request_token", 71 "http://api.twitter.com/oauth/access_token", 72 "http://api.twitter.com/oauth/authorize", 73 .consumer_key = "xsDNKJuNZYkZyMcu914uEA", 74 .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo", 75 }; 76 77 static gboolean twitter_oauth_callback( struct oauth_info *info ); 78 79 static void twitter_oauth_start( struct im_connection *ic ) 80 { 81 struct twitter_data *td = ic->proto_data; 82 83 imcb_log( ic, "Requesting OAuth request token" ); 84 85 td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic ); 86 } 87 88 static gboolean twitter_oauth_callback( struct oauth_info *info ) 89 { 90 struct im_connection *ic = info->data; 91 struct twitter_data *td; 92 93 if( !g_slist_find( twitter_connections, ic ) ) 94 return FALSE; 95 96 td = ic->proto_data; 97 if( info->stage == OAUTH_REQUEST_TOKEN ) 98 { 99 char name[strlen(ic->acc->user)+9], *msg; 100 101 if( info->request_token == NULL ) 102 { 103 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 104 imc_logout( ic, TRUE ); 105 return FALSE; 106 } 107 108 sprintf( name, "twitter_%s", ic->acc->user ); 109 msg = g_strdup_printf( "To finish OAuth authentication, please visit " 110 "%s and respond with the resulting PIN code.", 111 info->auth_url ); 112 imcb_buddy_msg( ic, name, msg, 0, 0 ); 113 g_free( msg ); 114 } 115 else if( info->stage == OAUTH_ACCESS_TOKEN ) 116 { 117 if( info->token == NULL || info->token_secret == NULL ) 118 { 119 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 120 imc_logout( ic, TRUE ); 121 return FALSE; 122 } 123 124 /* IM mods didn't do this so far and it's ugly but I should 125 be able to get away with it... */ 126 g_free( ic->acc->pass ); 127 ic->acc->pass = oauth_to_string( info ); 128 129 twitter_main_loop_start( ic ); 130 } 131 132 return TRUE; 133 } 134 135 136 static char *set_eval_mode( set_t *set, char *value ) 137 { 138 if( g_strcasecmp( value, "one" ) == 0 || 139 g_strcasecmp( value, "many" ) == 0 || 140 g_strcasecmp( value, "chat" ) == 0 ) 141 return value; 142 else 143 return NULL; 144 } 145 146 static void twitter_init( account_t *acc ) 147 { 148 set_t *s; 149 150 s = set_add( &acc->set, "mode", "one", set_eval_mode, acc ); 151 s->flags |= ACC_SET_OFFLINE_ONLY; 152 153 s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc ); 154 } 155 156 /** 157 * Login method. Since the twitter API works with seperate HTTP request we 158 * only save the user and pass to the twitter_data object. 159 */ 160 static void twitter_login( account_t *acc ) 161 { 162 struct im_connection *ic = imcb_new( acc ); 163 struct twitter_data *td = g_new0( struct twitter_data, 1 ); 164 char name[strlen(acc->user)+9]; 165 166 twitter_connections = g_slist_append( twitter_connections, ic ); 167 ic->proto_data = td; 168 ic->flags |= OPT_DOES_HTML; 169 170 td->user = acc->user; 171 if( !set_getbool( &acc->set, "oauth" ) ) 172 td->pass = g_strdup( acc->pass ); 173 else if( strstr( acc->pass, "oauth_token=" ) ) 174 td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth ); 175 td->home_timeline_id = 0; 176 177 sprintf( name, "twitter_%s", acc->user ); 178 imcb_add_buddy( ic, name, NULL ); 179 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 180 181 if( td->pass || td->oauth_info ) 182 twitter_main_loop_start( ic ); 183 else 184 twitter_oauth_start( ic ); 185 } 186 88 187 /** 89 188 * Logout method. Just free the twitter_data. … … 104 203 if( td ) 105 204 { 205 oauth_info_free( td->oauth_info ); 206 g_free( td->pass ); 106 207 g_free( td ); 107 208 } … … 115 216 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) 116 217 { 117 // Let's just update the status. 118 // if ( g_strcasecmp(who, ic->acc->user) == 0 ) 119 twitter_post_status(ic, message); 120 // else 121 // twitter_direct_messages_new(ic, who, message); 218 struct twitter_data *td = ic->proto_data; 219 220 if (g_strncasecmp(who, "twitter_", 8) == 0 && 221 g_strcasecmp(who + 8, ic->acc->user) == 0) 222 { 223 if( set_getbool( &ic->acc->set, "oauth" ) && 224 td->oauth_info && td->oauth_info->token == NULL ) 225 { 226 if( !oauth_access_token( message, td->oauth_info ) ) 227 { 228 imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); 229 imc_logout( ic, TRUE ); 230 return FALSE; 231 } 232 } 233 else 234 twitter_post_status(ic, message); 235 } 236 else 237 { 238 twitter_direct_messages_new(ic, who, message); 239 } 122 240 return( 0 ); 123 241 } -
protocols/twitter/twitter.h
r6a9d068 rf924563 37 37 char* user; 38 38 char* pass; 39 struct oauth_info *oauth_info; 39 40 guint64 home_timeline_id; 40 41 gint main_loop_id; -
protocols/twitter/twitter_http.c
r6a9d068 rf924563 29 29 ****************************************************************************/ 30 30 31 #include "twitter_http.h"32 31 #include "twitter.h" 33 32 #include "bitlbee.h" … … 35 34 #include "misc.h" 36 35 #include "base64.h" 36 #include "oauth.h" 37 37 #include <ctype.h> 38 38 #include <errno.h> 39 40 #include "twitter_http.h" 39 41 40 42 … … 45 47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c 46 48 */ 47 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len)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) 48 50 { 49 51 url_t *url = g_new0( url_t, 1 ); … … 110 112 111 113 // If a pass and user are given we append them to the request. 112 if (userpass_base64) 114 if (oi) 115 { 116 char *full_header; 117 118 full_header = oauth_http_header(oi, is_post ? "POST" : "GET", 119 url_string, url_arguments); 120 121 tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); 122 g_free(request); 123 g_free(full_header); 124 request = tmp; 125 } 126 else if (userpass_base64) 113 127 { 114 128 tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64); -
protocols/twitter/twitter_http.h
r6a9d068 rf924563 28 28 #include "http_client.h" 29 29 30 struct oauth_info; 31 30 32 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, 31 char* user, char* pass, char** arguments, int arguments_len);33 char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len); 32 34 33 35 #endif //_TWITTER_HTTP_H -
protocols/twitter/twitter_lib.c
r6a9d068 rf924563 105 105 if (!bee_user_by_handle( ic->bee, ic, name )) 106 106 { 107 char *mode = set_getstr(&ic->acc->set, "mode"); 108 107 109 // The buddy is not in the list, add the buddy and set the status to logged in. 108 110 imcb_add_buddy( ic, name, NULL ); 109 111 imcb_rename_buddy( ic, name, fullname ); 110 if ( set_getbool( &ic->acc->set, "use_groupchat" ))112 if (g_strcasecmp(mode, "chat") == 0) 111 113 imcb_chat_add_buddy( td->home_timeline_gc, name ); 112 else 114 else if (g_strcasecmp(mode, "many") == 0) 113 115 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 114 116 } … … 128 130 args[0] = "cursor"; 129 131 args[1] = g_strdup_printf ("%d", next_cursor); 130 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2);132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 131 133 132 134 g_free(args[1]); … … 394 396 } 395 397 396 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2);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); 397 399 398 400 g_free(args[1]); … … 452 454 GSList *l = NULL; 453 455 struct twitter_xml_status *status; 454 456 char from[MAX_STRING]; 457 gboolean mode_one; 458 459 mode_one = g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "one" ) == 0; 460 461 if( mode_one ) 462 { 463 g_snprintf( from, sizeof( from ) - 1, "twitter_%s", ic->acc->user ); 464 from[MAX_STRING-1] = '\0'; 465 } 466 455 467 for ( l = list; l ; l = g_slist_next(l) ) 456 468 { 469 char *text = NULL; 470 457 471 status = l->data; 458 imcb_buddy_msg( ic, status->user->screen_name, status->text, 0, status->created_at ); 472 473 if( mode_one ) 474 text = g_strdup_printf( "\002<\002%s\002>\002 %s", 475 status->user->screen_name, status->text ); 476 else 477 twitter_add_buddy(ic, status->user->screen_name, status->user->name); 478 479 imcb_buddy_msg( ic, 480 mode_one ? from : status->user->screen_name, 481 mode_one ? text : status->text, 482 0, status->created_at ); 483 459 484 // Update the home_timeline_id to hold the highest id, so that by the next request 460 485 // we won't pick up the updates allready in the list. 461 486 td->home_timeline_id = td->home_timeline_id < status->id ? status->id : td->home_timeline_id; 487 488 g_free( text ); 462 489 } 463 490 } … … 483 510 { 484 511 td->http_fails = 0; 485 if (! ic->flags & OPT_LOGGED_IN)512 if (!(ic->flags & OPT_LOGGED_IN)) 486 513 imcb_connected(ic); 487 514 } … … 512 539 513 540 // See if the user wants to see the messages in a groupchat window or as private messages. 514 if ( set_getbool( &ic->acc->set, "use_groupchat" ))541 if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) 515 542 twitter_groupchat(ic, txl->list); 516 543 else … … 593 620 args[1] = g_strdup_printf ("%d", next_cursor); 594 621 595 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2);622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2); 596 623 597 624 g_free(args[1]); … … 612 639 if (req->status_code != 200) { 613 640 // It didn't go well, output the error and return. 614 imcb_error(ic, "Could not post tweet... HTTP STATUS: %d", req->status_code);641 imcb_error(ic, "Could not post message... HTTP STATUS: %d", req->status_code); 615 642 return; 616 643 } … … 627 654 args[0] = "status"; 628 655 args[1] = msg; 629 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2);656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2); 630 657 // g_free(args[1]); 631 658 } … … 645 672 args[3] = msg; 646 673 // Use the same callback as for twitter_post_status, since it does basically the same. 647 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4);674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4); 648 675 // g_free(args[1]); 649 676 // g_free(args[3]);
Note: See TracChangeset
for help on using the changeset viewer.