Changes in / [70ec7ab:5ca1416]
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
r70ec7ab r5ca1416 121 121 <description> 122 122 <para> 123 This command sdeletes an account from your account list. You should signoff the account before deleting it.123 This command 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> 855 856 </variablelist> 856 857 -
protocols/twitter/twitter.c
r70ec7ab r5ca1416 867 867 } 868 868 869 bee_user_t twitter_log_local_user; 870 869 871 /** Convert the given bitlbee tweet ID, bitlbee username, or twitter tweet ID 870 872 * into a twitter tweet ID. … … 897 899 bu = td->log[id].bu; 898 900 id = td->log[id].id; 899 /* Beware of dangling pointers! */900 if (!g_slist_find(ic->bee->users, bu)) {901 bu = NULL;902 }903 901 } else if (twitter_parse_id(arg, 10, &id)) { 904 902 /* Allow normal tweet IDs as well; not a very useful … … 911 909 } 912 910 if (bu_) { 911 if (bu == &twitter_log_local_user) { 912 /* HACK alert. There's no bee_user object for the local 913 * 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 } 913 921 *bu_ = bu; 914 922 } … … 1003 1011 in_reply_to = id; 1004 1012 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's 1019 * 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 of 1021 * the original message. */ 1022 twitter_log(ic, "https://twitter.com/statuses/%lld", id); 1023 } 1024 goto eof; 1025 1005 1026 } else if (g_strcasecmp(cmd[0], "post") == 0) { 1006 1027 message += 5; -
protocols/twitter/twitter.h
r70ec7ab r5ca1416 101 101 struct twitter_log_data { 102 102 guint64 id; 103 struct bee_user *bu; /* DANGER: can be a dead pointer. Check it first. */ 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; 104 106 }; 105 107 … … 110 112 */ 111 113 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 BitlBee 119 * threaded. :-) 120 */ 121 extern bee_user_t twitter_log_local_user; 112 122 113 123 void twitter_login_finish(struct im_connection *ic); -
protocols/twitter/twitter_lib.c
r70ec7ab r5ca1416 460 460 #endif 461 461 462 static char* expand_entities(char* text, const json_value *entities);462 static void expand_entities(char **text, const json_value *node); 463 463 464 464 /** … … 473 473 { 474 474 struct twitter_xml_status *txs; 475 const json_value *rt = NULL , *entities = NULL;475 const json_value *rt = 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;505 503 } 506 504 } … … 516 514 txs_free(rtxs); 517 515 } 518 } else if (entities){519 txs->text = expand_entities(txs->text, entities);516 } else { 517 expand_entities(&txs->text, node); 520 518 } 521 519 … … 534 532 { 535 533 struct twitter_xml_status *txs; 536 const json_value *entities = NULL;537 534 538 535 if (node->type != json_object) { … … 561 558 } 562 559 563 if (entities) { 564 txs->text = expand_entities(txs->text, entities); 565 } 560 expand_entities(&txs->text, node); 566 561 567 562 if (txs->text && txs->user && txs->id) { … … 573 568 } 574 569 575 static char* expand_entities(char* text, const json_value *entities) 576 { 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 577 590 JSON_O_FOREACH(entities, k, v) { 578 591 int i; … … 586 599 587 600 for (i = 0; i < v->u.array.length; i++) { 601 const char *format = "%s%s <%s>%s"; 602 588 603 if (v->u.array.values[i]->type != json_object) { 589 604 continue; … … 592 607 const char *kort = json_o_str(v->u.array.values[i], "url"); 593 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"); 594 610 char *pos, *new; 595 611 596 if (!kort || !disp || !(pos = strstr( text, kort))) {612 if (!kort || !disp || !(pos = strstr(*text, kort))) { 597 613 continue; 598 614 } 615 if (quote_url && strstr(full, quote_url)) { 616 format = "%s<%s> [%s]%s"; 617 disp = quote_text; 618 } 599 619 600 620 *pos = '\0'; 601 new = g_strdup_printf( "%s%s <%s>%s",text, kort,621 new = g_strdup_printf(format, *text, kort, 602 622 disp, pos + strlen(kort)); 603 623 604 g_free( text);605 text = new;606 } 607 } 608 609 return text;624 g_free(*text); 625 *text = new; 626 } 627 } 628 g_free(quote_text); 629 g_free(quote_url); 610 630 } 611 631 … … 681 701 if (g_strcasecmp(txs->user->screen_name, td->user) == 0) { 682 702 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; 683 705 } 684 706
Note: See TracChangeset
for help on using the changeset viewer.