diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-08 22:38:20 +0000 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-08 22:38:20 +0000 |
commit | 8e3b7acdfc96e086f1cd1c606e46d9a91d46a842 (patch) | |
tree | 9eb3d9f56cf4363f80911b4d33c4034022f64ee8 | |
parent | 0688e99d12297b6dda980803d1f1a54bf8590299 (diff) |
It logs in and fetches statuses! \o/ But, some corruption..
-rw-r--r-- | lib/json_util.c | 16 | ||||
-rw-r--r-- | lib/json_util.h | 11 | ||||
-rw-r--r-- | protocols/twitter/twitter_lib.c | 135 |
3 files changed, 98 insertions, 64 deletions
diff --git a/lib/json_util.c b/lib/json_util.c index 67cde749..43e687e3 100644 --- a/lib/json_util.c +++ b/lib/json_util.c @@ -26,7 +26,7 @@ #include "json_util.h" -json_value *json_o_get( json_value *obj, json_char *name ) +json_value *json_o_get( const json_value *obj, const json_char *name ) { int i; @@ -40,12 +40,22 @@ json_value *json_o_get( json_value *obj, json_char *name ) return NULL; } -const char *json_o_str( json_value *obj, json_char *name ) +const char *json_o_str( const json_value *obj, const json_char *name ) { json_value *ret = json_o_get( obj, name ); - if( ret ) + if( ret && ret->type == json_string ) return ret->u.string.ptr; else return NULL; } + +char *json_o_strdup( const json_value *obj, const json_char *name ) +{ + json_value *ret = json_o_get( obj, name ); + + if( ret && ret->type == json_string && ret->u.string.ptr ) + return g_memdup( ret->u.string.ptr, ret->u.string.length + 1 ); + else + return NULL; +} diff --git a/lib/json_util.h b/lib/json_util.h index c4e52eeb..fa4510bb 100644 --- a/lib/json_util.h +++ b/lib/json_util.h @@ -23,5 +23,12 @@ #include "json.h" -json_value *json_o_get( json_value *obj, json_char *name ); -const char *json_o_str( json_value *obj, json_char *name ); +#define JSON_O_FOREACH(o, k, v) \ + char *k; json_value *v; int __i; \ + for( __i = 0; k = (o)->u.object.values[__i].name, \ + v = (o)->u.object.values[__i].value, \ + __i < (o)->u.object.length; __i ++ ) + +json_value *json_o_get( const json_value *obj, const json_char *name ); +const char *json_o_str( const json_value *obj, const json_char *name ); +char *json_o_strdup( const json_value *obj, const json_char *name ); diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index a4ce28e7..47264db0 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -271,7 +271,7 @@ static xt_status twitter_xt_get_friends_id_list(json_value *node, struct twitter continue; txl->list = g_slist_prepend(txl->list, - g_strdup_printf("%ld", c->u.array.values[i]->u.integer)); + g_strdup_printf("%lld", c->u.array.values[i]->u.integer)); } @@ -402,6 +402,17 @@ static void twitter_http_get_users_lookup(struct http_request *req) twitter_get_users_lookup(ic); } +struct twitter_xml_user *twitter_xt_get_user(const json_value *node) +{ + struct twitter_xml_user *txu; + + txu = g_new0(struct twitter_xml_user, 1); + txu->name = g_strdup(json_o_str(node, "name")); + txu->screen_name = g_strdup(json_o_str(node, "screen_name")); + + return txu; +} + /** * Function to fill a twitter_xml_list struct. * It sets: @@ -421,10 +432,9 @@ static xt_status twitter_xt_get_users(json_value *node, struct twitter_xml_list // The root <users> node should hold the list of users <user> // Walk over the nodes children. for (i = 0; i < node->u.array.length; i ++) { - txu = g_new0(struct twitter_xml_user, 1); - txu->name = g_strdup(json_o_str(node->u.array.values[i], "name")); - txu->screen_name = g_strdup(json_o_str(node->u.array.values[i], "screen_name")); - txl->list = g_slist_prepend(txl->list, txu); + txu = twitter_xt_get_user(node->u.array.values[i]); + if (txu) + txl->list = g_slist_prepend(txl->list, txu); } return XT_HANDLED; @@ -444,31 +454,38 @@ static xt_status twitter_xt_get_users(json_value *node, struct twitter_xml_list * - the status id and * - the user in a twitter_xml_user struct. */ -static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_status *txs) +static xt_status twitter_xt_get_status(const json_value *node, struct twitter_xml_status *txs) { - struct xt_node *child, *rt = NULL; + const json_value *c, *rt = NULL, *entities = NULL; + int i; + + if (node->type != json_object) + return XT_ABORT; - // Walk over the nodes children. - for (child = node->children; child; child = child->next) { - if (g_strcasecmp("text", child->name) == 0) { - txs->text = g_memdup(child->text, child->text_len + 1); - } else if (g_strcasecmp("retweeted_status", child->name) == 0) { - rt = child; - } else if (g_strcasecmp("created_at", child->name) == 0) { + for (i = 0; i < node->u.object.length; i ++) { + const char *k = node->u.object.values[i].name; + const json_value *v = node->u.object.values[i].value; + + if (strcmp("text", k) == 0 && v->type == json_string) { + txs->text = g_memdup(v->u.string.ptr, v->u.string.length); + } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) { + rt = v; + } else if (strcmp("created_at", k) == 0 && v->type == json_string) { struct tm parsed; /* Very sensitive to changes to the formatting of this field. :-( Also assumes the timezone used is UTC since C time handling functions suck. */ - if (strptime(child->text, TWITTER_TIME_FORMAT, &parsed) != NULL) + if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) txs->created_at = mktime_utc(&parsed); - } else if (g_strcasecmp("user", child->name) == 0) { - txs->user = g_new0(struct twitter_xml_user, 1); -// twitter_xt_get_user(child, txs->user); - } else if (g_strcasecmp("id", child->name) == 0) { - txs->id = g_ascii_strtoull(child->text, NULL, 10); - } else if (g_strcasecmp("in_reply_to_status_id", child->name) == 0) { - txs->reply_to = g_ascii_strtoull(child->text, NULL, 10); + } else if (strcmp("user", k) == 0 && v->type == json_object) { + txs->user = twitter_xt_get_user(v); + } else if (strcmp("id", k) == 0 && v->type == json_integer) { + txs->id = v->u.integer; + } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) { + txs->reply_to = v->u.integer; + } else if (strcmp("entities", k) == 0 && v->type == json_object) { + txs->reply_to = v->u.integer; } } @@ -484,29 +501,29 @@ static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_ g_free(txs->text); txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text); txs_free(rtxs); - } else { - struct xt_node *urls, *url; - - urls = xt_find_path(node, "entities"); - if (urls != NULL) - urls = urls->children; - for (; urls; urls = urls->next) { - if (strcmp(urls->name, "urls") != 0 && strcmp(urls->name, "media") != 0) + } else if (entities && NULL) { + JSON_O_FOREACH (entities, k, v) { + int i; + + if (v->type != json_array) + continue; + if (strcmp(k, "urls") != 0 && strcmp(k, "media") != 0) continue; - for (url = urls ? urls->children : NULL; url; url = url->next) { - /* "short" is a reserved word. :-P */ - struct xt_node *kort = xt_find_node(url->children, "url"); - struct xt_node *disp = xt_find_node(url->children, "display_url"); + for (i = 0; i < v->u.array.length; i ++) { + if (v->u.array.values[i]->type != json_object) + continue; + + const char *kort = json_o_str(v->u.array.values[i], "url"); + const char *disp = json_o_str(v->u.array.values[i], "display_url"); char *pos, *new; - if (!kort || !kort->text || !disp || !disp->text || - !(pos = strstr(txs->text, kort->text))) + if (!kort || !disp || !(pos = strstr(txs->text, kort))) continue; *pos = '\0'; - new = g_strdup_printf("%s%s <%s>%s", txs->text, kort->text, - disp->text, pos + strlen(kort->text)); + new = g_strdup_printf("%s%s <%s>%s", txs->text, kort, + disp, pos + strlen(kort)); g_free(txs->text); txs->text = new; @@ -523,36 +540,36 @@ static xt_status twitter_xt_get_status(struct xt_node *node, struct twitter_xml_ * - all <status>es within the <status> element and * - the next_cursor. */ -static xt_status twitter_xt_get_status_list(struct im_connection *ic, struct xt_node *node, +static xt_status twitter_xt_get_status_list(struct im_connection *ic, const json_value *node, struct twitter_xml_list *txl) { struct twitter_xml_status *txs; - struct xt_node *child; + json_value *c; bee_user_t *bu; + int i; // Set the type of the list. txl->type = TXL_STATUS; + + if (node->type != json_array) + return XT_ABORT; // The root <statuses> node should hold the list of statuses <status> // Walk over the nodes children. - for (child = node->children; child; child = child->next) { - if (g_strcasecmp("status", child->name) == 0) { - txs = g_new0(struct twitter_xml_status, 1); - twitter_xt_get_status(child, txs); - // Put the item in the front of the list. - txl->list = g_slist_prepend(txl->list, txs); - - if (txs->user && txs->user->screen_name && - (bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name))) { - struct twitter_user_data *tud = bu->data; - - if (txs->id > tud->last_id) { - tud->last_id = txs->id; - tud->last_time = txs->created_at; - } + for (i = 0; i < node->u.array.length; i ++) { + txs = g_new0(struct twitter_xml_status, 1); + twitter_xt_get_status(node->u.array.values[i], txs); + // Put the item in the front of the list. + txl->list = g_slist_prepend(txl->list, txs); + + if (txs->user && txs->user->screen_name && + (bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name))) { + struct twitter_user_data *tud = bu->data; + + if (txs->id > tud->last_id) { + tud->last_id = txs->id; + tud->last_time = txs->created_at; } - } else if (g_strcasecmp("next_cursor", child->name) == 0) { -// twitter_xt_next_cursor(child, txl); } } @@ -878,7 +895,7 @@ static void twitter_http_get_home_timeline(struct http_request *req) { struct im_connection *ic = req->data; struct twitter_data *td; - struct xt_node *parsed; + json_value *parsed; struct twitter_xml_list *txl; // Check if the connection is still active. @@ -911,7 +928,7 @@ static void twitter_http_get_mentions(struct http_request *req) { struct im_connection *ic = req->data; struct twitter_data *td; - struct xt_node *parsed; + json_value *parsed; struct twitter_xml_list *txl; // Check if the connection is still active. |