Changeset 5ebff60 for protocols/twitter/twitter_lib.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter_lib.c
raf359b4 r5ebff60 24 24 25 25 /* For strptime(): */ 26 #if (__sun)26 #if (__sun) 27 27 #else 28 28 #define _XOPEN_SOURCE … … 70 70 static void txu_free(struct twitter_xml_user *txu) 71 71 { 72 if (txu == NULL) 73 return; 72 if (txu == NULL) { 73 return; 74 } 74 75 75 76 g_free(txu->name); … … 83 84 static void txs_free(struct twitter_xml_status *txs) 84 85 { 85 if (txs == NULL) 86 return; 86 if (txs == NULL) { 87 return; 88 } 87 89 88 90 g_free(txs->text); … … 98 100 { 99 101 GSList *l; 100 if (txl == NULL) 101 return; 102 103 if (txl == NULL) { 104 return; 105 } 102 106 103 107 for (l = txl->list; l; l = g_slist_next(l)) { … … 148 152 exact Twitter username. */ 149 153 imcb_buddy_nick_hint(ic, name, name); 150 if (td->timeline_gc) 154 if (td->timeline_gc) { 151 155 imcb_chat_add_buddy(td->timeline_gc, name); 152 } else if (td->flags & TWITTER_MODE_MANY) 156 } 157 } else if (td->flags & TWITTER_MODE_MANY) { 153 158 imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL); 159 } 154 160 } 155 161 } … … 171 177 err->type == json_object) { 172 178 const char *msg = json_o_str(err, "message"); 173 if (msg) 179 if (msg) { 174 180 ret = g_strdup_printf("%s (%s)", req->status_string, msg); 181 } 175 182 } 176 183 json_value_free(root); … … 189 196 json_value *ret; 190 197 char path[64] = "", *s; 191 198 192 199 if ((s = strchr(req->request, ' '))) { 193 path[sizeof(path) -1] = '\0';200 path[sizeof(path) - 1] = '\0'; 194 201 strncpy(path, s + 1, sizeof(path) - 1); 195 if ((s = strchr(path, '?')) || (s = strchr(path, ' '))) 202 if ((s = strchr(path, '?')) || (s = strchr(path, ' '))) { 196 203 *s = '\0'; 197 } 198 204 } 205 } 206 199 207 /* Kinda nasty. :-( Trying to suppress error messages, but only 200 208 for periodic (i.e. mentions/timeline) queries. */ 201 209 periodic = strstr(path, "timeline") || strstr(path, "mentions"); 202 210 203 211 if (req->status_code == 401 && logging_in) { 204 212 /* IIRC Twitter once had an outage where they were randomly … … 206 214 only during login. */ 207 215 imcb_error(ic, "Authentication failure (%s)", 208 216 twitter_parse_error(req)); 209 217 imc_logout(ic, FALSE); 210 218 return NULL; 211 219 } else if (req->status_code != 200) { 212 220 // It didn't go well, output the error and return. 213 if (!periodic || logging_in || ++td->http_fails >= 5) 221 if (!periodic || logging_in || ++td->http_fails >= 5) { 214 222 twitter_log(ic, "Error: Could not retrieve %s: %s", 215 path, twitter_parse_error(req)); 216 217 if (logging_in) 223 path, twitter_parse_error(req)); 224 } 225 226 if (logging_in) { 218 227 imc_logout(ic, TRUE); 228 } 219 229 return NULL; 220 230 } else { … … 224 234 if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) { 225 235 imcb_error(ic, "Could not retrieve %s: %s", 226 236 path, "XML parse error"); 227 237 } 228 238 return ret; … … 238 248 // Primitive, but hey! It works... 239 249 char *args[2]; 250 240 251 args[0] = "cursor"; 241 252 args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor); … … 257 268 258 269 c = json_o_get(node, "ids"); 259 if (!c || c->type != json_array) 270 if (!c || c->type != json_array) { 260 271 return FALSE; 261 262 for (i = 0; i < c->u.array.length; i ++) { 263 if (c->u.array.values[i]->type != json_integer) 272 } 273 274 for (i = 0; i < c->u.array.length; i++) { 275 if (c->u.array.values[i]->type != json_integer) { 264 276 continue; 265 277 } 278 266 279 txl->list = g_slist_prepend(txl->list, 267 268 } 269 280 g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer)); 281 } 282 270 283 c = json_o_get(node, "next_cursor"); 271 if (c && c->type == json_integer) 284 if (c && c->type == json_integer) { 272 285 txl->next_cursor = c->u.integer; 273 else286 } else { 274 287 txl->next_cursor = -1; 275 288 } 289 276 290 return TRUE; 277 291 } … … 292 306 293 307 // Check if the connection is still active. 294 if (!g_slist_find(twitter_connections, ic)) 295 return; 308 if (!g_slist_find(twitter_connections, ic)) { 309 return; 310 } 296 311 297 312 td = ic->proto_data; … … 301 316 302 317 // Parse the data. 303 if (!(parsed = twitter_parse_response(ic, req))) 304 return; 305 318 if (!(parsed = twitter_parse_response(ic, req))) { 319 return; 320 } 321 306 322 twitter_xt_get_friends_id_list(parsed, txl); 307 323 json_value_free(parsed); 308 324 309 325 td->follow_ids = txl->list; 310 if (txl->next_cursor) 326 if (txl->next_cursor) { 311 327 /* These were just numbers. Up to 4000 in a response AFAIK so if we get here 312 328 we may be using a spammer account. \o/ */ 313 329 twitter_get_friends_ids(ic, txl->next_cursor); 314 else330 } else { 315 331 /* Now to convert all those numbers into names.. */ 316 332 twitter_get_users_lookup(ic); 333 } 317 334 318 335 txl->list = NULL; … … 332 349 GString *ids = g_string_new(""); 333 350 int i; 334 351 335 352 /* We can request up to 100 users at a time. */ 336 for (i = 0; i < 100 && td->follow_ids; i 337 g_string_append_printf(ids, ",%s", (char *) td->follow_ids->data);353 for (i = 0; i < 100 && td->follow_ids; i++) { 354 g_string_append_printf(ids, ",%s", (char *) td->follow_ids->data); 338 355 g_free(td->follow_ids->data); 339 356 td->follow_ids = g_slist_remove(td->follow_ids, td->follow_ids->data); … … 354 371 * Callback for getting (twitter)friends... 355 372 * 356 * Be afraid, be very afraid! This function will potentially add hundreds of "friends". "Who has 357 * hundreds of friends?" you wonder? You probably not, since you are reading the source of 373 * Be afraid, be very afraid! This function will potentially add hundreds of "friends". "Who has 374 * hundreds of friends?" you wonder? You probably not, since you are reading the source of 358 375 * BitlBee... Get a life and meet new people! 359 376 */ … … 367 384 368 385 // Check if the connection is still active. 369 if (!g_slist_find(twitter_connections, ic)) 370 return; 386 if (!g_slist_find(twitter_connections, ic)) { 387 return; 388 } 371 389 372 390 txl = g_new0(struct twitter_xml_list, 1); … … 374 392 375 393 // Get the user list from the parsed xml feed. 376 if (!(parsed = twitter_parse_response(ic, req))) 377 return; 394 if (!(parsed = twitter_parse_response(ic, req))) { 395 return; 396 } 378 397 twitter_xt_get_users(parsed, txl); 379 398 json_value_free(parsed); … … 395 414 struct twitter_xml_user *txu; 396 415 json_value *jv; 397 416 398 417 txu = g_new0(struct twitter_xml_user, 1); 399 418 txu->name = g_strdup(json_o_str(node, "name")); 400 419 txu->screen_name = g_strdup(json_o_str(node, "screen_name")); 401 420 402 421 jv = json_o_get(node, "id"); 403 422 txu->uid = jv->u.integer; 404 423 405 424 return txu; 406 425 } … … 419 438 txl->type = TXL_USER; 420 439 421 if (!node || node->type != json_array) 440 if (!node || node->type != json_array) { 422 441 return FALSE; 442 } 423 443 424 444 // The root <users> node should hold the list of users <user> 425 445 // Walk over the nodes children. 426 for (i = 0; i < node->u.array.length; i 446 for (i = 0; i < node->u.array.length; i++) { 427 447 txu = twitter_xt_get_user(node->u.array.values[i]); 428 if (txu) 448 if (txu) { 429 449 txl->list = g_slist_prepend(txl->list, txu); 450 } 430 451 } 431 452 … … 453 474 struct twitter_xml_status *txs; 454 475 const json_value *rt = NULL, *entities = NULL; 455 456 if (node->type != json_object) 476 477 if (node->type != json_object) { 457 478 return FALSE; 479 } 458 480 txs = g_new0(struct twitter_xml_status, 1); 459 481 460 JSON_O_FOREACH 482 JSON_O_FOREACH(node, k, v) { 461 483 if (strcmp("text", k) == 0 && v->type == json_string) { 462 484 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); … … 470 492 this field. :-( Also assumes the timezone used 471 493 is UTC since C time handling functions suck. */ 472 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) 494 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 473 495 txs->created_at = mktime_utc(&parsed); 496 } 474 497 } else if (strcmp("user", k) == 0 && v->type == json_object) { 475 498 txs->user = twitter_xt_get_user(v); … … 497 520 } 498 521 499 if (txs->text && txs->user && txs->id) 522 if (txs->text && txs->user && txs->id) { 500 523 return txs; 501 524 } 525 502 526 txs_free(txs); 503 527 return NULL; … … 511 535 struct twitter_xml_status *txs; 512 536 const json_value *entities = NULL; 513 514 if (node->type != json_object) 537 538 if (node->type != json_object) { 515 539 return FALSE; 540 } 516 541 txs = g_new0(struct twitter_xml_status, 1); 517 542 518 JSON_O_FOREACH 543 JSON_O_FOREACH(node, k, v) { 519 544 if (strcmp("text", k) == 0 && v->type == json_string) { 520 545 txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1); … … 526 551 this field. :-( Also assumes the timezone used 527 552 is UTC since C time handling functions suck. */ 528 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) 553 if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) { 529 554 txs->created_at = mktime_utc(&parsed); 555 } 530 556 } else if (strcmp("sender", k) == 0 && v->type == json_object) { 531 557 txs->user = twitter_xt_get_user(v); … … 539 565 } 540 566 541 if (txs->text && txs->user && txs->id) 567 if (txs->text && txs->user && txs->id) { 542 568 return txs; 543 569 } 570 544 571 txs_free(txs); 545 572 return NULL; 546 573 } 547 574 548 static char* expand_entities(char* text, const json_value *entities) { 549 JSON_O_FOREACH (entities, k, v) { 575 static char* expand_entities(char* text, const json_value *entities) 576 { 577 JSON_O_FOREACH(entities, k, v) { 550 578 int i; 551 552 if (v->type != json_array) 579 580 if (v->type != json_array) { 553 581 continue; 554 if (strcmp(k, "urls") != 0 && strcmp(k, "media") != 0) 582 } 583 if (strcmp(k, "urls") != 0 && strcmp(k, "media") != 0) { 555 584 continue; 556 557 for (i = 0; i < v->u.array.length; i ++) { 558 if (v->u.array.values[i]->type != json_object) 585 } 586 587 for (i = 0; i < v->u.array.length; i++) { 588 if (v->u.array.values[i]->type != json_object) { 559 589 continue; 560 590 } 591 561 592 const char *kort = json_o_str(v->u.array.values[i], "url"); 562 593 const char *disp = json_o_str(v->u.array.values[i], "display_url"); 563 594 char *pos, *new; 564 565 if (!kort || !disp || !(pos = strstr(text, kort))) 595 596 if (!kort || !disp || !(pos = strstr(text, kort))) { 566 597 continue; 567 598 } 599 568 600 *pos = '\0'; 569 601 new = g_strdup_printf("%s%s <%s>%s", text, kort, 570 602 disp, pos + strlen(kort)); 571 603 572 604 g_free(text); 573 605 text = new; 574 606 } 575 607 } 576 608 577 609 return text; 578 610 } … … 592 624 // Set the type of the list. 593 625 txl->type = TXL_STATUS; 594 595 if (node->type != json_array) 626 627 if (node->type != json_array) { 596 628 return FALSE; 629 } 597 630 598 631 // The root <statuses> node should hold the list of statuses <status> 599 632 // Walk over the nodes children. 600 for (i = 0; i < node->u.array.length; i 633 for (i = 0; i < node->u.array.length; i++) { 601 634 txs = twitter_xt_get_status(node->u.array.values[i]); 602 if (!txs) 635 if (!txs) { 603 636 continue; 604 637 } 638 605 639 txl->list = g_slist_prepend(txl->list, txs); 606 640 } … … 612 646 Plus, show_ids is on by default and I don't see why anyone would disable it. */ 613 647 static char *twitter_msg_add_id(struct im_connection *ic, 614 648 struct twitter_xml_status *txs, const char *prefix) 615 649 { 616 650 struct twitter_data *td = ic->proto_data; … … 620 654 if (txs->reply_to) { 621 655 int i; 622 for (i = 0; i < TWITTER_LOG_LENGTH; i++) 656 for (i = 0; i < TWITTER_LOG_LENGTH; i++) { 623 657 if (td->log[i].id == txs->reply_to) { 624 658 reply_to = i; 625 659 break; 626 660 } 661 } 627 662 } 628 663 … … 636 671 } 637 672 } 638 673 639 674 td->log_id = (td->log_id + 1) % TWITTER_LOG_LENGTH; 640 675 td->log[td->log_id].id = txs->id; 641 676 td->log[td->log_id].bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name); 642 677 643 678 /* This is all getting hairy. :-( If we RT'ed something ourselves, 644 679 remember OUR id instead so undo will work. In other cases, the 645 680 original tweet's id should be remembered for deduplicating. */ 646 if (g_strcasecmp(txs->user->screen_name, td->user) == 0) 681 if (g_strcasecmp(txs->user->screen_name, td->user) == 0) { 647 682 td->log[td->log_id].id = txs->rt_id; 648 683 } 684 649 685 if (set_getbool(&ic->acc->set, "show_ids")) { 650 if (reply_to != -1) 686 if (reply_to != -1) { 651 687 return g_strdup_printf("\002[\002%02x->%02x\002]\002 %s%s", 652 688 td->log_id, reply_to, prefix, txs->text); 653 else689 } else { 654 690 return g_strdup_printf("\002[\002%02x\002]\002 %s%s", 655 691 td->log_id, prefix, txs->text); 692 } 656 693 } else { 657 if (*prefix) 694 if (*prefix) { 658 695 return g_strconcat(prefix, txs->text, NULL); 659 else696 } else { 660 697 return NULL; 698 } 661 699 } 662 700 } … … 678 716 switch (tf->type) { 679 717 case TWITTER_FILTER_TYPE_FOLLOW: 680 if (status->user->uid != tf->uid) 718 if (status->user->uid != tf->uid) { 681 719 continue; 720 } 682 721 break; 683 722 684 723 case TWITTER_FILTER_TYPE_TRACK: 685 if (strcasestr(status->text, tf->text) == NULL) 724 if (strcasestr(status->text, tf->text) == NULL) { 686 725 continue; 726 } 687 727 break; 688 728 … … 693 733 for (l = tf->groupchats; l; l = g_slist_next(l)) { 694 734 imcb_chat_msg(l->data, status->user->screen_name, 695 735 msg ? msg : status->text, 0, 0); 696 736 } 697 737 } … … 713 753 gc = twitter_groupchat_init(ic); 714 754 715 if (!me) 755 if (!me) { 716 756 /* MUST be done before twitter_msg_add_id() to avoid #872. */ 717 757 twitter_add_buddy(ic, status->user->screen_name, status->user->name); 758 } 718 759 msg = twitter_msg_add_id(ic, status, ""); 719 760 720 761 // Say it! 721 762 if (me) { … … 723 764 } else { 724 765 imcb_chat_msg(gc, status->user->screen_name, 725 766 msg ? msg : status->text, 0, status->created_at); 726 767 } 727 768 … … 744 785 } 745 786 746 if (td->flags & TWITTER_MODE_ONE) 787 if (td->flags & TWITTER_MODE_ONE) { 747 788 prefix = g_strdup_printf("\002<\002%s\002>\002 ", 748 789 status->user->screen_name); 749 else if (!me)790 } else if (!me) { 750 791 twitter_add_buddy(ic, status->user->screen_name, status->user->name); 751 else792 } else { 752 793 prefix = g_strdup("You: "); 794 } 753 795 754 796 text = twitter_msg_add_id(ic, status, prefix ? prefix : ""); … … 766 808 struct twitter_data *td = ic->proto_data; 767 809 char *last_id_str; 768 769 if (status->user == NULL || status->text == NULL) 770 return; 771 810 811 if (status->user == NULL || status->text == NULL) { 812 return; 813 } 814 772 815 /* Grrrr. Would like to do this during parsing, but can't access 773 816 settings from there. */ 774 if (set_getbool(&ic->acc->set, "strip_newlines")) 817 if (set_getbool(&ic->acc->set, "strip_newlines")) { 775 818 strip_newlines(status->text); 776 777 if (status->from_filter) 819 } 820 821 if (status->from_filter) { 778 822 twitter_status_show_filter(ic, status); 779 else if (td->flags & TWITTER_MODE_CHAT)823 } else if (td->flags & TWITTER_MODE_CHAT) { 780 824 twitter_status_show_chat(ic, status); 781 else825 } else { 782 826 twitter_status_show_msg(ic, status); 827 } 783 828 784 829 // Update the timeline_id to hold the highest id, so that by the next request … … 801 846 char c, *nl; 802 847 gboolean from_filter; 803 804 if (!g_slist_find(twitter_connections, ic)) 805 return; 806 848 849 if (!g_slist_find(twitter_connections, ic)) { 850 return; 851 } 852 807 853 ic->flags |= OPT_PONGED; 808 854 td = ic->proto_data; 809 855 810 856 if ((req->flags & HTTPC_EOF) || !req->reply_body) { 811 if (req == td->stream) 857 if (req == td->stream) { 812 858 td->stream = NULL; 813 else if (req == td->filter_stream)859 } else if (req == td->filter_stream) { 814 860 td->filter_stream = NULL; 861 } 815 862 816 863 imcb_error(ic, "Stream closed (%s)", req->status_string); … … 818 865 return; 819 866 } 820 867 821 868 /* MUST search for CRLF, not just LF: 822 869 https://dev.twitter.com/docs/streaming-apis/processing#Parsing_responses */ 823 if (!(nl = strstr(req->reply_body, "\r\n"))) 824 return; 825 870 if (!(nl = strstr(req->reply_body, "\r\n"))) { 871 return; 872 } 873 826 874 len = nl - req->reply_body; 827 875 if (len > 0) { 828 876 c = req->reply_body[len]; 829 877 req->reply_body[len] = '\0'; 830 878 831 879 if ((parsed = json_parse(req->reply_body, req->body_size))) { 832 880 from_filter = (req == td->filter_stream); … … 836 884 req->reply_body[len] = c; 837 885 } 838 886 839 887 http_flush_bytes(req, len + 2); 840 888 841 889 /* One notification might bring multiple events! */ 842 if (req->body_size > 0) 890 if (req->body_size > 0) { 843 891 twitter_http_stream(req); 892 } 844 893 } 845 894 … … 852 901 struct twitter_xml_status *txs; 853 902 json_value *c; 854 903 855 904 if ((txs = twitter_xt_get_status(o))) { 856 905 txs->from_filter = from_filter; … … 860 909 } else if ((c = json_o_get(o, "direct_message")) && 861 910 (txs = twitter_xt_get_dm(c))) { 862 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) 911 if (g_strcasecmp(txs->user->screen_name, td->user) != 0) { 863 912 imcb_buddy_msg(ic, txs->user->screen_name, 864 txs->text, 0, txs->created_at); 913 txs->text, 0, txs->created_at); 914 } 865 915 txs_free(txs); 866 916 return TRUE; … … 886 936 struct twitter_data *td = ic->proto_data; 887 937 int i; 888 938 889 939 for (i = 0; i < TWITTER_LOG_LENGTH; i++) { 890 940 if (td->log[i].id == txs->id) { … … 893 943 } 894 944 } 895 945 896 946 if (!(g_strcasecmp(txs->user->screen_name, td->user) == 0 || 897 947 set_getbool(&ic->acc->set, "fetch_mentions") || … … 905 955 return TRUE; 906 956 } 907 957 908 958 twitter_status_show(ic, txs); 909 959 910 960 return TRUE; 911 961 } … … 917 967 json_value *target = json_o_get(o, "target"); 918 968 const char *type = json_o_str(o, "event"); 919 969 920 970 if (!type || !source || source->type != json_object 921 971 || !target || target->type != json_object) { 922 972 return FALSE; 923 973 } 924 974 925 975 if (strcmp(type, "follow") == 0) { 926 976 struct twitter_xml_user *us = twitter_xt_get_user(source); … … 932 982 txu_free(ut); 933 983 } 934 984 935 985 return TRUE; 936 986 } … … 939 989 { 940 990 struct twitter_data *td = ic->proto_data; 941 char *args[2] = { "with", "followings"};942 991 char *args[2] = { "with", "followings" }; 992 943 993 if ((td->stream = twitter_http(ic, TWITTER_USER_STREAM_URL, 944 994 twitter_http_stream, ic, 0, args, 2))) { … … 948 998 return TRUE; 949 999 } 950 1000 951 1001 return FALSE; 952 1002 } … … 955 1005 { 956 1006 struct twitter_data *td = ic->proto_data; 957 char *args[4] = { "follow", NULL, "track", NULL};1007 char *args[4] = { "follow", NULL, "track", NULL }; 958 1008 GString *followstr = g_string_new(""); 959 1009 GString *trackstr = g_string_new(""); … … 967 1017 switch (tf->type) { 968 1018 case TWITTER_FILTER_TYPE_FOLLOW: 969 if (followstr->len > 0) 1019 if (followstr->len > 0) { 970 1020 g_string_append_c(followstr, ','); 1021 } 971 1022 972 1023 g_string_append_printf(followstr, "%" G_GUINT64_FORMAT, 973 1024 tf->uid); 974 1025 break; 975 1026 976 1027 case TWITTER_FILTER_TYPE_TRACK: 977 if (trackstr->len > 0) 1028 if (trackstr->len > 0) { 978 1029 g_string_append_c(trackstr, ','); 1030 } 979 1031 980 1032 g_string_append(trackstr, tf->text); … … 989 1041 args[3] = trackstr->str; 990 1042 991 if (td->filter_stream) 1043 if (td->filter_stream) { 992 1044 http_close(td->filter_stream); 1045 } 993 1046 994 1047 if ((td->filter_stream = twitter_http(ic, TWITTER_FILTER_STREAM_URL, 995 1048 twitter_http_stream, ic, 0, 996 1049 args, 4))) { 997 1050 /* This flag must be enabled or we'll get no data until EOF 998 1051 (which err, kind of, defeats the purpose of a streaming API). */ … … 1022 1075 1023 1076 // Check if the connection is still active. 1024 if (!g_slist_find(twitter_connections, ic)) 1025 return; 1077 if (!g_slist_find(twitter_connections, ic)) { 1078 return; 1079 } 1026 1080 1027 1081 td = ic->proto_data; 1028 1082 1029 if (!(parsed = twitter_parse_response(ic, req))) 1030 return; 1083 if (!(parsed = twitter_parse_response(ic, req))) { 1084 return; 1085 } 1031 1086 1032 1087 for (l = td->filters; l; l = g_slist_next(l)) { 1033 1088 tf = l->data; 1034 1089 1035 if (tf->type == TWITTER_FILTER_TYPE_FOLLOW) 1090 if (tf->type == TWITTER_FILTER_TYPE_FOLLOW) { 1036 1091 users = g_list_prepend(users, tf); 1037 } 1038 1039 if (parsed->type != json_array) 1092 } 1093 } 1094 1095 if (parsed->type != json_array) { 1040 1096 goto finish; 1097 } 1041 1098 1042 1099 for (i = 0; i < parsed->u.array.length; i++) { … … 1044 1101 name = json_o_str(parsed->u.array.values[i], "screen_name"); 1045 1102 1046 if (!name || !id || id->type != json_integer) 1103 if (!name || !id || id->type != json_integer) { 1047 1104 continue; 1105 } 1048 1106 1049 1107 for (u = users; u; u = g_list_next(u)) { … … 1062 1120 twitter_filter_stream(ic); 1063 1121 1064 if (!users) 1065 return; 1122 if (!users) { 1123 return; 1124 } 1066 1125 1067 1126 fstr = g_string_new(""); 1068 1127 1069 1128 for (u = users; u; u = g_list_next(u)) { 1070 if (fstr->len > 0) 1129 if (fstr->len > 0) { 1071 1130 g_string_append(fstr, ", "); 1131 } 1072 1132 1073 1133 g_string_append(fstr, tf->text); … … 1083 1143 { 1084 1144 struct twitter_data *td = ic->proto_data; 1085 char *args[2] = { "screen_name", NULL};1145 char *args[2] = { "screen_name", NULL }; 1086 1146 GString *ustr = g_string_new(""); 1087 1147 struct twitter_filter *tf; … … 1092 1152 tf = l->data; 1093 1153 1094 if (tf->type != TWITTER_FILTER_TYPE_FOLLOW || tf->uid != 0) 1154 if (tf->type != TWITTER_FILTER_TYPE_FOLLOW || tf->uid != 0) { 1095 1155 continue; 1096 1097 if (ustr->len > 0) 1156 } 1157 1158 if (ustr->len > 0) { 1098 1159 g_string_append_c(ustr, ','); 1160 } 1099 1161 1100 1162 g_string_append(ustr, tf->text); … … 1108 1170 args[1] = ustr->str; 1109 1171 req = twitter_http(ic, TWITTER_USERS_LOOKUP_URL, 1110 1111 1172 twitter_filter_users_post, 1173 ic, 0, args, 2); 1112 1174 1113 1175 g_string_free(ustr, TRUE); … … 1141 1203 twitter_get_mentions(ic, next_cursor); 1142 1204 } 1143 1205 1144 1206 return TRUE; 1145 1207 } … … 1161 1223 1162 1224 imcb_connected(ic); 1163 1225 1164 1226 if (!(td->flags & TWITTER_GOT_TIMELINE)) { 1165 1227 return; … … 1189 1251 while (output) { 1190 1252 struct twitter_xml_status *txs = output->data; 1191 if (txs->id != last_id) 1253 if (txs->id != last_id) { 1192 1254 twitter_status_show(ic, txs); 1255 } 1193 1256 last_id = txs->id; 1194 1257 output = g_slist_remove(output, txs); … … 1227 1290 1228 1291 if (twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, 1229 1230 if (++td->http_fails >= 5) 1292 td->timeline_id ? 6 : 4) == NULL) { 1293 if (++td->http_fails >= 5) { 1231 1294 imcb_error(ic, "Could not retrieve %s: %s", 1232 1295 TWITTER_HOME_TIMELINE_URL, "connection failed"); 1296 } 1233 1297 td->flags |= TWITTER_GOT_TIMELINE; 1234 1298 twitter_flush_timeline(ic); … … 1267 1331 if (twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions, 1268 1332 ic, 0, args, 6) == NULL) { 1269 if (++td->http_fails >= 5) 1333 if (++td->http_fails >= 5) { 1270 1334 imcb_error(ic, "Could not retrieve %s: %s", 1271 1335 TWITTER_MENTIONS_URL, "connection failed"); 1336 } 1272 1337 td->flags |= TWITTER_GOT_MENTIONS; 1273 1338 twitter_flush_timeline(ic); … … 1289 1354 1290 1355 // Check if the connection is still active. 1291 if (!g_slist_find(twitter_connections, ic)) 1292 return; 1356 if (!g_slist_find(twitter_connections, ic)) { 1357 return; 1358 } 1293 1359 1294 1360 td = ic->proto_data; … … 1298 1364 1299 1365 // The root <statuses> node should hold the list of statuses <status> 1300 if (!(parsed = twitter_parse_response(ic, req))) 1366 if (!(parsed = twitter_parse_response(ic, req))) { 1301 1367 goto end; 1368 } 1302 1369 twitter_xt_get_status_list(ic, parsed, txl); 1303 1370 json_value_free(parsed); … … 1305 1372 td->home_timeline_obj = txl; 1306 1373 1307 end: 1308 if (!g_slist_find(twitter_connections, ic)) 1309 return; 1374 end: 1375 if (!g_slist_find(twitter_connections, ic)) { 1376 return; 1377 } 1310 1378 1311 1379 td->flags |= TWITTER_GOT_TIMELINE; … … 1325 1393 1326 1394 // Check if the connection is still active. 1327 if (!g_slist_find(twitter_connections, ic)) 1328 return; 1395 if (!g_slist_find(twitter_connections, ic)) { 1396 return; 1397 } 1329 1398 1330 1399 td = ic->proto_data; … … 1334 1403 1335 1404 // The root <statuses> node should hold the list of statuses <status> 1336 if (!(parsed = twitter_parse_response(ic, req))) 1405 if (!(parsed = twitter_parse_response(ic, req))) { 1337 1406 goto end; 1407 } 1338 1408 twitter_xt_get_status_list(ic, parsed, txl); 1339 1409 json_value_free(parsed); … … 1341 1411 td->mentions_obj = txl; 1342 1412 1343 end: 1344 if (!g_slist_find(twitter_connections, ic)) 1345 return; 1413 end: 1414 if (!g_slist_find(twitter_connections, ic)) { 1415 return; 1416 } 1346 1417 1347 1418 td->flags |= TWITTER_GOT_MENTIONS; … … 1361 1432 1362 1433 // Check if the connection is still active. 1363 if (!g_slist_find(twitter_connections, ic)) 1364 return; 1434 if (!g_slist_find(twitter_connections, ic)) { 1435 return; 1436 } 1365 1437 1366 1438 td = ic->proto_data; 1367 1439 td->last_status_id = 0; 1368 1440 1369 if (!(parsed = twitter_parse_response(ic, req))) 1370 return; 1371 1441 if (!(parsed = twitter_parse_response(ic, req))) { 1442 return; 1443 } 1444 1372 1445 if ((id = json_o_get(parsed, "id")) && id->type == json_integer) { 1373 1446 td->last_status_id = id->u.integer; 1374 1447 } 1375 1448 1376 1449 json_value_free(parsed); 1377 1378 if (req->flags & TWITTER_HTTP_USER_ACK) 1450 1451 if (req->flags & TWITTER_HTTP_USER_ACK) { 1379 1452 twitter_log(ic, "Command processed successfully"); 1453 } 1380 1454 } 1381 1455 … … 1390 1464 g_strdup_printf("%" G_GUINT64_FORMAT, in_reply_to) 1391 1465 }; 1466 1392 1467 twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, 1393 1468 args, in_reply_to ? 4 : 2); 1394 1469 g_free(args[3]); 1395 1470 } … … 1402 1477 { 1403 1478 char *args[4]; 1479 1404 1480 args[0] = "screen_name"; 1405 1481 args[1] = who; … … 1413 1489 { 1414 1490 char *args[2]; 1491 1415 1492 args[0] = "screen_name"; 1416 1493 args[1] = who; 1417 1494 twitter_http(ic, create ? TWITTER_FRIENDSHIPS_CREATE_URL : TWITTER_FRIENDSHIPS_DESTROY_URL, 1418 1495 twitter_http_post, ic, 1, args, 2); 1419 1496 } 1420 1497 … … 1422 1499 { 1423 1500 char *url; 1501 1424 1502 url = g_strdup_printf("%s%" G_GUINT64_FORMAT "%s", 1425 1503 TWITTER_STATUS_DESTROY_URL, id, ".json"); … … 1432 1510 { 1433 1511 char *url; 1512 1434 1513 url = g_strdup_printf("%s%" G_GUINT64_FORMAT "%s", 1435 1514 TWITTER_STATUS_RETWEET_URL, id, ".json"); … … 1448 1527 NULL, 1449 1528 }; 1529 1450 1530 args[1] = screen_name; 1451 1531 twitter_http_f(ic, TWITTER_REPORT_SPAM_URL, twitter_http_post, … … 1462 1542 NULL, 1463 1543 }; 1544 1464 1545 args[1] = g_strdup_printf("%" G_GUINT64_FORMAT, id); 1465 1546 twitter_http_f(ic, TWITTER_FAVORITE_CREATE_URL, twitter_http_post,
Note: See TracChangeset
for help on using the changeset viewer.