full friends list support, add remove, and accept
This commit is contained in:
@@ -84,7 +84,7 @@ dc_account_t dc_account_new2(char const *email, char const *pass)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
dc_account_t dc_account_from_fullid(char const *fullid)
|
||||
dc_account_t dc_account_from_fullname(char const *fullid)
|
||||
{
|
||||
return_if_true(fullid == NULL, NULL);
|
||||
|
||||
@@ -226,7 +226,7 @@ char const *dc_account_discriminator(dc_account_t a)
|
||||
return a->discriminator;
|
||||
}
|
||||
|
||||
char const *dc_account_full_username(dc_account_t a)
|
||||
char const *dc_account_fullname(dc_account_t a)
|
||||
{
|
||||
return_if_true(a == NULL, NULL);
|
||||
return a->full;
|
||||
|
||||
150
libdc/src/api-friends.c
Normal file
150
libdc/src/api-friends.c
Normal file
@@ -0,0 +1,150 @@
|
||||
#include <dc/api.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
bool dc_api_get_friends(dc_api_t api, dc_account_t login)
|
||||
{
|
||||
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);
|
||||
|
||||
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
|
||||
goto_if_true(reply == NULL, cleanup);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* read the type also known as "typ"
|
||||
*/
|
||||
val = json_object_get(c, "type");
|
||||
if (val != NULL && json_is_integer(val)) {
|
||||
int state = json_integer_value(val);
|
||||
dc_account_set_friend_state(a, state);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dc_api_remove_friend(dc_api_t api, dc_account_t login, dc_account_t friend)
|
||||
{
|
||||
char *url = NULL;
|
||||
json_t *reply = NULL, *post = NULL;
|
||||
bool ret = false;
|
||||
|
||||
return_if_true(api == NULL, false);
|
||||
return_if_true(login == NULL || friend == NULL, false);
|
||||
return_if_true(dc_account_id(friend) == NULL, false);
|
||||
|
||||
asprintf(&url, "users/@me/relationships/%s", dc_account_id(friend));
|
||||
|
||||
post = dc_api_account_to_json(friend);
|
||||
return_if_true(post == NULL, false);
|
||||
|
||||
reply = dc_api_call_sync(api, "DELETE", dc_account_token(login), url, post);
|
||||
/* if no data comes back, then the whole thing was a success
|
||||
*/
|
||||
goto_if_true(reply != NULL, cleanup);
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
|
||||
free(url);
|
||||
json_decref(post);
|
||||
json_decref(reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dc_api_accept_friend(dc_api_t api, dc_account_t login, dc_account_t friend)
|
||||
{
|
||||
char *url = NULL;
|
||||
json_t *reply = NULL, *post = NULL;
|
||||
bool ret = false;
|
||||
|
||||
return_if_true(api == NULL, false);
|
||||
return_if_true(login == NULL || friend == NULL, false);
|
||||
return_if_true(dc_account_id(friend) == NULL, false);
|
||||
|
||||
asprintf(&url, "users/@me/relationships/%s", dc_account_id(friend));
|
||||
|
||||
post = dc_api_account_to_json(friend);
|
||||
return_if_true(post == NULL, false);
|
||||
|
||||
reply = dc_api_call_sync(api, "PUT", dc_account_token(login), url, post);
|
||||
/* no data = successful
|
||||
*/
|
||||
goto_if_true(reply != NULL, cleanup);
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
|
||||
free(url);
|
||||
json_decref(post);
|
||||
json_decref(reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dc_api_add_friend(dc_api_t api, dc_account_t login, dc_account_t friend)
|
||||
{
|
||||
char const *url = "users/@me/relationships";
|
||||
json_t *reply = NULL, *post = NULL;
|
||||
bool ret = false;
|
||||
|
||||
return_if_true(api == NULL, false);
|
||||
return_if_true(login == NULL, false);
|
||||
|
||||
post = dc_api_account_to_json(friend);
|
||||
return_if_true(post == NULL, false);
|
||||
|
||||
reply = dc_api_call_sync(api, "POST", dc_account_token(login), url, post);
|
||||
/* apparently if no data comes back, then the whole thing was a success
|
||||
*/
|
||||
goto_if_true(reply != NULL, cleanup);
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
|
||||
json_decref(post);
|
||||
json_decref(reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
53
libdc/src/api-util.c
Normal file
53
libdc/src/api-util.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <dc/api.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
json_t *dc_api_account_to_json(dc_account_t a)
|
||||
{
|
||||
json_t *j = NULL;
|
||||
|
||||
return_if_true(a == NULL, NULL);
|
||||
return_if_true(dc_account_username(a) == NULL ||
|
||||
dc_account_discriminator(a) == NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
j = json_object();
|
||||
return_if_true(j == NULL, NULL);
|
||||
|
||||
json_object_set_new(j, "username",
|
||||
json_string(dc_account_username(a))
|
||||
);
|
||||
json_object_set_new(j, "discriminator",
|
||||
json_string(dc_account_discriminator(a))
|
||||
);
|
||||
|
||||
return j;
|
||||
}
|
||||
138
libdc/src/api.c
138
libdc/src/api.c
@@ -322,56 +322,6 @@ 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;
|
||||
}
|
||||
|
||||
static json_t *dc_api_user_to_json(dc_account_t a)
|
||||
{
|
||||
json_t *j = NULL;
|
||||
|
||||
return_if_true(a == NULL, NULL);
|
||||
return_if_true(dc_account_username(a) == NULL ||
|
||||
dc_account_discriminator(a) == NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
j = json_object();
|
||||
return_if_true(j == NULL, NULL);
|
||||
|
||||
json_object_set_new(j, "username",
|
||||
json_string(dc_account_username(a))
|
||||
);
|
||||
json_object_set_new(j, "discriminator",
|
||||
json_string(dc_account_discriminator(a))
|
||||
);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
|
||||
dc_account_t user)
|
||||
{
|
||||
@@ -414,94 +364,6 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dc_api_get_friends(dc_api_t api, dc_account_t login)
|
||||
{
|
||||
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);
|
||||
|
||||
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
|
||||
goto_if_true(reply == NULL, cleanup);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* read the type also known as "typ"
|
||||
*/
|
||||
val = json_object_get(c, "type");
|
||||
if (val != NULL && json_is_integer(val)) {
|
||||
int state = json_integer_value(val);
|
||||
dc_account_set_friend_state(a, state);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given account as a friend to the friends list
|
||||
*/
|
||||
bool dc_api_add_friend(dc_api_t api, dc_account_t login, dc_account_t friend)
|
||||
{
|
||||
char const *url = "users/@me/relationships";
|
||||
json_t *reply = NULL, *post = NULL;
|
||||
bool ret = false;
|
||||
|
||||
return_if_true(api == NULL, false);
|
||||
return_if_true(login == NULL, false);
|
||||
|
||||
post = dc_api_user_to_json(friend);
|
||||
return_if_true(post == NULL, false);
|
||||
|
||||
reply = dc_api_call_sync(api, "POST", dc_account_token(login), url, post);
|
||||
/* apparently if no data comes back, then the whole thing was a success
|
||||
*/
|
||||
goto_if_true(reply != NULL, cleanup);
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
|
||||
json_decref(post);
|
||||
json_decref(reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, GPtrArray **out)
|
||||
{
|
||||
char const *url = "users/@me/guilds";
|
||||
|
||||
@@ -22,10 +22,18 @@
|
||||
#include <event2/thread.h>
|
||||
|
||||
#include <dc/util.h>
|
||||
#include <dc/refable.h>
|
||||
#include <dc/account.h>
|
||||
|
||||
//#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)
|
||||
|
||||
/* These are internal helper methods, their ABI, and API stability
|
||||
* is not garuanteed. So please beware
|
||||
*/
|
||||
json_t *dc_api_account_to_json(dc_account_t a);
|
||||
dc_account_t dc_api_account_from_json(json_t *j);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user