commit e2b04277a86322e43b95cd25153ceceb70a3358e Author: Alfie King Date: Fri Feb 6 20:52:29 2026 +0000 /posts.json implemented diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f6f566 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +.vscode +creds.h \ No newline at end of file diff --git a/include/e621.h b/include/e621.h new file mode 100644 index 0000000..8b8f172 --- /dev/null +++ b/include/e621.h @@ -0,0 +1,117 @@ +#ifndef E621_HPP +#define E621_HPP + +// Includes +#include + +// Defines + +#ifndef E621_HOST +#define E621_HOST "https://e621.net" +#endif + +#ifndef E621_URL_BUF_SIZE +#define E621_URL_BUF_SIZE 2048 +#endif + +// Structs +typedef struct { + unsigned int width; + unsigned int height; + char *ext; + unsigned int size; + char *md5; + char *url; +} e6_file_t; + +typedef struct { + unsigned int width; + unsigned int height; + char *url; +} e6_preview_t; + +typedef struct { + bool has; + unsigned int width; + unsigned int height; + char *url; +} e6_sample_t; + +typedef struct { + unsigned int up; + unsigned int down; + int total; +} e6_score_t; + +typedef struct { + char **general; + int general_count; + char **artist; + int artist_count; + char **contributor; + int contributor_count; + char **copyright; + int copyright_count; + char **character; + int character_count; + char **species; + int species_count; + char **invalid; + int invalid_count; + char **meta; + int meta_count; + char **lore; + int lore_count; +} e6_tags_t; + +typedef struct flags_t { + bool pending; + bool flagged; + bool note_locked; + bool status_locked; + bool rating_locked; + bool deleted; +} e6_flags_t; + +typedef struct { + unsigned int parent_id; + bool has_children; + bool has_active_children; + int *children; +} e6_relationships_t; + +typedef struct { + unsigned int id; + char *created_at; + char *updated_at; + e6_file_t file; + e6_preview_t preview; + e6_sample_t sample; + e6_score_t score; + e6_tags_t tags; + char **locked_tags; + int locked_tags_count; + unsigned int change_seq; + e6_flags_t flags; + char *rating; + unsigned int fav_count; + int *pools; + e6_relationships_t relationships; + unsigned int approver_id; + unsigned int uploader_id; + char *description; + unsigned int comment_count; + bool is_favorited; +} e6_post_t; + +typedef struct { + char *username; + char *api_key; + char *project_name; + float project_ver; +} e6_auth_t; + +// Functions +e6_post_t *E6List(e6_auth_t auth, char **tags, int tags_count, unsigned int page, unsigned int limit); + +#endif \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..c02f157 --- /dev/null +++ b/makefile @@ -0,0 +1,39 @@ +# Compiler and linker settings +CXX = gcc +LDFLAGS = `curl-config --libs` -lssl -lcrypto +CXXFLAGS = -pedantic -std=c23 -I include `curl-config --cflags` + +# Source and object files +SRC = $(wildcard src/*.c) +OBJ = $(addprefix build/, $(notdir $(SRC:.c=.o))) + +# Target executable +TARGET = build/x86_64/main.x86_64 + +# Default target +all: clean dirs $(TARGET) + +# development target with debugging +dev: CXXFLAGS += -g +dev: all + +# Release target +release: CXXFLAGS += -O3 +release: all + +# Create build directory if it doesn't exist +dirs: + @mkdir -p build/x86_64 + +# Build target +$(TARGET): $(OBJ) + $(CXX) -o $@ $^ $(LDFLAGS) + +# Build object files +build/%.o: src/%.c + $(CXX) -c -o $@ $< $(CXXFLAGS) + +# Clean up build files +clean: + @rm -f $(OBJ) $(TARGET) + @echo "Cleaned up build files." \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..297ae4c --- /dev/null +++ b/readme.md @@ -0,0 +1,6 @@ +# C621 + +A C libary for the e621 api. + +## Y tho? +I made this cus i thought it was funny :3 \ No newline at end of file diff --git a/src/e621.c b/src/e621.c new file mode 100644 index 0000000..2558386 --- /dev/null +++ b/src/e621.c @@ -0,0 +1,97 @@ +// Includes +#include +#include +#include +#include +#include +#include "e621.h" + +struct Memory { + char *data; + size_t size; +}; + +struct curl_slist *MakeHeaders(e6_auth_t auth) { + struct curl_slist *headers = NULL; + + char auth_buf[256]; + char base64_buf[128]; + snprintf(auth_buf, sizeof(auth_buf), "%s:%s", auth.username, auth.api_key); + EVP_EncodeBlock((unsigned char*)base64_buf, (unsigned char*)auth_buf, strlen(auth_buf)); + memset(auth_buf, 0, sizeof(auth_buf)); + snprintf(auth_buf, sizeof(base64_buf), "Authorization: Basic %s", base64_buf); + headers = curl_slist_append(headers, auth_buf); + + char user_agent_buf[256]; + snprintf(user_agent_buf, sizeof(user_agent_buf), "User-Agent: %s/%f (by %s on e621)", auth.project_name, auth.project_ver, auth.username); + headers = curl_slist_append(headers, user_agent_buf); + + return headers; +} + +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) +{ + size_t total = size * nmemb; + struct Memory *mem = (struct Memory *)userdata; + + char *ptr = realloc(mem->data, mem->size + total + 1); + if (!ptr) + return 0; + + mem->data = ptr; + memcpy(&(mem->data[mem->size]), contents, total); + mem->size += total; + mem->data[mem->size] = '\0'; + + return total; +} + + +e6_post_t *E6List(e6_auth_t auth, char **tags, int tags_count, unsigned int page, unsigned int limit) { + CURL *curl = curl_easy_init(); + CURLcode result; + struct Memory read_buffer; + read_buffer.data = malloc(1); + read_buffer.size = 0; + + if (curl) { + char *url = (char *)malloc(E621_URL_BUF_SIZE); + strncpy(url, E621_HOST, E621_URL_BUF_SIZE); + strcat(url, "/posts.json?tags="); + + for (int i = 0; i < tags_count; i++) { + char *tag = tags[i]; + strncat(url, tag, strlen(tag)); + strcat(url, "+"); + } + + char page_buf[15]; + snprintf(page_buf, sizeof(page_buf), "&page=%d", page); + strncat(url, page_buf, strlen(page_buf)); + + char limit_buf[15]; + snprintf(limit_buf, sizeof(limit_buf), "&limit=%d", limit); + strncat(url, limit_buf, strlen(limit_buf)); + + struct curl_slist *headers = MakeHeaders(auth); + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&read_buffer); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + result = curl_easy_perform(curl); + + } else { + fprintf(stderr, "Failed to initialize CURL"); + exit(EXIT_FAILURE); + } + + if (result != CURLE_OK) { + fprintf(stderr, "CURL error: %s", curl_easy_strerror(result)); + return NULL; + } + + // Temp (testing purposes) + printf(read_buffer.data); + return NULL; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e41c705 --- /dev/null +++ b/src/main.c @@ -0,0 +1,9 @@ +#include "e621.h" +#include "creds.h" // provides the API key and username + +int main(int argc, char *argv[]) { + e6_auth_t auth = { USERNAME, API_KEY, "c621", 0.1 }; + + E6List(auth, (char* []){ "order:score", "cat" }, 2, 1, 3); + return 0; +}