14#include <cjson/cJSON.h>
17#define NEKOS_BASE_URL "https://nekos.best/api/v2/"
20#define NEKOS_MAX_AMOUNT 20
23#define NEKOS_MIN_QUERY_LEN 3
25#define NEKOS_MAX_QUERY_LEN 150
252static size_t nekos_write_callback(
const void *ptr,
size_t count,
size_t nmemb,
nekos_http_response *http_response) {
253 size_t size = count * nmemb;
254 size_t new_len = http_response->
len + size;
257 char* new_text = (
char*) realloc(http_response->
text, new_len + 1);
259 free(http_response->
text);
260 return CURLE_ABORTED_BY_CALLBACK;
264 memcpy(new_text + http_response->
len, ptr, size);
265 http_response->
text = new_text;
266 http_response->
len = new_len;
272 http_response->
len = 0;
273 http_response->
text = (
char*) malloc(1);
274 if (!http_response->
text)
278 CURL *curl = curl_easy_init();
283 curl_easy_setopt(curl, CURLOPT_URL, url);
284 curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L);
285 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, nekos_write_callback);
286 curl_easy_setopt(curl, CURLOPT_WRITEDATA, http_response);
289 CURLcode res = curl_easy_perform(curl);
294 curl_easy_cleanup(curl);
298static char* nekos_jsondup(
const cJSON *json,
const char* key) {
299 const cJSON *element = cJSON_GetObjectItemCaseSensitive(json, key);
300 char* str = (
char*) malloc(strlen(element->valuestring) + 1);
301 strcpy(str, element->valuestring);
313 cJSON *json = cJSON_ParseWithLength(http_response.
text, http_response.
len);
314 if (!json || !cJSON_IsObject(json))
318 endpoints->
len = cJSON_GetArraySize(json);
322 const cJSON *endpoint_obj;
324 cJSON_ArrayForEach(endpoint_obj, json) {
325 char* name = endpoint_obj->string;
326 endpoints->
endpoints[i].
name = (
char*) malloc(strlen(name) + 1);
329 const cJSON *format_obj = cJSON_GetObjectItemCaseSensitive(endpoint_obj,
"format");
337 free(http_response.
text);
342 for (
size_t i = 0; i < endpoints->
len; i++) {
361 nekos_status http_status = nekos_do_request(&http_response, url);
366 cJSON *json = cJSON_ParseWithLength(http_response.
text, http_response.
len);
367 if (!json || !cJSON_IsObject(json))
371 cJSON *results_obj = cJSON_GetObjectItemCaseSensitive(json,
"results");
372 results->
len = cJSON_GetArraySize(results_obj);
376 const cJSON *response_obj;
378 cJSON_ArrayForEach(response_obj, results_obj) {
379 results->
responses[i].
url = nekos_jsondup(response_obj,
"url");
395 free(http_response.
text);
405 char* query = curl_easy_escape(NULL, raw_query, 0);
408 size_t query_len = strlen(query);
415 snprintf(url, 256,
NEKOS_BASE_URL "search?query=%s&type=%d&amount=%d&category=%s", query, format + 1, amount, endpoint->
name);
417 snprintf(url, 256,
NEKOS_BASE_URL "search?query=%s&type=%d&amount=%d", query, format + 1, amount);
421 nekos_status http_status = nekos_do_request(&http_response, url);
426 cJSON *json = cJSON_ParseWithLength(http_response.
text, http_response.
len);
427 if (!json || !cJSON_IsObject(json))
431 cJSON *results_obj = cJSON_GetObjectItemCaseSensitive(json,
"results");
432 results->
len = cJSON_GetArraySize(results_obj);
436 const cJSON *response_obj;
438 cJSON_ArrayForEach(response_obj, results_obj) {
439 results->
responses[i].
url = nekos_jsondup(response_obj,
"url");
456 free(http_response.
text);
462 return nekos_do_request(http_response, url);
466 free(endpoint->
name);
470 for (
size_t i = 0; i < endpoints->
len; i++)
490 for (
size_t i = 0; i < results->
len; i++)
497 free(http_response->
text);
nekos_status nekos_search(nekos_result_list *results, const char *raw_query, int amount, const nekos_format format, const nekos_endpoint *endpoint)
Search for images.
#define NEKOS_MAX_QUERY_LEN
Maximum length of query string.
Definition nekosbest.h:25
nekos_format
Enum for the format of the image.
Definition nekosbest.h:37
@ NEKOS_GIF
Indicates that the response image is a gif and nekos_source_gif should be used.
Definition nekosbest.h:39
@ NEKOS_PNG
Indicates that the response image is a png and nekos_source_png should be used.
Definition nekosbest.h:38
nekos_status
Status codes for the nekos.best c wrapper.
Definition nekosbest.h:28
@ NEKOS_OK
Indicates that the operation was successful.
Definition nekosbest.h:29
@ NEKOS_LIBCURL_ERR
Indicates that there was an error with libcurl.
Definition nekosbest.h:31
@ NEKOS_CJSON_ERR
Indicates that there was an error with cJSON.
Definition nekosbest.h:32
@ NEKOS_INVALID_PARAM_ERR
Indicates that an invalid parameter was passed to a function.
Definition nekosbest.h:33
@ NEKOS_MEM_ERR
Indicates that there was a memory allocation error.
Definition nekosbest.h:30
#define NEKOS_BASE_URL
Base URL for nekos.best API.
Definition nekosbest.h:17
nekos_status nekos_download(nekos_http_response *http_response, const char *url)
Download an image.
#define NEKOS_MAX_AMOUNT
Maximum amount of results that can be requested.
Definition nekosbest.h:20
void nekos_free_result(const nekos_result *result)
Free a result.
nekos_endpoint * nekos_find_endpoint(const nekos_endpoint_list *endpoints, const char *name)
Find a specific endpoint in a list of endpoints/categories.
void nekos_free_http_response(const nekos_http_response *http_response)
Free an http response.
void nekos_free_endpoints(const nekos_endpoint_list *endpoints)
Free a list of endpoints.
void nekos_free_results(const nekos_result_list *results)
Free a list of results.
nekos_status nekos_category(nekos_result_list *results, const nekos_endpoint *endpoint, int amount)
Get a list of images from a category.
nekos_status nekos_endpoints(nekos_endpoint_list *endpoints)
Get a list of endpoints/categories.
void nekos_free_endpoint(const nekos_endpoint *endpoint)
Free an endpoint.
Struct for a list of endpoints/categories.
Definition nekosbest.h:49
nekos_endpoint * endpoints
[out] Array of endpoints/categories.
Definition nekosbest.h:50
size_t len
[out] Amount of endpoints/categories.
Definition nekosbest.h:51
Struct for an endpoint/category.
Definition nekosbest.h:43
char * name
[out] Name of the endpoint/category.
Definition nekosbest.h:44
nekos_format format
[out] Format of the endpoint/category.
Definition nekosbest.h:45
Struct for an http response.
Definition nekosbest.h:85
char * text
[out] Non-nullterminated text of the response.
Definition nekosbest.h:86
size_t len
[out] Length of the response text.
Definition nekosbest.h:87
Struct for a list of result images.
Definition nekosbest.h:77
nekos_result * responses
[out] Array of result images.
Definition nekosbest.h:78
size_t len
[out] Amount of result images.
Definition nekosbest.h:79
Struct for a result image.
Definition nekosbest.h:67
union nekos_result::@0 source
[out] Source information of the image.
nekos_source_gif * gif
[out] Source information for a gif (only use if the format is nekos_format::NEKOS_GIF ).
Definition nekosbest.h:70
nekos_source_png * png
[out] Source information for a png (only use if the format is nekos_format::NEKOS_PNG ).
Definition nekosbest.h:71
char * url
[out] URL to the image.
Definition nekosbest.h:73
nekos_format format
[out] Format of the image.
Definition nekosbest.h:68
Struct for a gif source.
Definition nekosbest.h:55
char * anime_name
[out] Name of the anime the gif is from.
Definition nekosbest.h:56
Struct for a png source.
Definition nekosbest.h:60
char * artist_href
[out] URL to the artist's page.
Definition nekosbest.h:62
char * artist_name
[out] Name of the artist of the png.
Definition nekosbest.h:61
char * source_url
[out] URL to the source of the png.
Definition nekosbest.h:63