diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Routes/Search.c | 57 | ||||
| -rw-r--r-- | src/Routes/Settings.c | 60 | ||||
| -rw-r--r-- | src/Routes/SettingsSave.c | 32 | ||||
| -rw-r--r-- | src/Utility/Utility.c | 84 | ||||
| -rw-r--r-- | src/Utility/Utility.h | 4 |
5 files changed, 233 insertions, 4 deletions
diff --git a/src/Routes/Search.c b/src/Routes/Search.c index e201e10..f0c5ad1 100644 --- a/src/Routes/Search.c +++ b/src/Routes/Search.c @@ -290,6 +290,13 @@ static const SearchEngine *find_enabled_engine(const char *engine_id) { return NULL; } +static int engine_allowed_for_user(const SearchEngine *eng, char **user_ids, + int user_count, int has_pref) { + if (!has_pref) + return 1; + return user_engines_contains(eng->id, user_ids, user_count); +} + static char *build_search_href(const char *query, const char *engine_id, int page) { const char *safe_query = query ? query : ""; @@ -350,6 +357,10 @@ int results_handler(UrlParams *params) { int page = 1; int btnI = 0; + char **user_engines = NULL; + int user_engine_count = 0; + int has_user_pref = (get_user_engines(&user_engines, &user_engine_count) == 0); + if (params) { for (int i = 0; i < params->count; i++) { if (strcmp(params->params[i].key, "q") == 0) { @@ -396,6 +407,11 @@ int results_handler(UrlParams *params) { if (!raw_query || strlen(raw_query) == 0) { send_redirect("/"); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); return -1; } @@ -412,7 +428,9 @@ int results_handler(UrlParams *params) { int enabled_engine_count = 0; for (int i = 0; i < ENGINE_COUNT; i++) { if (ENGINE_REGISTRY[i].enabled && - (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine)) { + (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine) && + engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines, + user_engine_count, has_user_pref)) { enabled_engine_count++; } } @@ -439,7 +457,9 @@ int results_handler(UrlParams *params) { int engine_idx = 0; for (int i = 0; i < ENGINE_COUNT; i++) { if (ENGINE_REGISTRY[i].enabled && - (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine)) { + (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine) && + engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines, + user_engine_count, has_user_pref)) { all_results[engine_idx] = NULL; jobs[engine_idx].engine = &ENGINE_REGISTRY[i]; jobs[engine_idx].query = raw_query; @@ -488,6 +508,11 @@ int results_handler(UrlParams *params) { snprintf(response, sizeof(response), "<h1>%s</h1>", rate_limit_msg); send_response(response); free(request_cache_key); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); return -1; } @@ -499,7 +524,9 @@ int results_handler(UrlParams *params) { int filter_engine_count = 0; for (int i = 0; i < ENGINE_COUNT; i++) { - if (ENGINE_REGISTRY[i].enabled) + if (ENGINE_REGISTRY[i].enabled && + engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines, + user_engine_count, has_user_pref)) filter_engine_count++; } @@ -516,7 +543,9 @@ int results_handler(UrlParams *params) { free(all_href); for (int i = 0; i < ENGINE_COUNT; i++) { - if (!ENGINE_REGISTRY[i].enabled) + if (!ENGINE_REGISTRY[i].enabled || + !engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines, + user_engine_count, has_user_pref)) continue; char *filter_href = @@ -575,6 +604,11 @@ int results_handler(UrlParams *params) { } } free(request_cache_key); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); if (redirect_url) { send_redirect(redirect_url); @@ -594,6 +628,11 @@ int results_handler(UrlParams *params) { } } free(request_cache_key); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); char no_results_html[128]; snprintf(no_results_html, sizeof(no_results_html), "<h1>%s</h1>", no_results_msg); @@ -696,6 +735,11 @@ int results_handler(UrlParams *params) { } } free(request_cache_key); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); return 0; } @@ -822,6 +866,11 @@ int results_handler(UrlParams *params) { } } free(locale); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } free_context(&ctx); return 0; diff --git a/src/Routes/Settings.c b/src/Routes/Settings.c index cfadd09..1ad85a7 100644 --- a/src/Routes/Settings.c +++ b/src/Routes/Settings.c @@ -1,4 +1,5 @@ #include "Settings.h" +#include "../Scraping/Scraping.h" #include "../Utility/Utility.h" #include <beaker.h> #include <stdlib.h> @@ -29,6 +30,48 @@ int settings_handler(UrlParams *params) { inner_counts[i] = 2; } + char **user_engines = NULL; + int user_engine_count = 0; + int has_user_pref = (get_user_engines(&user_engines, &user_engine_count) == 0); + + int enabled_count = 0; + for (int i = 0; i < ENGINE_COUNT; i++) { + if (ENGINE_REGISTRY[i].enabled) + enabled_count++; + } + + char ***engine_data = NULL; + int *engine_inner = NULL; + + if (enabled_count > 0) { + engine_data = malloc(sizeof(char **) * enabled_count); + engine_inner = malloc(sizeof(int) * enabled_count); + + int idx = 0; + for (int i = 0; i < ENGINE_COUNT; i++) { + if (!ENGINE_REGISTRY[i].enabled) + continue; + + int is_selected = !has_user_pref; + if (has_user_pref) { + for (int j = 0; j < user_engine_count; j++) { + if (strcmp(user_engines[j], ENGINE_REGISTRY[i].id) == 0) { + is_selected = 1; + break; + } + } + } + + engine_data[idx] = malloc(sizeof(char *) * 3); + engine_data[idx][0] = (char *)ENGINE_REGISTRY[i].id; + engine_data[idx][1] = (char *)ENGINE_REGISTRY[i].name; + engine_data[idx][2] = is_selected ? "checked" : ""; + engine_inner[idx] = 3; + + idx++; + } + } + TemplateContext ctx = new_context(); beaker_set_locale(&ctx, locale); context_set(&ctx, "query", query); @@ -36,9 +79,26 @@ int settings_handler(UrlParams *params) { context_set(&ctx, "locale", locale); context_set_array_of_arrays(&ctx, "locales", locale_data, locale_count, inner_counts); + if (enabled_count > 0) { + context_set_array_of_arrays(&ctx, "enabled_engines", engine_data, + enabled_count, engine_inner); + context_set(&ctx, "has_enabled_engines", "1"); + } + for (int i = 0; i < locale_count; i++) { free(locale_data[i]); } + if (engine_data) { + for (int i = 0; i < enabled_count; i++) + free(engine_data[i]); + free(engine_data); + } + free(engine_inner); + if (has_user_pref) { + for (int i = 0; i < user_engine_count; i++) + free(user_engines[i]); + free(user_engines); + } char *rendered_html = render_template("settings.html", &ctx); send_response(rendered_html); diff --git a/src/Routes/SettingsSave.c b/src/Routes/SettingsSave.c index 323fe0d..cacff50 100644 --- a/src/Routes/SettingsSave.c +++ b/src/Routes/SettingsSave.c @@ -1,11 +1,18 @@ #include "SettingsSave.h" +#include "../Scraping/Scraping.h" +#include "../Utility/Utility.h" #include <stdlib.h> #include <string.h> +#define MAX_ENGINE_IDS ENGINE_COUNT + int settings_save_handler(UrlParams *params) { const char *theme = ""; const char *locale = ""; const char *query = ""; + int engines_present = 0; + char selected_ids[ENGINE_COUNT][32]; + int selected_count = 0; if (params) { for (int i = 0; i < params->count; i++) { @@ -15,6 +22,19 @@ int settings_save_handler(UrlParams *params) { locale = params->params[i].value; } else if (strcmp(params->params[i].key, "q") == 0) { query = params->params[i].value; + } else if (strcmp(params->params[i].key, "engines_present") == 0) { + engines_present = 1; + } else if (strncmp(params->params[i].key, "engine_", 7) == 0 && + strcmp(params->params[i].value, "1") == 0) { + const char *engine_id = params->params[i].key + 7; + if (engine_id[0] != '\0' && is_engine_id_enabled(engine_id) && + selected_count < ENGINE_COUNT) { + strncpy(selected_ids[selected_count], engine_id, + sizeof(selected_ids[selected_count]) - 1); + selected_ids[selected_count][sizeof(selected_ids[selected_count]) - 1] = + '\0'; + selected_count++; + } } } } @@ -26,6 +46,18 @@ int settings_save_handler(UrlParams *params) { set_cookie("locale", locale, "Fri, 31 Dec 2038 23:59:59 GMT", "/", false, false); } + if (engines_present) { + char cookie_value[512]; + cookie_value[0] = '\0'; + for (int i = 0; i < selected_count; i++) { + if (i > 0) + strcat(cookie_value, ","); + strcat(cookie_value, selected_ids[i]); + } + set_cookie("engines", cookie_value, "Fri, 31 Dec 2038 23:59:59 GMT", "/", + false, false); + } + char redirect_url[512]; snprintf(redirect_url, sizeof(redirect_url), "/settings?q=%s", query); send_redirect(redirect_url); diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c index bffda4d..16656bb 100644 --- a/src/Utility/Utility.c +++ b/src/Utility/Utility.c @@ -1,4 +1,5 @@ #include "Utility.h" +#include "../Scraping/Scraping.h" #include <beaker.h> #include <stdio.h> #include <stdlib.h> @@ -34,6 +35,89 @@ char *get_locale(const char *default_locale) { return strdup(default_locale); } +static int engine_id_casecmp(const char *a, const char *b) { + while (*a && *b) { + char la = *a; + char lb = *b; + if (la >= 'A' && la <= 'Z') la = la - 'A' + 'a'; + if (lb >= 'A' && lb <= 'Z') lb = lb - 'A' + 'a'; + if (la != lb) return 0; + a++; + b++; + } + return *a == *b; +} + +int is_engine_id_enabled(const char *engine_id) { + if (!engine_id) return 0; + for (int i = 0; i < ENGINE_COUNT; i++) { + if (ENGINE_REGISTRY[i].enabled && + engine_id_casecmp(ENGINE_REGISTRY[i].id, engine_id)) { + return 1; + } + } + return 0; +} + +int get_user_engines(char ***out_ids, int *out_count) { + *out_ids = NULL; + *out_count = 0; + + char *cookie = get_cookie("engines"); + if (!cookie || cookie[0] == '\0') { + free(cookie); + return -1; + } + + char **ids = NULL; + int count = 0; + + char *copy = strdup(cookie); + if (!copy) { + free(cookie); + return -1; + } + + char *saveptr; + char *token = strtok_r(copy, ",", &saveptr); + while (token) { + while (*token == ' ' || *token == '\t') + token++; + + if (token[0] != '\0' && is_engine_id_enabled(token)) { + char **new_ids = realloc(ids, sizeof(char *) * (count + 1)); + if (new_ids) { + ids = new_ids; + ids[count] = strdup(token); + count++; + } + } + + token = strtok_r(NULL, ",", &saveptr); + } + + free(copy); + free(cookie); + + if (count == 0) { + free(ids); + return -1; + } + + *out_ids = ids; + *out_count = count; + return 0; +} + +int user_engines_contains(const char *engine_id, char **ids, int count) { + if (!engine_id || !ids) return 0; + for (int i = 0; i < count; i++) { + if (engine_id_casecmp(ids[i], engine_id)) + return 1; + } + return 0; +} + int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count) { diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h index 3863bc2..822c972 100644 --- a/src/Utility/Utility.h +++ b/src/Utility/Utility.h @@ -9,6 +9,10 @@ int hex_to_int(char c); char *get_theme(const char *default_theme); char *get_locale(const char *default_locale); +int is_engine_id_enabled(const char *engine_id); +int get_user_engines(char ***out_ids, int *out_count); +int user_engines_contains(const char *engine_id, char **ids, int count); + int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count); |
