149 lines
5.0 KiB
C
149 lines
5.0 KiB
C
#define _POSIX_C_SOURCE 200809L
|
|
|
|
#include "tools_internal.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "cjson/cJSON.h"
|
|
#include "../nostr_block_list.h"
|
|
|
|
static char* json_error_local(const char* msg) {
|
|
cJSON* root = cJSON_CreateObject();
|
|
if (!root) return NULL;
|
|
cJSON_AddBoolToObject(root, "success", 0);
|
|
cJSON_AddStringToObject(root, "error", msg ? msg : "unknown error");
|
|
char* out = cJSON_PrintUnformatted(root);
|
|
cJSON_Delete(root);
|
|
return out;
|
|
}
|
|
|
|
static cJSON* parse_args_local(const char* args_json) {
|
|
const char* raw = args_json ? args_json : "{}";
|
|
cJSON* args = cJSON_Parse(raw);
|
|
if (!args || !cJSON_IsObject(args)) {
|
|
cJSON_Delete(args);
|
|
return NULL;
|
|
}
|
|
return args;
|
|
}
|
|
|
|
char* execute_nostr_block_list(tools_context_t* ctx, const char* args_json) {
|
|
(void)ctx;
|
|
cJSON* args = parse_args_local(args_json);
|
|
if (!args) return json_error_local("invalid arguments JSON");
|
|
|
|
cJSON* type = cJSON_GetObjectItemCaseSensitive(args, "type");
|
|
const char* which = (type && cJSON_IsString(type) && type->valuestring) ? type->valuestring : "all";
|
|
|
|
char* raw = nostr_block_list_json();
|
|
cJSON_Delete(args);
|
|
if (!raw) return json_error_local("nostr_block_list unavailable");
|
|
|
|
cJSON* parsed = cJSON_Parse(raw);
|
|
free(raw);
|
|
if (!parsed || !cJSON_IsObject(parsed)) {
|
|
cJSON_Delete(parsed);
|
|
return json_error_local("nostr_block_list returned invalid JSON");
|
|
}
|
|
|
|
if (strcmp(which, "all") != 0 && strcmp(which, "p") != 0 && strcmp(which, "e") != 0 && strcmp(which, "t") != 0) {
|
|
cJSON_Delete(parsed);
|
|
return json_error_local("type must be one of: all, p, e, t");
|
|
}
|
|
|
|
if (strcmp(which, "all") == 0) {
|
|
char* out = cJSON_PrintUnformatted(parsed);
|
|
cJSON_Delete(parsed);
|
|
return out;
|
|
}
|
|
|
|
cJSON* out = cJSON_CreateObject();
|
|
if (!out) {
|
|
cJSON_Delete(parsed);
|
|
return NULL;
|
|
}
|
|
|
|
cJSON* success = cJSON_GetObjectItemCaseSensitive(parsed, "success");
|
|
cJSON_AddBoolToObject(out, "success", success && cJSON_IsBool(success) ? cJSON_IsTrue(success) : 1);
|
|
|
|
if (strcmp(which, "p") == 0) {
|
|
cJSON* arr = cJSON_Duplicate(cJSON_GetObjectItemCaseSensitive(parsed, "blocked_pubkeys"), 1);
|
|
if (!arr) arr = cJSON_CreateArray();
|
|
cJSON_AddItemToObject(out, "blocked_pubkeys", arr);
|
|
} else if (strcmp(which, "e") == 0) {
|
|
cJSON* arr = cJSON_Duplicate(cJSON_GetObjectItemCaseSensitive(parsed, "blocked_events"), 1);
|
|
if (!arr) arr = cJSON_CreateArray();
|
|
cJSON_AddItemToObject(out, "blocked_events", arr);
|
|
} else {
|
|
cJSON* arr = cJSON_Duplicate(cJSON_GetObjectItemCaseSensitive(parsed, "blocked_hashtags"), 1);
|
|
if (!arr) arr = cJSON_CreateArray();
|
|
cJSON_AddItemToObject(out, "blocked_hashtags", arr);
|
|
}
|
|
|
|
char* json = cJSON_PrintUnformatted(out);
|
|
cJSON_Delete(out);
|
|
cJSON_Delete(parsed);
|
|
return json;
|
|
}
|
|
|
|
char* execute_nostr_block_edit(tools_context_t* ctx, const char* args_json) {
|
|
(void)ctx;
|
|
cJSON* args = parse_args_local(args_json);
|
|
if (!args) return json_error_local("invalid arguments JSON");
|
|
|
|
cJSON* action = cJSON_GetObjectItemCaseSensitive(args, "action");
|
|
cJSON* items = cJSON_GetObjectItemCaseSensitive(args, "items");
|
|
cJSON* is_public = cJSON_GetObjectItemCaseSensitive(args, "public");
|
|
|
|
if (!action || !cJSON_IsString(action) || !action->valuestring ||
|
|
!items || !cJSON_IsArray(items)) {
|
|
cJSON_Delete(args);
|
|
return json_error_local("nostr_block_edit requires action and items");
|
|
}
|
|
|
|
int add_mode = strcmp(action->valuestring, "add") == 0;
|
|
int remove_mode = strcmp(action->valuestring, "remove") == 0;
|
|
if (!add_mode && !remove_mode) {
|
|
cJSON_Delete(args);
|
|
return json_error_local("action must be add or remove");
|
|
}
|
|
|
|
int public_mode = (is_public && cJSON_IsBool(is_public) && cJSON_IsTrue(is_public)) ? 1 : 0;
|
|
|
|
int affected = 0;
|
|
int count = cJSON_GetArraySize(items);
|
|
for (int i = 0; i < count; i++) {
|
|
cJSON* tuple = cJSON_GetArrayItem(items, i);
|
|
if (!tuple || !cJSON_IsArray(tuple) || cJSON_GetArraySize(tuple) < 2) {
|
|
continue;
|
|
}
|
|
|
|
cJSON* k = cJSON_GetArrayItem(tuple, 0);
|
|
cJSON* v = cJSON_GetArrayItem(tuple, 1);
|
|
if (!k || !v || !cJSON_IsString(k) || !cJSON_IsString(v) || !k->valuestring || !v->valuestring) {
|
|
continue;
|
|
}
|
|
|
|
int rc = add_mode
|
|
? nostr_block_list_add(k->valuestring, v->valuestring, public_mode)
|
|
: nostr_block_list_remove(k->valuestring, v->valuestring);
|
|
if (rc == 0) {
|
|
affected++;
|
|
}
|
|
}
|
|
|
|
cJSON_Delete(args);
|
|
|
|
cJSON* out = cJSON_CreateObject();
|
|
if (!out) return NULL;
|
|
cJSON_AddBoolToObject(out, "success", affected > 0 ? 1 : 0);
|
|
cJSON_AddStringToObject(out, "action", add_mode ? "add" : "remove");
|
|
cJSON_AddBoolToObject(out, "public", public_mode ? 1 : 0);
|
|
cJSON_AddNumberToObject(out, "items_affected", affected);
|
|
|
|
char* json = cJSON_PrintUnformatted(out);
|
|
cJSON_Delete(out);
|
|
return json;
|
|
}
|