commit 88886732e821f8f851b7147115a3d765a44fd0b4
parent e8ad02c7d6838c9dc5f29b8c9f3c92f426649a6c
Author: JayVii <jayvii[AT]posteo[DOT]de>
Date:   Wed, 10 Jul 2024 21:34:12 +0200
feat: use mappings for faster processing
Diffstat:
6 files changed, 116 insertions(+), 23 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+config/*.json
diff --git a/README.md b/README.md
@@ -64,7 +64,15 @@ Simply upload the entire content of this repository to your webhost. Edit
 sed -e 's/%%URL%%/http:\/\/search.example.com/g' -i opensearch.xml
 ```
 
-Search-Engines and `!keywords` are configured in `config/config.php`.
+Search-Engines and `!keywords` are configured in `config/config.php`. For fast
+access to `!keywords` and categories, seriĉi uses mappings written to `json`
+files. Before first run, you need to generate them from your config via
+`lib/generate_mappings.php`. This needs to be re-run everytime you adjust your
+`config/config.php`.
+
+```bash
+php lib/generate_mappings.php
+```
 
 Speed-Deployment:
 ```bash
@@ -73,7 +81,8 @@ mkdir -p /var/www/serci && \
   cd /var/www/serci && \
   wget https://src.jayvii.de/pub/serci/exports/main.tar.gz -O - | \
   tar xfvz - && \
-  sed -e "s/%%URL%%/https:\/\/${DOMAIN}/g" -i opensearch.xml
+  sed -e "s/%%URL%%/https:\/\/${DOMAIN}/g" -i opensearch.xml && \
+  php lib/generate_mappings.php
 ```
 
 Example-configuration for Apache2:
diff --git a/config/config.php b/config/config.php
@@ -342,4 +342,8 @@ $categories = array(
 */
 $default_search = "metager_web";
 
+/* Pre-generated mapping files */
+$searchkeys_file = "./config/keys_to_search.json";
+$searchcats_file = "./config/cats_to_search.json";
+
 ?>
diff --git a/index.php b/index.php
@@ -6,8 +6,11 @@
 
     /* Load Configuration */
     include("config/config.php");
+    include("lib/read_mappings.php");
 
-    /* Fetch and sanitize search query via GET request */
+    /* Fetch and sanitize search query via GET request
+    *  Allow both "query" and "q"
+    */
     $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
     if (!is_null($_GET["query"])) {
         $query = rawurldecode($_GET["query"]);
@@ -28,13 +31,10 @@
         $keyword = strtolower($keyword);
 
         /* Based on given keyword, choose a search engine */
-        $search = $default_search;
-        foreach (array_keys($searches) as $key) {
-            if (array_search($keyword, $searches[$key]["keywords"]) !== false) {
-                /* If keyword has been found, assign search engine & end loop */
-                $search = $key;
-                break;
-            }
+        if (array_search($keyword, array_keys($searchkeys)) !== false) {
+            $search = $searchkeys[$keyword];
+        } else {
+            $search = $default_search;
         }
 
         /* Strip keyword from search term */
@@ -189,11 +189,11 @@
 
         <!-- Search Engine Categorical Lists -->
         <?php
-            foreach (array_keys($categories) as $cat) {
+            foreach ($searchcats as $category => $searchids) {
         ?>
 
         <details>
-            <summary><?php echo $categories[$cat]["name"]; ?></summary>
+            <summary><?php echo $categories[$category]["name"]; ?></summary>
             <table>
                 <tr>
                     <th>Engine</th>
@@ -201,21 +201,14 @@
                 <tr>
                 <?php
                     /* Print one table row for each search engine in category */
-                    foreach (array_keys($searches) as $key) {
-                        /* Skrip, if search engine is not in current category */
-                        if (
-                            array_search($cat, $searches[$key]["categories"])
-                            === false
-                        ) {
-                            continue;
-                        }
+                    foreach ($searchids as $searchid) {
                 ?>
                 <tr>
                     <td>
-                        <a href="<?php echo $searches[$key]["website"]; ?>"
+                        <a href="<?php echo $searches[$searchid]["website"]; ?>"
                             target="_blank">
                             <?php
-                                echo $searches[$key]["name"];
+                                echo $searches[$searchid]["name"];
                             ?>
                         </a>
                     </td>
@@ -225,7 +218,7 @@
                                 echo "!" .
                                     implode(
                                         "</code>, <code>!",
-                                        $searches[$key]["keywords"]
+                                        $searches[$searchid]["keywords"]
                                     );
                             ?>
                         </code>
diff --git a/lib/generate_mappings.php b/lib/generate_mappings.php
@@ -0,0 +1,59 @@
+<?php
+
+include("./config/config.php");
+
+/* Keyword to Search Engine mapping ----------------------------------------- */
+
+$searchkeys = array();
+foreach (array_keys($searches) as $search) {
+    foreach ($searches[$search]["keywords"] as $keyword) {
+        $searchkeys[$keyword] = $search;
+    }
+}
+
+/* Export the mapping to file */
+$file = fopen(
+    $searchkeys_file,
+    "w"
+);
+fwrite(
+    $file,
+    json_encode($searchkeys)
+);
+fclose($file);
+
+/* Category to Search Engine mapping ---------------------------------------- */
+
+$searchcats = array();
+foreach (array_keys($categories) as $category) {
+
+    $currentcat = array();
+    foreach (array_keys($searches) as $search) {
+
+        /* Skrip, if search engine is not in current category */
+        if (
+            array_search($category, $searches[$search]["categories"])
+            === false
+        ) {
+            continue;
+        }
+
+        /* Add to current category */
+        array_push($currentcat, $search);
+    }
+
+    $searchcats[$category] = $currentcat;
+}
+
+/* Export the mapping to file */
+$file = fopen(
+    $searchcats_file,
+    "w"
+);
+fwrite(
+    $file,
+    json_encode($searchcats)
+);
+fclose($file);
+
+?>
diff --git a/lib/read_mappings.php b/lib/read_mappings.php
@@ -0,0 +1,27 @@
+<?php
+
+/* Keyword to Search Engine mapping ----------------------------------------- */
+
+$file = fopen(
+    $searchkeys_file,
+    "r"
+);
+$searchkeys = json_decode(
+    fread($file, filesize($searchkeys_file)),
+    true
+);
+fclose($file);
+
+/* Category to Search Engine mapping ---------------------------------------- */
+
+$file = fopen(
+    $searchcats_file,
+    "r"
+);
+$searchcats = json_decode(
+    fread($file, filesize($searchcats_file)),
+    true
+);
+fclose($file);
+
+?>