Skip to content

Commit

Permalink
Merge remote-tracking branch 'bitlbee/pr/70'
Browse files Browse the repository at this point in the history
  • Loading branch information
dequis committed Apr 16, 2016
2 parents c9603a3 + 166a571 commit 991c75f
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 4 deletions.
8 changes: 8 additions & 0 deletions protocols/twitter/twitter.c
Expand Up @@ -344,6 +344,8 @@ void twitter_login_finish(struct im_connection *ic)
!(td->flags & TWITTER_HAVE_FRIENDS)) {
imcb_log(ic, "Getting contact list");
twitter_get_friends_ids(ic, -1);
twitter_get_mutes_ids(ic, -1);
twitter_get_noretweets_ids(ic, -1);
} else {
twitter_main_loop_start(ic);
}
Expand Down Expand Up @@ -955,6 +957,12 @@ static void twitter_handle_command(struct im_connection *ic, char *message)
} else if (g_strcasecmp(cmd[0], "unfollow") == 0 && cmd[1]) {
twitter_remove_buddy(ic, cmd[1], NULL);
goto eof;
} else if (g_strcasecmp(cmd[0], "mute") == 0 && cmd[1]) {
twitter_mute_create_destroy(ic, cmd[1], 1);
goto eof;
} else if (g_strcasecmp(cmd[0], "unmute") == 0 && cmd[1]) {
twitter_mute_create_destroy(ic, cmd[1], 0);
goto eof;
} else if ((g_strcasecmp(cmd[0], "report") == 0 ||
g_strcasecmp(cmd[0], "spam") == 0) && cmd[1]) {
char *screen_name;
Expand Down
2 changes: 2 additions & 0 deletions protocols/twitter/twitter.h
Expand Up @@ -60,6 +60,8 @@ struct twitter_data {
guint64 timeline_id;

GSList *follow_ids;
GSList *mutes_ids;
GSList *noretweets_ids;
GSList *filters;

guint64 last_status_id; /* For undo */
Expand Down
189 changes: 185 additions & 4 deletions protocols/twitter/twitter_lib.c
Expand Up @@ -239,6 +239,8 @@ static json_value *twitter_parse_response(struct im_connection *ic, struct http_
}

static void twitter_http_get_friends_ids(struct http_request *req);
static void twitter_http_get_mutes_ids(struct http_request *req);
static void twitter_http_get_noretweets_ids(struct http_request *req);

/**
* Get the friends ids.
Expand All @@ -255,6 +257,34 @@ void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor)
g_free(args[1]);
}

/**
* Get the muted users ids.
*/
void twitter_get_mutes_ids(struct im_connection *ic, gint64 next_cursor)
{
char *args[2];

args[0] = "cursor";
args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
twitter_http(ic, TWITTER_MUTES_IDS_URL, twitter_http_get_mutes_ids, ic, 0, args, 2);

g_free(args[1]);
}

/**
* Get the ids for users from whom we should ignore retweets.
*/
void twitter_get_noretweets_ids(struct im_connection *ic, gint64 next_cursor)
{
char *args[2];

args[0] = "cursor";
args[1] = g_strdup_printf("%" G_GINT64_FORMAT, next_cursor);
twitter_http(ic, TWITTER_NORETWEETS_IDS_URL, twitter_http_get_noretweets_ids, ic, 0, args, 2);

g_free(args[1]);
}

/**
* Fill a list of ids.
*/
Expand Down Expand Up @@ -336,6 +366,92 @@ static void twitter_http_get_friends_ids(struct http_request *req)
txl_free(txl);
}

/**
* Callback for getting the mutes ids.
*/
static void twitter_http_get_mutes_ids(struct http_request *req)
{
struct im_connection *ic = req->data;
json_value *parsed;
struct twitter_xml_list *txl;
struct twitter_data *td;

// Check if the connection is stil active
if (!g_slist_find(twitter_connections, ic)) {
return;
}

td = ic->proto_data;

// Parse the data.
if (!(parsed = twitter_parse_response(ic, req))) {
return;
}

txl = g_new0(struct twitter_xml_list, 1);
txl->list = td->mutes_ids;

/* mute ids API response is similar enough to friends response
to reuse this method */
twitter_xt_get_friends_id_list(parsed, txl);
json_value_free(parsed);

td->mutes_ids = txl->list;
if (txl->next_cursor) {
/* Recurse while there are still more pages */
twitter_get_mutes_ids(ic, txl->next_cursor);
}

txl->list = NULL;
txl_free(txl);
}

/**
* Callback for getting the no-retweets ids.
*/
static void twitter_http_get_noretweets_ids(struct http_request *req)
{
struct im_connection *ic = req->data;
json_value *parsed;
struct twitter_xml_list *txl;
struct twitter_data *td;

// Check if the connection is stil active
if (!g_slist_find(twitter_connections, ic)) {
return;
}

td = ic->proto_data;

// Parse the data.
if (!(parsed = twitter_parse_response(ic, req))) {
return;
}

txl = g_new0(struct twitter_xml_list, 1);
txl->list = td->noretweets_ids;

// Process the retweet ids
txl->type = TXL_ID;
if (parsed->type == json_array) {
unsigned int i;
for (i = 0; i < parsed->u.array.length; i++) {
json_value *c = parsed->u.array.values[i];
if (c->type != json_integer) {
continue;
}
txl->list = g_slist_prepend(txl->list,
g_strdup_printf("%"PRIu64, c->u.integer));
}
}

json_value_free(parsed);
td->noretweets_ids = txl->list;

txl->list = NULL;
txl_free(txl);
}

static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl);
static void twitter_http_get_users_lookup(struct http_request *req);

Expand Down Expand Up @@ -830,10 +946,29 @@ static void twitter_status_show(struct im_connection *ic, struct twitter_xml_sta
{
struct twitter_data *td = ic->proto_data;
char *last_id_str;
char *uid_str;

if (status->user == NULL || status->text == NULL) {
return;
}

/* Check this is not a tweet that should be muted */
uid_str = g_strdup_printf("%" PRIu64, status->user->uid);
if (getenv("BITLBEE_DEBUG")) {
GSList *item;
fprintf(stderr, "Checking mutes; this uid=%s\n", uid_str);
for (item = td->mutes_ids; item != NULL; item = item->next) {
fprintf(stderr, " id: %s\n", (char *)item->data);
}
}
if (g_slist_find_custom(td->mutes_ids, uid_str, (GCompareFunc)strcmp)) {
g_free(uid_str);
return;
}
if (status->id != status->rt_id && g_slist_find_custom(td->noretweets_ids, uid_str, (GCompareFunc)strcmp)) {
g_free(uid_str);
return;
}

/* Grrrr. Would like to do this during parsing, but can't access
settings from there. */
Expand All @@ -856,6 +991,7 @@ static void twitter_status_show(struct im_connection *ic, struct twitter_xml_sta
last_id_str = g_strdup_printf("%" G_GUINT64_FORMAT, td->timeline_id);
set_setstr(&ic->acc->set, "_last_tweet", last_id_str);
g_free(last_id_str);
g_free(uid_str);
}

static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter);
Expand Down Expand Up @@ -992,22 +1128,54 @@ static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value
json_value *source = json_o_get(o, "source");
json_value *target = json_o_get(o, "target");
const char *type = json_o_str(o, "event");
struct twitter_xml_user *us = NULL;
struct twitter_xml_user *ut = NULL;

if (!type || !source || source->type != json_object
|| !target || target->type != json_object) {
return FALSE;
}

if (strcmp(type, "follow") == 0) {
struct twitter_xml_user *us = twitter_xt_get_user(source);
struct twitter_xml_user *ut = twitter_xt_get_user(target);
us = twitter_xt_get_user(source);
ut = twitter_xt_get_user(target);
if (g_strcasecmp(us->screen_name, td->user) == 0) {
twitter_add_buddy(ic, ut->screen_name, ut->name);
}
txu_free(us);
txu_free(ut);
} else if (strcmp(type, "mute") == 0) {
GSList *found;
char *uid_str;
ut = twitter_xt_get_user(target);
uid_str = g_strdup_printf("%" PRIu64, ut->uid);
if (!(found = g_slist_find_custom(td->mutes_ids, uid_str,
(GCompareFunc)strcmp))) {
td->mutes_ids = g_slist_prepend(td->mutes_ids, uid_str);
}
twitter_log(ic, "Muted user %s", ut->screen_name);
if (getenv("BITLBEE_DEBUG")) {
fprintf(stderr, "New mute: %s %"PRIu64"\n",
ut->screen_name, ut->uid);
}
} else if (strcmp(type, "unmute") == 0) {
GSList *found;
char *uid_str;
ut = twitter_xt_get_user(target);
uid_str = g_strdup_printf("%" PRIu64, ut->uid);
if ((found = g_slist_find_custom(td->mutes_ids, uid_str,
(GCompareFunc)strcmp))) {
td->mutes_ids = g_slist_remove(td->mutes_ids, found);
}
g_free(uid_str);
twitter_log(ic, "Unmuted user %s", ut->screen_name);
if (getenv("BITLBEE_DEBUG")) {
fprintf(stderr, "New unmute: %s %"PRIu64"\n",
ut->screen_name, ut->uid);
}
}

txu_free(us);
txu_free(ut);

return TRUE;
}

Expand Down Expand Up @@ -1523,6 +1691,19 @@ void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int
twitter_http_post, ic, 1, args, 2);
}

/**
* Mute or unmute a user
*/
void twitter_mute_create_destroy(struct im_connection *ic, char *who, int create)
{
char *args[2];

args[0] = "screen_name";
args[1] = who;
twitter_http(ic, create ? TWITTER_MUTES_CREATE_URL : TWITTER_MUTES_DESTROY_URL,
twitter_http_post, ic, 1, args, 2);
}

void twitter_status_destroy(struct im_connection *ic, guint64 id)
{
char *url;
Expand Down
9 changes: 9 additions & 0 deletions protocols/twitter/twitter_lib.h
Expand Up @@ -62,6 +62,8 @@
/* Social graphs URLs */
#define TWITTER_FRIENDS_IDS_URL "/friends/ids.json"
#define TWITTER_FOLLOWERS_IDS_URL "/followers/ids.json"
#define TWITTER_MUTES_IDS_URL "/mutes/users/ids.json"
#define TWITTER_NORETWEETS_IDS_URL "/friendships/no_retweets/ids.json"

/* Account URLs */
#define TWITTER_ACCOUNT_RATE_LIMIT_URL "/account/rate_limit_status.json"
Expand All @@ -75,6 +77,10 @@
#define TWITTER_BLOCKS_CREATE_URL "/blocks/create/"
#define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/"

/* Mute URLs */
#define TWITTER_MUTES_CREATE_URL "/mutes/users/create.json"
#define TWITTER_MUTES_DESTROY_URL "/mutes/users/destroy.json"

/* Report spam */
#define TWITTER_REPORT_SPAM_URL "/users/report_spam.json"

Expand All @@ -86,11 +92,14 @@ gboolean twitter_open_stream(struct im_connection *ic);
gboolean twitter_open_filter_stream(struct im_connection *ic);
gboolean twitter_get_timeline(struct im_connection *ic, gint64 next_cursor);
void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor);
void twitter_get_mutes_ids(struct im_connection *ic, gint64 next_cursor);
void twitter_get_noretweets_ids(struct im_connection *ic, gint64 next_cursor);
void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor);

void twitter_post_status(struct im_connection *ic, char *msg, guint64 in_reply_to);
void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message);
void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create);
void twitter_mute_create_destroy(struct im_connection *ic, char *who, int create);
void twitter_status_destroy(struct im_connection *ic, guint64 id);
void twitter_status_retweet(struct im_connection *ic, guint64 id);
void twitter_report_spam(struct im_connection *ic, char *screen_name);
Expand Down

0 comments on commit 991c75f

Please sign in to comment.