source: protocols/twitter/twitter.c @ acba168

Last change on this file since acba168 was 508c340, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-04-26T00:42:37Z

Successfully posted a tweet!

Twitter's tricky. It returns vars (user_id, screen_name) in the access token
that, the way I read the spec, should be included in all subsequent queries.
However, stuff only started to work when I dropped those vars.

This code's definitely not pretty ATM. Need to clean up now that it actually
works.

  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[1b221e0]1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
4*  Simple module to facilitate twitter functionality.                       *
5*                                                                           *
6*  Copyright 2009 Geert Mulders <g.c.w.m.mulders@gmail.com>                 *
7*                                                                           *
8*  This library is free software; you can redistribute it and/or            *
9*  modify it under the terms of the GNU Lesser General Public               *
10*  License as published by the Free Software Foundation, version            *
11*  2.1.                                                                     *
12*                                                                           *
13*  This library is distributed in the hope that it will be useful,          *
14*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
15*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
16*  Lesser General Public License for more details.                          *
17*                                                                           *
18*  You should have received a copy of the GNU Lesser General Public License *
19*  along with this library; if not, write to the Free Software Foundation,  *
20*  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA           *
21*                                                                           *
22****************************************************************************/
23
24#include "nogaim.h"
25#include "twitter.h"
26#include "twitter_http.h"
27#include "twitter_lib.h"
28
29
30/**
[62d2cfb]31 * Main loop function
32 */
[1b221e0]33gboolean twitter_main_loop(gpointer data, gint fd, b_input_condition cond)
34{
35        struct im_connection *ic = data;
[3e69802]36       
[1b221e0]37        // Check if we are still logged in...
[3bd4a93]38        if (!g_slist_find( twitter_connections, ic ))
[1b221e0]39                return 0;
40
[62d2cfb]41        // If the user uses multiple private message windows we need to get the
42        // users buddies.
[e88fbe27]43        if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "many") == 0)
[62d2cfb]44                twitter_get_statuses_friends(ic, -1);
45
[1b221e0]46        // Do stuff..
47        twitter_get_home_timeline(ic, -1);
48
49        // If we are still logged in run this function again after timeout.
50        return (ic->flags & OPT_LOGGED_IN) == OPT_LOGGED_IN;
51}
52
[e88fbe27]53static char *set_eval_mode( set_t *set, char *value )
54{
55        if( g_strcasecmp( value, "one" ) == 0 ||
56            g_strcasecmp( value, "many" ) == 0 ||
[db57e7c]57            g_strcasecmp( value, "chat" ) == 0 )
[e88fbe27]58                return value;
59        else
60                return NULL;
61}
[1b221e0]62
63static void twitter_init( account_t *acc )
64{
[62d2cfb]65        set_t *s;
[e88fbe27]66       
67        s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
[2abceca]68        s->flags |= ACC_SET_OFFLINE_ONLY;
[1b221e0]69}
70
71/**
72 * Login method. Since the twitter API works with seperate HTTP request we
73 * only save the user and pass to the twitter_data object.
74 */
75static void twitter_login( account_t *acc )
76{
77        struct im_connection *ic = imcb_new( acc );
78        struct twitter_data *td = g_new0( struct twitter_data, 1 );
[e88fbe27]79        char name[strlen(acc->user)+9];
[62d2cfb]80
[d569019]81        twitter_connections = g_slist_append( twitter_connections, ic );
82
[1b221e0]83        td->user = acc->user;
[508c340]84        if( strstr( acc->pass, "oauth_token=" ) == NULL )
85                td->pass = g_strdup( acc->pass );
86        else
87                td->oauth = g_strdup( acc->pass );
[1b221e0]88        td->home_timeline_id = 0;
89
90        ic->proto_data = td;
91
[d569019]92        imcb_log( ic, "Connecting to Twitter" );
[1b221e0]93
94        // Run this once. After this queue the main loop function.
95        twitter_main_loop(ic, -1, 0);
96
97        // Queue the main_loop
[2abceca]98        // Save the return value, so we can remove the timeout on logout.
99        td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);
[e88fbe27]100       
101        sprintf( name, "twitter_%s", acc->user );
102        imcb_add_buddy( ic, name, NULL );
103        imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL );
[1b221e0]104}
105
106/**
107 * Logout method. Just free the twitter_data.
108 */
109static void twitter_logout( struct im_connection *ic )
110{
111        struct twitter_data *td = ic->proto_data;
112       
113        // Set the status to logged out.
114        ic->flags = 0;
115
[2abceca]116        // Remove the main_loop function from the function queue.
117        b_event_remove(td->main_loop_id);
118
[37d84b3]119        if(td->home_timeline_gc)
120                imcb_chat_free(td->home_timeline_gc);
[1014cab]121
[1b221e0]122        if( td )
123        {
[508c340]124                g_free( td->pass );
125                g_free( td->oauth );
[1b221e0]126                g_free( td );
127        }
[62d2cfb]128
129        twitter_connections = g_slist_remove( twitter_connections, ic );
[1b221e0]130}
131
132/**
133 *
134 */
135static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
136{
[e88fbe27]137        if (g_strncasecmp(who, "twitter_", 8) == 0 &&
138            g_strcasecmp(who + 8, ic->acc->user) == 0)
[62d2cfb]139                twitter_post_status(ic, message);
[e88fbe27]140        else
141                twitter_direct_messages_new(ic, who, message);
142       
[1b221e0]143        return( 0 );
144}
145
146/**
147 *
148 */
149static void twitter_set_my_name( struct im_connection *ic, char *info )
150{
151}
152
153static void twitter_get_info(struct im_connection *ic, char *who) 
154{
155}
156
157static void twitter_add_buddy( struct im_connection *ic, char *who, char *group )
158{
159}
160
161static void twitter_remove_buddy( struct im_connection *ic, char *who, char *group )
162{
163}
164
165static void twitter_chat_msg( struct groupchat *c, char *message, int flags )
166{
[2abceca]167        if( c && message )
168                twitter_post_status(c->ic, message);
[1b221e0]169}
170
171static void twitter_chat_invite( struct groupchat *c, char *who, char *message )
172{
173}
174
175static void twitter_chat_leave( struct groupchat *c )
176{
[16592d8]177        struct twitter_data *td = c->ic->proto_data;
178       
179        if( c != td->home_timeline_gc )
180                return; /* WTF? */
181       
182        /* If the user leaves the channel: Fine. Rejoin him/her once new
183           tweets come in. */
184        imcb_chat_free(td->home_timeline_gc);
185        td->home_timeline_gc = NULL;
[1b221e0]186}
187
188static struct groupchat *twitter_chat_with( struct im_connection *ic, char *who )
189{
190        return NULL;
191}
192
193static void twitter_keepalive( struct im_connection *ic )
194{
195}
196
197static void twitter_add_permit( struct im_connection *ic, char *who )
198{
199}
200
201static void twitter_rem_permit( struct im_connection *ic, char *who )
202{
203}
204
205static void twitter_add_deny( struct im_connection *ic, char *who )
206{
207}
208
209static void twitter_rem_deny( struct im_connection *ic, char *who )
210{
211}
212
213static int twitter_send_typing( struct im_connection *ic, char *who, int typing )
214{
215        return( 1 );
216}
217
218//static char *twitter_set_display_name( set_t *set, char *value )
219//{
220//      return value;
221//}
222
223void twitter_initmodule()
224{
225        struct prpl *ret = g_new0(struct prpl, 1);
226       
227        ret->name = "twitter";
228        ret->login = twitter_login;
229        ret->init = twitter_init;
230        ret->logout = twitter_logout;
231        ret->buddy_msg = twitter_buddy_msg;
232        ret->get_info = twitter_get_info;
233        ret->set_my_name = twitter_set_my_name;
234        ret->add_buddy = twitter_add_buddy;
235        ret->remove_buddy = twitter_remove_buddy;
236        ret->chat_msg = twitter_chat_msg;
237        ret->chat_invite = twitter_chat_invite;
238        ret->chat_leave = twitter_chat_leave;
239        ret->chat_with = twitter_chat_with;
240        ret->keepalive = twitter_keepalive;
241        ret->add_permit = twitter_add_permit;
242        ret->rem_permit = twitter_rem_permit;
243        ret->add_deny = twitter_add_deny;
244        ret->rem_deny = twitter_rem_deny;
245        ret->send_typing = twitter_send_typing;
246        ret->handle_cmp = g_strcasecmp;
247
248        register_protocol(ret);
[62d2cfb]249
250        // Initialise the twitter_connections GSList.
251        twitter_connections = NULL;
[1b221e0]252}
253
Note: See TracBrowser for help on using the repository browser.