diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-11 14:42:20 +0000 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-11 14:42:20 +0000 |
commit | dff0e0bdf3acea7d301242421b4fa906ff46278d (patch) | |
tree | 3b95b54d5e0dd290763f62a865a2a35dce117d44 /protocols | |
parent | ddc2de54664ec25b95bbce997fbbb6a7104f1203 (diff) |
Showing tweets now, and leaking less memory. Still lots of cleanup left
to do.
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/twitter/twitter.c | 21 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.c | 80 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.h | 3 |
3 files changed, 73 insertions, 31 deletions
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 93ef4ae2..ea440a15 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -4,6 +4,7 @@ * Simple module to facilitate twitter functionality. * * * * Copyright 2009 Geert Mulders <g.c.w.m.mulders@gmail.com> * +* Copyright 2010-2012 Wilmer van der Gaast <wilmer@gaast.net> * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * @@ -65,11 +66,18 @@ static void twitter_main_loop_start(struct im_connection *ic) // Run this once. After this queue the main loop function. twitter_main_loop(ic, -1, 0); - - // Queue the main_loop - // Save the return value, so we can remove the timeout on logout. - td->main_loop_id = - b_timeout_add(set_getint(&ic->acc->set, "fetch_interval") * 1000, twitter_main_loop, ic); + + if (set_getbool(&ic->acc->set, "stream")) { + /* That fetch was just to get backlog, the stream will give + us the rest. \o/ */ + twitter_open_stream(ic); + } else { + /* Not using the streaming API, so keep polling the old- + fashioned way. :-( */ + td->main_loop_id = + b_timeout_add(set_getint(&ic->acc->set, "fetch_interval") * 1000, + twitter_main_loop, ic); + } } static void twitter_oauth_start(struct im_connection *ic); @@ -278,6 +286,9 @@ static void twitter_init(account_t * acc) s = set_add(&acc->set, "show_old_mentions", "20", set_eval_int, acc); s = set_add(&acc->set, "strip_newlines", "false", set_eval_bool, acc); + + s = set_add(&acc->set, "stream", "true", set_eval_bool, acc); + s->flags |= ACC_SET_OFFLINE_ONLY; } /** diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index 8d10a406..031d824e 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -175,7 +175,7 @@ char *twitter_parse_error(struct http_request *req) if (req->body_size > 0) { root = json_parse(req->reply_body); err = json_o_get(root, "errors"); - if (err->type == json_array && (err = err->u.array.values[0]) && + if (err && err->type == json_array && (err = err->u.array.values[0]) && err->type == json_object) { const char *msg = json_o_str(err, "message"); if (msg) @@ -528,7 +528,7 @@ static gboolean twitter_xt_get_status(const json_value *node, struct twitter_xml } } - return TRUE; + return txs->text && txs->user && txs->id; } /** @@ -726,15 +726,19 @@ static void twitter_private_message_chat(struct im_connection *ic, GSList * list } } -static void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor); -static void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor); +static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o); static void twitter_http_stream(struct http_request *req) { - int len; - int i; + struct im_connection *ic = req->data; + //struct twitter_data *td = ic->proto_data; + json_value *parsed; + int len, i; char c; - json_value *j; + + if (!g_slist_find(twitter_connections, ic)) + return; + //td = ic->proto_data;; printf( "%d bytes in stream\n", req->body_size ); @@ -762,13 +766,54 @@ static void twitter_http_stream(struct http_request *req) req->reply_body[len] = '\0'; printf("JSON: %s\n", req->reply_body); - printf("parsed: %p\n", (j = json_parse(req->reply_body))); - json_value_free(j); + printf("parsed: %p\n", (parsed = json_parse(req->reply_body))); + if (parsed) { + twitter_stream_handle_object(ic, parsed); + } + json_value_free(parsed); req->reply_body[len] = c; http_flush_bytes(req, len); + + /* One notification might bring multiple events! */ + if (req->body_size > 0) + twitter_http_stream(req); +} + +static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o) +{ + struct twitter_xml_status *txs = g_new0(struct twitter_xml_status, 1); + + if (twitter_xt_get_status(o, txs)) { + GSList *output = g_slist_append(NULL, txs); + twitter_groupchat(ic, output); + txs_free(txs); + g_slist_free(output); + return TRUE; + } + txs_free(txs); + return FALSE; } +gboolean twitter_open_stream(struct im_connection *ic) +{ + struct twitter_data *td = ic->proto_data; + char *args[4] = {"with", "followings", "delimited", "length"}; + + if ((td->stream = twitter_http(ic, TWITTER_USER_STREAM_URL, + twitter_http_stream, ic, 0, args, 4))) { + /* This flag must be enabled or we'll get no data until EOF + (which err, kind of, defeats the purpose of a streaming API). */ + td->stream->flags |= HTTPC_STREAMING; + return TRUE; + } + + return FALSE; +} + +static void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor); +static void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor); + /** * Get the timeline with optionally mentions */ @@ -791,23 +836,6 @@ void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor) if (include_mentions) { twitter_get_mentions(ic, next_cursor); } - - static int bla = 0; - - if (bla) - return; - bla = 1; - - char *args[4]; - args[0] = "with"; - args[1] = "followings"; - args[2] = "delimited"; - args[3] = "length"; - - if ((td->stream = twitter_http(ic, "https://userstream.twitter.com/1.1/user.json", - twitter_http_stream, ic, 0, args, 4))) { - td->stream->flags |= HTTPC_STREAMING; - } } /** diff --git a/protocols/twitter/twitter_lib.h b/protocols/twitter/twitter_lib.h index 624fc80a..d5f5b16a 100644 --- a/protocols/twitter/twitter_lib.h +++ b/protocols/twitter/twitter_lib.h @@ -78,6 +78,9 @@ /* Report spam */ #define TWITTER_REPORT_SPAM_URL "/report_spam.json" +#define TWITTER_USER_STREAM_URL "https://userstream.twitter.com/1.1/user.json" + +gboolean twitter_open_stream(struct im_connection *ic); void twitter_get_timeline(struct im_connection *ic, gint64 next_cursor); void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor); void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor); |