Changes in protocols/twitter/twitter_lib.c [ce402b2:85c3004]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter_lib.c
rce402b2 r85c3004 51 51 52 52 struct twitter_xml_user { 53 guint64 uid;54 53 char *name; 55 54 char *screen_name; … … 62 61 guint64 id, rt_id; /* Usually equal, with RTs id == *original* id */ 63 62 guint64 reply_to; 64 gboolean from_filter;65 struct twitter_xml_status *rt;66 63 }; 67 64 … … 89 86 g_free(txs->text); 90 87 txu_free(txs->user); 91 txs_free(txs->rt);92 88 g_free(txs); 93 89 } … … 396 392 { 397 393 struct twitter_xml_user *txu; 398 json_value *jv;399 394 400 395 txu = g_new0(struct twitter_xml_user, 1); 401 396 txu->name = g_strdup(json_o_str(node, "name")); 402 397 txu->screen_name = g_strdup(json_o_str(node, "screen_name")); 403 404 jv = json_o_get(node, "id");405 txu->uid = jv->u.integer;406 398 407 399 return txu; … … 491 483 if (rtxs) { 492 484 g_free(txs->text); 493 txs->text = g_strdup (rtxs->text);485 txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text); 494 486 txs->id = rtxs->id; 495 txs ->rt = rtxs;487 txs_free(rtxs); 496 488 } 497 489 } else if (entities) { … … 611 603 } 612 604 613 /**614 * Function to properly format a tweet as per the users configuration.615 */616 static char *twitter_msg_get_text(struct im_connection *ic, int log_id, int reply_to,617 struct twitter_xml_status *txs, const char *prefix) {618 gchar * format = set_getstr(&ic->acc->set, "format_string");619 GString * text = g_string_new(NULL);620 621 gchar *c;622 if (reply_to != -1)623 format = set_getstr(&ic->acc->set, "reply_format_string");624 if (txs->rt)625 format = set_getstr(&ic->acc->set, "retweet_format_string");626 627 for (c = format; *c ; c++) {628 if (!(*c == '%' && *(c+1))) {629 text = g_string_append_c(text, *c);630 continue;631 }632 c++; // Move past the %633 switch (*c) {634 case 'i':635 g_string_append_printf(text, "%02x", log_id);636 break;637 case 'r':638 if (reply_to != -1) // In case someone does put %r in the wrong format_string639 g_string_append_printf(text, "%02x", reply_to);640 break;641 case 'a':642 if (txs->rt) // In case someone does put %a in the wrong format_string643 text = g_string_append(text, txs->rt->user->screen_name);644 break;645 case 'c':646 text = g_string_append(text, txs->text);647 break;648 default:649 text = g_string_append_c(text, *c);650 }651 }652 text = g_string_prepend(text, prefix);653 return g_string_free(text, FALSE);654 }655 656 605 /* Will log messages either way. Need to keep track of IDs for stream deduping. 657 606 Plus, show_ids is on by default and I don't see why anyone would disable it. */ … … 692 641 td->log[td->log_id].id = txs->rt_id; 693 642 694 return twitter_msg_get_text(ic, td->log_id, reply_to, txs, prefix); 695 } 696 697 /** 698 * Function that is called to see the filter statuses in groupchat windows. 699 */ 700 static void twitter_status_show_filter(struct im_connection *ic, struct twitter_xml_status *status) 701 { 702 struct twitter_data *td = ic->proto_data; 703 char *msg = twitter_msg_add_id(ic, status, ""); 704 struct twitter_filter *tf; 705 GSList *f; 706 GSList *l; 707 708 for (f = td->filters; f; f = g_slist_next(f)) { 709 tf = f->data; 710 711 switch (tf->type) { 712 case TWITTER_FILTER_TYPE_FOLLOW: 713 if (status->user->uid != tf->uid) 714 continue; 715 break; 716 717 case TWITTER_FILTER_TYPE_TRACK: 718 if (strcasestr(status->text, tf->text) == NULL) 719 continue; 720 break; 721 722 default: 723 continue; 724 } 725 726 for (l = tf->groupchats; l; l = g_slist_next(l)) { 727 imcb_chat_msg(l->data, status->user->screen_name, 728 msg ? msg : status->text, 0, 0); 729 } 730 } 731 732 g_free(msg); 643 if (set_getbool(&ic->acc->set, "show_ids")) { 644 if (reply_to != -1) 645 return g_strdup_printf("\002[\002%02x->%02x\002]\002 %s%s", 646 td->log_id, reply_to, prefix, txs->text); 647 else 648 return g_strdup_printf("\002[\002%02x\002]\002 %s%s", 649 td->log_id, prefix, txs->text); 650 } else { 651 if (*prefix) 652 return g_strconcat(prefix, txs->text, NULL); 653 else 654 return NULL; 655 } 733 656 } 734 657 … … 808 731 strip_newlines(status->text); 809 732 810 if (status->from_filter) 811 twitter_status_show_filter(ic, status); 812 else if (td->flags & TWITTER_MODE_CHAT) 733 if (td->flags & TWITTER_MODE_CHAT) 813 734 twitter_status_show_chat(ic, status); 814 735 else … … 824 745 } 825 746 826 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o , gboolean from_filter);747 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o); 827 748 828 749 static void twitter_http_stream(struct http_request *req) … … 833 754 int len = 0; 834 755 char c, *nl; 835 gboolean from_filter;836 756 837 757 if (!g_slist_find(twitter_connections, ic)) … … 842 762 843 763 if ((req->flags & HTTPC_EOF) || !req->reply_body) { 844 if (req == td->stream) 845 td->stream = NULL; 846 else if (req == td->filter_stream) 847 td->filter_stream = NULL; 848 764 td->stream = NULL; 849 765 imcb_error(ic, "Stream closed (%s)", req->status_string); 850 766 imc_logout(ic, TRUE); … … 863 779 864 780 if ((parsed = json_parse(req->reply_body, req->body_size))) { 865 from_filter = (req == td->filter_stream); 866 twitter_stream_handle_object(ic, parsed, from_filter); 781 twitter_stream_handle_object(ic, parsed); 867 782 } 868 783 json_value_free(parsed); … … 880 795 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs); 881 796 882 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o , gboolean from_filter)797 static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o) 883 798 { 884 799 struct twitter_data *td = ic->proto_data; … … 887 802 888 803 if ((txs = twitter_xt_get_status(o))) { 889 txs->from_filter = from_filter;890 804 gboolean ret = twitter_stream_handle_status(ic, txs); 891 805 txs_free(txs); … … 985 899 } 986 900 987 static gboolean twitter_filter_stream(struct im_connection *ic)988 {989 struct twitter_data *td = ic->proto_data;990 char *args[4] = {"follow", NULL, "track", NULL};991 GString *followstr = g_string_new("");992 GString *trackstr = g_string_new("");993 gboolean ret = FALSE;994 struct twitter_filter *tf;995 GSList *l;996 997 for (l = td->filters; l; l = g_slist_next(l)) {998 tf = l->data;999 1000 switch (tf->type) {1001 case TWITTER_FILTER_TYPE_FOLLOW:1002 if (followstr->len > 0)1003 g_string_append_c(followstr, ',');1004 1005 g_string_append_printf(followstr, "%" G_GUINT64_FORMAT,1006 tf->uid);1007 break;1008 1009 case TWITTER_FILTER_TYPE_TRACK:1010 if (trackstr->len > 0)1011 g_string_append_c(trackstr, ',');1012 1013 g_string_append(trackstr, tf->text);1014 break;1015 1016 default:1017 continue;1018 }1019 }1020 1021 args[1] = followstr->str;1022 args[3] = trackstr->str;1023 1024 if (td->filter_stream)1025 http_close(td->filter_stream);1026 1027 if ((td->filter_stream = twitter_http(ic, TWITTER_FILTER_STREAM_URL,1028 twitter_http_stream, ic, 0,1029 args, 4))) {1030 /* This flag must be enabled or we'll get no data until EOF1031 (which err, kind of, defeats the purpose of a streaming API). */1032 td->filter_stream->flags |= HTTPC_STREAMING;1033 ret = TRUE;1034 }1035 1036 g_string_free(followstr, TRUE);1037 g_string_free(trackstr, TRUE);1038 1039 return ret;1040 }1041 1042 static void twitter_filter_users_post(struct http_request *req)1043 {1044 struct im_connection *ic = req->data;1045 struct twitter_data *td;1046 struct twitter_filter *tf;1047 GList *users = NULL;1048 json_value *parsed;1049 json_value *id;1050 const char *name;1051 GString *fstr;1052 GSList *l;1053 GList *u;1054 int i;1055 1056 // Check if the connection is still active.1057 if (!g_slist_find(twitter_connections, ic))1058 return;1059 1060 td = ic->proto_data;1061 1062 if (!(parsed = twitter_parse_response(ic, req)))1063 return;1064 1065 for (l = td->filters; l; l = g_slist_next(l)) {1066 tf = l->data;1067 1068 if (tf->type == TWITTER_FILTER_TYPE_FOLLOW)1069 users = g_list_prepend(users, tf);1070 }1071 1072 if (parsed->type != json_array)1073 goto finish;1074 1075 for (i = 0; i < parsed->u.array.length; i++) {1076 id = json_o_get(parsed->u.array.values[i], "id");1077 name = json_o_str(parsed->u.array.values[i], "screen_name");1078 1079 if (!name || !id || id->type != json_integer)1080 continue;1081 1082 for (u = users; u; u = g_list_next(u)) {1083 tf = u->data;1084 1085 if (g_strcasecmp(tf->text, name) == 0) {1086 tf->uid = id->u.integer;1087 users = g_list_delete_link(users, u);1088 break;1089 }1090 }1091 }1092 1093 finish:1094 json_value_free(parsed);1095 twitter_filter_stream(ic);1096 1097 if (!users)1098 return;1099 1100 fstr = g_string_new("");1101 1102 for (u = users; u; u = g_list_next(u)) {1103 if (fstr->len > 0)1104 g_string_append(fstr, ", ");1105 1106 g_string_append(fstr, tf->text);1107 }1108 1109 imcb_error(ic, "Failed UID acquisitions: %s", fstr->str);1110 1111 g_string_free(fstr, TRUE);1112 g_list_free(users);1113 }1114 1115 gboolean twitter_open_filter_stream(struct im_connection *ic)1116 {1117 struct twitter_data *td = ic->proto_data;1118 char *args[2] = {"screen_name", NULL};1119 GString *ustr = g_string_new("");1120 struct twitter_filter *tf;1121 struct http_request *req;1122 GSList *l;1123 1124 for (l = td->filters; l; l = g_slist_next(l)) {1125 tf = l->data;1126 1127 if (tf->type != TWITTER_FILTER_TYPE_FOLLOW || tf->uid != 0)1128 continue;1129 1130 if (ustr->len > 0)1131 g_string_append_c(ustr, ',');1132 1133 g_string_append(ustr, tf->text);1134 }1135 1136 if (ustr->len == 0) {1137 g_string_free(ustr, TRUE);1138 return twitter_filter_stream(ic);1139 }1140 1141 args[1] = ustr->str;1142 req = twitter_http(ic, TWITTER_USERS_LOOKUP_URL,1143 twitter_filter_users_post,1144 ic, 0, args, 2);1145 1146 g_string_free(ustr, TRUE);1147 return req != NULL;1148 }1149 1150 901 static void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor); 1151 902 static void twitter_get_mentions(struct im_connection *ic, gint64 next_cursor);
Note: See TracChangeset
for help on using the changeset viewer.