feat: configure search engines in user settings
This commit is contained in:
parent
614bd26cb3
commit
8176078105
5 changed files with 233 additions and 4 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue