Changeset 73ee390 for protocols/twitter/twitter.c
- Timestamp:
- 2015-01-26T03:46:03Z (10 years ago)
- Branches:
- master
- Children:
- dfaa46d
- Parents:
- 5eab298f
- git-author:
- jgeboski <jgeboski@…> (15-12-14 12:17:12)
- git-committer:
- jgeboski <jgeboski@…> (26-01-15 03:46:03)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/twitter/twitter.c
r5eab298f r73ee390 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 … … 436 645 437 646 if (td) { 647 if (td->filter_update_id > 0) 648 b_event_remove(td->filter_update_id); 649 438 650 http_close(td->stream); 651 twitter_filter_remove_all(ic); 439 652 oauth_info_free(td->oauth_info); 440 653 g_free(td->user); … … 509 722 } 510 723 724 static struct groupchat *twitter_chat_join(struct im_connection *ic, 725 const char *room, const char *nick, 726 const char *password, set_t **sets) 727 { 728 struct groupchat *c = imcb_chat_new(ic, room); 729 GSList *fs = twitter_filter_parse(c, room); 730 GString *topic = g_string_new(""); 731 struct twitter_filter *tf; 732 GSList *l; 733 734 fs = g_slist_sort(fs, (GCompareFunc) twitter_filter_cmp); 735 736 for (l = fs; l; l = g_slist_next(l)) { 737 tf = l->data; 738 739 if (topic->len > 0) 740 g_string_append(topic, ", "); 741 742 if (tf->type == TWITTER_FILTER_TYPE_FOLLOW) 743 g_string_append_c(topic, '@'); 744 745 g_string_append(topic, tf->text); 746 } 747 748 if (topic->len > 0) 749 g_string_prepend(topic, "Twitter Filter: "); 750 751 imcb_chat_topic(c, NULL, topic->str, 0); 752 imcb_chat_add_buddy(c, ic->acc->user); 753 754 if (topic->len == 0) { 755 imcb_error(ic, "Failed to handle any filters"); 756 imcb_chat_free(c); 757 c = NULL; 758 } 759 760 g_string_free(topic, TRUE); 761 g_slist_free(fs); 762 763 return c; 764 } 765 511 766 static void twitter_chat_leave(struct groupchat *c) 512 767 { 513 768 struct twitter_data *td = c->ic->proto_data; 514 769 515 if (c != td->timeline_gc) 516 return; /* WTF? */ 770 if (c != td->timeline_gc) { 771 twitter_filter_remove(c); 772 imcb_chat_free(c); 773 return; 774 } 517 775 518 776 /* If the user leaves the channel: Fine. Rejoin him/her once new … … 748 1006 ret->chat_msg = twitter_chat_msg; 749 1007 ret->chat_invite = twitter_chat_invite; 1008 ret->chat_join = twitter_chat_join; 750 1009 ret->chat_leave = twitter_chat_leave; 751 1010 ret->keepalive = twitter_keepalive;
Note: See TracChangeset
for help on using the changeset viewer.