Files
didactyl/src/tools/tool_nostr_block.c
T

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;
}