aboutsummaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2012-11-11 14:42:20 +0000
committerWilmer van der Gaast <wilmer@gaast.net>2012-11-11 14:42:20 +0000
commitdff0e0bdf3acea7d301242421b4fa906ff46278d (patch)
tree3b95b54d5e0dd290763f62a865a2a35dce117d44 /protocols
parentddc2de54664ec25b95bbce997fbbb6a7104f1203 (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.c21
-rw-r--r--protocols/twitter/twitter_lib.c80
-rw-r--r--protocols/twitter/twitter_lib.h3
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);