Changes in protocols/twitter/twitter.c [6220254:7ceb6b2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
r6220254 r7ceb6b2 37 37 imcb_log( ic, fmt ); \ 38 38 } while( 0 ); 39 39 40 40 GSList *twitter_connections = NULL; 41 41 … … 46 46 { 47 47 struct im_connection *ic = data; 48 48 49 49 // Check if we are still logged in... 50 if (!g_slist_find( twitter_connections, ic))50 if (!g_slist_find(twitter_connections, ic)) 51 51 return 0; 52 52 … … 58 58 } 59 59 60 static void twitter_main_loop_start( struct im_connection *ic)60 static void twitter_main_loop_start(struct im_connection *ic) 61 61 { 62 62 struct twitter_data *td = ic->proto_data; 63 64 imcb_log( ic, "Getting initial statuses");63 64 imcb_log(ic, "Getting initial statuses"); 65 65 66 66 // Run this once. After this queue the main loop function. … … 72 72 } 73 73 74 static void twitter_oauth_start( struct im_connection *ic);75 76 void twitter_login_finish( struct im_connection *ic)74 static void twitter_oauth_start(struct im_connection *ic); 75 76 void twitter_login_finish(struct im_connection *ic) 77 77 { 78 78 struct twitter_data *td = ic->proto_data; 79 80 if( set_getbool( &ic->acc->set, "oauth" ) && !td->oauth_info ) 81 twitter_oauth_start( ic ); 82 else if( g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "one" ) != 0 && 83 !( td->flags & TWITTER_HAVE_FRIENDS ) ) 84 { 85 imcb_log( ic, "Getting contact list" ); 86 twitter_get_statuses_friends( ic, -1 ); 87 } 88 else 89 twitter_main_loop_start( ic ); 90 } 91 92 static const struct oauth_service twitter_oauth = 93 { 79 80 if (set_getbool(&ic->acc->set, "oauth") && !td->oauth_info) 81 twitter_oauth_start(ic); 82 else if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "one") != 0 && 83 !(td->flags & TWITTER_HAVE_FRIENDS)) { 84 imcb_log(ic, "Getting contact list"); 85 twitter_get_friends_ids(ic, -1); 86 //twitter_get_statuses_friends(ic, -1); 87 } else 88 twitter_main_loop_start(ic); 89 } 90 91 static const struct oauth_service twitter_oauth = { 94 92 "http://api.twitter.com/oauth/request_token", 95 93 "http://api.twitter.com/oauth/access_token", … … 99 97 }; 100 98 101 static const struct oauth_service identica_oauth = 102 { 99 static const struct oauth_service identica_oauth = { 103 100 "http://identi.ca/api/oauth/request_token", 104 101 "http://identi.ca/api/oauth/access_token", … … 108 105 }; 109 106 110 static gboolean twitter_oauth_callback( struct oauth_info *info);111 112 static const struct oauth_service *get_oauth_service( struct im_connection *ic)107 static gboolean twitter_oauth_callback(struct oauth_info *info); 108 109 static const struct oauth_service *get_oauth_service(struct im_connection *ic) 113 110 { 114 111 struct twitter_data *td = ic->proto_data; 115 116 if ( strstr( td->url_host, "identi.ca" ))112 113 if (strstr(td->url_host, "identi.ca")) 117 114 return &identica_oauth; 118 115 else 119 116 return &twitter_oauth; 120 117 121 118 /* Could add more services, or allow configuring your own base URL + 122 119 API keys. */ 123 120 } 124 121 125 static void twitter_oauth_start( struct im_connection *ic)122 static void twitter_oauth_start(struct im_connection *ic) 126 123 { 127 124 struct twitter_data *td = ic->proto_data; 128 129 imcb_log( ic, "Requesting OAuth request token");130 131 td->oauth_info = oauth_request_token( get_oauth_service( ic ), twitter_oauth_callback, ic);132 125 126 imcb_log(ic, "Requesting OAuth request token"); 127 128 td->oauth_info = oauth_request_token(get_oauth_service(ic), twitter_oauth_callback, ic); 129 133 130 /* We need help from the user to complete OAuth login, so don't time 134 131 out on this login. */ … … 136 133 } 137 134 138 static gboolean twitter_oauth_callback( struct oauth_info *info)135 static gboolean twitter_oauth_callback(struct oauth_info *info) 139 136 { 140 137 struct im_connection *ic = info->data; 141 138 struct twitter_data *td; 142 143 if ( !g_slist_find( twitter_connections, ic ))139 140 if (!g_slist_find(twitter_connections, ic)) 144 141 return FALSE; 145 142 146 143 td = ic->proto_data; 147 if( info->stage == OAUTH_REQUEST_TOKEN ) 148 { 149 char name[strlen(ic->acc->user)+9], *msg; 150 151 if( info->request_token == NULL ) 152 { 153 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 154 imc_logout( ic, TRUE ); 144 if (info->stage == OAUTH_REQUEST_TOKEN) { 145 char name[strlen(ic->acc->user) + 9], *msg; 146 147 if (info->request_token == NULL) { 148 imcb_error(ic, "OAuth error: %s", twitter_parse_error(info->http)); 149 imc_logout(ic, TRUE); 155 150 return FALSE; 156 151 } 157 158 sprintf( name, "%s_%s", td->prefix, ic->acc->user ); 159 msg = g_strdup_printf( "To finish OAuth authentication, please visit " 160 "%s and respond with the resulting PIN code.", 161 info->auth_url ); 162 imcb_buddy_msg( ic, name, msg, 0, 0 ); 163 g_free( msg ); 164 } 165 else if( info->stage == OAUTH_ACCESS_TOKEN ) 166 { 167 if( info->token == NULL || info->token_secret == NULL ) 168 { 169 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 170 imc_logout( ic, TRUE ); 152 153 sprintf(name, "%s_%s", td->prefix, ic->acc->user); 154 msg = g_strdup_printf("To finish OAuth authentication, please visit " 155 "%s and respond with the resulting PIN code.", 156 info->auth_url); 157 imcb_buddy_msg(ic, name, msg, 0, 0); 158 g_free(msg); 159 } else if (info->stage == OAUTH_ACCESS_TOKEN) { 160 if (info->token == NULL || info->token_secret == NULL) { 161 imcb_error(ic, "OAuth error: %s", twitter_parse_error(info->http)); 162 imc_logout(ic, TRUE); 171 163 return FALSE; 164 } else { 165 const char *sn = oauth_params_get(&info->params, "screen_name"); 166 167 if (sn != NULL && ic->acc->prpl->handle_cmp(sn, ic->acc->user) != 0) { 168 imcb_log(ic, "Warning: You logged in via OAuth as %s " 169 "instead of %s.", sn, ic->acc->user); 170 } 171 g_free(td->user); 172 td->user = g_strdup(sn); 172 173 } 173 else 174 { 175 const char *sn = oauth_params_get( &info->params, "screen_name" ); 176 177 if( sn != NULL && ic->acc->prpl->handle_cmp( sn, ic->acc->user ) != 0 ) 178 { 179 imcb_log( ic, "Warning: You logged in via OAuth as %s " 180 "instead of %s.", sn, ic->acc->user ); 181 } 182 } 183 174 184 175 /* IM mods didn't do this so far and it's ugly but I should 185 176 be able to get away with it... */ 186 g_free( ic->acc->pass);187 ic->acc->pass = oauth_to_string( info);188 189 twitter_login_finish( ic);190 } 191 177 g_free(ic->acc->pass); 178 ic->acc->pass = oauth_to_string(info); 179 180 twitter_login_finish(ic); 181 } 182 192 183 return TRUE; 193 184 } 194 185 195 186 196 static char *set_eval_mode( set_t *set, char *value ) 197 { 198 if( g_strcasecmp( value, "one" ) == 0 || 199 g_strcasecmp( value, "many" ) == 0 || 200 g_strcasecmp( value, "chat" ) == 0 ) 187 static char *set_eval_mode(set_t * set, char *value) 188 { 189 if (g_strcasecmp(value, "one") == 0 || 190 g_strcasecmp(value, "many") == 0 || g_strcasecmp(value, "chat") == 0) 201 191 return value; 202 192 else … … 204 194 } 205 195 206 static gboolean twitter_length_check( struct im_connection *ic, gchar *msg)207 { 208 int max = set_getint( &ic->acc->set, "message_length"), len;209 210 if ( max == 0 || ( len = g_utf8_strlen( msg, -1 ) ) <= max)196 static gboolean twitter_length_check(struct im_connection *ic, gchar * msg) 197 { 198 int max = set_getint(&ic->acc->set, "message_length"), len; 199 200 if (max == 0 || (len = g_utf8_strlen(msg, -1)) <= max) 211 201 return TRUE; 212 213 imcb_error( ic, "Maximum message length exceeded: %d > %d", len, max);214 202 203 imcb_error(ic, "Maximum message length exceeded: %d > %d", len, max); 204 215 205 return FALSE; 216 206 } 217 207 218 static void twitter_init( account_t *acc)208 static void twitter_init(account_t * acc) 219 209 { 220 210 set_t *s; 221 211 char *def_url; 222 212 char *def_oauth; 223 224 if( strcmp( acc->prpl->name, "twitter" ) == 0 ) 225 { 213 214 if (strcmp(acc->prpl->name, "twitter") == 0) { 226 215 def_url = TWITTER_API_URL; 227 216 def_oauth = "true"; 228 } 229 else /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */ 230 { 217 } else { /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */ 218 231 219 def_url = IDENTICA_API_URL; 232 220 def_oauth = "false"; 233 221 } 234 235 s = set_add( &acc->set, "auto_reply_timeout", "10800", set_eval_int, acc);236 237 s = set_add( &acc->set, "base_url", def_url, NULL, acc);222 223 s = set_add(&acc->set, "auto_reply_timeout", "10800", set_eval_int, acc); 224 225 s = set_add(&acc->set, "base_url", def_url, NULL, acc); 238 226 s->flags |= ACC_SET_OFFLINE_ONLY; 239 240 s = set_add( &acc->set, "commands", "true", set_eval_bool, acc);241 242 s = set_add( &acc->set, "message_length", "140", set_eval_int, acc);243 244 s = set_add( &acc->set, "mode", "chat", set_eval_mode, acc);227 228 s = set_add(&acc->set, "commands", "true", set_eval_bool, acc); 229 230 s = set_add(&acc->set, "message_length", "140", set_eval_int, acc); 231 232 s = set_add(&acc->set, "mode", "chat", set_eval_mode, acc); 245 233 s->flags |= ACC_SET_OFFLINE_ONLY; 246 247 s = set_add( &acc->set, "show_ids", "false", set_eval_bool, acc);234 235 s = set_add(&acc->set, "show_ids", "false", set_eval_bool, acc); 248 236 s->flags |= ACC_SET_OFFLINE_ONLY; 249 250 s = set_add( &acc->set, "oauth", def_oauth, set_eval_bool, acc);237 238 s = set_add(&acc->set, "oauth", def_oauth, set_eval_bool, acc); 251 239 } 252 240 … … 255 243 * only save the user and pass to the twitter_data object. 256 244 */ 257 static void twitter_login( account_t *acc)258 { 259 struct im_connection *ic = imcb_new( acc);245 static void twitter_login(account_t * acc) 246 { 247 struct im_connection *ic = imcb_new(acc); 260 248 struct twitter_data *td; 261 char name[strlen(acc->user) +9];249 char name[strlen(acc->user) + 9]; 262 250 url_t url; 263 264 if( !url_set( &url, set_getstr( &ic->acc->set, "base_url" ) ) ||265 ( url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS ) )266 {267 imcb_error( ic, "Incorrect API base URL: %s", set_getstr( &ic->acc->set, "base_url" ));268 imc_logout( ic, FALSE);251 char *s; 252 253 if (!url_set(&url, set_getstr(&ic->acc->set, "base_url")) || 254 (url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS)) { 255 imcb_error(ic, "Incorrect API base URL: %s", set_getstr(&ic->acc->set, "base_url")); 256 imc_logout(ic, FALSE); 269 257 return; 270 258 } 271 272 twitter_connections = g_slist_append( twitter_connections, ic ); 273 td = g_new0( struct twitter_data, 1 ); 259 260 imcb_log(ic, "Connecting"); 261 262 twitter_connections = g_slist_append(twitter_connections, ic); 263 td = g_new0(struct twitter_data, 1); 274 264 ic->proto_data = td; 275 265 td->user = g_strdup(acc->user); 266 276 267 td->url_ssl = url.proto == PROTO_HTTPS; 277 268 td->url_port = url.port; 278 td->url_host = g_strdup( url.host ); 279 if( strcmp( url.file, "/" ) != 0 ) 280 td->url_path = g_strdup( url.file ); 281 else 282 td->url_path = g_strdup( "" ); 283 if( g_str_has_suffix( url.host, ".com" ) ) 284 td->prefix = g_strndup( url.host, strlen( url.host ) - 4 ); 285 else 286 td->prefix = g_strdup( url.host ); 269 td->url_host = g_strdup(url.host); 270 if (strcmp(url.file, "/") != 0) 271 td->url_path = g_strdup(url.file); 272 else { 273 td->url_path = g_strdup(""); 274 if (g_str_has_suffix(url.host, "twitter.com")) 275 /* May fire for people who turned on HTTPS. */ 276 imcb_error(ic, "Warning: Twitter requires a version number in API calls " 277 "now. Try resetting the base_url account setting."); 278 } 287 279 288 td->user = acc->user; 289 if( strstr( acc->pass, "oauth_token=" ) ) 290 td->oauth_info = oauth_from_string( acc->pass, get_oauth_service( ic ) ); 280 /* Hacky string mangling: Turn identi.ca into identi.ca and api.twitter.com 281 into twitter, and try to be sensible if we get anything else. */ 282 td->prefix = g_strdup(url.host); 283 if (g_str_has_suffix(td->prefix, ".com")) 284 td->prefix[strlen(url.host) - 4] = '\0'; 285 if ((s = strrchr(td->prefix, '.')) && strlen(s) > 4) { 286 /* If we have at least 3 chars after the last dot, cut off the rest. 287 (mostly a www/api prefix or sth) */ 288 s = g_strdup(s + 1); 289 g_free(td->prefix); 290 td->prefix = s; 291 } 291 292 292 sprintf( name, "%s_%s", td->prefix, acc->user ); 293 imcb_add_buddy( ic, name, NULL ); 294 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 295 296 if( set_getbool( &acc->set, "show_ids" ) ) 297 td->log = g_new0( struct twitter_log_data, TWITTER_LOG_LENGTH ); 298 299 imcb_log( ic, "Connecting" ); 300 301 twitter_login_finish( ic ); 293 if (strstr(acc->pass, "oauth_token=")) 294 td->oauth_info = oauth_from_string(acc->pass, get_oauth_service(ic)); 295 296 sprintf(name, "%s_%s", td->prefix, acc->user); 297 imcb_add_buddy(ic, name, NULL); 298 imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL); 299 300 if (set_getbool(&acc->set, "show_ids")) 301 td->log = g_new0(struct twitter_log_data, TWITTER_LOG_LENGTH); 302 303 twitter_login_finish(ic); 302 304 } 303 305 … … 305 307 * Logout method. Just free the twitter_data. 306 308 */ 307 static void twitter_logout( struct im_connection *ic)309 static void twitter_logout(struct im_connection *ic) 308 310 { 309 311 struct twitter_data *td = ic->proto_data; 310 312 311 313 // Set the status to logged out. 312 ic->flags &= ~ 314 ic->flags &= ~OPT_LOGGED_IN; 313 315 314 316 // Remove the main_loop function from the function queue. 315 317 b_event_remove(td->main_loop_id); 316 318 317 if (td->home_timeline_gc)319 if (td->home_timeline_gc) 318 320 imcb_chat_free(td->home_timeline_gc); 319 321 320 if( td ) 321 { 322 oauth_info_free( td->oauth_info ); 323 g_free( td->prefix ); 324 g_free( td->url_host ); 325 g_free( td->url_path ); 326 g_free( td->pass ); 327 g_free( td->log ); 328 g_free( td ); 329 } 330 331 twitter_connections = g_slist_remove( twitter_connections, ic ); 332 } 333 334 static void twitter_handle_command( struct im_connection *ic, char *message ); 322 if (td) { 323 oauth_info_free(td->oauth_info); 324 g_free(td->user); 325 g_free(td->prefix); 326 g_free(td->url_host); 327 g_free(td->url_path); 328 g_free(td->log); 329 g_free(td); 330 } 331 332 twitter_connections = g_slist_remove(twitter_connections, ic); 333 } 334 335 static void twitter_handle_command(struct im_connection *ic, char *message); 335 336 336 337 /** 337 338 * 338 339 */ 339 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away)340 static int twitter_buddy_msg(struct im_connection *ic, char *who, char *message, int away) 340 341 { 341 342 struct twitter_data *td = ic->proto_data; 342 int plen = strlen( td->prefix);343 343 int plen = strlen(td->prefix); 344 344 345 if (g_strncasecmp(who, td->prefix, plen) == 0 && who[plen] == '_' && 345 g_strcasecmp(who + plen + 1, ic->acc->user) == 0) 346 { 347 if( set_getbool( &ic->acc->set, "oauth" ) && 348 td->oauth_info && td->oauth_info->token == NULL ) 349 { 350 char pin[strlen(message)+1], *s; 351 352 strcpy( pin, message ); 353 for( s = pin + sizeof( pin ) - 2; s > pin && isspace( *s ); s -- ) 346 g_strcasecmp(who + plen + 1, ic->acc->user) == 0) { 347 if (set_getbool(&ic->acc->set, "oauth") && 348 td->oauth_info && td->oauth_info->token == NULL) { 349 char pin[strlen(message) + 1], *s; 350 351 strcpy(pin, message); 352 for (s = pin + sizeof(pin) - 2; s > pin && isspace(*s); s--) 354 353 *s = '\0'; 355 for( s = pin; *s && isspace( *s ); s ++ ) {} 356 357 if( !oauth_access_token( s, td->oauth_info ) ) 358 { 359 imcb_error( ic, "OAuth error: %s", "Failed to send access token request" ); 360 imc_logout( ic, TRUE ); 354 for (s = pin; *s && isspace(*s); s++) { 355 } 356 357 if (!oauth_access_token(s, td->oauth_info)) { 358 imcb_error(ic, "OAuth error: %s", 359 "Failed to send access token request"); 360 imc_logout(ic, TRUE); 361 361 return FALSE; 362 362 } 363 } 364 else 363 } else 365 364 twitter_handle_command(ic, message); 366 } 367 else 368 { 365 } else { 369 366 twitter_direct_messages_new(ic, who, message); 370 367 } 371 return ( 0);368 return (0); 372 369 } 373 370 … … 375 372 * 376 373 */ 377 static void twitter_set_my_name( struct im_connection *ic, char *info)378 { 379 } 380 381 static void twitter_get_info(struct im_connection *ic, char *who) 382 { 383 } 384 385 static void twitter_add_buddy( struct im_connection *ic, char *who, char *group)374 static void twitter_set_my_name(struct im_connection *ic, char *info) 375 { 376 } 377 378 static void twitter_get_info(struct im_connection *ic, char *who) 379 { 380 } 381 382 static void twitter_add_buddy(struct im_connection *ic, char *who, char *group) 386 383 { 387 384 twitter_friendships_create_destroy(ic, who, 1); 388 385 } 389 386 390 static void twitter_remove_buddy( struct im_connection *ic, char *who, char *group)387 static void twitter_remove_buddy(struct im_connection *ic, char *who, char *group) 391 388 { 392 389 twitter_friendships_create_destroy(ic, who, 0); 393 390 } 394 391 395 static void twitter_chat_msg( struct groupchat *c, char *message, int flags)396 { 397 if ( c && message)398 twitter_handle_command( c->ic, message);399 } 400 401 static void twitter_chat_invite( struct groupchat *c, char *who, char *message)402 { 403 } 404 405 static void twitter_chat_leave( struct groupchat *c)392 static void twitter_chat_msg(struct groupchat *c, char *message, int flags) 393 { 394 if (c && message) 395 twitter_handle_command(c->ic, message); 396 } 397 398 static void twitter_chat_invite(struct groupchat *c, char *who, char *message) 399 { 400 } 401 402 static void twitter_chat_leave(struct groupchat *c) 406 403 { 407 404 struct twitter_data *td = c->ic->proto_data; 408 409 if ( c != td->home_timeline_gc)410 return; 411 405 406 if (c != td->home_timeline_gc) 407 return; /* WTF? */ 408 412 409 /* If the user leaves the channel: Fine. Rejoin him/her once new 413 410 tweets come in. */ … … 416 413 } 417 414 418 static void twitter_keepalive( struct im_connection *ic)419 { 420 } 421 422 static void twitter_add_permit( struct im_connection *ic, char *who)423 { 424 } 425 426 static void twitter_rem_permit( struct im_connection *ic, char *who)427 { 428 } 429 430 static void twitter_add_deny( struct im_connection *ic, char *who)431 { 432 } 433 434 static void twitter_rem_deny( struct im_connection *ic, char *who)415 static void twitter_keepalive(struct im_connection *ic) 416 { 417 } 418 419 static void twitter_add_permit(struct im_connection *ic, char *who) 420 { 421 } 422 423 static void twitter_rem_permit(struct im_connection *ic, char *who) 424 { 425 } 426 427 static void twitter_add_deny(struct im_connection *ic, char *who) 428 { 429 } 430 431 static void twitter_rem_deny(struct im_connection *ic, char *who) 435 432 { 436 433 } … … 438 435 //static char *twitter_set_display_name( set_t *set, char *value ) 439 436 //{ 440 // 437 // return value; 441 438 //} 442 439 443 static void twitter_buddy_data_add( struct bee_user *bu)444 { 445 bu->data = g_new0( struct twitter_user_data, 1);446 } 447 448 static void twitter_buddy_data_free( struct bee_user *bu)449 { 450 g_free( bu->data);451 } 452 453 static void twitter_handle_command( struct im_connection *ic, char *message)440 static void twitter_buddy_data_add(struct bee_user *bu) 441 { 442 bu->data = g_new0(struct twitter_user_data, 1); 443 } 444 445 static void twitter_buddy_data_free(struct bee_user *bu) 446 { 447 g_free(bu->data); 448 } 449 450 static void twitter_handle_command(struct im_connection *ic, char *message) 454 451 { 455 452 struct twitter_data *td = ic->proto_data; 456 453 char *cmds, **cmd, *new = NULL; 457 454 guint64 in_reply_to = 0; 458 459 cmds = g_strdup( message ); 460 cmd = split_command_parts( cmds ); 461 462 if( cmd[0] == NULL ) 463 { 464 g_free( cmds ); 455 456 cmds = g_strdup(message); 457 cmd = split_command_parts(cmds); 458 459 if (cmd[0] == NULL) { 460 g_free(cmds); 465 461 return; 466 } 467 else if( !set_getbool( &ic->acc->set, "commands" ) ) 468 { 462 } else if (!set_getbool(&ic->acc->set, "commands")) { 469 463 /* Not supporting commands. */ 470 } 471 else if( g_strcasecmp( cmd[0], "undo" ) == 0 ) 472 { 464 } else if (g_strcasecmp(cmd[0], "undo") == 0) { 473 465 guint64 id; 474 475 if ( cmd[1])476 id = g_ascii_strtoull( cmd[1], NULL, 10);466 467 if (cmd[1]) 468 id = g_ascii_strtoull(cmd[1], NULL, 10); 477 469 else 478 470 id = td->last_status_id; 479 471 480 472 /* TODO: User feedback. */ 481 if ( id)482 twitter_status_destroy( ic, id);473 if (id) 474 twitter_status_destroy(ic, id); 483 475 else 484 twitter_msg( ic, "Could not undo last action");485 486 g_free( cmds);476 twitter_msg(ic, "Could not undo last action"); 477 478 g_free(cmds); 487 479 return; 488 } 489 else if( g_strcasecmp( cmd[0], "follow" ) == 0 && cmd[1] ) 490 { 491 twitter_add_buddy( ic, cmd[1], NULL ); 492 g_free( cmds ); 480 } else if (g_strcasecmp(cmd[0], "follow") == 0 && cmd[1]) { 481 twitter_add_buddy(ic, cmd[1], NULL); 482 g_free(cmds); 493 483 return; 494 } 495 else if( g_strcasecmp( cmd[0], "unfollow" ) == 0 && cmd[1] ) 496 { 497 twitter_remove_buddy( ic, cmd[1], NULL ); 498 g_free( cmds ); 484 } else if (g_strcasecmp(cmd[0], "unfollow") == 0 && cmd[1]) { 485 twitter_remove_buddy(ic, cmd[1], NULL); 486 g_free(cmds); 499 487 return; 500 } 501 else if( g_strcasecmp( cmd[0], "rt" ) == 0 && cmd[1] ) 502 { 488 } else if (g_strcasecmp(cmd[0], "rt") == 0 && cmd[1]) { 503 489 struct twitter_user_data *tud; 504 490 bee_user_t *bu; 505 491 guint64 id; 506 507 if ( ( bu = bee_user_by_handle( ic->bee, ic, cmd[1] )) &&508 ( tud = bu->data ) && tud->last_id)492 493 if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) && 494 (tud = bu->data) && tud->last_id) 509 495 id = tud->last_id; 510 else 511 { 512 id = g_ascii_strtoull( cmd[1], NULL, 10 ); 513 if( id < TWITTER_LOG_LENGTH && td->log ) 496 else { 497 id = g_ascii_strtoull(cmd[1], NULL, 10); 498 if (id < TWITTER_LOG_LENGTH && td->log) 514 499 id = td->log[id].id; 515 500 } 516 501 517 502 td->last_status_id = 0; 518 if ( id)519 twitter_status_retweet( ic, id);503 if (id) 504 twitter_status_retweet(ic, id); 520 505 else 521 twitter_msg( 522 "post any statuses recently", cmd[1]);523 524 g_free( cmds);506 twitter_msg(ic, "User `%s' does not exist or didn't " 507 "post any statuses recently", cmd[1]); 508 509 g_free(cmds); 525 510 return; 526 } 527 else if( g_strcasecmp( cmd[0], "reply" ) == 0 && cmd[1] && cmd[2] ) 528 { 511 } else if (g_strcasecmp(cmd[0], "reply") == 0 && cmd[1] && cmd[2]) { 529 512 struct twitter_user_data *tud; 530 513 bee_user_t *bu = NULL; 531 514 guint64 id = 0; 532 533 if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[1] ) ) && 534 ( tud = bu->data ) && tud->last_id ) 535 { 515 516 if ((bu = bee_user_by_handle(ic->bee, ic, cmd[1])) && 517 (tud = bu->data) && tud->last_id) { 536 518 id = tud->last_id; 537 } 538 else if( ( id = g_ascii_strtoull( cmd[1], NULL, 10 ) ) && 539 ( id < TWITTER_LOG_LENGTH ) && td->log ) 540 { 519 } else if (sscanf(cmd[1], "%" G_GUINT64_FORMAT, &id) == 1 && 520 (id < TWITTER_LOG_LENGTH) && td->log) { 541 521 bu = td->log[id].bu; 542 if ( g_slist_find( ic->bee->users, bu ))522 if (g_slist_find(ic->bee->users, bu)) 543 523 id = td->log[id].id; 544 524 else 545 525 bu = NULL; 546 526 } 547 if( !id || !bu ) 548 { 549 twitter_msg( ic, "User `%s' does not exist or didn't " 550 "post any statuses recently", cmd[1] ); 527 if (!id || !bu) { 528 twitter_msg(ic, "User `%s' does not exist or didn't " 529 "post any statuses recently", cmd[1]); 551 530 return; 552 531 } 553 message = new = g_strdup_printf( "@%s %s", bu->handle, 554 message + ( cmd[2] - cmd[0] ) ); 532 message = new = g_strdup_printf("@%s %s", bu->handle, message + (cmd[2] - cmd[0])); 555 533 in_reply_to = id; 556 } 557 else if( g_strcasecmp( cmd[0], "post" ) == 0 ) 558 { 534 } else if (g_strcasecmp(cmd[0], "post") == 0) { 559 535 message += 5; 560 536 } 561 537 562 538 { 563 539 char *s; 564 540 bee_user_t *bu; 565 566 if( !twitter_length_check( ic, message ) ) 567 { 568 g_free( new ); 569 g_free( cmds ); 570 return; 541 542 if (!twitter_length_check(ic, message)) { 543 g_free(new); 544 g_free(cmds); 545 return; 571 546 } 572 573 s = cmd[0] + strlen( cmd[0] ) - 1; 574 if( !new && s > cmd[0] && ( *s == ':' || *s == ',' ) ) 575 { 547 548 s = cmd[0] + strlen(cmd[0]) - 1; 549 if (!new && s > cmd[0] && (*s == ':' || *s == ',')) { 576 550 *s = '\0'; 577 578 if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[0] ) ) ) 579 { 551 552 if ((bu = bee_user_by_handle(ic->bee, ic, cmd[0]))) { 580 553 struct twitter_user_data *tud = bu->data; 581 582 new = g_strdup_printf( 583 message + ( s - cmd[0] ) + 2);554 555 new = g_strdup_printf("@%s %s", bu->handle, 556 message + (s - cmd[0]) + 2); 584 557 message = new; 585 586 if ( time( NULL) < tud->last_time +587 set_getint( &ic->acc->set, "auto_reply_timeout" ))558 559 if (time(NULL) < tud->last_time + 560 set_getint(&ic->acc->set, "auto_reply_timeout")) 588 561 in_reply_to = tud->last_id; 589 562 } 590 563 } 591 564 592 565 /* If the user runs undo between this request and its response 593 566 this would delete the second-last Tweet. Prevent that. */ 594 567 td->last_status_id = 0; 595 twitter_post_status( ic, message, in_reply_to);596 g_free( new);597 } 598 g_free( cmds);568 twitter_post_status(ic, message, in_reply_to); 569 g_free(new); 570 } 571 g_free(cmds); 599 572 } 600 573 … … 602 575 { 603 576 struct prpl *ret = g_new0(struct prpl, 1); 604 577 605 578 ret->options = OPT_NOOTR; 606 579 ret->name = "twitter"; … … 624 597 ret->buddy_data_free = twitter_buddy_data_free; 625 598 ret->handle_cmp = g_strcasecmp; 626 599 627 600 register_protocol(ret); 628 601
Note: See TracChangeset
for help on using the changeset viewer.