aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-08-07 20:39:01 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-08-07 20:39:01 +0100
commit7b87539aedd967884d4e4eed75d1052a233720eb (patch)
tree404b5801b795c6a0c416f4fce43b1cda51444c9a
parentdaae10fbfe16bac26f74af91faf253d377f1b166 (diff)
Add commands to the Twitter module, starting with undo (which deletes
either your most recent tweet, or a specific id (pass it as an argument)).
-rw-r--r--lib/misc.c3
-rw-r--r--protocols/twitter/twitter.c105
-rw-r--r--protocols/twitter/twitter.h1
-rw-r--r--protocols/twitter/twitter_lib.c27
-rw-r--r--protocols/twitter/twitter_lib.h1
5 files changed, 113 insertions, 24 deletions
diff --git a/lib/misc.c b/lib/misc.c
index 26d22ae0..fda19c19 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -651,6 +651,9 @@ int md5_verify_password( char *password, char *hash )
return ret;
}
+/* Split commands (root-style, *not* IRC-style). Handles "quoting of"
+ white\ space in 'various ways'. Returns a NULL-terminated static
+ char** so watch out with nested use! Definitely not thread-safe. */
char **split_command_parts( char *command )
{
static char *cmd[IRC_MAX_ARGS+1];
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c
index f718eeb7..85d10a56 100644
--- a/protocols/twitter/twitter.c
+++ b/protocols/twitter/twitter.c
@@ -188,6 +188,8 @@ static void twitter_init( account_t *acc )
s = set_add( &acc->set, "base_url", def_url, NULL, acc );
s->flags |= ACC_SET_OFFLINE_ONLY;
+ s = set_add( &acc->set, "commands", "true", set_eval_bool, acc );
+
s = set_add( &acc->set, "message_length", "140", set_eval_int, acc );
s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
@@ -273,6 +275,8 @@ static void twitter_logout( struct im_connection *ic )
twitter_connections = g_slist_remove( twitter_connections, ic );
}
+static void twitter_handle_command( struct im_connection *ic, char *message );
+
/**
*
*/
@@ -301,8 +305,8 @@ static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message
return FALSE;
}
}
- else if( twitter_length_check(ic, message) )
- twitter_post_status(ic, message);
+ else
+ twitter_handle_command(ic, message);
}
else
{
@@ -334,28 +338,8 @@ static void twitter_remove_buddy( struct im_connection *ic, char *who, char *gro
static void twitter_chat_msg( struct groupchat *c, char *message, int flags )
{
- if( c && message && twitter_length_check( c->ic, message ) )
- {
- char *s, *new = NULL;
-
- if( ( s = strchr( message, ':' ) ) ||
- ( s = strchr( message, ',' ) ) )
- {
- bee_user_t *bu;
-
- new = g_strdup( message );
- new[s-message] = '\0';
- if( ( bu = bee_user_by_handle( c->ic->bee, c->ic, new ) ) )
- {
- sprintf( new, "@%s", bu->handle );
- new[s-message+1] = ' ';
- message = new;
- }
- }
-
- twitter_post_status( c->ic, message );
- g_free( new );
- }
+ if( c && message )
+ twitter_handle_command( c->ic, message );
}
static void twitter_chat_invite( struct groupchat *c, char *who, char *message )
@@ -410,6 +394,79 @@ static int twitter_send_typing( struct im_connection *ic, char *who, int typing
// return value;
//}
+static void twitter_handle_command( struct im_connection *ic, char *message )
+{
+ struct twitter_data *td = ic->proto_data;
+ char *cmds, **cmd;
+
+ cmds = g_strdup( message );
+ cmd = split_command_parts( cmds );
+
+ if( cmd[0] == NULL )
+ {
+ g_free( cmds );
+ return;
+ }
+ else if( !set_getbool( &ic->set, "commands" ) )
+ {
+ /* Not supporting commands. */
+ }
+ else if( g_strcasecmp( cmd[0], "undo" ) == 0 )
+ {
+ guint64 id;
+
+ if( cmd[1] )
+ {
+ char *end = NULL;
+
+ id = g_ascii_strtoull( cmd[1], &end, 10 );
+ if( end == NULL )
+ id = 0;
+ }
+ else
+ id = td->last_status_id;
+
+ /* TODO: User feedback. */
+ if( id )
+ twitter_status_destroy( ic, id );
+
+ g_free( cmds );
+ return;
+ }
+ else if( g_strcasecmp( cmd[0], "post" ) == 0 )
+ {
+ message += 5;
+ }
+
+ {
+ char *s, *new = NULL;
+ bee_user_t *bu;
+
+ if( !twitter_length_check( ic, message ) )
+ {
+ g_free( cmds );
+ return;
+ }
+
+ s = cmd[0] + strlen( cmd[0] ) - 1;
+ if( s > cmd[0] && ( *s == ':' || *s == ',' ) )
+ {
+ *s = '\0';
+
+ if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[0] ) ) )
+ {
+ new = g_strdup_printf( "@%s %s", bu->handle,
+ message + ( s - cmd[0] ) + 2 );
+ message = new;
+ }
+ }
+
+ twitter_post_status( ic, message );
+ g_free( new );
+ }
+ g_free( cmds );
+}
+
void twitter_initmodule()
{
struct prpl *ret = g_new0(struct prpl, 1);
diff --git a/protocols/twitter/twitter.h b/protocols/twitter/twitter.h
index b7e41fc5..9485520f 100644
--- a/protocols/twitter/twitter.h
+++ b/protocols/twitter/twitter.h
@@ -43,6 +43,7 @@ struct twitter_data
char* pass;
struct oauth_info *oauth_info;
guint64 home_timeline_id;
+ guint64 last_status_id; /* For undo */
gint main_loop_id;
struct groupchat *home_timeline_gc;
gint http_fails;
diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c
index 5c89e4f6..a24e9969 100644
--- a/protocols/twitter/twitter_lib.c
+++ b/protocols/twitter/twitter_lib.c
@@ -735,17 +735,36 @@ void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor)
static void twitter_http_post(struct http_request *req)
{
struct im_connection *ic = req->data;
+ struct twitter_data *td;
// Check if the connection is still active.
if( !g_slist_find( twitter_connections, ic ) )
return;
+ td = ic->proto_data;
+ td->last_status_id = 0;
+
// Check if the HTTP request went well.
if (req->status_code != 200) {
// It didn't go well, output the error and return.
imcb_error(ic, "HTTP error: %s", twitter_parse_error(req));
return;
}
+
+ if (req->body_size > 0)
+ {
+ struct xt_parser *xp = NULL;
+ struct xt_node *node;
+
+ xp = xt_new(NULL, NULL);
+ xt_feed(xp, req->reply_body, req->body_size);
+
+ if ((node = xt_find_node(xp->root, "status")) &&
+ (node = xt_find_node(node->children, "id")) && node->text)
+ td->last_status_id = g_ascii_strtoull( node->text, NULL, 10 );
+
+ xt_free(xp);
+ }
}
/**
@@ -784,3 +803,11 @@ void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int
args[1] = who;
twitter_http(ic, create ? TWITTER_FRIENDSHIPS_CREATE_URL : TWITTER_FRIENDSHIPS_DESTROY_URL, twitter_http_post, ic, 1, args, 2);
}
+
+void twitter_status_destroy(struct im_connection *ic, guint64 id)
+{
+ char *url;
+ url = g_strdup_printf("%s%llu%s", TWITTER_STATUS_DESTROY_URL, (unsigned long long) id, ".xml");
+ twitter_http(ic, url, twitter_http_post, ic, 1, NULL, 0);
+ g_free(url);
+}
diff --git a/protocols/twitter/twitter_lib.h b/protocols/twitter/twitter_lib.h
index 5a3c3f68..4f3b16c7 100644
--- a/protocols/twitter/twitter_lib.h
+++ b/protocols/twitter/twitter_lib.h
@@ -83,6 +83,7 @@ void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor);
void twitter_post_status(struct im_connection *ic, char *msg);
void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message);
void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create);
+void twitter_status_destroy(struct im_connection *ic, guint64 id);
#endif //_TWITTER_LIB_H