aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Routes/Images.c56
-rw-r--r--src/Routes/Search.c123
-rw-r--r--src/Utility/Utility.c99
-rw-r--r--src/Utility/Utility.h10
4 files changed, 176 insertions, 112 deletions
diff --git a/src/Routes/Images.c b/src/Routes/Images.c
index d5a1951..9d45be7 100644
--- a/src/Routes/Images.c
+++ b/src/Routes/Images.c
@@ -15,6 +15,30 @@ static char *build_images_request_cache_key(const char *query, int page,
return cache_compute_key(query, page, scope_key);
}
+static char *build_images_href(const char *query, int page) {
+ const char *safe_query = query ? query : "";
+ size_t needed = strlen("/images?q=") + strlen(safe_query) + 1;
+ if (page > 1)
+ needed += strlen("&p=") + 16;
+
+ char *href = (char *)malloc(needed);
+ if (!href)
+ return NULL;
+
+ snprintf(href, needed, "/images?q=%s", safe_query);
+ if (page > 1) {
+ char page_buf[16];
+ snprintf(page_buf, sizeof(page_buf), "%d", page);
+ strcat(href, "&p=");
+ strcat(href, page_buf);
+ }
+ return href;
+}
+
+static char *images_href_builder(int page, void *data) {
+ return build_images_href((const char *)data, page);
+}
+
int images_handler(UrlParams *params) {
extern Config global_config;
TemplateContext ctx = new_context();
@@ -33,14 +57,6 @@ int images_handler(UrlParams *params) {
}
}
- char page_str[16], prev_str[16], next_str[16], two_prev_str[16],
- two_next_str[16];
-
- snprintf(page_str, sizeof(page_str), "%d", page);
- snprintf(prev_str, sizeof(prev_str), "%d", page > 1 ? page - 1 : 0);
- snprintf(next_str, sizeof(next_str), "%d", page + 1);
- snprintf(two_prev_str, sizeof(two_prev_str), "%d", page > 2 ? page - 2 : 0);
- snprintf(two_next_str, sizeof(two_next_str), "%d", page + 2);
context_set(&ctx, "query", raw_query);
char *theme = get_theme("");
@@ -55,11 +71,15 @@ int images_handler(UrlParams *params) {
const char *error_images_msg = beaker_get_locale_value(locale, "error_images");
if (!error_images_msg) error_images_msg = "Error fetching images";
- context_set(&ctx, "page", page_str);
- context_set(&ctx, "prev_page", prev_str);
- context_set(&ctx, "next_page", next_str);
- context_set(&ctx, "two_prev_page", two_prev_str);
- context_set(&ctx, "two_next_page", two_next_str);
+ char ***pager_matrix = NULL;
+ int *pager_inner_counts = NULL;
+ int pager_count = build_pagination(page, locale, images_href_builder,
+ (void *)raw_query, &pager_matrix,
+ &pager_inner_counts);
+ if (pager_count > 0) {
+ context_set_array_of_arrays(&ctx, "pagination_links", pager_matrix,
+ pager_count, pager_inner_counts);
+ }
char *display_query = url_decode_query(raw_query);
context_set(&ctx, "query", display_query);
@@ -170,6 +190,16 @@ int images_handler(UrlParams *params) {
free(image_matrix);
free(inner_counts);
+ if (pager_count > 0) {
+ for (int i = 0; i < pager_count; i++) {
+ for (int j = 0; j < LINK_FIELD_COUNT; j++)
+ free(pager_matrix[i][j]);
+ free(pager_matrix[i]);
+ }
+ free(pager_matrix);
+ free(pager_inner_counts);
+ }
+
free_image_results(results, result_count);
free(request_cache_key);
free(display_query);
diff --git a/src/Routes/Search.c b/src/Routes/Search.c
index 9219620..e201e10 100644
--- a/src/Routes/Search.c
+++ b/src/Routes/Search.c
@@ -32,8 +32,6 @@ typedef struct {
enum {
RESULT_FIELD_COUNT = 6,
- LINK_FIELD_COUNT = 3,
- PAGER_WINDOW_SIZE = 5,
};
static InfoBox fetch_wiki_wrapper(char *query) {
@@ -189,66 +187,6 @@ static int add_infobox_to_collection(InfoBox *infobox, char ****collection,
return current_count + 1;
}
-static int add_link_to_collection(const char *href, const char *label,
- const char *class_name, char ****collection,
- int **inner_counts, int current_count) {
- char ***old_collection = *collection;
- int *old_inner_counts = *inner_counts;
- char ***new_collection =
- (char ***)malloc(sizeof(char **) * (current_count + 1));
- int *new_inner_counts =
- (int *)malloc(sizeof(int) * (current_count + 1));
-
- if (!new_collection || !new_inner_counts) {
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- if (*collection && current_count > 0) {
- memcpy(new_collection, *collection, sizeof(char **) * current_count);
- }
- if (*inner_counts && current_count > 0) {
- memcpy(new_inner_counts, *inner_counts, sizeof(int) * current_count);
- }
-
- *collection = new_collection;
- *inner_counts = new_inner_counts;
-
- (*collection)[current_count] =
- (char **)malloc(sizeof(char *) * LINK_FIELD_COUNT);
- if (!(*collection)[current_count]) {
- *collection = old_collection;
- *inner_counts = old_inner_counts;
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- (*collection)[current_count][0] = strdup(href ? href : "");
- (*collection)[current_count][1] = strdup(label ? label : "");
- (*collection)[current_count][2] = strdup(class_name ? class_name : "");
-
- if (!(*collection)[current_count][0] || !(*collection)[current_count][1] ||
- !(*collection)[current_count][2]) {
- free((*collection)[current_count][0]);
- free((*collection)[current_count][1]);
- free((*collection)[current_count][2]);
- free((*collection)[current_count]);
- *collection = old_collection;
- *inner_counts = old_inner_counts;
- free(new_collection);
- free(new_inner_counts);
- return current_count;
- }
-
- (*inner_counts)[current_count] = LINK_FIELD_COUNT;
-
- free(old_collection);
- free(old_inner_counts);
- return current_count + 1;
-}
-
static int add_warning_to_collection(const char *engine_name,
const char *warning_message,
char ****collection, int **inner_counts,
@@ -385,6 +323,16 @@ static char *build_search_href(const char *query, const char *engine_id,
return href;
}
+typedef struct {
+ const char *query;
+ const char *engine_id;
+} SearchHrefData;
+
+static char *search_href_builder(int page, void *data) {
+ SearchHrefData *d = (SearchHrefData *)data;
+ return build_search_href(d->query, d->engine_id, page);
+}
+
static char *build_search_request_cache_key(const char *query,
const char *engine_id, int page,
const char *client_key) {
@@ -436,6 +384,16 @@ int results_handler(UrlParams *params) {
snprintf(page_str, sizeof(page_str), "%d", page);
context_set(&ctx, "page", page_str);
+ char prev_str[16], next_str[16], two_prev_str[16], two_next_str[16];
+ snprintf(prev_str, sizeof(prev_str), "%d", page > 1 ? page - 1 : 0);
+ snprintf(next_str, sizeof(next_str), "%d", page + 1);
+ snprintf(two_prev_str, sizeof(two_prev_str), "%d", page > 2 ? page - 2 : 0);
+ snprintf(two_next_str, sizeof(two_next_str), "%d", page + 2);
+ context_set(&ctx, "prev_page", prev_str);
+ context_set(&ctx, "next_page", next_str);
+ context_set(&ctx, "two_prev_page", two_prev_str);
+ context_set(&ctx, "two_next_page", two_next_str);
+
if (!raw_query || strlen(raw_query) == 0) {
send_redirect("/");
free_context(&ctx);
@@ -810,43 +768,10 @@ int results_handler(UrlParams *params) {
char ***pager_matrix = NULL;
int *pager_inner_counts = NULL;
- int pager_count = 0;
- int pager_start = page <= 3 ? 1 : page - 2;
- int pager_end = pager_start + PAGER_WINDOW_SIZE - 1;
-
- if (page > 3) {
- char *first_href = build_search_href(raw_query, selected_engine_id, 1);
- pager_count = add_link_to_collection(first_href, "First", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(first_href);
- }
-
- if (page > 1) {
- char *prev_href =
- build_search_href(raw_query, selected_engine_id, page - 1);
- pager_count = add_link_to_collection(prev_href, "Prev", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(prev_href);
- }
-
- for (int i = pager_start; i <= pager_end; i++) {
- char label[16];
- snprintf(label, sizeof(label), "%d", i);
- char *page_href = build_search_href(raw_query, selected_engine_id, i);
- pager_count = add_link_to_collection(
- page_href, label,
- i == page ? "pagination-btn pagination-current" : "pagination-btn",
- &pager_matrix, &pager_inner_counts, pager_count);
- free(page_href);
- }
-
- char *next_href = build_search_href(raw_query, selected_engine_id, page + 1);
- pager_count = add_link_to_collection(next_href, "Next", "pagination-btn",
- &pager_matrix, &pager_inner_counts,
- pager_count);
- free(next_href);
+ SearchHrefData href_data = { .query = raw_query, .engine_id = selected_engine_id };
+ int pager_count = build_pagination(page, locale, search_href_builder,
+ &href_data, &pager_matrix,
+ &pager_inner_counts);
if (pager_count > 0) {
context_set_array_of_arrays(&ctx, "pagination_links", pager_matrix,
diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c
index 0d7a28e..bffda4d 100644
--- a/src/Utility/Utility.c
+++ b/src/Utility/Utility.c
@@ -1,5 +1,6 @@
#include "Utility.h"
#include <beaker.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,3 +33,101 @@ char *get_locale(const char *default_locale) {
free(cookie);
return strdup(default_locale);
}
+
+int add_link_to_collection(const char *href, const char *label,
+ const char *class_name, char ****collection,
+ int **inner_counts, int current_count) {
+ char ***old_collection = *collection;
+ int *old_inner_counts = *inner_counts;
+ char ***new_collection =
+ (char ***)malloc(sizeof(char **) * (current_count + 1));
+ int *new_inner_counts =
+ (int *)malloc(sizeof(int) * (current_count + 1));
+
+ if (!new_collection || !new_inner_counts) {
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ if (*collection && current_count > 0) {
+ memcpy(new_collection, *collection, sizeof(char **) * current_count);
+ }
+ if (*inner_counts && current_count > 0) {
+ memcpy(new_inner_counts, *inner_counts, sizeof(int) * current_count);
+ }
+
+ *collection = new_collection;
+ *inner_counts = new_inner_counts;
+
+ (*collection)[current_count] =
+ (char **)malloc(sizeof(char *) * LINK_FIELD_COUNT);
+ if (!(*collection)[current_count]) {
+ *collection = old_collection;
+ *inner_counts = old_inner_counts;
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ (*collection)[current_count][0] = strdup(href ? href : "");
+ (*collection)[current_count][1] = strdup(label ? label : "");
+ (*collection)[current_count][2] = strdup(class_name ? class_name : "");
+
+ if (!(*collection)[current_count][0] || !(*collection)[current_count][1] ||
+ !(*collection)[current_count][2]) {
+ free((*collection)[current_count][0]);
+ free((*collection)[current_count][1]);
+ free((*collection)[current_count][2]);
+ free((*collection)[current_count]);
+ *collection = old_collection;
+ *inner_counts = old_inner_counts;
+ free(new_collection);
+ free(new_inner_counts);
+ return current_count;
+ }
+
+ (*inner_counts)[current_count] = LINK_FIELD_COUNT;
+
+ free(old_collection);
+ free(old_inner_counts);
+ return current_count + 1;
+}
+
+int build_pagination(int page, const char *locale,
+ char *(*href_builder)(int page, void *data), void *data,
+ char ****out_matrix, int **out_inner_counts) {
+ enum { PAGER_WINDOW_SIZE = 5 };
+
+ *out_matrix = NULL;
+ *out_inner_counts = NULL;
+ int count = 0;
+
+ int pager_start = page <= 3 ? 1 : page - 2;
+ int pager_end = pager_start + PAGER_WINDOW_SIZE - 1;
+
+ if (page > 1) {
+ char *href = href_builder(page - 1, data);
+ count = add_link_to_collection(href, "<", "pagination-btn prev",
+ out_matrix, out_inner_counts, count);
+ free(href);
+ }
+
+ for (int i = pager_start; i <= pager_end; i++) {
+ char label[16];
+ snprintf(label, sizeof(label), "%d", i);
+ char *href = href_builder(i, data);
+ count = add_link_to_collection(
+ href, label,
+ i == page ? "pagination-btn pagination-current" : "pagination-btn",
+ out_matrix, out_inner_counts, count);
+ free(href);
+ }
+
+ char *href = href_builder(page + 1, data);
+ count = add_link_to_collection(href, ">", "pagination-btn next",
+ out_matrix, out_inner_counts, count);
+ free(href);
+
+ return count;
+}
diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h
index 387aae0..3863bc2 100644
--- a/src/Utility/Utility.h
+++ b/src/Utility/Utility.h
@@ -3,8 +3,18 @@
#include <beaker.h>
+#define LINK_FIELD_COUNT 3
+
int hex_to_int(char c);
char *get_theme(const char *default_theme);
char *get_locale(const char *default_locale);
+int add_link_to_collection(const char *href, const char *label,
+ const char *class_name, char ****collection,
+ int **inner_counts, int current_count);
+
+int build_pagination(int page, const char *locale,
+ char *(*href_builder)(int page, void *data), void *data,
+ char ****out_matrix, int **out_inner_counts);
+
#endif