Changes in / [5ca1416:70ec7ab]
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
r5ca1416 r70ec7ab 121 121 <description> 122 122 <para> 123 This command deletes an account from your account list. You should signoff the account before deleting it.123 This commands deletes an account from your account list. You should signoff the account before deleting it. 124 124 </para> 125 125 … … 853 853 <varlistentry><term>favourite <screenname|#id></term><listitem><para>Favo<emphasis>u</emphasis>rite the given user's most recent tweet, or the given tweet ID.</para></listitem></varlistentry> 854 854 <varlistentry><term>post <message></term><listitem><para>Post a tweet</para></listitem></varlistentry> 855 <varlistentry><term>url <screenname|#id></term><listitem><para>Show URL for a tweet to open it in a browser (and see context)</para></listitem></varlistentry>856 855 </variablelist> 857 856 -
protocols/twitter/twitter.c
r5ca1416 r70ec7ab 867 867 } 868 868 869 bee_user_t twitter_log_local_user;870 871 869 /** Convert the given bitlbee tweet ID, bitlbee username, or twitter tweet ID 872 870 * into a twitter tweet ID. … … 899 897 bu = td->log[id].bu; 900 898 id = td->log[id].id; 899 /* Beware of dangling pointers! */ 900 if (!g_slist_find(ic->bee->users, bu)) { 901 bu = NULL; 902 } 901 903 } else if (twitter_parse_id(arg, 10, &id)) { 902 904 /* Allow normal tweet IDs as well; not a very useful … … 909 911 } 910 912 if (bu_) { 911 if (bu == &twitter_log_local_user) {912 /* HACK alert. There's no bee_user object for the local913 * user so just fake one for the few cmds that need it. */914 twitter_log_local_user.handle = td->user;915 } else {916 /* Beware of dangling pointers! */917 if (!g_slist_find(ic->bee->users, bu)) {918 bu = NULL;919 }920 }921 913 *bu_ = bu; 922 914 } … … 1011 1003 in_reply_to = id; 1012 1004 allow_post = TRUE; 1013 } else if (g_strcasecmp(cmd[0], "url") == 0) {1014 id = twitter_message_id_from_command_arg(ic, cmd[1], &bu);1015 if (!id) {1016 twitter_log(ic, "Tweet `%s' does not exist", cmd[1]);1017 } else {1018 /* More common link is twitter.com/$UID/status/$ID (and that's1019 * what this will 302 to) but can't generate that since for RTs,1020 * bu here points at the retweeter while id contains the id of1021 * the original message. */1022 twitter_log(ic, "https://twitter.com/statuses/%lld", id);1023 }1024 goto eof;1025 1026 1005 } else if (g_strcasecmp(cmd[0], "post") == 0) { 1027 1006 message += 5; -
protocols/twitter/twitter.h
r5ca1416 r70ec7ab 101 101 struct twitter_log_data { 102 102 guint64 id; 103 /* DANGER: bu can be a dead pointer. Check it first. 104 * twitter_message_id_from_command_arg() will do this. */ 105 struct bee_user *bu; 103 struct bee_user *bu; /* DANGER: can be a dead pointer. Check it first. */ 106 104 }; 107 105 … … 112 110 */ 113 111 extern GSList *twitter_connections; 114 115 /**116 * Evil hack: Fake bee_user which will always point at the local user.117 * Sometimes used as a return value by twitter_message_id_from_command_arg.118 * NOT thread safe but don't you dare to even think of ever making BitlBee119 * threaded. :-)120 */121 extern bee_user_t twitter_log_local_user;122 112 123 113 void twitter_login_finish(struct im_connection *ic); -
protocols/twitter/twitter_lib.c
r5ca1416 r70ec7ab 460 460 #endif 461 461 462 static void expand_entities(char **text, const json_value *node);462 static char* expand_entities(char* text, const json_value *entities); 463 463 464 464 /** … … 473 473 { 474 474 struct twitter_xml_status *txs; 475 const json_value *rt = NULL ;475 const json_value *rt = NULL, *entities = NULL; 476 476 477 477 if (node->type != json_object) { … … 501 501 } else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) { 502 502 txs->reply_to = v->u.integer; 503 } else if (strcmp("entities", k) == 0 && v->type == json_object) { 504 entities = v; 503 505 } 504 506 } … … 514 516 txs_free(rtxs); 515 517 } 516 } else {517 expand_entities(&txs->text, node);518 } else if (entities) { 519 txs->text = expand_entities(txs->text, entities); 518 520 } 519 521 … … 532 534 { 533 535 struct twitter_xml_status *txs; 536 const json_value *entities = NULL; 534 537 535 538 if (node->type != json_object) { … … 558 561 } 559 562 560 expand_entities(&txs->text, node); 563 if (entities) { 564 txs->text = expand_entities(txs->text, entities); 565 } 561 566 562 567 if (txs->text && txs->user && txs->id) { … … 568 573 } 569 574 570 static void expand_entities(char **text, const json_value *node) 571 { 572 json_value *entities, *quoted; 573 char *quote_url = NULL, *quote_text = NULL; 574 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) { 578 /* New "retweets with comments" feature. Note that this info 579 * seems to be included in the streaming API only! Grab the 580 * full message and try to insert it when we run into the 581 * Tweet entity. */ 582 struct twitter_xml_status *txs = twitter_xt_get_status(quoted); 583 quote_text = g_strdup_printf("@%s: %s", txs->user->screen_name, txs->text); 584 quote_url = g_strdup_printf("%s/status/%" G_GUINT64_FORMAT, txs->user->screen_name, txs->id); 585 txs_free(txs); 586 } else { 587 quoted = NULL; 588 } 589 575 static char* expand_entities(char* text, const json_value *entities) 576 { 590 577 JSON_O_FOREACH(entities, k, v) { 591 578 int i; … … 599 586 600 587 for (i = 0; i < v->u.array.length; i++) { 601 const char *format = "%s%s <%s>%s";602 603 588 if (v->u.array.values[i]->type != json_object) { 604 589 continue; … … 607 592 const char *kort = json_o_str(v->u.array.values[i], "url"); 608 593 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");610 594 char *pos, *new; 611 595 612 if (!kort || !disp || !(pos = strstr( *text, kort))) {596 if (!kort || !disp || !(pos = strstr(text, kort))) { 613 597 continue; 614 598 } 615 if (quote_url && strstr(full, quote_url)) {616 format = "%s<%s> [%s]%s";617 disp = quote_text;618 }619 599 620 600 *pos = '\0'; 621 new = g_strdup_printf( format, *text, kort,601 new = g_strdup_printf("%s%s <%s>%s", text, kort, 622 602 disp, pos + strlen(kort)); 623 603 624 g_free( *text);625 *text = new;626 } 627 } 628 g_free(quote_text); 629 g_free(quote_url);604 g_free(text); 605 text = new; 606 } 607 } 608 609 return text; 630 610 } 631 611 … … 701 681 if (g_strcasecmp(txs->user->screen_name, td->user) == 0) { 702 682 td->log[td->log_id].id = txs->rt_id; 703 /* More useful than NULL. */704 td->log[td->log_id].bu = &twitter_log_local_user;705 683 } 706 684
Note: See TracChangeset
for help on using the changeset viewer.