Changeset 62d2cfb
- Timestamp:
- 2010-03-25T21:31:27Z (15 years ago)
- Branches:
- master
- Children:
- 2abceca
- Parents:
- b4dd253
- Location:
- protocols/twitter
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
rb4dd253 r62d2cfb 29 29 30 30 /** 31 * *Main loop function32 * */31 * Main loop function 32 */ 33 33 gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond) 34 34 { … … 38 38 return 0; 39 39 40 // If the user uses multiple private message windows we need to get the 41 // users buddies. 42 if (!set_getbool( &ic->acc->set, "use_groupchat" )) 43 twitter_get_statuses_friends(ic, -1); 44 40 45 // Do stuff.. 41 46 twitter_get_home_timeline(ic, -1); … … 48 53 static void twitter_init( account_t *acc ) 49 54 { 55 set_t *s; 56 s = set_add( &acc->set, "use_groupchat", "false", set_eval_bool, acc ); 50 57 } 51 58 … … 58 65 struct im_connection *ic = imcb_new( acc ); 59 66 struct twitter_data *td = g_new0( struct twitter_data, 1 ); 60 67 61 68 td->user = acc->user; 62 69 td->pass = acc->pass; … … 68 75 ic->flags = OPT_LOGGED_IN; 69 76 70 // Try to get the buddies...71 //twitter_get_friends_ids(ic, -1);72 73 //twitter_get_home_timeline(ic, -1);74 75 77 // Run this once. After this queue the main loop function. 76 78 twitter_main_loop(ic, -1, 0); … … 81 83 imcb_log( ic, "Connecting to twitter" ); 82 84 imcb_connected(ic); 85 86 twitter_connections = g_slist_append( twitter_connections, ic ); 83 87 } 84 88 … … 97 101 g_free( td ); 98 102 } 103 104 twitter_connections = g_slist_remove( twitter_connections, ic ); 99 105 } 100 106 … … 104 110 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) 105 111 { 106 imcb_log( ic, "In twitter_buddy_msg..."); 107 twitter_post_status(ic, message); 112 // Let's just update the status. 113 // if ( g_strcasecmp(who, ic->acc->user) == 0 ) 114 twitter_post_status(ic, message); 115 // else 116 // twitter_direct_messages_new(ic, who, message); 108 117 return( 0 ); 109 118 } … … 124 133 static void twitter_set_my_name( struct im_connection *ic, char *info ) 125 134 { 126 imcb_log( ic, "In twitter_set_my_name..." );127 // char * aap = twitter_http("http://gertje.org", NULL, ic, 1, "geert", "poep", NULL, 0);128 129 // imcb_log( ic, aap );130 // g_free(aap);131 135 } 132 136 … … 218 222 219 223 register_protocol(ret); 220 } 221 224 225 // Initialise the twitter_connections GSList. 226 twitter_connections = NULL; 227 } 228 -
protocols/twitter/twitter.h
rb4dd253 r62d2cfb 41 41 }; 42 42 43 /** 44 * This has the same function as the msn_connections GSList. We use this to 45 * make sure the connection is still alive in callbacks before we do anything 46 * else. 47 */ 48 GSList *twitter_connections; 49 43 50 #endif //_TWITTER_H -
protocols/twitter/twitter_lib.c
rb4dd253 r62d2cfb 34 34 35 35 #define TXL_STATUS 1 36 #define TXL_ID 1 36 #define TXL_USER 2 37 #define TXL_ID 3 38 39 static void twitter_imcb_chat_msg( struct groupchat *c, char *who, char *msg, uint32_t flags, time_t sent_at ); 37 40 38 41 struct twitter_xml_list { 42 int type; 39 43 int next_cursor; 40 44 GSList *list; … … 54 58 }; 55 59 56 void txl_free(struct twitter_xml_list *txl, int type); 57 void txs_free(struct twitter_xml_status *txs); 58 void txu_free(struct twitter_xml_user *txu); 60 /** 61 * Frees a twitter_xml_user struct. 62 */ 63 static void txu_free(struct twitter_xml_user *txu) 64 { 65 g_free(txu->name); 66 g_free(txu->screen_name); 67 } 68 69 70 /** 71 * Frees a twitter_xml_status struct. 72 */ 73 static void txs_free(struct twitter_xml_status *txs) 74 { 75 g_free(txs->created_at); 76 g_free(txs->text); 77 txu_free(txs->user); 78 } 79 80 /** 81 * Free a twitter_xml_list struct. 82 * type is the type of list the struct holds. 83 */ 84 static void txl_free(struct twitter_xml_list *txl) 85 { 86 GSList *l; 87 for ( l = txl->list; l ; l = g_slist_next(l) ) 88 if (txl->type == TXL_STATUS) 89 txs_free((struct twitter_xml_status *)l->data); 90 else if (txl->type == TXL_ID) 91 g_free(l->data); 92 g_slist_free(txl->list); 93 } 94 95 /** 96 * Add a buddy if it is not allready added, set the status to logged in. 97 */ 98 static void twitter_add_buddy(struct im_connection *ic, char *name) 99 { 100 // Check if the buddy is allready in the buddy list. 101 if (!user_findhandle( ic, name )) 102 { 103 // The buddy is not in the list, add the buddy and set the status to logged in. 104 imcb_add_buddy( ic, name, NULL ); 105 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 106 } 107 } 59 108 60 109 static void twitter_http_get_friends_ids(struct http_request *req); … … 93 142 { 94 143 struct xt_node *child; 144 145 // Set the list type. 146 txl->type = TXL_ID; 95 147 96 148 // The root <statuses> node should hold the list of statuses <status> … … 122 174 123 175 ic = req->data; 176 177 // Check if the connection is still active. 178 if( !g_slist_find( twitter_connections, ic ) ) 179 return; 124 180 125 181 // Check if the HTTP request went well. … … 142 198 twitter_get_friends_ids(ic, txl->next_cursor); 143 199 144 txl_free(txl , TXL_ID);200 txl_free(txl); 145 201 g_free(txl); 146 202 } … … 170 226 return XT_HANDLED; 171 227 } 228 229 /** 230 * Function to fill a twitter_xml_list struct. 231 * It sets: 232 * - all <user>s from the <users> element. 233 */ 234 static xt_status twitter_xt_get_users( struct xt_node *node, struct twitter_xml_list *txl ) 235 { 236 struct twitter_xml_user *txu; 237 struct xt_node *child; 238 239 // Set the type of the list. 240 txl->type = TXL_USER; 241 242 // The root <users> node should hold the list of users <user> 243 // Walk over the nodes children. 244 for( child = node->children ; child ; child = child->next ) 245 { 246 if ( g_strcasecmp( "user", child->name ) == 0) 247 { 248 txu = g_new0(struct twitter_xml_user, 1); 249 twitter_xt_get_user(child, txu); 250 // Put the item in the front of the list. 251 txl->list = g_slist_prepend (txl->list, txu); 252 } 253 } 254 255 return XT_HANDLED; 256 } 257 258 /** 259 * Function to fill a twitter_xml_list struct. 260 * It calls twitter_xt_get_users to get the <user>s from a <users> element. 261 * It sets: 262 * - the next_cursor. 263 */ 264 static xt_status twitter_xt_get_user_list( struct xt_node *node, struct twitter_xml_list *txl ) 265 { 266 struct xt_node *child; 267 268 // Set the type of the list. 269 txl->type = TXL_USER; 270 271 // The root <user_list> node should hold a users <users> element 272 // Walk over the nodes children. 273 for( child = node->children ; child ; child = child->next ) 274 { 275 if ( g_strcasecmp( "users", child->name ) == 0) 276 { 277 twitter_xt_get_users(child, txl); 278 } 279 else if ( g_strcasecmp( "next_cursor", child->name ) == 0) 280 { 281 twitter_xt_next_cursor(child, txl); 282 } 283 } 284 285 return XT_HANDLED; 286 } 287 172 288 173 289 /** … … 218 334 struct xt_node *child; 219 335 336 // Set the type of the list. 337 txl->type = TXL_STATUS; 338 220 339 // The root <statuses> node should hold the list of statuses <status> 221 340 // Walk over the nodes children. … … 264 383 265 384 /** 385 * Function that is called to see the statuses in a groupchat window. 386 */ 387 static void twitter_groupchat(struct im_connection *ic, GSList *list) 388 { 389 struct twitter_data *td = ic->proto_data; 390 GSList *l = NULL; 391 struct twitter_xml_status *status; 392 struct groupchat *gc; 393 394 // Create a new groupchat if it does not exsist. 395 if (!td->home_timeline_gc) 396 { 397 td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); 398 // Add the current user to the chat... 399 imcb_chat_add_buddy( gc, ic->acc->user ); 400 } 401 else 402 { 403 gc = td->home_timeline_gc; 404 } 405 406 for ( l = list; l ; l = g_slist_next(l) ) 407 { 408 status = l->data; 409 twitter_add_buddy(ic, status->user->screen_name); 410 // Say it! 411 twitter_imcb_chat_msg (gc, status->user->screen_name, status->text, 0, 0 ); 412 // Update the home_timeline_id to hold the highest id, so that by the next request 413 // we won't pick up the updates allready in the list. 414 td->home_timeline_id = td->home_timeline_id < status->id ? status->id : td->home_timeline_id; 415 } 416 } 417 418 /** 419 * Function that is called to see statuses as private messages. 420 */ 421 static void twitter_private_message_chat(struct im_connection *ic, GSList *list) 422 { 423 struct twitter_data *td = ic->proto_data; 424 GSList *l = NULL; 425 struct twitter_xml_status *status; 426 427 for ( l = list; l ; l = g_slist_next(l) ) 428 { 429 status = l->data; 430 imcb_buddy_msg( ic, status->user->screen_name, status->text, 0, 0 ); 431 // Update the home_timeline_id to hold the highest id, so that by the next request 432 // we won't pick up the updates allready in the list. 433 td->home_timeline_id = td->home_timeline_id < status->id ? status->id : td->home_timeline_id; 434 } 435 } 436 437 /** 266 438 * Callback for getting the home timeline. 267 439 */ 268 440 static void twitter_http_get_home_timeline(struct http_request *req) 269 441 { 270 struct im_connection *ic = req->data; ;442 struct im_connection *ic = req->data; 271 443 struct xt_parser *parser; 272 444 struct twitter_xml_list *txl; 273 struct twitter_data *td = ic->proto_data; 274 struct groupchat *gc; 445 446 // Check if the connection is still active. 447 if( !g_slist_find( twitter_connections, ic ) ) 448 return; 275 449 276 450 // Check if the HTTP request went well. … … 283 457 txl = g_new0(struct twitter_xml_list, 1); 284 458 txl->list = NULL; 285 459 286 460 // Parse the data. 287 461 parser = xt_new( NULL, txl ); … … 290 464 twitter_xt_get_status_list(parser->root, txl); 291 465 xt_free( parser ); 292 293 GSList *l; 294 struct twitter_xml_status *status; 295 296 // Create a new groupchat if it does not exsist. 297 if (!td->home_timeline_gc) 298 { 299 td->home_timeline_gc = gc = imcb_chat_new( ic, "home/timeline" ); 300 // Add the current user to the chat... 301 imcb_chat_add_buddy( gc, ic->acc->user ); 302 } 466 467 // See if the user wants to see the messages in a groupchat window or as private messages. 468 if (set_getbool( &ic->acc->set, "use_groupchat" )) 469 twitter_groupchat(ic, txl->list); 303 470 else 304 { 305 gc = td->home_timeline_gc; 306 } 307 471 twitter_private_message_chat(ic, txl->list); 472 473 // Free the structure. 474 txl_free(txl); 475 g_free(txl); 476 } 477 478 /** 479 * Callback for getting (twitter)friends... 480 * 481 * Be afraid, be very afraid! This function will potentially add hundreds of "friends". "Who has 482 * hundreds of friends?" you wonder? You probably not, since you are reading the source of 483 * BitlBee... Get a life and meet new people! 484 */ 485 static void twitter_http_get_statuses_friends(struct http_request *req) 486 { 487 struct im_connection *ic = req->data; 488 struct xt_parser *parser; 489 struct twitter_xml_list *txl; 490 491 // Check if the connection is still active. 492 if( !g_slist_find( twitter_connections, ic ) ) 493 return; 494 495 // Check if the HTTP request went well. 496 if (req->status_code != 200) { 497 // It didn't go well, output the error and return. 498 imcb_error(ic, "Could not retrieve home/timeline. HTTP STATUS: %d", req->status_code); 499 return; 500 } 501 502 txl = g_new0(struct twitter_xml_list, 1); 503 txl->list = NULL; 504 505 // Parse the data. 506 parser = xt_new( NULL, txl ); 507 xt_feed( parser, req->reply_body, req->body_size ); 508 509 // Get the user list from the parsed xml feed. 510 twitter_xt_get_user_list(parser->root, txl); 511 xt_free( parser ); 512 513 GSList *l = NULL; 514 struct twitter_xml_user *user; 515 // Add the users as buddies. 308 516 for ( l = txl->list; l ; l = g_slist_next(l) ) 309 517 { 310 status = l->data; 311 // TODO Put the next part in a new function.... 312 313 // Ugly hack, to show current user in chat... 314 if ( g_strcasecmp(status->user->screen_name, ic->acc->user) == 0) 315 { 316 char *tmp = g_strdup_printf ("_%s_", status->user->screen_name); 317 g_free(status->user->screen_name); 318 status->user->screen_name = tmp; 319 } 320 321 // Check if the buddy is allready in the buddy list. 322 if (!user_findhandle( ic, status->user->screen_name )) 323 { 324 // The buddy is not in the list, add the buddy... 325 imcb_add_buddy( ic, status->user->screen_name, NULL ); 326 imcb_buddy_status( ic, status->user->screen_name, OPT_LOGGED_IN, NULL, NULL ); 327 } 328 329 // Say it! 330 imcb_chat_msg (gc, status->user->screen_name, status->text, 0, 0 ); 331 // Update the home_timeline_id to hold the highest id, so that by the next request 332 // we won't pick up the updates allready in the list. 333 td->home_timeline_id = td->home_timeline_id < status->id ? status->id : td->home_timeline_id; 334 } 335 336 // Free the structure. 337 txl_free(txl, TXL_STATUS); 518 user = l->data; 519 twitter_add_buddy(ic, user->screen_name); 520 } 521 522 // if the next_cursor is set to something bigger then 0 there are more friends to gather. 523 if (txl->next_cursor > 0) 524 twitter_get_statuses_friends(ic, txl->next_cursor); 525 526 // Free the structure. 527 txl_free(txl); 338 528 g_free(txl); 339 529 } 340 530 341 531 /** 342 * Free a twitter_xml_list struct. 343 * type is the type of list the struct holds. 344 */ 345 void txl_free(struct twitter_xml_list *txl, int type) 346 { 347 GSList *l; 348 for ( l = txl->list; l ; l = g_slist_next(l) ) 349 if (type == TXL_STATUS) 350 txs_free((struct twitter_xml_status *)l->data); 351 else if (type == TXL_ID) 352 g_free(l->data); 353 g_slist_free(txl->list); 354 } 355 356 /** 357 * Frees a twitter_xml_status struct. 358 */ 359 void txs_free(struct twitter_xml_status *txs) 360 { 361 g_free(txs->created_at); 362 g_free(txs->text); 363 txu_free(txs->user); 364 } 365 366 /** 367 * Frees a twitter_xml_user struct. 368 */ 369 void txu_free(struct twitter_xml_user *txu) 370 { 371 g_free(txu->name); 372 g_free(txu->screen_name); 532 * Get the friends. 533 */ 534 void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor) 535 { 536 struct twitter_data *td = ic->proto_data; 537 538 char* args[2]; 539 args[0] = "cursor"; 540 args[1] = g_strdup_printf ("%d", next_cursor); 541 542 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2); 543 544 g_free(args[1]); 373 545 } 374 546 … … 379 551 { 380 552 struct im_connection *ic = req->data; 553 554 // Check if the connection is still active. 555 if( !g_slist_find( twitter_connections, ic ) ) 556 return; 381 557 382 558 // Check if the HTTP request went well. … … 400 576 args[1] = msg; 401 577 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2); 402 g_free(args[1]); 403 } 404 405 578 // g_free(args[1]); 579 } 580 581 582 /** 583 * Function to POST a new message to twitter. 584 */ 585 void twitter_direct_messages_new(struct im_connection *ic, char *who, char *msg) 586 { 587 struct twitter_data *td = ic->proto_data; 588 589 char* args[4]; 590 args[0] = "screen_name"; 591 args[1] = who; 592 args[2] = "text"; 593 args[3] = msg; 594 // Use the same callback as for twitter_post_status, since it does basically the same. 595 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4); 596 // g_free(args[1]); 597 // g_free(args[3]); 598 } 599 600 601 /** 602 * This function "overwrites" the imcb_chat_msg function. Because in the original the logged in user is filtered out. 603 */ 604 static void twitter_imcb_chat_msg( struct groupchat *c, char *who, char *msg, uint32_t flags, time_t sent_at ) 605 { 606 struct im_connection *ic = c->ic; 607 char *wrapped; 608 user_t *u; 609 610 u = user_findhandle( ic, who ); 611 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) 612 || ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 613 strip_html( msg ); 614 615 wrapped = word_wrap( msg, 425 ); 616 if( c && u ) 617 { 618 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, "", wrapped ); 619 } 620 else 621 { 622 imcb_log( ic, "Message from/to conversation %s@%p (unknown conv/user): %s", who, c, wrapped ); 623 } 624 g_free( wrapped ); 625 } 626 -
protocols/twitter/twitter_lib.h
rb4dd253 r62d2cfb 51 51 /* Direct messages URLs */ 52 52 #define TWITTER_DIRECT_MESSAGES_URL TWITTER_API_URL "/direct_messages.xml" 53 #define TWITTER_DIRECT_MESSAGE 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_MESSAGE DESTROY_URL TWITTER_API_URL "/direct_messages/destroy/"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/" 56 56 57 57 /* Friendships URLs */ … … 78 78 void twitter_get_friends_ids(struct im_connection *ic, int next_cursor); 79 79 void twitter_get_home_timeline(struct im_connection *ic, int next_cursor); 80 void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor); 80 81 81 void twitter_post_status(struct im_connection *ic, char* msg); 82 void twitter_post_status(struct im_connection *ic, char *msg); 83 void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message); 82 84 83 85 #endif //_TWITTER_LIB_H
Note: See TracChangeset
for help on using the changeset viewer.