suddenly friend listing support

This commit is contained in:
2019-07-03 21:14:23 +02:00
parent b307906cf4
commit de6d02fd58
16 changed files with 400 additions and 79 deletions

View File

@@ -30,6 +30,10 @@ struct dc_account_
/* authentication token
*/
char *token;
/* friends we have
*/
GPtrArray *friends;
};
static void dc_account_free(dc_account_t ptr)
@@ -44,6 +48,11 @@ static void dc_account_free(dc_account_t ptr)
free(ptr->full);
free(ptr->token);
if (ptr->friends != NULL) {
g_ptr_array_unref(ptr->friends);
ptr->friends = NULL;
}
free(ptr);
}
@@ -53,6 +62,10 @@ dc_account_t dc_account_new(void)
ptr->ref.cleanup = (dc_cleanup_t)dc_account_free;
ptr->friends = g_ptr_array_new_with_free_func(
(GDestroyNotify)dc_unref
);
return dc_ref(ptr);
}
@@ -144,7 +157,7 @@ void dc_account_update_full(dc_account_t a)
free(a->full);
a->full = NULL;
asprintf(&a->full, "%s/%s",
asprintf(&a->full, "%s#%s",
(a->username != NULL ? a->username : ""),
(a->discriminator != NULL ? a->discriminator : "")
);
@@ -185,3 +198,26 @@ char const *dc_account_full_username(dc_account_t a)
return_if_true(a == NULL, NULL);
return a->full;
}
void dc_account_set_friends(dc_account_t a, dc_account_t *friends, size_t len)
{
size_t i = 0;
return_if_true(a == NULL || a->friends == NULL,);
g_ptr_array_remove_range(a->friends, 0, a->friends->len);
for (i = 0; i < len; i++) {
g_ptr_array_add(a->friends, friends[i]);
}
}
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
{
return_if_true(a == NULL || a->friends == NULL, NULL);
return (dc_account_t)g_ptr_array_index(a->friends, i);
}
size_t dc_account_friends_size(dc_account_t a)
{
return_if_true(a == NULL || a->friends == NULL, 0);
return a->friends->len;
}

View File

@@ -322,6 +322,33 @@ cleanup:
return ret;
}
static dc_account_t dc_api_account_from_json(json_t *j)
{
dc_account_t user = dc_account_new();
json_t *val = NULL;
goto_if_true(!json_is_object(j), error);
val = json_object_get(j, "username");
goto_if_true(val == NULL || !json_is_string(val), error);
dc_account_set_username(user, json_string_value(val));
val = json_object_get(j, "discriminator");
goto_if_true(val == NULL || !json_is_string(val), error);
dc_account_set_discriminator(user, json_string_value(val));
val = json_object_get(j, "id");
goto_if_true(val == NULL || !json_is_string(val), error);
dc_account_set_id(user, json_string_value(val));
return user;
error:
dc_unref(user);
return NULL;
}
bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
dc_account_t user)
{
@@ -333,7 +360,11 @@ bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
return_if_true(login == NULL, false);
return_if_true(user == NULL, false);
asprintf(&url, "users/%s", dc_account_id(user));
if (user == login) {
url = strdup("users/@me");
} else {
asprintf(&url, "users/%s", dc_account_id(user));
}
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup);
@@ -360,25 +391,49 @@ cleanup:
return ret;
}
bool dc_api_get_friends(dc_api_t api, dc_account_t login, GPtrArray **friends)
bool dc_api_get_friends(dc_api_t api, dc_account_t login)
{
char *url = NULL;
json_t *reply = NULL;
char const *url = "users/@me/relationships";
json_t *reply = NULL, *c = NULL, *val = NULL;
bool ret = false;
size_t i = 0;
GPtrArray *f = g_ptr_array_new_with_free_func((GDestroyNotify)dc_unref);
return_if_true(api == NULL, false);
return_if_true(login == NULL, false);
asprintf(&url, "users/%s/guilds", dc_account_id(login));
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup);
dc_util_dump_json(reply);
goto_if_true(!json_is_array(reply), cleanup);
json_array_foreach(reply, i, c) {
/* the return is an array of objects, with a "user" member
* type 1 is probably a friend
*/
val = json_object_get(c, "user");
if (val == NULL) {
continue;
}
dc_account_t a = dc_api_account_from_json(val);
if (a == NULL) {
continue;
}
g_ptr_array_add(f, a);
}
if (f->len == 0) {
/* me_irl :-(
*/
}
dc_account_set_friends(login, (dc_account_t*)f->pdata, f->len);
ret = true;
cleanup:
g_ptr_array_free(f, FALSE);
json_decref(reply);
reply = NULL;
@@ -387,7 +442,7 @@ cleanup:
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, GPtrArray **out)
{
char *url = NULL;
char const *url = "users/@me/guilds";
json_t *reply = NULL, *c = NULL, *val = NULL;
size_t i = 0;
bool ret = false;
@@ -398,8 +453,6 @@ bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, GPtrArray **out)
return_if_true(api == NULL, false);
return_if_true(login == NULL, false);
asprintf(&url, "users/%s/guilds", dc_account_id(login));
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup);
@@ -426,7 +479,6 @@ bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, GPtrArray **out)
cleanup:
free(url);
json_decref(reply);
if (guilds) {

View File

@@ -23,7 +23,7 @@
#include <dc/util.h>
#define DEBUG
//#define DEBUG
#define return_if_true(v,r) do { if (v) return r; } while(0)
#define goto_if_true(v,l) do { if (v) goto l; } while(0)

View File

@@ -191,6 +191,12 @@ void dc_loop_add_api(dc_loop_t l, dc_api_t a)
g_ptr_array_add(l->apis, p);
}
void dc_loop_abort(dc_loop_t l)
{
return_if_true(l == NULL || l->base == NULL,);
event_base_loopbreak(l->base);
}
bool dc_loop_once(dc_loop_t l)
{
return_if_true(l == NULL, false);