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;
|
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,
|
static char *build_search_href(const char *query, const char *engine_id,
|
||||||
int page) {
|
int page) {
|
||||||
const char *safe_query = query ? query : "";
|
const char *safe_query = query ? query : "";
|
||||||
|
|
@ -350,6 +357,10 @@ int results_handler(UrlParams *params) {
|
||||||
int page = 1;
|
int page = 1;
|
||||||
int btnI = 0;
|
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) {
|
if (params) {
|
||||||
for (int i = 0; i < params->count; i++) {
|
for (int i = 0; i < params->count; i++) {
|
||||||
if (strcmp(params->params[i].key, "q") == 0) {
|
if (strcmp(params->params[i].key, "q") == 0) {
|
||||||
|
|
@ -396,6 +407,11 @@ int results_handler(UrlParams *params) {
|
||||||
|
|
||||||
if (!raw_query || strlen(raw_query) == 0) {
|
if (!raw_query || strlen(raw_query) == 0) {
|
||||||
send_redirect("/");
|
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);
|
free_context(&ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +428,9 @@ int results_handler(UrlParams *params) {
|
||||||
int enabled_engine_count = 0;
|
int enabled_engine_count = 0;
|
||||||
for (int i = 0; i < ENGINE_COUNT; i++) {
|
for (int i = 0; i < ENGINE_COUNT; i++) {
|
||||||
if (ENGINE_REGISTRY[i].enabled &&
|
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++;
|
enabled_engine_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +457,9 @@ int results_handler(UrlParams *params) {
|
||||||
int engine_idx = 0;
|
int engine_idx = 0;
|
||||||
for (int i = 0; i < ENGINE_COUNT; i++) {
|
for (int i = 0; i < ENGINE_COUNT; i++) {
|
||||||
if (ENGINE_REGISTRY[i].enabled &&
|
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;
|
all_results[engine_idx] = NULL;
|
||||||
jobs[engine_idx].engine = &ENGINE_REGISTRY[i];
|
jobs[engine_idx].engine = &ENGINE_REGISTRY[i];
|
||||||
jobs[engine_idx].query = raw_query;
|
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);
|
snprintf(response, sizeof(response), "<h1>%s</h1>", rate_limit_msg);
|
||||||
send_response(response);
|
send_response(response);
|
||||||
free(request_cache_key);
|
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);
|
free_context(&ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +524,9 @@ int results_handler(UrlParams *params) {
|
||||||
|
|
||||||
int filter_engine_count = 0;
|
int filter_engine_count = 0;
|
||||||
for (int i = 0; i < ENGINE_COUNT; i++) {
|
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++;
|
filter_engine_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -516,7 +543,9 @@ int results_handler(UrlParams *params) {
|
||||||
free(all_href);
|
free(all_href);
|
||||||
|
|
||||||
for (int i = 0; i < ENGINE_COUNT; i++) {
|
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;
|
continue;
|
||||||
|
|
||||||
char *filter_href =
|
char *filter_href =
|
||||||
|
|
@ -575,6 +604,11 @@ int results_handler(UrlParams *params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(request_cache_key);
|
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);
|
free_context(&ctx);
|
||||||
if (redirect_url) {
|
if (redirect_url) {
|
||||||
send_redirect(redirect_url);
|
send_redirect(redirect_url);
|
||||||
|
|
@ -594,6 +628,11 @@ int results_handler(UrlParams *params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(request_cache_key);
|
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);
|
free_context(&ctx);
|
||||||
char no_results_html[128];
|
char no_results_html[128];
|
||||||
snprintf(no_results_html, sizeof(no_results_html), "<h1>%s</h1>", no_results_msg);
|
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);
|
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);
|
free_context(&ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -822,6 +866,11 @@ int results_handler(UrlParams *params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(locale);
|
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);
|
free_context(&ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "../Scraping/Scraping.h"
|
||||||
#include "../Utility/Utility.h"
|
#include "../Utility/Utility.h"
|
||||||
#include <beaker.h>
|
#include <beaker.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -29,6 +30,48 @@ int settings_handler(UrlParams *params) {
|
||||||
inner_counts[i] = 2;
|
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();
|
TemplateContext ctx = new_context();
|
||||||
beaker_set_locale(&ctx, locale);
|
beaker_set_locale(&ctx, locale);
|
||||||
context_set(&ctx, "query", query);
|
context_set(&ctx, "query", query);
|
||||||
|
|
@ -36,9 +79,26 @@ int settings_handler(UrlParams *params) {
|
||||||
context_set(&ctx, "locale", locale);
|
context_set(&ctx, "locale", locale);
|
||||||
context_set_array_of_arrays(&ctx, "locales", locale_data, locale_count, inner_counts);
|
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++) {
|
for (int i = 0; i < locale_count; i++) {
|
||||||
free(locale_data[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);
|
char *rendered_html = render_template("settings.html", &ctx);
|
||||||
send_response(rendered_html);
|
send_response(rendered_html);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
#include "SettingsSave.h"
|
#include "SettingsSave.h"
|
||||||
|
#include "../Scraping/Scraping.h"
|
||||||
|
#include "../Utility/Utility.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MAX_ENGINE_IDS ENGINE_COUNT
|
||||||
|
|
||||||
int settings_save_handler(UrlParams *params) {
|
int settings_save_handler(UrlParams *params) {
|
||||||
const char *theme = "";
|
const char *theme = "";
|
||||||
const char *locale = "";
|
const char *locale = "";
|
||||||
const char *query = "";
|
const char *query = "";
|
||||||
|
int engines_present = 0;
|
||||||
|
char selected_ids[ENGINE_COUNT][32];
|
||||||
|
int selected_count = 0;
|
||||||
|
|
||||||
if (params) {
|
if (params) {
|
||||||
for (int i = 0; i < params->count; i++) {
|
for (int i = 0; i < params->count; i++) {
|
||||||
|
|
@ -15,6 +22,19 @@ int settings_save_handler(UrlParams *params) {
|
||||||
locale = params->params[i].value;
|
locale = params->params[i].value;
|
||||||
} else if (strcmp(params->params[i].key, "q") == 0) {
|
} else if (strcmp(params->params[i].key, "q") == 0) {
|
||||||
query = params->params[i].value;
|
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);
|
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];
|
char redirect_url[512];
|
||||||
snprintf(redirect_url, sizeof(redirect_url), "/settings?q=%s", query);
|
snprintf(redirect_url, sizeof(redirect_url), "/settings?q=%s", query);
|
||||||
send_redirect(redirect_url);
|
send_redirect(redirect_url);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
#include "../Scraping/Scraping.h"
|
||||||
#include <beaker.h>
|
#include <beaker.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -34,6 +35,89 @@ char *get_locale(const char *default_locale) {
|
||||||
return strdup(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,
|
int add_link_to_collection(const char *href, const char *label,
|
||||||
const char *class_name, char ****collection,
|
const char *class_name, char ****collection,
|
||||||
int **inner_counts, int current_count) {
|
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_theme(const char *default_theme);
|
||||||
char *get_locale(const char *default_locale);
|
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,
|
int add_link_to_collection(const char *href, const char *label,
|
||||||
const char *class_name, char ****collection,
|
const char *class_name, char ****collection,
|
||||||
int **inner_counts, int current_count);
|
int **inner_counts, int current_count);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue