Changeset c9b5817


Ignore:
Timestamp:
2012-11-25T00:55:47Z (12 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
e9bdfbc
Parents:
5f2f728
Message:

Minor rework: Always fill td->log now and use it not just for show_ids, but
also for stream deduplication. Also, drop tweets from unknown people unless
fetch_mentions is set. The stream will feed us that spam either way but not
everyone wants to see it.

Last, fixing a bug where in streaming mode, per-user last tweet times were
no longer getting tracked.

Location:
protocols/twitter
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • protocols/twitter/twitter.c

    r5f2f728 rc9b5817  
    286286
    287287        s = set_add(&acc->set, "show_ids", "true", set_eval_bool, acc);
    288         s->flags |= ACC_SET_OFFLINE_ONLY;
    289288
    290289        s = set_add(&acc->set, "show_old_mentions", "20", set_eval_int, acc);
     
    363362        imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL);
    364363
    365         if (set_getbool(&acc->set, "show_ids"))
    366                 td->log = g_new0(struct twitter_log_data, TWITTER_LOG_LENGTH);
     364        td->log = g_new0(struct twitter_log_data, TWITTER_LOG_LENGTH);
     365        td->log_id = -1;
    367366
    368367        twitter_login_finish(ic);
  • protocols/twitter/twitter_lib.c

    r5f2f728 rc9b5817  
    458458 *  - the user in a twitter_xml_user struct.
    459459 */
    460 static gboolean twitter_xt_get_status(const json_value *node, struct twitter_xml_status *txs)
    461 {
     460static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
     461{
     462        struct twitter_xml_status *txs;
    462463        const json_value *rt = NULL, *entities = NULL;
    463464       
    464465        if (node->type != json_object)
    465466                return FALSE;
     467        txs = g_new0(struct twitter_xml_status, 1);
    466468
    467469        JSON_O_FOREACH (node, k, v) {
     
    492494           wasn't truncated because it may be lying. */
    493495        if (rt) {
    494                 struct twitter_xml_status *rtxs = g_new0(struct twitter_xml_status, 1);
    495                 if (!twitter_xt_get_status(rt, rtxs)) {
     496                struct twitter_xml_status *rtxs = twitter_xt_get_status(rt);
     497                if (rtxs) {
     498                        g_free(txs->text);
     499                        txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text);
     500                        txs->id = rtxs->id;
    496501                        txs_free(rtxs);
    497                         return TRUE;
    498                 }
    499 
    500                 g_free(txs->text);
    501                 txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text);
    502                 txs_free(rtxs);
     502                }
    503503        } else if (entities) {
    504504                txs->text = expand_entities(txs->text, entities);
    505505        }
    506506
    507         return txs->text && txs->user && txs->id;
     507        if (txs->text && txs->user && txs->id)
     508                return txs;
     509       
     510        txs_free(txs);
     511        return NULL;
    508512}
    509513
     
    585589{
    586590        struct twitter_xml_status *txs;
    587         bee_user_t *bu;
    588591        int i;
    589592
     
    597600        // Walk over the nodes children.
    598601        for (i = 0; i < node->u.array.length; i ++) {
    599                 txs = g_new0(struct twitter_xml_status, 1);
    600                 twitter_xt_get_status(node->u.array.values[i], txs);
    601                 // Put the item in the front of the list.
     602                txs = twitter_xt_get_status(node->u.array.values[i]);
     603                if (!txs)
     604                        continue;
     605               
    602606                txl->list = g_slist_prepend(txl->list, txs);
    603 
    604                 if (txs->user && txs->user->screen_name &&
    605                     (bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name))) {
    606                         struct twitter_user_data *tud = bu->data;
    607 
    608                         if (txs->id > tud->last_id) {
    609                                 tud->last_id = txs->id;
    610                                 tud->last_time = txs->created_at;
    611                         }
    612                 }
    613607        }
    614608
     
    616610}
    617611
     612/* Will log messages either way. Need to keep track of IDs for stream deduping.
     613   Plus, show_ids is on by default and I don't see why anyone would disable it. */
    618614static char *twitter_msg_add_id(struct im_connection *ic,
    619615                                struct twitter_xml_status *txs, const char *prefix)
    620616{
    621617        struct twitter_data *td = ic->proto_data;
    622         char *ret = NULL;
    623 
    624         if (!set_getbool(&ic->acc->set, "show_ids")) {
     618        int reply_to = -1;
     619        bee_user_t *bu;
     620
     621        if (txs->reply_to) {
     622                int i;
     623                for (i = 0; i < TWITTER_LOG_LENGTH; i++)
     624                        if (td->log[i].id == txs->reply_to) {
     625                                reply_to = i;
     626                                break;
     627                        }
     628        }
     629
     630        if (txs->user && txs->user->screen_name &&
     631            (bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name))) {
     632                struct twitter_user_data *tud = bu->data;
     633
     634                if (txs->id > tud->last_id) {
     635                        tud->last_id = txs->id;
     636                        tud->last_time = txs->created_at;
     637                }
     638        }
     639       
     640        td->log_id = (td->log_id + 1) % TWITTER_LOG_LENGTH;
     641        td->log[td->log_id].id = txs->id;
     642        td->log[td->log_id].bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name);
     643       
     644        if (set_getbool(&ic->acc->set, "show_ids")) {
     645                if (reply_to != -1)
     646                        return g_strdup_printf("\002[\002%02d->%02d\002]\002 %s%s",
     647                                               td->log_id, reply_to, prefix, txs->text);
     648                else
     649                        return g_strdup_printf("\002[\002%02d\002]\002 %s%s",
     650                                               td->log_id, prefix, txs->text);
     651        } else {
    625652                if (*prefix)
    626653                        return g_strconcat(prefix, txs->text, NULL);
     
    628655                        return NULL;
    629656        }
    630 
    631         td->log[td->log_id].id = txs->id;
    632         td->log[td->log_id].bu = bee_user_by_handle(ic->bee, ic, txs->user->screen_name);
    633         if (txs->reply_to) {
    634                 int i;
    635                 for (i = 0; i < TWITTER_LOG_LENGTH; i++)
    636                         if (td->log[i].id == txs->reply_to) {
    637                                 ret = g_strdup_printf("\002[\002%02d->%02d\002]\002 %s%s",
    638                                                       td->log_id, i, prefix, txs->text);
    639                                 break;
    640                         }
    641         }
    642         if (ret == NULL)
    643                 ret = g_strdup_printf("\002[\002%02d\002]\002 %s%s", td->log_id, prefix, txs->text);
    644         td->log_id = (td->log_id + 1) % TWITTER_LOG_LENGTH;
    645 
    646         return ret;
    647657}
    648658
     
    826836
    827837static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o);
     838static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs);
    828839
    829840static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o)
    830841{
    831842        struct twitter_data *td = ic->proto_data;
    832         struct twitter_xml_status *txs = g_new0(struct twitter_xml_status, 1);
     843        struct twitter_xml_status *txs;
    833844        json_value *c;
    834845       
    835         if (twitter_xt_get_status(o, txs)) {
    836                 GSList *output = g_slist_append(NULL, txs);
    837                 twitter_groupchat(ic, output);
    838                 txs_free(txs);
    839                 g_slist_free(output);
    840                 return TRUE;
     846        if ((txs = twitter_xt_get_status(o))) {
     847                return twitter_stream_handle_status(ic, txs);
    841848        } else if ((c = json_o_get(o, "direct_message")) &&
    842849                   twitter_xt_get_dm(c, txs)) {
     
    860867                return TRUE;
    861868        }
     869        return FALSE;
     870}
     871
     872static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs)
     873{
     874        struct twitter_data *td = ic->proto_data;
     875        int i;
     876       
     877        for (i = 0; i < TWITTER_LOG_LENGTH; i++) {
     878                if (td->log[i].id == txs->id) {
     879                        /* Got a duplicate (RT, surely). Drop it. */
     880                        txs_free(txs);
     881                        return TRUE;
     882                }
     883        }
     884       
     885        if (!(set_getbool(&ic->acc->set, "fetch_mentions") ||
     886              bee_user_by_handle(ic->bee, ic, txs->user->screen_name))) {
     887                /* Tweet is from an unknown person and the user does not want
     888                   to see @mentions, so drop it. twitter_stream_handle_event()
     889                   picks up new follows so this simple filter should be safe. */
     890                /* TODO: The streaming API seems to do poor @mention matching.
     891                   I.e. I'm getting mentions for @WilmerSomething, not just for
     892                   @Wilmer. But meh. You want spam, you get spam. */
     893                return TRUE;
     894        }
     895       
     896        GSList *output = g_slist_append(NULL, txs);
     897        twitter_groupchat(ic, output);
    862898        txs_free(txs);
    863         return FALSE;
     899        g_slist_free(output);
     900        return TRUE;
    864901}
    865902
Note: See TracChangeset for help on using the changeset viewer.