Changeset 62d2cfb for protocols/twitter


Ignore:
Timestamp:
2010-03-25T21:31:27Z (15 years ago)
Author:
Geert Mulders <g.c.w.m.mulders@…>
Branches:
master
Children:
2abceca
Parents:
b4dd253
Message:

Added option to get tweeds either through groupchat or privmes.

Location:
protocols/twitter
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • protocols/twitter/twitter.c

    rb4dd253 r62d2cfb  
    2929
    3030/**
    31  *  * Main loop function
    32  *   */
     31 * Main loop function
     32 */
    3333gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond)
    3434{
     
    3838                return 0;
    3939
     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
    4045        // Do stuff..
    4146        twitter_get_home_timeline(ic, -1);
     
    4853static void twitter_init( account_t *acc )
    4954{
     55        set_t *s;
     56        s = set_add( &acc->set, "use_groupchat", "false", set_eval_bool, acc );
    5057}
    5158
     
    5865        struct im_connection *ic = imcb_new( acc );
    5966        struct twitter_data *td = g_new0( struct twitter_data, 1 );
    60        
     67
    6168        td->user = acc->user;
    6269        td->pass = acc->pass;
     
    6875        ic->flags = OPT_LOGGED_IN;
    6976
    70         // Try to get the buddies...
    71         //twitter_get_friends_ids(ic, -1);
    72 
    73         //twitter_get_home_timeline(ic, -1);
    74 
    7577        // Run this once. After this queue the main loop function.
    7678        twitter_main_loop(ic, -1, 0);
     
    8183        imcb_log( ic, "Connecting to twitter" );
    8284        imcb_connected(ic);
     85
     86        twitter_connections = g_slist_append( twitter_connections, ic );
    8387}
    8488
     
    97101                g_free( td );
    98102        }
     103
     104        twitter_connections = g_slist_remove( twitter_connections, ic );
    99105}
    100106
     
    104110static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    105111{
    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);
    108117        return( 0 );
    109118}
     
    124133static void twitter_set_my_name( struct im_connection *ic, char *info )
    125134{
    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);
    131135}
    132136
     
    218222
    219223        register_protocol(ret);
    220 }
    221 
     224
     225        // Initialise the twitter_connections GSList.
     226        twitter_connections = NULL;
     227}
     228
  • protocols/twitter/twitter.h

    rb4dd253 r62d2cfb  
    4141};
    4242
     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 */
     48GSList *twitter_connections;
     49
    4350#endif //_TWITTER_H
  • protocols/twitter/twitter_lib.c

    rb4dd253 r62d2cfb  
    3434
    3535#define TXL_STATUS 1
    36 #define TXL_ID 1
     36#define TXL_USER 2
     37#define TXL_ID 3
     38
     39static void twitter_imcb_chat_msg( struct groupchat *c, char *who, char *msg, uint32_t flags, time_t sent_at );
    3740
    3841struct twitter_xml_list {
     42        int type;
    3943        int next_cursor;
    4044        GSList *list;
     
    5458};
    5559
    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 */
     63static 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 */
     73static 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 */
     84static 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 */
     98static 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}
    59108
    60109static void twitter_http_get_friends_ids(struct http_request *req);
     
    93142{
    94143        struct xt_node *child;
     144       
     145        // Set the list type.
     146        txl->type = TXL_ID;
    95147
    96148        // The root <statuses> node should hold the list of statuses <status>
     
    122174
    123175        ic = req->data;
     176
     177        // Check if the connection is still active.
     178        if( !g_slist_find( twitter_connections, ic ) )
     179                return;
    124180
    125181        // Check if the HTTP request went well.
     
    142198                twitter_get_friends_ids(ic, txl->next_cursor);
    143199
    144         txl_free(txl, TXL_ID);
     200        txl_free(txl);
    145201        g_free(txl);
    146202}
     
    170226        return XT_HANDLED;
    171227}
     228
     229/**
     230 * Function to fill a twitter_xml_list struct.
     231 * It sets:
     232 *  - all <user>s from the <users> element.
     233 */
     234static 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 */
     264static 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
    172288
    173289/**
     
    218334        struct xt_node *child;
    219335
     336        // Set the type of the list.
     337        txl->type = TXL_STATUS;
     338
    220339        // The root <statuses> node should hold the list of statuses <status>
    221340        // Walk over the nodes children.
     
    264383
    265384/**
     385 * Function that is called to see the statuses in a groupchat window.
     386 */
     387static 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 */
     421static 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/**
    266438 * Callback for getting the home timeline.
    267439 */
    268440static void twitter_http_get_home_timeline(struct http_request *req)
    269441{
    270         struct im_connection *ic = req->data;;
     442        struct im_connection *ic = req->data;
    271443        struct xt_parser *parser;
    272444        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;
    275449
    276450        // Check if the HTTP request went well.
     
    283457        txl = g_new0(struct twitter_xml_list, 1);
    284458        txl->list = NULL;
    285        
     459
    286460        // Parse the data.
    287461        parser = xt_new( NULL, txl );
     
    290464        twitter_xt_get_status_list(parser->root, txl);
    291465        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);
    303470        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 */
     485static 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.
    308516        for ( l = txl->list; l ; l = g_slist_next(l) )
    309517        {
    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);
    338528        g_free(txl);
    339529}
    340530
    341531/**
    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 */
     534void 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]);
    373545}
    374546
     
    379551{
    380552        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;
    381557
    382558        // Check if the HTTP request went well.
     
    400576        args[1] = msg;
    401577        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 */
     585void 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 */
     604static 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  
    5151/* Direct messages URLs */
    5252#define TWITTER_DIRECT_MESSAGES_URL TWITTER_API_URL "/direct_messages.xml"
    53 #define TWITTER_DIRECT_MESSAGENEW_URL TWITTER_API_URL "/direct_messages/new.xml"
    54 #define TWITTER_DIRECT_MESSAGESSENT_URL TWITTER_API_URL "/direct_messages/sent.xml"
    55 #define TWITTER_DIRECT_MESSAGEDESTROY_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/"
    5656
    5757/* Friendships URLs */
     
    7878void twitter_get_friends_ids(struct im_connection *ic, int next_cursor);
    7979void twitter_get_home_timeline(struct im_connection *ic, int next_cursor);
     80void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor);
    8081
    81 void twitter_post_status(struct im_connection *ic, char* msg);
     82void twitter_post_status(struct im_connection *ic, char *msg);
     83void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message);
    8284
    8385#endif //_TWITTER_LIB_H
Note: See TracChangeset for help on using the changeset viewer.