began work on guilds

This commit is contained in:
Florian Stinglmayr 2019-06-25 18:20:27 +02:00
parent aed7dacf29
commit 523725f375
8 changed files with 150 additions and 39 deletions

View File

@ -11,12 +11,14 @@ SET(SOURCES
"include/dc/account.h" "include/dc/account.h"
"include/dc/api.h" "include/dc/api.h"
"include/dc/apisync.h" "include/dc/apisync.h"
"include/dc/guild.h"
"include/dc/loop.h" "include/dc/loop.h"
"include/dc/refable.h" "include/dc/refable.h"
"include/dc/util.h" "include/dc/util.h"
"src/account.c" "src/account.c"
"src/api.c" "src/api.c"
"src/apisync.c" "src/apisync.c"
"src/guild.c"
"src/loop.c" "src/loop.c"
"src/refable.c" "src/refable.c"
"src/util.c" "src/util.c"

View File

@ -25,6 +25,8 @@ char const *dc_account_username(dc_account_t a);
void dc_account_set_discriminator(dc_account_t a, char const *id); void dc_account_set_discriminator(dc_account_t a, char const *id);
char const *dc_account_discriminator(dc_account_t a); char const *dc_account_discriminator(dc_account_t a);
char const *dc_account_full_username(dc_account_t a);
void dc_account_set_token(dc_account_t a, char const *token); void dc_account_set_token(dc_account_t a, char const *token);
char const *dc_account_token(dc_account_t a); char const *dc_account_token(dc_account_t a);
bool dc_account_has_token(dc_account_t a); bool dc_account_has_token(dc_account_t a);

View File

@ -25,13 +25,30 @@ void dc_api_signal(dc_api_t api, CURL *easy, int code);
/* internal curl stuff /* internal curl stuff
*/ */
dc_api_sync_t dc_api_call(dc_api_t api, char const *token, dc_api_sync_t dc_api_call(dc_api_t api, char const *token,
char const *method, json_t *j); char const *verb, char const *method,
json_t *j);
json_t *dc_api_call_sync(dc_api_t api, char const *token, json_t *dc_api_call_sync(dc_api_t api, char const *token,
char const *method, json_t *j); char const *verb, char const *method,
json_t *j);
/**
* Authenticate a given user account. The user account should have
* email, and password set. If the auth succeeds the account will have
* a login token, and will from now on be the "login account". You
* will have to pass that account to various other functions for
* authentication.
*/
bool dc_api_authenticate(dc_api_t api, dc_account_t account); bool dc_api_authenticate(dc_api_t api, dc_account_t account);
bool dc_api_userinfo(dc_api_t api, dc_account_t logion,
/**
* Retrieve basic user information for the given account. The first
* parameter is the user account holding login info, while the second
* is the account you wish to retrieve information about.
*/
bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
dc_account_t user); dc_account_t user);
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login,
GPtrArray *guilds);
#endif #endif

17
libdc/include/dc/guild.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef DC_GUILD_H
#define DC_GUILD_H
/* Discords version of groups or chat servers
*/
struct dc_guild_;
typedef struct dc_guild_ *dc_guild_t;
dc_guild_t dc_guild_new(void);
char const *dc_guild_name(dc_guild_t d);
void dc_guild_set_name(dc_guild_t d, char const *val);
char const *dc_guild_id(dc_guild_t d);
void dc_guild_set_id(dc_guild_t d, char const *val);
#endif

View File

@ -38,6 +38,11 @@ static void dc_account_free(dc_account_t ptr)
free(ptr->email); free(ptr->email);
free(ptr->password); free(ptr->password);
free(ptr->id);
free(ptr->username);
free(ptr->discriminator);
free(ptr->full);
free(ptr->token);
free(ptr); free(ptr);
} }

View File

@ -100,33 +100,15 @@ static int debug_callback(CURL *handle, curl_infotype type,
} }
#endif #endif
static int header_callback(char *data, size_t sz, size_t num, dc_api_t api) static dc_api_sync_t
{ dc_api_do(dc_api_t api, char const *verb,
char *ptr = NULL; char const *url, char const *token,
if ((ptr = strstr(data, "set-cookie")) != NULL) {
free(api->cookie);
api->cookie = NULL;
if ((ptr = strstr(data, ":")) != NULL) {
api->cookie = strdup(ptr+1);
if ((ptr = strstr(api->cookie, ";")) != NULL) {
*ptr = '\0';
}
}
}
return sz * num;
}
static dc_api_sync_t dc_api_post(dc_api_t api,
char const *url,
char const *token,
char const *data, int64_t len) char const *data, int64_t len)
{ {
return_if_true(api == NULL, NULL); return_if_true(api == NULL, NULL);
return_if_true(api->curl == NULL, NULL); return_if_true(api->curl == NULL, NULL);
return_if_true(url == NULL, NULL); return_if_true(url == NULL, NULL);
return_if_true(verb == NULL, NULL);
CURL *c = NULL; CURL *c = NULL;
bool ret = false; bool ret = false;
@ -144,8 +126,6 @@ static dc_api_sync_t dc_api_post(dc_api_t api,
curl_easy_setopt(c, CURLOPT_URL, url); curl_easy_setopt(c, CURLOPT_URL, url);
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(c, CURLOPT_WRITEDATA, dc_api_sync_stream(sync)); curl_easy_setopt(c, CURLOPT_WRITEDATA, dc_api_sync_stream(sync));
curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_setopt(c, CURLOPT_HEADERDATA, api);
if (api->cookie != NULL) { if (api->cookie != NULL) {
curl_easy_setopt(c, CURLOPT_COOKIE, api->cookie); curl_easy_setopt(c, CURLOPT_COOKIE, api->cookie);
@ -177,15 +157,23 @@ static dc_api_sync_t dc_api_post(dc_api_t api,
curl_easy_setopt(c, CURLOPT_DEBUGFUNCTION, debug_callback); curl_easy_setopt(c, CURLOPT_DEBUGFUNCTION, debug_callback);
#endif #endif
if (data != NULL) { if (strcmp(verb, "POST") == 0) {
curl_easy_setopt(c, CURLOPT_POST, 1UL); curl_easy_setopt(c, CURLOPT_POST, 1UL);
curl_easy_setopt(c, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); curl_easy_setopt(c, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
}
if (data != NULL) {
curl_easy_setopt(c, CURLOPT_COPYPOSTFIELDS, data); curl_easy_setopt(c, CURLOPT_COPYPOSTFIELDS, data);
if (len >= 0) { if (len >= 0) {
curl_easy_setopt(c, CURLOPT_POSTFIELDSIZE_LARGE, len); curl_easy_setopt(c, CURLOPT_POSTFIELDSIZE_LARGE, len);
} }
} }
if (strcmp(verb, "PUT") == 0 ||
strcmp(verb, "DELETE") == 0) {
curl_easy_setopt(c, CURLOPT_CUSTOMREQUEST, verb);
}
if (curl_multi_add_handle(api->curl, c) != CURLM_OK) { if (curl_multi_add_handle(api->curl, c) != CURLM_OK) {
goto cleanup; goto cleanup;
} }
@ -206,7 +194,8 @@ cleanup:
} }
dc_api_sync_t dc_api_call(dc_api_t api, char const *token, dc_api_sync_t dc_api_call(dc_api_t api, char const *token,
char const *method, json_t *j) char const *verb, char const *method,
json_t *j)
{ {
char *data = NULL; char *data = NULL;
char *url = NULL; char *url = NULL;
@ -220,7 +209,7 @@ dc_api_sync_t dc_api_call(dc_api_t api, char const *token,
goto_if_true(data == NULL, cleanup); goto_if_true(data == NULL, cleanup);
} }
s = dc_api_post(api, url, token, data, -1); s = dc_api_do(api, verb, url, token, data, -1);
goto_if_true(s == NULL, cleanup); goto_if_true(s == NULL, cleanup);
cleanup: cleanup:
@ -235,12 +224,13 @@ cleanup:
} }
json_t *dc_api_call_sync(dc_api_t api, char const *token, json_t *dc_api_call_sync(dc_api_t api, char const *token,
char const *method, json_t *j) char const *verb, char const *method,
json_t *j)
{ {
dc_api_sync_t s = NULL; dc_api_sync_t s = NULL;
json_t *reply = NULL; json_t *reply = NULL;
s = dc_api_call(api, token, method, j); s = dc_api_call(api, verb, token, method, j);
goto_if_true(s == NULL, cleanup); goto_if_true(s == NULL, cleanup);
if (!dc_api_sync_wait(s)) { if (!dc_api_sync_wait(s)) {
@ -302,7 +292,7 @@ bool dc_api_authenticate(dc_api_t api, dc_account_t account)
json_string(dc_account_password(account)) json_string(dc_account_password(account))
); );
reply = dc_api_call_sync(api, NULL, DISCORD_API_AUTH, j); reply = dc_api_call_sync(api, "POST", NULL, DISCORD_API_AUTH, j);
goto_if_true(reply == NULL, cleanup); goto_if_true(reply == NULL, cleanup);
if (dc_api_error(j, NULL, NULL)) { if (dc_api_error(j, NULL, NULL)) {
@ -332,7 +322,7 @@ cleanup:
return ret; return ret;
} }
bool dc_api_userinfo(dc_api_t api, dc_account_t login, bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
dc_account_t user) dc_account_t user)
{ {
char *url = NULL; char *url = NULL;
@ -345,7 +335,7 @@ bool dc_api_userinfo(dc_api_t api, dc_account_t login,
asprintf(&url, "users/%s", dc_account_id(user)); asprintf(&url, "users/%s", dc_account_id(user));
reply = dc_api_call_sync(api, dc_account_token(login), url, NULL); reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup); goto_if_true(reply == NULL, cleanup);
val = json_object_get(reply, "username"); val = json_object_get(reply, "username");
@ -371,3 +361,25 @@ cleanup:
return ret; return ret;
} }
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login,
{
char *url = NULL;
json_t *reply = NULL, *val = NULL;
bool ret = false;
return_if_true(api == NULL, false);
return_if_true(login == NULL, false);
return_if_true(user == NULL, false);
asprintf(&url, "users/%s/guilds", dc_account_id(user));
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup);
cleanup:
json_decref(reply);
return ret;
}

56
libdc/src/guild.c Normal file
View File

@ -0,0 +1,56 @@
#include <dc/guild.h>
#include <dc/refable.h>
#include "internal.h"
struct dc_guild_
{
dc_refable_t ref;
char *name;
char *id;
};
static void dc_guild_free(dc_guild_t ptr)
{
free(ptr->name);
free(ptr->id);
free(ptr);
}
dc_guild_t dc_guild_new(void)
{
dc_guild_t p = calloc(1, sizeof(struct dc_guild_));
return_if_true(p == NULL, NULL);
p->ref.cleanup = (dc_cleanup_t)dc_guild_free;
return p;
}
char const *dc_guild_name(dc_guild_t d)
{
return_if_true(d == NULL, NULL);
return d->name;
}
void dc_guild_set_name(dc_guild_t d, char const *val)
{
return_if_true(d == NULL || val == NULL,);
free(d->name);
d->name = strdup(val);
}
char const *dc_guild_id(dc_guild_t d)
{
return_if_true(d == NULL, NULL);
return d->id;
}
void dc_guild_set_id(dc_guild_t d, char const *val)
{
return_if_true(d == NULL || val == NULL,);
free(d->id);
d->id = strdup(val);
}

View File

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