Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/twitter/twitter_lib.c

    rbbff22d r58d285a  
    240240
    241241static void twitter_http_get_friends_ids(struct http_request *req);
     242static void twitter_http_get_mutes_ids(struct http_request *req);
     243static void twitter_http_get_noretweets_ids(struct http_request *req);
    242244
    243245/**
     
    252254        args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
    253255        twitter_http(ic, TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, args, 2);
     256
     257        g_free(args[1]);
     258}
     259
     260/**
     261 * Get the muted users ids.
     262 */
     263void twitter_get_mutes_ids(struct im_connection *ic, gint64 next_cursor)
     264{
     265        char *args[2];
     266
     267        args[0] = "cursor";
     268        args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
     269        twitter_http(ic, TWITTER_MUTES_IDS_URL, twitter_http_get_mutes_ids, ic, 0, args, 2);
     270
     271        g_free(args[1]);
     272}
     273
     274/**
     275 * Get the ids for users from whom we should ignore retweets.
     276 */
     277void twitter_get_noretweets_ids(struct im_connection *ic, gint64 next_cursor)
     278{
     279        char *args[2];
     280
     281        args[0] = "cursor";
     282        args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
     283        twitter_http(ic, TWITTER_NORETWEETS_IDS_URL, twitter_http_get_noretweets_ids, ic, 0, args, 2);
    254284
    255285        g_free(args[1]);
     
    337367}
    338368
     369/**
     370 * Callback for getting the mutes ids.
     371 */
     372static void twitter_http_get_mutes_ids(struct http_request *req)
     373{
     374        struct im_connection *ic = req->data;
     375        json_value *parsed;
     376        struct twitter_xml_list *txl;
     377        struct twitter_data *td;
     378
     379        // Check if the connection is stil active
     380        if (!g_slist_find(twitter_connections, ic)) {
     381                return;
     382        }
     383
     384        td = ic->proto_data;
     385
     386        if (req->status_code != 200) {
     387                /* Fail silently */
     388                return;
     389        }
     390
     391        // Parse the data.
     392        if (!(parsed = twitter_parse_response(ic, req))) {
     393                return;
     394        }
     395
     396        txl = g_new0(struct twitter_xml_list, 1);
     397        txl->list = td->mutes_ids;
     398
     399        /* mute ids API response is similar enough to friends response
     400           to reuse this method */
     401        twitter_xt_get_friends_id_list(parsed, txl);
     402        json_value_free(parsed);
     403
     404        td->mutes_ids = txl->list;
     405        if (txl->next_cursor) {
     406                /* Recurse while there are still more pages */
     407                twitter_get_mutes_ids(ic, txl->next_cursor);
     408        }
     409
     410        txl->list = NULL;
     411        txl_free(txl);
     412}
     413
     414/**
     415 * Callback for getting the no-retweets ids.
     416 */
     417static void twitter_http_get_noretweets_ids(struct http_request *req)
     418{
     419        struct im_connection *ic = req->data;
     420        json_value *parsed;
     421        struct twitter_xml_list *txl;
     422        struct twitter_data *td;
     423
     424        // Check if the connection is stil active
     425        if (!g_slist_find(twitter_connections, ic)) {
     426                return;
     427        }
     428
     429        if (req->status_code != 200) {
     430                /* Fail silently */
     431                return;
     432        }
     433
     434        td = ic->proto_data;
     435
     436        // Parse the data.
     437        if (!(parsed = twitter_parse_response(ic, req))) {
     438                return;
     439        }
     440
     441        txl = g_new0(struct twitter_xml_list, 1);
     442        txl->list = td->noretweets_ids;
     443       
     444        // Process the retweet ids
     445        txl->type = TXL_ID;
     446        if (parsed->type == json_array) {
     447                unsigned int i;
     448                for (i = 0; i < parsed->u.array.length; i++) {
     449                        json_value *c = parsed->u.array.values[i];
     450                        if (c->type != json_integer) {
     451                                continue;
     452                        }
     453                        txl->list = g_slist_prepend(txl->list,
     454                                                    g_strdup_printf("%"PRIu64, c->u.integer));
     455                }
     456        }
     457
     458        json_value_free(parsed);
     459        td->noretweets_ids = txl->list;
     460
     461        txl->list = NULL;
     462        txl_free(txl);
     463}
     464
    339465static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl);
    340466static void twitter_http_get_users_lookup(struct http_request *req);
     
    461587#endif
    462588
    463 static void expand_entities(char **text, const json_value *node);
     589static void expand_entities(char **text, const json_value *node, const json_value *extended_node);
    464590
    465591/**
     
    473599static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
    474600{
    475         struct twitter_xml_status *txs;
     601        struct twitter_xml_status *txs = {0};
    476602        const json_value *rt = NULL;
     603        const json_value *text_value = NULL;
     604        const json_value *extended_node = NULL;
    477605
    478606        if (node->type != json_object) {
     
    482610
    483611        JSON_O_FOREACH(node, k, v) {
    484                 if (strcmp("text", k) == 0 && v->type == json_string) {
    485                         txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
    486                         strip_html(txs->text);
     612                if (strcmp("text", k) == 0 && v->type == json_string && text_value == NULL) {
     613                        text_value = v;
     614                } else if (strcmp("full_text", k) == 0 && v->type == json_string) {
     615                        text_value = v;
     616                } else if (strcmp("extended_tweet", k) == 0 && v->type == json_object) {
     617                        text_value = json_o_get(v, "full_text");
     618                        extended_node = v;
    487619                } else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {
    488620                        rt = v;
     
    510642                struct twitter_xml_status *rtxs = twitter_xt_get_status(rt);
    511643                if (rtxs) {
    512                         g_free(txs->text);
    513644                        txs->text = g_strdup_printf("RT @%s: %s", rtxs->user->screen_name, rtxs->text);
    514645                        txs->id = rtxs->id;
    515646                        txs_free(rtxs);
    516647                }
    517         } else {
    518                 expand_entities(&txs->text, node);
     648        } else if (text_value && text_value->type == json_string) {
     649                txs->text = g_memdup(text_value->u.string.ptr, text_value->u.string.length + 1);
     650                strip_html(txs->text);
     651                expand_entities(&txs->text, node, extended_node);
    519652        }
    520653
     
    559692        }
    560693
    561         expand_entities(&txs->text, node);
     694        expand_entities(&txs->text, node, NULL);
    562695
    563696        if (txs->text && txs->user && txs->id) {
     
    569702}
    570703
    571 static void expand_entities(char **text, const json_value *node)
    572 {
    573         json_value *entities, *quoted;
     704static void expand_entities(char **text, const json_value *node, const json_value *extended_node)
     705{
     706        json_value *entities, *extended_entities, *quoted;
    574707        char *quote_url = NULL, *quote_text = NULL;
    575708
     
    589722        }
    590723
     724        if (extended_node) {
     725                extended_entities = json_o_get(extended_node, "entities");
     726                if (extended_entities && extended_entities->type == json_object) {
     727                        entities = extended_entities;
     728                }
     729        }
     730
    591731        JSON_O_FOREACH(entities, k, v) {
    592732                int i;
     
    831971        struct twitter_data *td = ic->proto_data;
    832972        char *last_id_str;
     973        char *uid_str;
    833974
    834975        if (status->user == NULL || status->text == NULL) {
     976                return;
     977        }
     978       
     979        /* Check this is not a tweet that should be muted */
     980        uid_str = g_strdup_printf("%" PRIu64, status->user->uid);
     981
     982        if (g_slist_find_custom(td->mutes_ids, uid_str, (GCompareFunc)strcmp)) {
     983                g_free(uid_str);
     984                return;
     985        }
     986        if (status->id != status->rt_id && g_slist_find_custom(td->noretweets_ids, uid_str, (GCompareFunc)strcmp)) {
     987                g_free(uid_str);
    835988                return;
    836989        }
     
    8571010        set_setstr(&ic->acc->set, "_last_tweet", last_id_str);
    8581011        g_free(last_id_str);
     1012        g_free(uid_str);
    8591013}
    8601014
     
    8741028        }
    8751029
    876         ic->flags |= OPT_PONGED;
    8771030        td = ic->proto_data;
    8781031
     
    8901043                imc_logout(ic, TRUE);
    8911044                return;
     1045        }
     1046
     1047        if (req == td->stream) {
     1048                ic->flags |= OPT_PONGED;
    8921049        }
    8931050
     
    9931150        json_value *target = json_o_get(o, "target");
    9941151        const char *type = json_o_str(o, "event");
     1152        struct twitter_xml_user *us = NULL;
     1153        struct twitter_xml_user *ut = NULL;
    9951154
    9961155        if (!type || !source || source->type != json_object
     
    10001159
    10011160        if (strcmp(type, "follow") == 0) {
    1002                 struct twitter_xml_user *us = twitter_xt_get_user(source);
    1003                 struct twitter_xml_user *ut = twitter_xt_get_user(target);
     1161                us = twitter_xt_get_user(source);
     1162                ut = twitter_xt_get_user(target);
    10041163                if (g_strcasecmp(us->screen_name, td->user) == 0) {
    10051164                        twitter_add_buddy(ic, ut->screen_name, ut->name);
    10061165                }
    1007                 txu_free(us);
    1008                 txu_free(ut);
    1009         }
     1166        } else if (strcmp(type, "mute") == 0) {
     1167                GSList *found;
     1168                char *uid_str;
     1169                ut = twitter_xt_get_user(target);
     1170                uid_str = g_strdup_printf("%" PRIu64, ut->uid);
     1171                if (!(found = g_slist_find_custom(td->mutes_ids, uid_str,
     1172                                                  (GCompareFunc)strcmp))) {
     1173                        td->mutes_ids = g_slist_prepend(td->mutes_ids, uid_str);
     1174                }
     1175                twitter_log(ic, "Muted user %s", ut->screen_name);
     1176                if (getenv("BITLBEE_DEBUG")) {
     1177                        fprintf(stderr, "New mute: %s %"PRIu64"\n",
     1178                                ut->screen_name, ut->uid);
     1179                }
     1180        } else if (strcmp(type, "unmute") == 0) {
     1181                GSList *found;
     1182                char *uid_str;
     1183                ut = twitter_xt_get_user(target);
     1184                uid_str = g_strdup_printf("%" PRIu64, ut->uid);
     1185                if ((found = g_slist_find_custom(td->mutes_ids, uid_str,
     1186                                                (GCompareFunc)strcmp))) {
     1187                        char *found_str = found->data;
     1188                        td->mutes_ids = g_slist_delete_link(td->mutes_ids, found);
     1189                        g_free(found_str);
     1190                }
     1191                g_free(uid_str);
     1192                twitter_log(ic, "Unmuted user %s", ut->screen_name);
     1193                if (getenv("BITLBEE_DEBUG")) {
     1194                        fprintf(stderr, "New unmute: %s %"PRIu64"\n",
     1195                                ut->screen_name, ut->uid);
     1196                }
     1197        }
     1198
     1199        txu_free(us);
     1200        txu_free(ut);
    10101201
    10111202        return TRUE;
     
    13051496        td->flags &= ~TWITTER_GOT_TIMELINE;
    13061497
    1307         char *args[6];
     1498        char *args[8];
    13081499        args[0] = "cursor";
    13091500        args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
    13101501        args[2] = "include_entities";
    13111502        args[3] = "true";
     1503        args[4] = "tweet_mode";
     1504        args[5] = "extended";
    13121505        if (td->timeline_id) {
    1313                 args[4] = "since_id";
    1314                 args[5] = g_strdup_printf("%" G_GUINT64_FORMAT, td->timeline_id);
     1506                args[6] = "since_id";
     1507                args[7] = g_strdup_printf("%" G_GUINT64_FORMAT, td->timeline_id);
    13151508        }
    13161509
    13171510        if (twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args,
    1318                          td->timeline_id ? 6 : 4) == NULL) {
     1511                         td->timeline_id ? 8 : 6) == NULL) {
    13191512                if (++td->http_fails >= 5) {
    13201513                        imcb_error(ic, "Could not retrieve %s: %s",
     
    13271520        g_free(args[1]);
    13281521        if (td->timeline_id) {
    1329                 g_free(args[5]);
     1522                g_free(args[7]);
    13301523        }
    13311524}
     
    13421535        td->flags &= ~TWITTER_GOT_MENTIONS;
    13431536
    1344         char *args[6];
     1537        char *args[8];
    13451538        args[0] = "cursor";
    13461539        args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
     
    13541547                args[5] = g_strdup_printf("%d", set_getint(&ic->acc->set, "show_old_mentions"));
    13551548        }
     1549        args[6] = "tweet_mode";
     1550        args[7] = "extended";
    13561551
    13571552        if (twitter_http(ic, TWITTER_MENTIONS_URL, twitter_http_get_mentions,
    1358                          ic, 0, args, 6) == NULL) {
     1553                         ic, 0, args, 8) == NULL) {
    13591554                if (++td->http_fails >= 5) {
    13601555                        imcb_error(ic, "Could not retrieve %s: %s",
     
    15241719}
    15251720
     1721/**
     1722 * Mute or unmute a user
     1723 */
     1724void twitter_mute_create_destroy(struct im_connection *ic, char *who, int create)
     1725{
     1726        char *args[2];
     1727
     1728        args[0] = "screen_name";
     1729        args[1] = who;
     1730        twitter_http(ic, create ? TWITTER_MUTES_CREATE_URL : TWITTER_MUTES_DESTROY_URL,
     1731                     twitter_http_post, ic, 1, args, 2);
     1732}
     1733
    15261734void twitter_status_destroy(struct im_connection *ic, guint64 id)
    15271735{
Note: See TracChangeset for help on using the changeset viewer.