Changes in protocols/twitter/twitter_lib.c [f81d8b8:1201fcb]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter_lib.c
rf81d8b8 r1201fcb 36 36 #include "base64.h" 37 37 #include "twitter_lib.h" 38 #include " parson.h"38 #include "json_util.h" 39 39 #include <ctype.h> 40 40 #include <errno.h> … … 64 64 gboolean from_filter; 65 65 }; 66 67 #define JSON_O_FOREACH(o, k, v) \68 const char *k; const JSON_Value *v; int __i; \69 for (__i = 0; json_object_get_tuple(o, __i, &k, &v); __i++)70 66 71 67 /** … … 170 166 { 171 167 static char *ret = NULL; 172 JSON_Value *root, *err;168 json_value *root, *err; 173 169 174 170 g_free(ret); … … 176 172 177 173 if (req->body_size > 0) { 178 root = json_parse_string(req->reply_body); 179 err = json_object_get_value(json_object(root), "errors"); 180 if (err && json_type(err) == JSONArray && 181 (err = json_array_get_value(json_array(err), 0)) && 182 json_type(err) == JSONObject) { 183 const char *msg = json_object_get_string(json_object(err), "message"); 174 root = json_parse(req->reply_body, req->body_size); 175 err = json_o_get(root, "errors"); 176 if (err && err->type == json_array && (err = err->u.array.values[0]) && 177 err->type == json_object) { 178 const char *msg = json_o_str(err, "message"); 184 179 if (msg) { 185 180 ret = g_strdup_printf("%s (%s)", req->status_string, msg); … … 194 189 /* WATCH OUT: This function might or might not destroy your connection. 195 190 Sub-optimal indeed, but just be careful when this returns NULL! */ 196 static JSON_Value *twitter_parse_response(struct im_connection *ic, struct http_request *req)191 static json_value *twitter_parse_response(struct im_connection *ic, struct http_request *req) 197 192 { 198 193 gboolean logging_in = !(ic->flags & OPT_LOGGED_IN); 199 194 gboolean periodic; 200 195 struct twitter_data *td = ic->proto_data; 201 JSON_Value *ret;196 json_value *ret; 202 197 char path[64] = "", *s; 203 198 … … 237 232 } 238 233 239 if ((ret = json_parse _string(req->reply_body)) == NULL) {234 if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) { 240 235 imcb_error(ic, "Could not retrieve %s: %s", 241 236 path, "XML parse error"); … … 264 259 * Fill a list of ids. 265 260 */ 266 static gboolean twitter_xt_get_friends_id_list( JSON_Value *node, struct twitter_xml_list *txl)267 { 268 JSON_Array*c;261 static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl) 262 { 263 json_value *c; 269 264 int i; 270 265 … … 272 267 txl->type = TXL_ID; 273 268 274 if (!(c = json_object_get_array(json_object(node), "ids"))) { 269 c = json_o_get(node, "ids"); 270 if (!c || c->type != json_array) { 275 271 return FALSE; 276 272 } 277 273 278 for (i = 0; i < json_array_get_count(c); i++) { 279 jint id = json_array_get_integer(c, i); 274 for (i = 0; i < c->u.array.length; i++) { 275 if (c->u.array.values[i]->type != json_integer) { 276 continue; 277 } 280 278 281 279 txl->list = g_slist_prepend(txl->list, 282 g_strdup_printf("% lld", id));283 } 284 285 JSON_Value *next = json_object_get_value(json_object(node), "next_cursor");286 if ( next && json_type(next) == JSONInteger) {287 txl->next_cursor = json_integer(next);280 g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer)); 281 } 282 283 c = json_o_get(node, "next_cursor"); 284 if (c && c->type == json_integer) { 285 txl->next_cursor = c->u.integer; 288 286 } else { 289 287 txl->next_cursor = -1; … … 301 299 { 302 300 struct im_connection *ic; 303 JSON_Value *parsed;301 json_value *parsed; 304 302 struct twitter_xml_list *txl; 305 303 struct twitter_data *td; … … 339 337 } 340 338 341 static gboolean twitter_xt_get_users( JSON_Value *node, struct twitter_xml_list *txl);339 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl); 342 340 static void twitter_http_get_users_lookup(struct http_request *req); 343 341 … … 380 378 { 381 379 struct im_connection *ic = req->data; 382 JSON_Value *parsed;380 json_value *parsed; 383 381 struct twitter_xml_list *txl; 384 382 GSList *l = NULL; … … 412 410 } 413 411 414 struct twitter_xml_user *twitter_xt_get_user(const JSON_Object*node)412 struct twitter_xml_user *twitter_xt_get_user(const json_value *node) 415 413 { 416 414 struct twitter_xml_user *txu; 417 418 if (!node) 419 return NULL; 415 json_value *jv; 420 416 421 417 txu = g_new0(struct twitter_xml_user, 1); 422 txu->name = g_strdup(json_object_get_string(node, "name")); 423 txu->screen_name = g_strdup(json_object_get_string(node, "screen_name")); 424 txu->uid = json_object_get_integer(node, "id"); 418 txu->name = g_strdup(json_o_str(node, "name")); 419 txu->screen_name = g_strdup(json_o_str(node, "screen_name")); 420 421 jv = json_o_get(node, "id"); 422 txu->uid = jv->u.integer; 425 423 426 424 return txu; … … 432 430 * - all <user>s from the <users> element. 433 431 */ 434 static gboolean twitter_xt_get_users( JSON_Value *node, struct twitter_xml_list *txl)432 static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl) 435 433 { 436 434 struct twitter_xml_user *txu; … … 440 438 txl->type = TXL_USER; 441 439 442 if ( json_type(node) != JSONArray) {440 if (!node || node->type != json_array) { 443 441 return FALSE; 444 442 } 445 443 446 444 // The root <users> node should hold the list of users <user> 447 445 // Walk over the nodes children. 448 JSON_Array *arr = json_array(node); 449 for (i = 0; i < json_array_get_count(arr); i++) { 450 JSON_Object *o = json_array_get_object(arr, i); 451 if (!o) 452 continue; 453 txu = twitter_xt_get_user(o); 446 for (i = 0; i < node->u.array.length; i++) { 447 txu = twitter_xt_get_user(node->u.array.values[i]); 454 448 if (txu) { 455 449 txl->list = g_slist_prepend(txl->list, txu); … … 466 460 #endif 467 461 468 static void expand_entities(char **text, const JSON_Object*node);462 static void expand_entities(char **text, const json_value *node); 469 463 470 464 /** … … 476 470 * - the user in a twitter_xml_user struct. 477 471 */ 478 static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object*node)472 static struct twitter_xml_status *twitter_xt_get_status(const json_value *node) 479 473 { 480 474 struct twitter_xml_status *txs; 481 const JSON_Object*rt = NULL;482 483 if ( !node) {475 const json_value *rt = NULL; 476 477 if (node->type != json_object) { 484 478 return FALSE; 485 479 } … … 487 481 488 482 JSON_O_FOREACH(node, k, v) { 489 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {490 // TODO: Huh strip html? In json? Not sure whether I have to..483 if (strcmp("text", k) == 0 && v->type == json_string) { 484 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); 491 485 strip_html(txs->text); 492 } else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) {493 // Handling below.494 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {486 } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) { 487 rt = v; 488 } else if (strcmp("created_at", k) == 0 && v->type == json_string) { 495 489 struct tm parsed; 496 490 … … 498 492 this field. :-( Also assumes the timezone used 499 493 is UTC since C time handling functions suck. */ 500 if (strptime( json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {494 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 501 495 txs->created_at = mktime_utc(&parsed); 502 496 } 503 } else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) {504 txs->user = twitter_xt_get_user( json_object(v));505 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {506 txs->rt_id = txs->id = json_integer(v);507 } else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) {508 txs->reply_to = json_integer(v);497 } else if (strcmp("user", k) == 0 && v->type == json_object) { 498 txs->user = twitter_xt_get_user(v); 499 } else if (strcmp("id", k) == 0 && v->type == json_integer) { 500 txs->rt_id = txs->id = v->u.integer; 501 } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) { 502 txs->reply_to = v->u.integer; 509 503 } 510 504 } … … 535 529 * Function to fill a twitter_xml_status struct (DM variant). 536 530 */ 537 static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object*node)531 static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node) 538 532 { 539 533 struct twitter_xml_status *txs; 540 534 541 if ( !node) {535 if (node->type != json_object) { 542 536 return FALSE; 543 537 } … … 545 539 546 540 JSON_O_FOREACH(node, k, v) { 547 if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) { 541 if (strcmp("text", k) == 0 && v->type == json_string) { 542 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); 548 543 strip_html(txs->text); 549 } else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {544 } else if (strcmp("created_at", k) == 0 && v->type == json_string) { 550 545 struct tm parsed; 551 546 … … 553 548 this field. :-( Also assumes the timezone used 554 549 is UTC since C time handling functions suck. */ 555 if (strptime( json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {550 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 556 551 txs->created_at = mktime_utc(&parsed); 557 552 } 558 } else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) {559 txs->user = twitter_xt_get_user( json_object(v));560 } else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {561 txs->id = json_integer(v);553 } else if (strcmp("sender", k) == 0 && v->type == json_object) { 554 txs->user = twitter_xt_get_user(v); 555 } else if (strcmp("id", k) == 0 && v->type == json_integer) { 556 txs->id = v->u.integer; 562 557 } 563 558 } … … 573 568 } 574 569 575 static void expand_entities(char **text, const JSON_Object*node)576 { 577 JSON_Object*entities, *quoted;570 static void expand_entities(char **text, const json_value *node) 571 { 572 json_value *entities, *quoted; 578 573 char *quote_url = NULL, *quote_text = NULL; 579 574 580 if (!( entities = json_object_get_object(node, "entities")))581 return; 582 if ((quoted = json_o bject_get_object(node, "quoted_status"))) {575 if (!((entities = json_o_get(node, "entities")) && entities->type == json_object)) 576 return; 577 if ((quoted = json_o_get(node, "quoted_status")) && quoted->type == json_object) { 583 578 /* New "retweets with comments" feature. Note that this info 584 579 * seems to be included in the streaming API only! Grab the … … 596 591 int i; 597 592 598 if ( json_type(v) != JSONArray) {593 if (v->type != json_array) { 599 594 continue; 600 595 } … … 603 598 } 604 599 605 for (i = 0; i < json_array_get_count(json_array(v)); i++) {600 for (i = 0; i < v->u.array.length; i++) { 606 601 const char *format = "%s%s <%s>%s"; 607 JSON_Object *r = json_array_get_object(json_array(v), i); 608 609 if (!r) { 602 603 if (v->u.array.values[i]->type != json_object) { 610 604 continue; 611 605 } 612 606 613 const char *kort = json_o bject_get_string(r, "url");614 const char *disp = json_o bject_get_string(r, "display_url");615 const char *full = json_o bject_get_string(r, "expanded_url");607 const char *kort = json_o_str(v->u.array.values[i], "url"); 608 const char *disp = json_o_str(v->u.array.values[i], "display_url"); 609 const char *full = json_o_str(v->u.array.values[i], "expanded_url"); 616 610 char *pos, *new; 617 611 … … 642 636 * - the next_cursor. 643 637 */ 644 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,638 static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node, 645 639 struct twitter_xml_list *txl) 646 640 { … … 651 645 txl->type = TXL_STATUS; 652 646 653 if ( json_type(node) != JSONArray) {647 if (node->type != json_array) { 654 648 return FALSE; 655 649 } … … 657 651 // The root <statuses> node should hold the list of statuses <status> 658 652 // Walk over the nodes children. 659 for (i = 0; i < json_array_get_count(json_array(node)); i++) {660 txs = twitter_xt_get_status( json_array_get_object(json_array(node), i));653 for (i = 0; i < node->u.array.length; i++) { 654 txs = twitter_xt_get_status(node->u.array.values[i]); 661 655 if (!txs) { 662 656 continue; … … 864 858 } 865 859 866 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object*o, gboolean from_filter);860 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter); 867 861 868 862 static void twitter_http_stream(struct http_request *req) … … 870 864 struct im_connection *ic = req->data; 871 865 struct twitter_data *td; 872 JSON_Value *parsed;866 json_value *parsed; 873 867 int len = 0; 874 868 char c, *nl; … … 908 902 req->reply_body[len] = '\0'; 909 903 910 if ((parsed = json_parse _string(req->reply_body))) {904 if ((parsed = json_parse(req->reply_body, req->body_size))) { 911 905 from_filter = (req == td->filter_stream); 912 twitter_stream_handle_object(ic, json_object(parsed), from_filter);906 twitter_stream_handle_object(ic, parsed, from_filter); 913 907 } 914 908 json_value_free(parsed); … … 924 918 } 925 919 926 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object*o);920 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o); 927 921 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 928 922 929 static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object*o, gboolean from_filter)923 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter) 930 924 { 931 925 struct twitter_data *td = ic->proto_data; 932 926 struct twitter_xml_status *txs; 933 JSON_Object*c;927 json_value *c; 934 928 935 929 if ((txs = twitter_xt_get_status(o))) { … … 938 932 txs_free(txs); 939 933 return ret; 940 } else if ((c = json_o bject_get_object(o, "direct_message")) &&934 } else if ((c = json_o_get(o, "direct_message")) && 941 935 (txs = twitter_xt_get_dm(c))) { 942 936 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { … … 946 940 txs_free(txs); 947 941 return TRUE; 948 } else if ( json_object_get_string(o, "event")) {942 } else if ((c = json_o_get(o, "event")) && c->type == json_string) { 949 943 twitter_stream_handle_event(ic, o); 950 944 return TRUE; 951 } else if ((c = json_o bject_get_object(o, "disconnect"))) {945 } else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) { 952 946 /* HACK: Because we're inside an event handler, we can't just 953 947 disconnect here. Instead, just change the HTTP status string 954 948 into a Twitter status string. */ 955 char *reason = g_strdup(json_object_get_string(c, "reason"));949 char *reason = json_o_strdup(c, "reason"); 956 950 if (reason) { 957 951 g_free(td->stream->status_string); … … 992 986 } 993 987 994 static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o) 995 { 996 struct twitter_data *td = ic->proto_data; 997 JSON_Object *source = json_object_get_object(o, "source"); 998 JSON_Object *target = json_object_get_object(o, "target"); 999 const char *type = json_object_get_string(o, "event"); 1000 1001 if (!type || !source || !target) { 988 static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o) 989 { 990 struct twitter_data *td = ic->proto_data; 991 json_value *source = json_o_get(o, "source"); 992 json_value *target = json_o_get(o, "target"); 993 const char *type = json_o_str(o, "event"); 994 995 if (!type || !source || source->type != json_object 996 || !target || target->type != json_object) { 1002 997 return FALSE; 1003 998 } … … 1096 1091 struct twitter_filter *tf; 1097 1092 GList *users = NULL; 1098 JSON_Value *parsed; 1093 json_value *parsed; 1094 json_value *id; 1095 const char *name; 1099 1096 GString *fstr; 1100 1097 GSList *l; … … 1121 1118 } 1122 1119 1123 if ( json_type(parsed) != JSONArray) {1120 if (parsed->type != json_array) { 1124 1121 goto finish; 1125 1122 } 1126 1123 1127 for (i = 0; i < json_array_get_count(json_array(parsed)); i++) { 1128 JSON_Object *o = json_array_get_object(json_array(parsed), i); 1129 jint id = json_object_get_integer(o, "id"); 1130 const char *name = json_object_get_string(o, "screen_name"); 1131 1132 if (!name || !id) { 1124 for (i = 0; i < parsed->u.array.length; i++) { 1125 id = json_o_get(parsed->u.array.values[i], "id"); 1126 name = json_o_str(parsed->u.array.values[i], "screen_name"); 1127 1128 if (!name || !id || id->type != json_integer) { 1133 1129 continue; 1134 1130 } … … 1138 1134 1139 1135 if (g_strcasecmp(tf->text, name) == 0) { 1140 tf->uid = id ;1136 tf->uid = id->u.integer; 1141 1137 users = g_list_delete_link(users, u); 1142 1138 break; … … 1379 1375 struct im_connection *ic = req->data; 1380 1376 struct twitter_data *td; 1381 JSON_Value *parsed;1377 json_value *parsed; 1382 1378 struct twitter_xml_list *txl; 1383 1379 … … 1418 1414 struct im_connection *ic = req->data; 1419 1415 struct twitter_data *td; 1420 JSON_Value *parsed;1416 json_value *parsed; 1421 1417 struct twitter_xml_list *txl; 1422 1418 … … 1458 1454 struct im_connection *ic = req->data; 1459 1455 struct twitter_data *td; 1460 JSON_Value *parsed; 1461 jint id; 1456 json_value *parsed, *id; 1462 1457 1463 1458 // Check if the connection is still active. … … 1473 1468 } 1474 1469 1475 if ((id = json_o bject_get_integer(json_object(parsed), "id"))) {1476 td->last_status_id = id ;1470 if ((id = json_o_get(parsed, "id")) && id->type == json_integer) { 1471 td->last_status_id = id->u.integer; 1477 1472 } 1478 1473 … … 1578 1573 g_free(args[1]); 1579 1574 } 1575 1576 static void twitter_http_status_show_url(struct http_request *req) 1577 { 1578 struct im_connection *ic = req->data; 1579 json_value *parsed, *id; 1580 const char *name; 1581 1582 // Check if the connection is still active. 1583 if (!g_slist_find(twitter_connections, ic)) { 1584 return; 1585 } 1586 1587 if (!(parsed = twitter_parse_response(ic, req))) { 1588 return; 1589 } 1590 1591 /* for the parson branch: 1592 name = json_object_dotget_string(json_object(parsed), "user.screen_name"); 1593 id = json_object_get_integer(json_object(parsed), "id"); 1594 */ 1595 1596 name = json_o_str(json_o_get(parsed, "user"), "screen_name"); 1597 id = json_o_get(parsed, "id"); 1598 1599 if (name && id && id->type == json_integer) { 1600 twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer); 1601 } else { 1602 twitter_log(ic, "Error: could not fetch tweet url."); 1603 } 1604 1605 json_value_free(parsed); 1606 } 1607 1608 void twitter_status_show_url(struct im_connection *ic, guint64 id) 1609 { 1610 char *url = g_strdup_printf("%s%" G_GUINT64_FORMAT "%s", TWITTER_STATUS_SHOW_URL, id, ".json"); 1611 twitter_http(ic, url, twitter_http_status_show_url, ic, 0, NULL, 0); 1612 g_free(url); 1613 }
Note: See TracChangeset
for help on using the changeset viewer.