Changes in protocols/twitter/twitter.c [7549d00:ce402b2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
r7549d00 rce402b2 31 31 32 32 GSList *twitter_connections = NULL; 33 34 static int twitter_filter_cmp(struct twitter_filter *tf1, 35 struct twitter_filter *tf2) 36 { 37 int i1 = 0; 38 int i2 = 0; 39 int i; 40 41 static const twitter_filter_type_t types[] = { 42 /* Order of the types */ 43 TWITTER_FILTER_TYPE_FOLLOW, 44 TWITTER_FILTER_TYPE_TRACK 45 }; 46 47 for (i = 0; i < G_N_ELEMENTS(types); i++) { 48 if (types[i] == tf1->type) { 49 i1 = i + 1; 50 break; 51 } 52 } 53 54 for (i = 0; i < G_N_ELEMENTS(types); i++) { 55 if (types[i] == tf2->type) { 56 i2 = i + 1; 57 break; 58 } 59 } 60 61 if (i1 != i2) { 62 /* With different types, return their difference */ 63 return i1 - i2; 64 } 65 66 /* With the same type, return the text comparison */ 67 return g_strcasecmp(tf1->text, tf2->text); 68 } 69 70 static gboolean twitter_filter_update(gpointer data, gint fd, 71 b_input_condition cond) 72 { 73 struct im_connection *ic = data; 74 struct twitter_data *td = ic->proto_data; 75 76 if (td->filters) { 77 twitter_open_filter_stream(ic); 78 } else if (td->filter_stream) { 79 http_close(td->filter_stream); 80 td->filter_stream = NULL; 81 } 82 83 td->filter_update_id = 0; 84 return FALSE; 85 } 86 87 static struct twitter_filter *twitter_filter_get(struct groupchat *c, 88 twitter_filter_type_t type, 89 const char *text) 90 { 91 struct twitter_data *td = c->ic->proto_data; 92 struct twitter_filter *tf = NULL; 93 struct twitter_filter tfc = {type, (char*) text}; 94 GSList *l; 95 96 for (l = td->filters; l; l = g_slist_next(l)) { 97 tf = l->data; 98 99 if (twitter_filter_cmp(tf, &tfc) == 0) 100 break; 101 102 tf = NULL; 103 } 104 105 if (!tf) { 106 tf = g_new0(struct twitter_filter, 1); 107 tf->type = type; 108 tf->text = g_strdup(text); 109 td->filters = g_slist_prepend(td->filters, tf); 110 } 111 112 if (!g_slist_find(tf->groupchats, c)) 113 tf->groupchats = g_slist_prepend(tf->groupchats, c); 114 115 if (td->filter_update_id > 0) 116 b_event_remove(td->filter_update_id); 117 118 /* Wait for other possible filter changes to avoid request spam */ 119 td->filter_update_id = b_timeout_add(TWITTER_FILTER_UPDATE_WAIT, 120 twitter_filter_update, c->ic); 121 return tf; 122 } 123 124 static void twitter_filter_free(struct twitter_filter *tf) 125 { 126 g_slist_free(tf->groupchats); 127 g_free(tf->text); 128 g_free(tf); 129 } 130 131 static void twitter_filter_remove(struct groupchat *c) 132 { 133 struct twitter_data *td = c->ic->proto_data; 134 struct twitter_filter *tf; 135 GSList *l = td->filters; 136 GSList *p; 137 138 while (l != NULL) { 139 tf = l->data; 140 tf->groupchats = g_slist_remove(tf->groupchats, c); 141 142 p = l; 143 l = g_slist_next(l); 144 145 if (!tf->groupchats) { 146 twitter_filter_free(tf); 147 td->filters = g_slist_delete_link(td->filters, p); 148 } 149 } 150 151 if (td->filter_update_id > 0) 152 b_event_remove(td->filter_update_id); 153 154 /* Wait for other possible filter changes to avoid request spam */ 155 td->filter_update_id = b_timeout_add(TWITTER_FILTER_UPDATE_WAIT, 156 twitter_filter_update, c->ic);} 157 158 static void twitter_filter_remove_all(struct im_connection *ic) 159 { 160 struct twitter_data *td = ic->proto_data; 161 GSList *chats = NULL; 162 struct twitter_filter *tf; 163 GSList *l = td->filters; 164 GSList *p; 165 166 while (l != NULL) { 167 tf = l->data; 168 169 /* Build up a list of groupchats to be freed */ 170 for (p = tf->groupchats; p; p = g_slist_next(p)) { 171 if (!g_slist_find(chats, p->data)) 172 chats = g_slist_prepend(chats, p->data); 173 } 174 175 p = l; 176 l = g_slist_next(l); 177 twitter_filter_free(p->data); 178 td->filters = g_slist_delete_link(td->filters, p); 179 } 180 181 l = chats; 182 183 while (l != NULL) { 184 p = l; 185 l = g_slist_next(l); 186 187 /* Freed each remaining groupchat */ 188 imcb_chat_free(p->data); 189 chats = g_slist_delete_link(chats, p); 190 } 191 192 if (td->filter_stream) { 193 http_close(td->filter_stream); 194 td->filter_stream = NULL; 195 } 196 } 197 198 static GSList *twitter_filter_parse(struct groupchat *c, const char *text) 199 { 200 char **fs = g_strsplit(text, ";", 0); 201 GSList *ret = NULL; 202 struct twitter_filter *tf; 203 char **f; 204 char *v; 205 int i; 206 int t; 207 208 static const twitter_filter_type_t types[] = { 209 TWITTER_FILTER_TYPE_FOLLOW, 210 TWITTER_FILTER_TYPE_TRACK 211 }; 212 213 static const char *typestrs[] = { 214 "follow", 215 "track" 216 }; 217 218 for (f = fs; *f; f++) { 219 if ((v = strchr(*f, ':')) == NULL) 220 continue; 221 222 *(v++) = 0; 223 224 for (t = -1, i = 0; i < G_N_ELEMENTS(types); i++) { 225 if (g_strcasecmp(typestrs[i], *f) == 0) { 226 t = i; 227 break; 228 } 229 } 230 231 if (t < 0 || strlen(v) == 0) 232 continue; 233 234 tf = twitter_filter_get(c, types[t], v); 235 ret = g_slist_prepend(ret, tf); 236 } 237 238 g_strfreev(fs); 239 return ret; 240 } 241 33 242 /** 34 243 * Main loop function … … 51 260 struct twitter_data *td = ic->proto_data; 52 261 53 char *last_tweet = set_getstr(&ic->acc->set, " last_tweet");262 char *last_tweet = set_getstr(&ic->acc->set, "_last_tweet"); 54 263 if (last_tweet) 55 264 td->timeline_id = g_ascii_strtoull(last_tweet, NULL, 0); … … 330 539 331 540 s = set_add(&acc->set, "strip_newlines", "false", set_eval_bool, acc); 332 333 s = set_add(&acc->set, "last_tweet", "0", NULL, acc); 334 s->flags |= SET_HIDDEN; 541 542 s = set_add(&acc->set, "format_string", "\002[\002%i\002]\002 %c", NULL, acc); 543 s = set_add(&acc->set, "retweet_format_string", "\002[\002%i\002]\002 RT @%a: %c", NULL, acc); 544 s = set_add(&acc->set, "reply_format_string", "\002[\002%i->%r\002]\002 %c", NULL, acc); 545 546 s = set_add(&acc->set, "_last_tweet", "0", NULL, acc); 547 s->flags |= SET_HIDDEN | SET_NOSAVE; 335 548 336 549 if (strcmp(acc->prpl->name, "twitter") == 0) { … … 436 649 437 650 if (td) { 651 if (td->filter_update_id > 0) 652 b_event_remove(td->filter_update_id); 653 438 654 http_close(td->stream); 655 twitter_filter_remove_all(ic); 439 656 oauth_info_free(td->oauth_info); 440 657 g_free(td->user); … … 509 726 } 510 727 728 static struct groupchat *twitter_chat_join(struct im_connection *ic, 729 const char *room, const char *nick, 730 const char *password, set_t **sets) 731 { 732 struct groupchat *c = imcb_chat_new(ic, room); 733 GSList *fs = twitter_filter_parse(c, room); 734 GString *topic = g_string_new(""); 735 struct twitter_filter *tf; 736 GSList *l; 737 738 fs = g_slist_sort(fs, (GCompareFunc) twitter_filter_cmp); 739 740 for (l = fs; l; l = g_slist_next(l)) { 741 tf = l->data; 742 743 if (topic->len > 0) 744 g_string_append(topic, ", "); 745 746 if (tf->type == TWITTER_FILTER_TYPE_FOLLOW) 747 g_string_append_c(topic, '@'); 748 749 g_string_append(topic, tf->text); 750 } 751 752 if (topic->len > 0) 753 g_string_prepend(topic, "Twitter Filter: "); 754 755 imcb_chat_topic(c, NULL, topic->str, 0); 756 imcb_chat_add_buddy(c, ic->acc->user); 757 758 if (topic->len == 0) { 759 imcb_error(ic, "Failed to handle any filters"); 760 imcb_chat_free(c); 761 c = NULL; 762 } 763 764 g_string_free(topic, TRUE); 765 g_slist_free(fs); 766 767 return c; 768 } 769 511 770 static void twitter_chat_leave(struct groupchat *c) 512 771 { 513 772 struct twitter_data *td = c->ic->proto_data; 514 773 515 if (c != td->timeline_gc) 516 return; /* WTF? */ 774 if (c != td->timeline_gc) { 775 twitter_filter_remove(c); 776 imcb_chat_free(c); 777 return; 778 } 517 779 518 780 /* If the user leaves the channel: Fine. Rejoin him/her once new … … 674 936 in_reply_to = id; 675 937 allow_post = TRUE; 938 } else if (g_strcasecmp(cmd[0], "rawreply") == 0 && cmd[1] && cmd[2]) { 939 id = twitter_message_id_from_command_arg(ic, cmd[1], NULL); 940 if (!id) { 941 twitter_log(ic, "Tweet `%s' does not exist", cmd[1]); 942 goto eof; 943 } 944 message = cmd[2]; 945 in_reply_to = id; 946 allow_post = TRUE; 676 947 } else if (g_strcasecmp(cmd[0], "post") == 0) { 677 948 message += 5; … … 748 1019 ret->chat_msg = twitter_chat_msg; 749 1020 ret->chat_invite = twitter_chat_invite; 1021 ret->chat_join = twitter_chat_join; 750 1022 ret->chat_leave = twitter_chat_leave; 751 1023 ret->keepalive = twitter_keepalive;
Note: See TracChangeset
for help on using the changeset viewer.