diff --git a/include/mastodont_list.h b/include/mastodont_list.h index 2dfd969..6fd3a3d 100644 --- a/include/mastodont_list.h +++ b/include/mastodont_list.h @@ -18,12 +18,29 @@ #include #include #include +#include + +enum mstdnt_list_replies_policy +{ + MSTDNT_LIST_REPLIES_POLICY_NONE, + MSTDNT_LIST_REPLIES_POLICY_LIST, + // Not sure why there is one for followed... you cannot add + // people to a list who don't follow you? I'd imagine it's the same as + // the last one. + MSTDNT_LIST_REPLIES_POLICY_FOLLOWED +}; struct mstdnt_list { char* id; char* title; - char* replies_policy; + enum mstdnt_list_replies_policy replies_policy; +}; + +struct mstdnt_list_args +{ + char* title; + enum mstdnt_list_replies_policy replies_policy; }; int mstdnt_list_json(struct mstdnt_list* list, cJSON* js); @@ -33,8 +50,50 @@ int mstdnt_lists_json(struct mstdnt_list* lists[], cJSON* json); int mastodont_get_lists(mastodont_t* api, - struct mstdnt_list* lists[], struct mstdnt_storage* storage, + struct mstdnt_list* lists[], size_t* size); +int mastodont_get_list(mastodont_t* api, + char* id, + struct mstdnt_storage* storage, + struct mstdnt_list* lists); + +int mastodont_create_list(mastodont_t* api, + struct mstdnt_list_args* args, + struct mstdnt_storage* storage, + struct mstdnt_list* list); + +int mastodont_update_list(mastodont_t* api, + char* id, + struct mstdnt_list_args* args, + struct mstdnt_storage* storage, + struct mstdnt_list* list); + +int mastodont_delete_list(mastodont_t* api, + char* id, + struct mstdnt_storage* storage); + +int mastodont_list_get_accounts(mastodont_t* data, + char* id, + struct mstdnt_account_args* args, + struct mstdnt_storage* storage, + struct mstdnt_account* accts[], + size_t* accts_len); + +int mastodont_list_add_accounts(mastodont_t* api, + char* id, + char** account_ids, + size_t account_ids_len, + struct mstdnt_storage* storage); + +int mastodont_list_remove_accounts(mastodont_t* api, + char* id, + char** account_ids, + size_t account_ids_len, + struct mstdnt_storage* storage); + +// Cleanup +void mstdnt_cleanup_lists(struct mstdnt_list* lists, size_t len); + #endif /* MASTODONT_LIST_H */ diff --git a/src/list.c b/src/list.c index e5cdc67..978e865 100644 --- a/src/list.c +++ b/src/list.c @@ -26,6 +26,18 @@ struct mstdnt_get_lists_args { size_t* size; }; +static void _mstdnt_val_replies_policy_call(cJSON* v, void* _type) +{ + enum mstdnt_list_replies_policy* type = _type; + + if (strcmp("none", v->valuestring) == 0) + *type = MSTDNT_LIST_REPLIES_POLICY_NONE; + else if (strcmp("list", v->valuestring) == 0) + *type = MSTDNT_LIST_REPLIES_POLICY_LIST; + else if (strcmp("followed", v->valuestring) == 0) + *type = MSTDNT_LIST_REPLIES_POLICY_FOLLOWED; +} + int mstdnt_list_json(struct mstdnt_list* list, cJSON* js) { cJSON* v; @@ -33,22 +45,26 @@ int mstdnt_list_json(struct mstdnt_list* list, cJSON* js) /* Zero out */ memset(list, 0, sizeof(struct mstdnt_list)); - struct _mstdnt_str_val strings[] = { - { "id", &(list->id) }, - { "title", &(list->title) }, - { "replies_policy", &(list->replies_policy) } + struct _mstdnt_val_ref vals[] = { + { "id", &(list->id), _mstdnt_val_string_call }, + { "title", &(list->title), _mstdnt_val_string_call }, + { "replies_policy", &(list->replies_policy), _mstdnt_val_replies_policy_call } }; for (v = js; v; v = v->next) - if (_mstdnt_key_val_iter(v, strings, _mstdnt_arr_len(strings), - NULL, 0) == 1) - return 1; + _mstdnt_key_val_ref(v, vals, _mstdnt_arr_len(vals)); + return 0; } -GENERATE_JSON_ARRAY_FUNC(mstdnt_lists_json, struct mstdnt_list, mstdnt_list_json) - +GENERATE_JSON_ARRAY_FUNC(mstdnt_lists_json, struct mstdnt_list, mstdnt_list_json); + +static int mstdnt_list_json_callback(cJSON* json, void* _args) +{ + return mstdnt_list_json(_args, json); +} + static int mstdnt_lists_json_callback(cJSON* json, void* _args) { struct mstdnt_get_lists_args* args = _args; @@ -56,8 +72,8 @@ static int mstdnt_lists_json_callback(cJSON* json, void* _args) } int mastodont_get_lists(mastodont_t* data, - struct mstdnt_list* lists[], struct mstdnt_storage* storage, + struct mstdnt_list* lists[], size_t* size) { struct mstdnt_get_lists_args args = { @@ -78,3 +94,219 @@ int mastodont_get_lists(mastodont_t* data, return mastodont_request(data, &req_args); } + +int mastodont_get_list(mastodont_t* data, + char* id, + struct mstdnt_storage* storage, + struct mstdnt_list* list) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s", id); + + struct mastodont_request_args req_args = { + storage, + url, + NULL, 0, + NULL, 0, + CURLOPT_HTTPGET, + NULL, + list, + mstdnt_list_json_callback + }; + + return mastodont_request(data, &req_args); +} + +static const char* replies_policy_str(enum mstdnt_list_replies_policy pol) +{ + switch (pol) + { + case MSTDNT_LIST_REPLIES_POLICY_LIST: + return "list"; + case MSTDNT_LIST_REPLIES_POLICY_FOLLOWED: + return "followed"; + case MSTDNT_LIST_REPLIES_POLICY_NONE: + default: + return "none"; + } +} + +int mastodont_create_list(mastodont_t* data, + struct mstdnt_list_args* args, + struct mstdnt_storage* storage, + struct mstdnt_list* list) +{ + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_STRING, "title", { .s = args->title } }, + { _MSTDNT_QUERY_STRING, "replies_policy", { .s = (char*)replies_policy_str(args->replies_policy) } }, + }; + + struct mastodont_request_args req_args = { + storage, + "api/v1/lists", + NULL, 0, + params, _mstdnt_arr_len(params), + CURLOPT_POST, + NULL, + list, + mstdnt_list_json_callback + }; + + return mastodont_request(data, &req_args); +} + +int mastodont_update_list(mastodont_t* data, + char* id, + struct mstdnt_list_args* args, + struct mstdnt_storage* storage, + struct mstdnt_list* list) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s", id); + + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_STRING, "title", { .s = args->title } }, + { _MSTDNT_QUERY_STRING, "replies_policy", { .s = (char*)replies_policy_str(args->replies_policy) } }, + }; + + struct mastodont_request_args req_args = { + storage, + url, + NULL, 0, + params, _mstdnt_arr_len(params), + CURLOPT_PUT, + NULL, + list, + mstdnt_list_json_callback + }; + + return mastodont_request(data, &req_args); +} + +int mastodont_delete_list(mastodont_t* api, + char* id, + struct mstdnt_storage* storage) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s", id); + + struct mastodont_request_args req_args = { + storage, + url, + NULL, 0, + NULL, 0, + CURLOPT_CUSTOMREQUEST, + "DELETE", + NULL, + NULL, + }; + + return mastodont_request(api, &req_args); +} + +int mastodont_list_add_accounts(mastodont_t* api, + char* id, + char** account_ids, + size_t account_ids_len, + struct mstdnt_storage* storage) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s/accounts", id); + + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_ARRAY, "account_ids", + { + .a.arr = account_ids, + .a.arr_len = account_ids_len + } + }, + }; + + struct mastodont_request_args req_args = { + storage, + url, + NULL, 0, + params, _mstdnt_arr_len(params), + CURLOPT_POST, + NULL, + NULL, + NULL, + }; + + return mastodont_request(api, &req_args); +} + +int mastodont_list_remove_accounts(mastodont_t* api, + char* id, + char** account_ids, + size_t account_ids_len, + struct mstdnt_storage* storage) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s/accounts", id); + + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_ARRAY, "account_ids", + { + .a.arr = account_ids, + .a.arr_len = account_ids_len + } + }, + }; + + struct mastodont_request_args req_args = { + storage, + url, + NULL, 0, + params, _mstdnt_arr_len(params), + CURLOPT_CUSTOMREQUEST, + "DELETE", + NULL, + NULL, + }; + + return mastodont_request(api, &req_args); +} + +int mastodont_list_get_accounts(mastodont_t* data, + char* id, + struct mstdnt_account_args* args, + struct mstdnt_storage* storage, + struct mstdnt_account* accts[], + size_t* accts_len) +{ + char url[MSTDNT_URLSIZE]; + snprintf(url, MSTDNT_URLSIZE, "api/v1/lists/%s/accounts", id); + struct _mstdnt_accounts_args _args = { + accts, + accts_len, + }; + + struct _mstdnt_query_param params[] = { + { _MSTDNT_QUERY_STRING, "max_id", { .s = args->max_id } }, + { _MSTDNT_QUERY_STRING, "min_id", { .s = args->min_id } }, + { _MSTDNT_QUERY_STRING, "since_id", { .s = args->since_id } }, + { _MSTDNT_QUERY_INT, "offset", { .i = args->offset } }, + { _MSTDNT_QUERY_INT, "limit", { .i = args->limit } }, + { _MSTDNT_QUERY_INT, "with_relationships", { .i = args->with_relationships } }, + }; + + struct mastodont_request_args req_args = { + storage, + url, + params, _mstdnt_arr_len(params), + NULL, 0, + CURLOPT_HTTPGET, + NULL, + &_args, + mstdnt_accounts_json_callback, + }; + + return mastodont_request(data, &req_args); +} + +void mstdnt_cleanup_lists(struct mstdnt_list* lists, size_t len) +{ + if (!lists) return; + free(lists); +}