diff --git a/api.php b/api.php
@@ -1,9 +1,10 @@
<?php
- $config = require "config.php";
require "misc/tools.php";
+ require "misc/search_engine.php";
- if (!isset($_REQUEST["q"]))
- {
+ $opts = load_opts();
+
+ if (!$opts->query) {
echo "<p>Example API request: <a href=\"./api.php?q=gentoo&p=2&t=0\">./api.php?q=gentoo&p=2&t=0</a></p>
<br/>
<p>\"q\" is the keyword</p>
@@ -16,54 +17,7 @@
die();
}
- $query = $_REQUEST["q"];
- $query_encoded = urlencode($query);
- $page = isset($_REQUEST["p"]) ? (int) $_REQUEST["p"] : 0;
- $type = isset($_REQUEST["t"]) ? (int) $_REQUEST["t"] : 0;
-
- $results = array();
-
- switch ($type)
- {
- case 0:
- $engine=$config->preferred_engines['text'];
- if (is_null($engine))
- $engine = "google";
- require "engines/$engine/text.php";
- $results = get_text_results($query, $page);
- break;
- case 1:
- require "engines/qwant/image.php";
- $results = get_image_results($query_encoded, $page);
- break;
- case 2:
- require "engines/invidious/video.php";
- $results = get_video_results($query_encoded);
- break;
- case 3:
- if ($config->disable_bittorent_search)
- $results = array("error" => "disabled");
- else
- {
- require "engines/bittorrent/merge.php";
- $results = get_merged_torrent_results($query_encoded);
- }
- break;
- case 4:
- if ($config->disable_hidden_service_search)
- $results = array("error" => "disabled");
- else
- {
- require "engines/ahmia/hidden_service.php";
- $results = get_hidden_service_results($query_encoded);
- }
- break;
- default:
- require "engines/google/text.php";
- $results = get_text_results($query_encoded, $page);
- break;
- }
-
+ $results = fetch_search_results($opts, false);
header("Content-Type: application/json");
echo json_encode($results);
?>
diff --git a/config.php.example b/config.php.example
@@ -4,13 +4,9 @@
// e.g.: fr -> https://google.fr/
"google_domain" => "com",
- // Google results will be in this language
- "google_language_site" => "",
- "google_language_results" => "",
- "google_number_of_results" => 10,
-
- // You can set a language for results in wikipedia
- "wikipedia_language" => "en",
+ // Results will be in this language
+ "language" => "",
+ "number_of_results" => 10,
// You can use any Invidious instance here
"invidious_instance_for_video_results" => "https://invidious.snopyta.org",
@@ -21,7 +17,8 @@
"disable_hidden_service_search" => false,
// Fallback to another librex instance if google search fails
- "instance_fallback" => false, // This might generate a 504 Gateway Timeout error, we are looking into this.
+ // This may greatly increase the time it takes to get a result and in some cases results in 504 errors
+ "instance_fallback" => false,
/*
Preset privacy friendly frontends for users, these can be overwritten by users in the settings
@@ -31,74 +28,74 @@
"frontends" => array(
"invidious" => array(
"instance_url" => "",
- "project_url" => "https://docs.invidious.io/instances/",
+ "project_url" => "https://docs.invidious.io/instances/",
"original_name" => "YouTube",
"original_url" => "youtube.com"
),
"rimgo" => array(
"instance_url" => "",
- "project_url" => "https://codeberg.org/video-prize-ranch/rimgo#instances",
+ "project_url" => "https://codeberg.org/video-prize-ranch/rimgo#instances",
"original_name" => "Imgur",
"original_url" => "imgur.com"
),
"scribe" => array(
"instance_url" => "",
- "project_url" => "https://git.sr.ht/~edwardloveall/scribe/tree/main/docs/instances.md",
+ "project_url" => "https://git.sr.ht/~edwardloveall/scribe/tree/main/docs/instances.md",
"original_name" => "Medium",
"original_url" => "medium.com"
),
"gothub" => array(
"instance_url" => "",
- "project_url" => "https://codeberg.org/gothub/gothub#instances",
+ "project_url" => "https://codeberg.org/gothub/gothub#instances",
"original_name" => "GitHub",
"original_url" => "github.com"
),
"nitter" => array(
"instance_url" => "",
- "project_url" => "https://github.com/zedeus/nitter/wiki/Instances",
+ "project_url" => "https://github.com/zedeus/nitter/wiki/Instances",
"original_name" => "Twitter",
"original_url" => "twitter.com"
),
"libreddit" => array(
"instance_url" => "",
- "project_url" => "https://github.com/libreddit/libreddit-instances/blob/master/instances.md",
+ "project_url" => "https://github.com/libreddit/libreddit-instances/blob/master/instances.md",
"original_name" => "Reddit",
"original_url" => "reddit.com"
),
"proxitok" => array(
"instance_url" => "",
- "project_url" => "https://github.com/pablouser1/ProxiTok/wiki/Public-instances",
+ "project_url" => "https://github.com/pablouser1/ProxiTok/wiki/Public-instances",
"original_name" => "TikTok",
"original_url" => "tiktok.com"
),
"wikiless" => array(
"instance_url" => "",
- "project_url" => "https://github.com/Metastem/wikiless#instances",
+ "project_url" => "https://github.com/Metastem/wikiless#instances",
"original_name" => "Wikipedia",
"original_url" => "wikipedia.org"
),
"quetre" => array(
"instance_url" => "",
- "project_url" => "https://github.com/zyachel/quetre#instances",
+ "project_url" => "https://github.com/zyachel/quetre#instances",
"original_name" => "Quora",
"original_url" => "quora.com"
),
"libremdb" => array(
"instance_url" => "",
- "project_url" => "https://github.com/zyachel/libremdb#instances",
+ "project_url" => "https://github.com/zyachel/libremdb#instances",
"original_name" => "IMDb",
"original_url" => "imdb.com"
),
"breezewiki" => array(
"instance_url" => "",
- "project_url" => "https://docs.breezewiki.com/Links.html",
+ "project_url" => "https://docs.breezewiki.com/Links.html",
"original_name" => "Fandom",
"original_url" => "fandom.com"
),
"anonymousoverflow" => array(
"instance_url" => "",
- "project_url" => "https://github.com/httpjamesm/AnonymousOverflow#clearnet-instances",
+ "project_url" => "https://github.com/httpjamesm/AnonymousOverflow#clearnet-instances",
"original_name" => "StackOverflow",
"original_url" => "stackoverflow.com"
),
@@ -115,10 +112,10 @@
"original_url" => "goodreads.com"
)
),
-
+
"preferred_engines" => array(
-
+
/* replace with "text" => "duckduckgo" to use duckduckgo instead
* (recommended if being ratelimited */
"text" => "google"
@@ -150,7 +147,7 @@
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP,
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP,
CURLOPT_MAXREDIRS => 5,
- CURLOPT_TIMEOUT => 18,
+ CURLOPT_TIMEOUT => 3,
CURLOPT_VERBOSE => false
)
);
diff --git a/engines/ahmia/hidden_service.php b/engines/ahmia/hidden_service.php
@@ -1,53 +1,40 @@
<?php
- function get_hidden_service_results($query)
- {
- global $config;
+ require "engines/text/text.php";
- $url = "https://ahmia.fi/search/?q=$query";
- $response = request($url);
- $xpath = get_xpath($response);
-
- $results = array();
-
- foreach($xpath->query("//ol[@class='searchResults']//li[@class='result']") as $result)
- {
- $url = "http://" . $xpath->evaluate(".//cite", $result)[0]->textContent;
- $title = remove_special($xpath->evaluate(".//h4", $result)[0]->textContent);
- $description = $xpath->evaluate(".//p", $result)[0]->textContent;
-
- array_push($results,
- array (
- "title" => $title ? htmlspecialchars($title) : "No description provided",
- "url" => htmlspecialchars($url),
- "base_url" => htmlspecialchars(get_base_url($url)),
- "description" => htmlspecialchars($description)
- )
- );
+ class TorSearch extends EngineRequest {
+ public function get_request_url() {
+ return "https://ahmia.fi/search/?q=" . urlencode($this->query);
}
- return $results;
- }
-
- function print_hidden_service_results($results)
- {
- echo "<div class=\"text-result-container\">";
-
- foreach($results as $result)
- {
- $title = $result["title"];
- $url = $result["url"];
- $base_url = $result["base_url"];
- $description = $result["description"];
-
- echo "<div class=\"text-result-wrapper\">";
- echo "<a href=\"$url\">";
- echo "$base_url";
- echo "<h2>$title</h2>";
- echo "</a>";
- echo "<span>$description</span>";
- echo "</div>";
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ $results = array();
+ $xpath = get_xpath($response);
+
+ if (!$xpath)
+ return $results;
+
+ foreach($xpath->query("//ol[@class='searchResults']//li[@class='result']") as $result)
+ {
+ $url = "http://" . $xpath->evaluate(".//cite", $result)[0]->textContent;
+ $title = remove_special($xpath->evaluate(".//h4", $result)[0]->textContent);
+ $description = $xpath->evaluate(".//p", $result)[0]->textContent;
+
+ array_push($results,
+ array (
+ "title" => $title ? htmlspecialchars($title) : "No description provided",
+ "url" => htmlspecialchars($url),
+ "base_url" => htmlspecialchars(get_base_url($url)),
+ "description" => htmlspecialchars($description)
+ )
+ );
+ }
+
+ return $results;
}
- echo "</div>";
+ public static function print_results($results) {
+ TextSearch::print_results($results);
+ }
}
?>
diff --git a/engines/bittorrent/1337x.php b/engines/bittorrent/1337x.php
@@ -1,34 +1,40 @@
<?php
- $_1337x_url = "https://1337x.to/search/$query/1/";
+ class _1337xRequest extends EngineRequest {
+ public function get_request_url() {
+ $query = urlencode($this->query);
+ return "https://1337x.to/search/$query/1/";
+ }
- function get_1337x_results($response)
- {
- global $config;
- $xpath = get_xpath($response);
- $results = array();
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
- foreach($xpath->query("//table/tbody/tr") as $result)
- {
+ $xpath = get_xpath($response);
+ $results = array();
- $name = $xpath->evaluate(".//td[@class='coll-1 name']/a", $result)[1]->textContent;
- $magnet = "./engines/bittorrent/get_magnet_1337x.php?url=https://1337x.to" . $xpath->evaluate(".//td[@class='coll-1 name']/a/@href", $result)[1]->textContent;
- $size_unformatted = explode(" ", $xpath->evaluate(".//td[contains(@class, 'coll-4 size')]", $result)[0]->textContent);
- $size = $size_unformatted[0] . " " . preg_replace("/[0-9]+/", "", $size_unformatted[1]);
- $seeders = $xpath->evaluate(".//td[@class='coll-2 seeds']", $result)[0]->textContent;
- $leechers = $xpath->evaluate(".//td[@class='coll-3 leeches']", $result)[0]->textContent;
+ if (!$xpath)
+ return $results;
- array_push($results,
- array (
- "name" => htmlspecialchars($name),
- "seeders" => (int) $seeders,
- "leechers" => (int) $leechers,
- "magnet" => htmlspecialchars($magnet),
- "size" => htmlspecialchars($size),
- "source" => "1337x.to"
- )
- );
- }
+ foreach($xpath->query("//table/tbody/tr") as $result) {
+ $name = $xpath->evaluate(".//td[@class='coll-1 name']/a", $result)[1]->textContent;
+ $magnet = "./engines/bittorrent/get_magnet_1337x.php?url=https://1337x.to" . $xpath->evaluate(".//td[@class='coll-1 name']/a/@href", $result)[1]->textContent;
+ $size_unformatted = explode(" ", $xpath->evaluate(".//td[contains(@class, 'coll-4 size')]", $result)[0]->textContent);
+ $size = $size_unformatted[0] . " " . preg_replace("/[0-9]+/", "", $size_unformatted[1]);
+ $seeders = $xpath->evaluate(".//td[@class='coll-2 seeds']", $result)[0]->textContent;
+ $leechers = $xpath->evaluate(".//td[@class='coll-3 leeches']", $result)[0]->textContent;
- return $results;
+ array_push($results,
+ array (
+ "name" => htmlspecialchars($name),
+ "seeders" => (int) $seeders,
+ "leechers" => (int) $leechers,
+ "magnet" => htmlspecialchars($magnet),
+ "size" => htmlspecialchars($size),
+ "source" => "1337x.to"
+ )
+ );
+ }
+
+ return $results;
+ }
}
?>
diff --git a/engines/bittorrent/merge.php b/engines/bittorrent/merge.php
@@ -1,89 +1,48 @@
<?php
+ class TorrentSearch extends EngineRequest {
+ public function __construct($opts, $mh) {
+ parent::__construct($opts, $mh);
- function get_merged_torrent_results($query)
- {
- global $config;
+ require "engines/bittorrent/thepiratebay.php";
+ require "engines/bittorrent/rutor.php";
+ require "engines/bittorrent/yts.php";
+ require "engines/bittorrent/torrentgalaxy.php";
+ require "engines/bittorrent/1337x.php";
+ require "engines/bittorrent/sukebei.php";
- require "engines/bittorrent/thepiratebay.php";
- require "engines/bittorrent/rutor.php";
- require "engines/bittorrent/nyaa.php";
- require "engines/bittorrent/yts.php";
- require "engines/bittorrent/torrentgalaxy.php";
- require "engines/bittorrent/1337x.php";
- require "engines/bittorrent/sukebei.php";
-
- $query = urlencode($query);
-
- $torrent_urls = array(
- $thepiratebay_url,
- $rutor_url,
- $nyaa_url,
- $yts_url,
- $torrentgalaxy_url,
- $_1337x_url,
- $sukebei_url
- );
-
- $mh = curl_multi_init();
- $chs = $results = array();
-
- foreach ($torrent_urls as $url)
- {
- $ch = curl_init($url);
- curl_setopt_array($ch, $config->curl_settings);
- array_push($chs, $ch);
- curl_multi_add_handle($mh, $ch);
+ $this->requests = array(
+ new PirateBayRequest($opts, $mh),
+ new _1337xRequest($opts, $mh),
+ new NyaaRequest($opts, $mh),
+ new RutorRequest($opts, $mh),
+ new SukebeiRequest($opts, $mh),
+ new TorrentGalaxyRequest($opts, $mh),
+ new YTSRequest($opts, $mh),
+ );
}
- $running = null;
- do {
- curl_multi_exec($mh, $running);
- } while ($running);
+ public function get_results() {
+ $results = array();
+ foreach ($this->requests as $request) {
+ if ($request->successful())
+ $results = array_merge($results, $request->get_results());
+ }
- for ($i=0; count($chs)>$i; $i++)
- {
- $response = curl_multi_getcontent($chs[$i]);
+ $seeders = array_column($results, "seeders");
+ array_multisort($seeders, SORT_DESC, $results);
- switch ($i)
- {
- case 0:
- $results = array_merge($results, get_thepiratebay_results($response));
- break;
- case 1:
- $results = array_merge($results, get_rutor_results($response));
- break;
- case 2:
- $results = array_merge($results, get_nyaa_results($response));
- break;
- case 3:
- $results = array_merge($results, get_yts_results($response));
- break;
- case 4:
- $results = array_merge($results, get_torrentgalaxy_results($response));
- break;
- case 5:
- $results = array_merge($results, get_1337x_results($response));
- break;
- case 6:
- $results = array_merge($results, get_sukebei_results($response));
- break;
- }
+ return $results;
}
-
- $seeders = array_column($results, "seeders");
- array_multisort($seeders, SORT_DESC, $results);
- return $results;
- }
+ public static function print_results($results) {
+ echo "<div class=\"text-result-container\">";
- function print_merged_torrent_results($results)
- {
- echo "<div class=\"text-result-container\">";
+ if (empty($results)) {
+ echo "<p>There are no results. Please try different keywords!</p>";
+ return;
+ }
- if (!empty($results))
- {
- foreach($results as $result)
- {
+ foreach($results as $result) {
$source = $result["source"];
$name = $result["name"];
$magnet = $result["magnet"];
@@ -101,11 +60,9 @@
echo "$size</span>";
echo "</div>";
}
- }
- else
- echo "<p>There are no results. Please try different keywords!</p>";
- echo "</div>";
+ echo "</div>";
+ }
}
?>
diff --git a/engines/bittorrent/nyaa.php b/engines/bittorrent/nyaa.php
@@ -1,35 +1,53 @@
<?php
- $nyaa_url = "https://nyaa.si/?q=$query";
+ class NyaaRequest extends EngineRequest {
+ public $SOURCE = "nyaa.si";
- function get_nyaa_results($response)
- {
- global $config;
- $xpath = get_xpath($response);
- $results = array();
+ public function get_request_url() {
+ return "https://$this->SOURCE/?q=" . urlencode($this->query);
+ }
- foreach($xpath->query("//tbody/tr") as $result)
- {
- $name = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result)[0]->textContent;
- $centered = $xpath->evaluate(".//td[@class='text-center']", $result);
- $magnet = $xpath->evaluate(".//a[2]/@href", $centered[0])[0]->textContent;
- $magnet_without_tracker = explode("&tr=", $magnet)[0];
- $magnet = $magnet_without_tracker . $config->bittorent_trackers;
- $size = $centered[1]->textContent;
- $seeders = $centered[3]->textContent;
- $leechers = $centered[4]->textContent;
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ $xpath = get_xpath($response);
+ $results = array();
- array_push($results,
- array (
- "name" => htmlspecialchars($name),
- "seeders" => (int) $seeders,
- "leechers" => (int) $leechers,
- "magnet" => htmlspecialchars($magnet),
- "size" => htmlspecialchars($size),
- "source" => "nyaa.si"
- )
- );
- }
+ if (!$xpath)
+ return $results;
+
+ foreach($xpath->query("//tbody/tr") as $result)
+ {
+ $name_node = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result);
+ if ($name_node->length > 0) {
+ $name = $name_node[0]->textContent;
+ } else {
+ $name = "";
+ }
+ $centered = $xpath->evaluate(".//td[@class='text-center']", $result);
+ $magnet_node = $xpath->evaluate(".//a[2]/@href", $centered[0]);
+ if ($magnet_node->length > 0) {
+ $magnet = $magnet_node[0]->textContent;
+ $magnet_without_tracker = explode("&tr=", $magnet)[0];
+ $magnet = $magnet_without_tracker . $this->opts->bittorent_trackers;
+ } else {
+ $magnet = "";
+ }
+ $size = $centered[1]->textContent;
+ $seeders = $centered[3]->textContent;
+ $leechers = $centered[4]->textContent;
- return $results;
+ array_push($results,
+ array (
+ "name" => htmlspecialchars($name),
+ "seeders" => (int) $seeders,
+ "leechers" => (int) $leechers,
+ "magnet" => htmlspecialchars($magnet),
+ "size" => htmlspecialchars($size),
+ "source" => $this->SOURCE
+ )
+ );
+ }
+
+ return $results;
+ }
}
?>
diff --git a/engines/bittorrent/rutor.php b/engines/bittorrent/rutor.php
@@ -1,36 +1,41 @@
<?php
- $rutor_url = "http://rutor.info/search/$query";
+ class RutorRequest extends EngineRequest {
+ public function get_request_url() {
+ return "http://rutor.info/search/" . urlencode($this->query);
+ }
- function get_rutor_results($response)
- {
- global $config;
- $xpath = get_xpath($response);
- $results = array();
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ $xpath = get_xpath($response);
+ $results = array();
+ if (!$xpath)
+ return $results;
- foreach($xpath->query("//table/tr[@class='gai' or @class='tum']") as $result)
- {
- $name = $xpath->evaluate(".//td/a", $result)[2]->textContent;
- $magnet = $xpath->evaluate(".//td/a/@href", $result)[1]->textContent;
- $magnet_without_tracker = explode("&tr=", $magnet)[0];
- $magnet = $magnet_without_tracker . $config->bittorent_trackers;
- $td = $xpath->evaluate(".//td", $result);
- $size = $td[count($td) == 5 ? 3 : 2]->textContent;
- $seeders = $xpath->evaluate(".//span", $result)[0]->textContent;
- $leechers = $xpath->evaluate(".//span", $result)[1]->textContent;
+ foreach($xpath->query("//table/tr[@class='gai' or @class='tum']") as $result)
+ {
+ $name = $xpath->evaluate(".//td/a", $result)[2]->textContent;
+ $magnet = $xpath->evaluate(".//td/a/@href", $result)[1]->textContent;
+ $magnet_without_tracker = explode("&tr=", $magnet)[0];
+ $magnet = $magnet_without_tracker . $this->opts->bittorrent_trackers;
+ $td = $xpath->evaluate(".//td", $result);
+ $size = $td[count($td) == 5 ? 3 : 2]->textContent;
+ $seeders = $xpath->evaluate(".//span", $result)[0]->textContent;
+ $leechers = $xpath->evaluate(".//span", $result)[1]->textContent;
- array_push($results,
- array (
- "name" => htmlspecialchars($name),
- "seeders" => (int) filter_var($seeders, FILTER_SANITIZE_NUMBER_INT),
- "leechers" => (int) filter_var($leechers, FILTER_SANITIZE_NUMBER_INT),
- "magnet" => htmlspecialchars($magnet),
- "size" => htmlspecialchars($size),
- "source" => "rutor.info"
- )
- );
- }
+ array_push($results,
+ array (
+ "name" => htmlspecialchars($name),
+ "seeders" => (int) filter_var($seeders, FILTER_SANITIZE_NUMBER_INT),
+ "leechers" => (int) filter_var($leechers, FILTER_SANITIZE_NUMBER_INT),
+ "magnet" => htmlspecialchars($magnet),
+ "size" => htmlspecialchars($size),
+ "source" => "rutor.info"
+ )
+ );
+ }
- return $results;
+ return $results;
+ }
}
?>
diff --git a/engines/bittorrent/sukebei.php b/engines/bittorrent/sukebei.php
@@ -1,44 +1,6 @@
<?php
- $sukebei_url = "https://sukebei.nyaa.si/?q=$query";
-
- function get_sukebei_results($response)
- {
- global $config;
- $xpath = get_xpath($response);
- $results = array();
-
- foreach($xpath->query("//tbody/tr") as $result)
- {
- $name_node = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result);
- if ($name_node->length > 0) {
- $name = $name_node[0]->textContent;
- } else {
- $name = "";
- }
- $centered = $xpath->evaluate(".//td[@class='text-center']", $result);
- $magnet_node = $xpath->evaluate(".//a[2]/@href", $centered[0]);
- if ($magnet_node->length > 0) {
- $magnet = $magnet_node[0]->textContent;
- $magnet_without_tracker = explode("&tr=", $magnet)[0];
- $magnet = $magnet_without_tracker . $config->bittorent_trackers;
- } else {
- $magnet = "";
- }
- $size = $centered[1]->textContent;
- $seeders = $centered[3]->textContent;
- $leechers = $centered[4]->textContent;
-
- array_push($results,
- array (
- "name" => htmlspecialchars($name),
- "seeders" => (int) $seeders,
- "leechers" => (int) $leechers,
- "magnet" => htmlspecialchars($magnet),
- "size" => htmlspecialchars($size),
- "source" => "sukebei.nyaa.si"
- )
- );
- }
- return $results;
+ include "engines/bittorrent/nyaa.php";
+ class SukebeiRequest extends NyaaRequest {
+ public $SOURCE = "sukebei.nyaa.si";
}
?>
diff --git a/engines/bittorrent/thepiratebay.php b/engines/bittorrent/thepiratebay.php
@@ -1,44 +1,46 @@
<?php
-
- $thepiratebay_url = "https://apibay.org/q.php?q=$query";
-
- function get_thepiratebay_results($response)
- {
- global $config;
- $results = array();
- $json_response = json_decode($response, true);
-
- if (empty($json_response))
- {
- return $results;
+ class PirateBayRequest extends EngineRequest {
+ public function get_request_url() {
+ return "https://apibay.org/q.php?q=" . urlencode($this->query);
}
- foreach ($json_response as $response)
- {
- $size = human_filesize($response["size"]);
- $hash = $response["info_hash"];
- $name = $response["name"];
- $seeders = (int) $response["seeders"];
- $leechers = (int) $response["leechers"];
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ $results = array();
+ $json_response = json_decode($response, true);
+
+ if (empty($json_response))
+ {
+ return $results;
+ }
+
+ foreach ($json_response as $response)
+ {
+ $size = human_filesize($response["size"]);
+ $hash = $response["info_hash"];
+ $name = $response["name"];
+ $seeders = (int) $response["seeders"];
+ $leechers = (int) $response["leechers"];
+
+ $magnet = "magnet:?xt=urn:btih:$hash&dn=$name" . $this->opts->bittorrent_trackers;
+
+ if ($name == "No results returned")
+ break;
+
+ array_push($results,
+ array (
+ "size" => htmlspecialchars($size),
+ "name" => htmlspecialchars($name),
+ "seeders" => (int) htmlspecialchars($seeders),
+ "leechers" => (int) htmlspecialchars($leechers),
+ "magnet" => htmlspecialchars($magnet),
+ "source" => "thepiratebay.org"
+ )
+ );
+ }
- $magnet = "magnet:?xt=urn:btih:$hash&dn=$name" . $config->bittorent_trackers;
-
- if ($name == "No results returned")
- break;
-
- array_push($results,
- array (
- "size" => htmlspecialchars($size),
- "name" => htmlspecialchars($name),
- "seeders" => (int) htmlspecialchars($seeders),
- "leechers" => (int) htmlspecialchars($leechers),
- "magnet" => htmlspecialchars($magnet),
- "source" => "thepiratebay.org"
- )
- );
+ return $results;
+
}
-
- return $results;
-
}
?>
diff --git a/engines/bittorrent/torrentgalaxy.php b/engines/bittorrent/torrentgalaxy.php
@@ -1,34 +1,41 @@
<?php
- $torrentgalaxy_url = "https://torrentgalaxy.to/torrents.php?search=$query#results";
+ class TorrentGalaxyRequest extends EngineRequest {
+ public function get_request_url() {
+ $query = urlencode($this->query);
+ return "https://torrentgalaxy.to/torrents.php?search=$query#results";
+ }
- function get_torrentgalaxy_results($response)
- {
- global $config;
- $xpath = get_xpath($response);
- $results = array();
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ $xpath = get_xpath($response);
+ $results = array();
- foreach($xpath->query("//div[@class='tgxtablerow txlight']") as $result)
- {
- $name = $xpath->evaluate(".//div[contains(@class, 'clickable-row')]", $result)[0]->textContent;
- $magnet = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/a/@href", $result)[1]->textContent;
- $magnet_without_tracker = explode("&tr=", $magnet)[0];
- $magnet = $magnet_without_tracker . $config->bittorent_trackers;
- $size = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span", $result)[0]->textContent;
- $seeders = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span/font", $result)[1]->textContent;
- $leechers = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span/font", $result)[2]->textContent;
+ if (!$xpath)
+ return $results;
- array_push($results,
- array (
- "name" => htmlspecialchars($name),
- "seeders" => (int) $seeders,
- "leechers" => (int) $leechers,
- "magnet" => htmlspecialchars($magnet),
- "size" => htmlspecialchars($size),
- "source" => "torrentgalaxy.to"
- )
- );
- }
+ foreach($xpath->query("//div[@class='tgxtablerow txlight']") as $result)
+ {
+ $name = $xpath->evaluate(".//div[contains(@class, 'clickable-row')]", $result)[0]->textContent;
+ $magnet = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/a/@href", $result)[1]->textContent;
+ $magnet_without_tracker = explode("&tr=", $magnet)[0];
+ $magnet = $magnet_without_tracker . $this->opts->bittorrent_trackers;
+ $size = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span", $result)[0]->textContent;
+ $seeders = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span/font", $result)[1]->textContent;
+ $leechers = $xpath->evaluate(".//div[@class='tgxtablecell collapsehide rounded txlight']/span/font", $result)[2]->textContent;
- return $results;
+ array_push($results,
+ array (
+ "name" => htmlspecialchars($name),
+ "seeders" => (int) $seeders,
+ "leechers" => (int) $leechers,
+ "magnet" => htmlspecialchars($magnet),
+ "size" => htmlspecialchars($size),
+ "source" => "torrentgalaxy.to"
+ )
+ );
+ }
+
+ return $results;
+ }
}
?>
diff --git a/engines/bittorrent/yts.php b/engines/bittorrent/yts.php
@@ -1,14 +1,18 @@
<?php
- $yts_url = "https://yts.mx/api/v2/list_movies.json?query_term=$query";
+ class YTSRequest extends EngineRequest {
+ public function get_request_url() {
+ return "https://yts.mx/api/v2/list_movies.json?query_term=" . urlencode($this->query);
+ }
+
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+ global $config;
+ $results = array();
+ $json_response = json_decode($response, true);
- function get_yts_results($response)
- {
- global $config;
- $results = array();
- $json_response = json_decode($response, true);
+ if ($json_response["status"] != "ok" || $json_response["data"]["movie_count"] == 0)
+ return $results;
- if ($json_response["status"] == "ok" && $json_response["data"]["movie_count"] != 0)
- {
foreach ($json_response["data"]["movies"] as $movie)
{
$name = $movie["title"];
@@ -22,24 +26,22 @@
$leechers = $torrent["peers"];
$size = $torrent["size"];
- $magnet = "magnet:?xt=urn:btih:$hash&dn=$name_encoded$config->bittorent_trackers";
-
- array_push($results,
- array (
- "size" => htmlspecialchars($size),
- "name" => htmlspecialchars($name),
- "seeders" => htmlspecialchars($seeders),
- "leechers" => htmlspecialchars($leechers),
- "magnet" => htmlspecialchars($magnet),
- "source" => "yts.mx"
- )
- );
-
+ $magnet = "magnet:?xt=urn:btih:$hash&dn=$name_encoded$this->opts->bittorrent_trackers";
+
+ array_push($results,
+ array (
+ "size" => htmlspecialchars($size),
+ "name" => htmlspecialchars($name),
+ "seeders" => htmlspecialchars($seeders),
+ "leechers" => htmlspecialchars($leechers),
+ "magnet" => htmlspecialchars($magnet),
+ "source" => "yts.mx"
+ )
+ );
}
}
- }
- return $results;
-
+ return $results;
+ }
}
?>
diff --git a/engines/duckduckgo/text.php b/engines/duckduckgo/text.php
@@ -1,204 +0,0 @@
-<?php
- function get_text_results($query, $page)
- {
- global $config;
-
- $mh = curl_multi_init();
- $query_encoded = urlencode($query);
- $results = array();
-
- // $domain = $config->google_domain;
- $domain = 'com';
- $site_language = isset($_COOKIE["google_language_site"]) ? trim(htmlspecialchars($_COOKIE["google_language_site"])) : $config->google_language_site;
- $results_language = isset($_COOKIE["google_language_results"]) ? trim(htmlspecialchars($_COOKIE["google_language_results"])) : $config->google_language_results;
- $number_of_results = isset($_COOKIE["google_number_of_results"]) ? trim(htmlspecialchars($_COOKIE["google_number_of_results"])) : $config->google_number_of_results;
-
- $url = "https://html.duckduckgo.$domain/html/?q=$query_encoded&kd=-1&s=" . 3 * $page;
- if (3 > strlen($site_language) && 0 < strlen($site_language))
- $url .= "&hl=$site_language";
-
- if (3 > strlen($results_language) && 0 < strlen($results_language))
- $url .= "&lr=lang_$results_language";
-
- if (3 > strlen($number_of_results) && 0 < strlen($number_of_results))
- $url .= "&num=$number_of_results";
-
- if (isset($_COOKIE["safe_search"]))
- $url .= "&safe=medium";
-
- $google_ch = curl_init($url);
- curl_setopt_array($google_ch, $config->curl_settings);
- curl_multi_add_handle($mh, $google_ch);
-
- $special_search = $page ? 0 : check_for_special_search($query);
- $special_ch = null;
- $url = null;
- if ($special_search != 0)
- {
- switch ($special_search)
- {
- case 1:
- $url = "https://cdn.moneyconvert.net/api/latest.json";
- break;
- case 2:
- $split_query = explode(" ", $query);
- $reversed_split_q = array_reverse($split_query);
- $word_to_define = $reversed_split_q[1];
- $url = "https://api.dictionaryapi.dev/api/v2/entries/en/$word_to_define";
- break;
- case 5:
- $url = "https://wttr.in/@" . $_SERVER["REMOTE_ADDR"] . "?format=j1";
- break;
- case 6:
- $url = "https://check.torproject.org/torbulkexitlist";
- break;
- case 7:
- $wikipedia_language = isset($_COOKIE["wikipedia_language"]) ? trim(htmlspecialchars($_COOKIE["wikipedia_language"])) : $config->wikipedia_language;
- if (in_array($wikipedia_language, json_decode(file_get_contents("static/misc/wikipedia_langs.json"), true)))
- $url = "https://$wikipedia_language.wikipedia.org/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=$query_encoded";
- break;
- }
-
- if ($url != NULL)
- {
- $special_ch = curl_init($url);
- curl_setopt_array($special_ch, $config->curl_settings);
- curl_multi_add_handle($mh, $special_ch);
- }
- }
-
- $running = null;
- do {
- curl_multi_exec($mh, $running);
- } while ($running);
-
- if (curl_getinfo($google_ch)['http_code'] != '200')
- {
- require "engines/librex/text.php";
- return get_librex_results($query, $page);
- }
-
-
-
- if ($special_search != 0)
- {
- $special_result = null;
-
- switch ($special_search)
- {
- case 1:
- require "engines/special/currency.php";
- $special_result = currency_results($query, curl_multi_getcontent($special_ch));
- break;
- case 2:
- require "engines/special/definition.php";
- $special_result = definition_results($query, curl_multi_getcontent($special_ch));
- break;
-
- case 3:
- require "engines/special/ip.php";
- $special_result = ip_result();
- break;
- case 4:
- require "engines/special/user_agent.php";
- $special_result = user_agent_result();
- break;
- case 5:
- require "engines/special/weather.php";
- $special_result = weather_results(curl_multi_getcontent($special_ch));
- break;
- case 6:
- require "engines/special/tor.php";
- $special_result = tor_result(curl_multi_getcontent($special_ch));
- break;
- case 7:
- require "engines/special/wikipedia.php";
- $special_result = wikipedia_results($query, curl_multi_getcontent($special_ch));
- break;
- }
-
- if ($special_result != null)
- array_push($results, $special_result);
- }
-
- $xpath = get_xpath(curl_multi_getcontent($google_ch));
-
- foreach($xpath->query("/html/body/div[1]/div[". count($xpath->query('/html/body/div[1]/div')) ."]/div/div/div/div") as $result)
- {
- $url = $xpath->evaluate(".//h2[@class='result__title']//a/@href", $result)[0];
-
- if ($url == null)
- continue;
-
- if (!empty($results)) // filter duplicate results, ignore special result
- {
- if (!array_key_exists("special_response", end($results)))
- if (end($results)["url"] == $url->textContent)
- continue;
- }
-
- $url = $url->textContent;
-
- $url = check_for_privacy_frontend($url);
-
- $title = $xpath->evaluate(".//h2[@class='result__title']", $result)[0];
- $description = $xpath->evaluate(".//a[@class='result__snippet']", $result)[0];
-
- array_push($results,
- array (
- "title" => htmlspecialchars($title->textContent),
- "url" => htmlspecialchars($url),
- "base_url" => htmlspecialchars(get_base_url($url)),
- "description" => $description == null ?
- "No description was provided for this site." :
- htmlspecialchars($description->textContent)
- )
- );
- }
-
- return $results;
- }
-
- function print_text_results($results)
- {
- $special = $results[0];
- if (array_key_exists("special_response", $special))
- {
- $response = $special["special_response"]["response"];
- $source = $special["special_response"]["source"];
-
- echo "<p class=\"special-result-container\">";
- if (array_key_exists("image", $special["special_response"]))
- {
- $image_url = $special["special_response"]["image"];
- echo "<img src=\"image_proxy.php?url=$image_url\">";
- }
- echo $response;
- if ($source)
- echo "<a href=\"$source\" target=\"_blank\">$source</a>";
- echo "</p>";
-
- array_shift($results);
- }
-
- echo "<div class=\"text-result-container\">";
-
- foreach($results as $result)
- {
- $title = $result["title"];
- $url = $result["url"];
- $base_url = $result["base_url"];
- $description = $result["description"];
-
- echo "<div class=\"text-result-wrapper\">";
- echo "<a href=\"$url\">";
- echo "$base_url";
- echo "<h2>$title</h2>";
- echo "</a>";
- echo "<span>$description</span>";
- echo "</div>";
- }
-
- echo "</div>";
- }
-?>
diff --git a/engines/google/text.php b/engines/google/text.php
@@ -1,226 +0,0 @@
-<?php
- function get_text_results($query, $page)
- {
- global $config;
-
- $mh = curl_multi_init();
- $query_encoded = str_replace("%22", "\"", urlencode($query));
- $results = array();
-
- $domain = $config->google_domain;
- $site_language = isset($_COOKIE["google_language_site"]) ? trim(htmlspecialchars($_COOKIE["google_language_site"])) : $config->google_language_site;
- $results_language = isset($_COOKIE["google_language_results"]) ? trim(htmlspecialchars($_COOKIE["google_language_results"])) : $config->google_language_results;
- $number_of_results = isset($_COOKIE["google_number_of_results"]) ? trim(htmlspecialchars($_COOKIE["google_number_of_results"])) : $config->google_number_of_results;
-
- $url = "https://www.google.$domain/search?q=$query_encoded&nfpr=1&start=$page";
- error_log($url);
-
- if (3 > strlen($site_language) && 0 < strlen($site_language))
- $url .= "&hl=$site_language";
-
- if (3 > strlen($results_language) && 0 < strlen($results_language))
- $url .= "&lr=lang_$results_language";
-
- if (3 > strlen($number_of_results) && 0 < strlen($number_of_results))
- $url .= "&num=$number_of_results";
-
- if (isset($_COOKIE["safe_search"]))
- $url .= "&safe=medium";
-
- $google_ch = curl_init($url);
- curl_setopt_array($google_ch, $config->curl_settings);
- curl_multi_add_handle($mh, $google_ch);
-
- $special_search = $page ? 0 : check_for_special_search($query);
- $special_ch = null;
- $url = null;
- if ($special_search != 0)
- {
- switch ($special_search)
- {
- case 1:
- $url = "https://cdn.moneyconvert.net/api/latest.json";
- break;
- case 2:
- $split_query = explode(" ", $query);
- $reversed_split_q = array_reverse($split_query);
- $word_to_define = $reversed_split_q[1];
- $url = "https://api.dictionaryapi.dev/api/v2/entries/en/$word_to_define";
- break;
- case 5:
- $url = "https://wttr.in/@" . $_SERVER["REMOTE_ADDR"] . "?format=j1";
- break;
- case 6:
- $url = "https://check.torproject.org/torbulkexitlist";
- break;
- case 7:
- $wikipedia_language = isset($_COOKIE["wikipedia_language"]) ? trim(htmlspecialchars($_COOKIE["wikipedia_language"])) : $config->wikipedia_language;
- if (in_array($wikipedia_language, json_decode(file_get_contents("static/misc/wikipedia_langs.json"), true)))
- $url = "https://$wikipedia_language.wikipedia.org/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=$query_encoded";
- break;
- }
-
- if ($url != NULL)
- {
- $special_ch = curl_init($url);
- curl_setopt_array($special_ch, $config->curl_settings);
- curl_multi_add_handle($mh, $special_ch);
- }
- }
-
- $running = null;
- do {
- curl_multi_exec($mh, $running);
- } while ($running);
-
- if (curl_getinfo($google_ch)['http_code'] != '200')
- {
- require "engines/librex/text.php";
- return get_librex_results($query, $page);
- }
-
-
- $special_result = array();
- if ($special_search != 0)
- {
-
- switch ($special_search)
- {
- case 1:
- require "engines/special/currency.php";
- $special_result = currency_results($query, curl_multi_getcontent($special_ch));
- break;
- case 2:
- require "engines/special/definition.php";
- $special_result = definition_results($query, curl_multi_getcontent($special_ch));
- break;
-
- case 3:
- require "engines/special/ip.php";
- $special_result = ip_result();
- break;
- case 4:
- require "engines/special/user_agent.php";
- $special_result = user_agent_result();
- break;
- case 5:
- require "engines/special/weather.php";
- $special_result = weather_results(curl_multi_getcontent($special_ch));
- break;
- case 6:
- require "engines/special/tor.php";
- $special_result = tor_result(curl_multi_getcontent($special_ch));
- break;
- case 7:
- require "engines/special/wikipedia.php";
- $special_result = wikipedia_results($query, curl_multi_getcontent($special_ch));
- break;
- }
- }
-
- $xpath = get_xpath(curl_multi_getcontent($google_ch));
-
- $didyoumean = $xpath->query(".//a[@class='gL9Hy']")[0];
-
- if (!is_null($didyoumean))
- $special_result["did_you_mean"] = $didyoumean->textContent;
-
- if (!empty($special_result))
- array_push($results, $special_result);
-
-
-
- foreach($xpath->query("//div[@id='search']//div[contains(@class, 'g')]") as $result)
- {
- $url = $xpath->evaluate(".//div[@class='yuRUbf']//a/@href", $result)[0];
-
- if ($url == null)
- continue;
-
- if (!empty($results)) // filter duplicate results, ignore special result
- {
- if (!array_key_exists("special_response", end($results)))
- if (end($results)["url"] == $url->textContent)
- continue;
- }
-
- $url = $url->textContent;
-
- $url = check_for_privacy_frontend($url);
-
- $title = $xpath->evaluate(".//h3", $result)[0];
- $description = $xpath->evaluate(".//div[contains(@class, 'VwiC3b')]", $result)[0];
-
- array_push($results,
- array (
- "title" => htmlspecialchars($title->textContent),
- "url" => htmlspecialchars($url),
- "base_url" => htmlspecialchars(get_base_url($url)),
- "description" => $description == null ?
- "No description was provided for this site." :
- htmlspecialchars($description->textContent)
- )
- );
- }
-
- return $results;
- }
-
- function print_text_results($results)
- {
-
- if (empty($results))
- return;
-
- $special = $results[0];
-
- if (array_key_exists("did_you_mean", $special))
- {
- $didyoumean = $special["did_you_mean"];
- $new_url = "/search.php?q=" . urlencode($didyoumean);
- echo "<p class=\"did-you-mean\">Did you mean ";
- echo "<a href=\"$new_url\">$didyoumean</a>";
- echo "?</p>";
- }
-
- if (array_key_exists("special_response", $special))
- {
- $response = $special["special_response"]["response"];
- $source = $special["special_response"]["source"];
-
- echo "<p class=\"special-result-container\">";
- if (array_key_exists("image", $special["special_response"]))
- {
- $image_url = $special["special_response"]["image"];
- echo "<img src=\"image_proxy.php?url=$image_url\">";
- }
- echo $response;
- if ($source)
- echo "<a href=\"$source\" target=\"_blank\">$source</a>";
- echo "</p>";
- }
-
- echo "<div class=\"text-result-container\">";
-
- foreach($results as $result)
- {
- if (!array_key_exists("title", $result))
- continue;
-
- $title = $result["title"];
- $url = $result["url"];
- $base_url = $result["base_url"];
- $description = $result["description"];
-
- echo "<div class=\"text-result-wrapper\">";
- echo "<a href=\"$url\">";
- echo "$base_url";
- echo "<h2>$title</h2>";
- echo "</a>";
- echo "<span>$description</span>";
- echo "</div>";
- }
-
- echo "</div>";
- }
-?>
diff --git a/engines/invidious/video.php b/engines/invidious/video.php
@@ -1,68 +1,67 @@
<?php
- function get_video_results($query)
- {
- global $config;
- $instance_url = $config->invidious_instance_for_video_results;
-
- $url = "$instance_url/api/v1/search?q=$query";
- $response = request($url);
- $json_response = json_decode($response, true);
- $results = array();
+ class VideoSearch extends EngineRequest {
+ public function get_request_url() {
+ $this->instance_url = $this->opts->invidious_instance_for_video_results;
+ $query = urlencode($this->query);
+ return "$this->instance_url/api/v1/search?q=$query";
+ }
+
+ public function get_results() {
+ $results = array();
+ $response = curl_multi_getcontent($this->ch);
+ $json_response = json_decode($response, true);
- foreach ($json_response as $response)
- {
- if ($response["type"] == "video")
- {
- $title = $response["title"];
- $url = "https://youtube.com/watch?v=" . $response["videoId"];
- $url = check_for_privacy_frontend($url);
- $uploader = $response["author"];
- $views = $response["viewCount"];
- $date = $response["publishedText"];
- $thumbnail = $instance_url . "/vi/" . explode("/vi/" ,$response["videoThumbnails"][4]["url"])[1];
+ foreach ($json_response as $response) {
+ if ($response["type"] == "video") {
+ $title = $response["title"];
+ $url = "https://youtube.com/watch?v=" . $response["videoId"];
+ $url = check_for_privacy_frontend($url, $this->opts);
+ $uploader = $response["author"];
+ $views = $response["viewCount"];
+ $date = $response["publishedText"];
+ $thumbnail = $this->instance_url . "/vi/" . explode("/vi/" ,$response["videoThumbnails"][4]["url"])[1];
- array_push($results,
- array (
- "title" => htmlspecialchars($title),
- "url" => htmlspecialchars($url),
- "base_url" => htmlspecialchars(get_base_url($url)),
- "uploader" => htmlspecialchars($uploader),
- "views" => htmlspecialchars($views),
- "date" => htmlspecialchars($date),
- "thumbnail" => htmlspecialchars($thumbnail)
- )
- );
+ array_push($results,
+ array (
+ "title" => htmlspecialchars($title),
+ "url" => htmlspecialchars($url),
+ "base_url" => htmlspecialchars(get_base_url($url)),
+ "uploader" => htmlspecialchars($uploader),
+ "views" => htmlspecialchars($views),
+ "date" => htmlspecialchars($date),
+ "thumbnail" => htmlspecialchars($thumbnail)
+ )
+ );
+ }
}
- }
- return $results;
- }
+ return $results;
+ }
- function print_video_results($results)
- {
- echo "<div class=\"text-result-container\">";
+ public static function print_results($results) {
+ echo "<div class=\"text-result-container\">";
- foreach($results as $result)
- {
- $title = $result["title"];
- $url = $result["url"];
- $base_url = $result["base_url"];
- $uploader = $result["uploader"];
- $views = $result["views"];
- $date = $result["date"];
- $thumbnail = $result["thumbnail"];
+ foreach($results as $result) {
+ $title = $result["title"];
+ $url = $result["url"];
+ $base_url = $result["base_url"];
+ $uploader = $result["uploader"];
+ $views = $result["views"];
+ $date = $result["date"];
+ $thumbnail = $result["thumbnail"];
- echo "<div class=\"text-result-wrapper\">";
- echo "<a href=\"$url\">";
- echo "$base_url";
- echo "<h2>$title</h2>";
- echo "<img class=\"video-img\" src=\"image_proxy.php?url=$thumbnail\">";
- echo "<br>";
- echo "<span>$uploader - $date - $views views</span>";
- echo "</a>";
- echo "</div>";
- }
+ echo "<div class=\"text-result-wrapper\">";
+ echo "<a href=\"$url\">";
+ echo "$base_url";
+ echo "<h2>$title</h2>";
+ echo "<img class=\"video-img\" src=\"image_proxy.php?url=$thumbnail\">";
+ echo "<br>";
+ echo "<span>$uploader - $date - $views views</span>";
+ echo "</a>";
+ echo "</div>";
+ }
- echo "</div>";
+ echo "</div>";
+ }
}
?>
diff --git a/engines/librex/fallback.php b/engines/librex/fallback.php
@@ -0,0 +1,63 @@
+<?php
+
+ class LibreXFallback extends EngineRequest {
+ public function __construct($instance, $opts, $mh) {
+ $this->instance = $instance;
+ parent::__construct($opts, $mh);
+ }
+
+ public function get_request_url() {
+ return $this->instance . "api.php?" . opts_to_params($this->opts);
+ }
+
+ public function get_results() {
+ $response = curl_exec($this->ch);
+ $response = json_decode($response, true);
+ if (!$response)
+ return array();
+
+ return array_values($response);
+ }
+ }
+
+
+ function get_librex_results($opts) {
+ if (!$opts->do_fallback)
+ return array();
+
+ $instances_json = json_decode(file_get_contents("instances.json"), true);
+
+ if (empty($instances_json["instances"]))
+ return array();
+
+ // TODO pick instances which aren't on cooldown
+
+ $instances = array_map(fn($n) => $n['clearnet'], array_filter($instances_json['instances'], fn($n) => !is_null($n['clearnet'])));
+ shuffle($instances);
+
+ $results = array();
+ $tries = 0;
+
+ do {
+ $tries++;
+
+ $instance = array_pop($instances);
+
+ if (parse_url($instance)["host"] == parse_url($_SERVER['HTTP_HOST'])["host"])
+ continue;
+
+ $librex_request = new LibreXFallback($instance, $opts, null);
+ $results = $librex_request->get_results();
+
+ if (count($results) > 1)
+ return $results;
+
+ } while ( !empty($instances));
+
+ if (empty($instances))
+ return array();
+
+ return array_values($results);
+ }
+
+?>
diff --git a/engines/librex/text.php b/engines/librex/text.php
@@ -1,53 +0,0 @@
-<?php
-
- function get_librex_results($query, $page)
- {
- global $config;
-
- if (isset($_REQUEST["nfb"]) && $_REQUEST["nfb"] == "1")
- return array();
-
- if (!$config->instance_fallback)
- return array();
-
- $instances_json = json_decode(file_get_contents("instances.json"), true);
-
- if (empty($instances_json["instances"]))
- return array();
-
-
- $instances = array_map(fn($n) => $n['clearnet'], array_filter($instances_json['instances'], fn($n) => !is_null($n['clearnet'])));
- shuffle($instances);
-
- $query_encoded = urlencode($query);
-
- $results = array();
- $tries = 0;
-
- do {
- $tries++;
-
- $instance = array_pop($instances);
-
- if (parse_url($instance)["host"] == parse_url($_SERVER['HTTP_HOST'])["host"])
- continue;
-
- $url = $instance . "api.php?q=$query_encoded&p=$page&t=0&nfb=1";
-
- $librex_ch = curl_init($url);
- curl_setopt_array($librex_ch, $config->curl_settings);
- copy_cookies($librex_ch);
- $response = curl_exec($librex_ch);
- curl_close($librex_ch);
-
- $code = curl_getinfo($librex_ch)["http_code"];
- $results = json_decode($response, true);
-
- } while ( !empty($instances) && ($results == null || count($results) <= 1));
-
- if (empty($instances))
- return array();
-
- return array_values($results);
- }
-?>
diff --git a/engines/qwant/image.php b/engines/qwant/image.php
@@ -1,60 +1,63 @@
<?php
- function get_image_results($query, $page)
- {
- global $config;
+ class QwantImageSearch extends EngineRequest {
+ public function get_request_url() {
+ $page = $this->page / 10 + 1; // qwant has a different page system
+ $query = urlencode($this->query);
+
+ return "https://lite.qwant.com/?q=$query&t=images&p=$page";
+ }
- $page = $page / 10 + 1; // qwant has a different page system
+ public function get_results() {
+ $results = array();
+ $xpath = get_xpath(curl_multi_getcontent($this->ch));
+
+ if (!$xpath)
+ return $results;
+
+ foreach($xpath->query("//a[@rel='noopener']") as $result)
+ {
+ $image = $xpath->evaluate(".//img", $result)[0];
+
+ if ($image)
+ {
+ $encoded_url = $result->getAttribute("href");
+ $encoded_url_split1 = explode("==/", $encoded_url)[1];
+ $encoded_url_split2 = explode("?position", $encoded_url_split1)[0];
+ $real_url = urldecode(base64_decode($encoded_url_split2));
+ $real_url = check_for_privacy_frontend($real_url, $this->opts);
+
+ $alt = $image->getAttribute("alt");
+ $thumbnail = urlencode($image->getAttribute("src"));
+
+ array_push($results,
+ array (
+ "thumbnail" => urldecode(htmlspecialchars($thumbnail)),
+ "alt" => htmlspecialchars($alt),
+ "url" => htmlspecialchars($real_url)
+ )
+ );
- $url = "https://lite.qwant.com/?q=$query&t=images&p=$page";
- $response = request($url);
- $xpath = get_xpath($response);
-
- $results = array();
-
- foreach($xpath->query("//a[@rel='noopener']") as $result)
- {
- $image = $xpath->evaluate(".//img", $result)[0];
+ }
+ }
- if ($image)
- {
- $encoded_url = $result->getAttribute("href");
- $encoded_url_split1 = explode("==/", $encoded_url)[1];
- $encoded_url_split2 = explode("?position", $encoded_url_split1)[0];
- $real_url = urldecode(base64_decode($encoded_url_split2));
- $real_url = check_for_privacy_frontend($real_url);
-
- $alt = $image->getAttribute("alt");
- $thumbnail = urlencode($image->getAttribute("src"));
-
- array_push($results,
- array (
- "thumbnail" => urldecode(htmlspecialchars($thumbnail)),
- "alt" => htmlspecialchars($alt),
- "url" => htmlspecialchars($real_url)
- )
- );
-
- }
+ return $results;
}
+
+ public static function print_results($results) {
+ echo "<div class=\"image-result-container\">";
- return $results;
- }
-
- function print_image_results($results)
- {
- echo "<div class=\"image-result-container\">";
-
- foreach($results as $result)
- {
- $thumbnail = urlencode($result["thumbnail"]);
- $alt = $result["alt"];
- $url = $result["url"];
+ foreach($results as $result)
+ {
+ $thumbnail = urlencode($result["thumbnail"]);
+ $alt = $result["alt"];
+ $url = $result["url"];
- echo "<a title=\"$alt\" href=\"$url\" target=\"_blank\">";
- echo "<img src=\"image_proxy.php?url=$thumbnail\">";
- echo "</a>";
- }
+ echo "<a title=\"$alt\" href=\"$url\" target=\"_blank\">";
+ echo "<img src=\"image_proxy.php?url=$thumbnail\">";
+ echo "</a>";
+ }
- echo "</div>";
+ echo "</div>";
+ }
}
?>
diff --git a/engines/special/currency.php b/engines/special/currency.php
@@ -1,18 +1,24 @@
<?php
- function currency_results($query, $response)
- {
- $split_query = explode(" ", $query);
-
- $base_currency = strtoupper($split_query[1]);
- $currency_to_convert = strtoupper($split_query[3]);
- $amount_to_convert = floatval($split_query[0]);
+ class CurrencyRequest extends EngineRequest {
+ public function get_request_url() {
+ return "https://cdn.moneyconvert.net/api/latest.json";
+ }
- $json_response = json_decode($response, true);
-
- $rates = $json_response["rates"];
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
+
+ $split_query = explode(" ", $this->query);
+
+ $base_currency = strtoupper($split_query[1]);
+ $currency_to_convert = strtoupper($split_query[3]);
+ $amount_to_convert = floatval($split_query[0]);
+
+ $json_response = json_decode($response, true);
+
+ $rates = $json_response["rates"];
- if (array_key_exists($base_currency, $rates) && array_key_exists($currency_to_convert, $rates))
- {
+ if (!array_key_exists($base_currency, $rates) || !array_key_exists($currency_to_convert, $rates))
+ return array();
$base_currency_response = $rates[$base_currency];
$currency_to_convert_response = $rates[$currency_to_convert];
@@ -26,6 +32,6 @@
"source" => $source
)
);
- }
+ }
}
?>
diff --git a/engines/special/definition.php b/engines/special/definition.php
@@ -1,9 +1,15 @@
<?php
- function definition_results($query, $response)
- {
- $split_query = explode(" ", $query);
+ class DefinitionRequest extends EngineRequest {
+
+ public function get_request_url() {
+ $split_query = explode(" ", $this->query);
$reversed_split_q = array_reverse($split_query);
$word_to_define = $reversed_split_q[1];
+ return "https://api.dictionaryapi.dev/api/v2/entries/en/$word_to_define";
+ }
+
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
$json_response = json_decode($response, true);
@@ -20,5 +26,6 @@
);
}
+ }
}
?>
diff --git a/engines/special/ip.php b/engines/special/ip.php
@@ -1,11 +1,12 @@
<?php
- function ip_result()
- {
+ class IPRequest extends EngineRequest {
+ function get_results() {
return array(
"special_response" => array(
"response" => $_SERVER["REMOTE_ADDR"],
"source" => null
)
);
+ }
}
?>
diff --git a/engines/special/special.php b/engines/special/special.php
@@ -0,0 +1,91 @@
+<?php
+
+ function check_for_special_search($query) {
+ if (isset($_COOKIE["disable_special"]))
+ return 0;
+
+ $query_lower = strtolower($query);
+ $split_query = explode(" ", $query);
+
+ if (strpos($query_lower, "to") && count($split_query) >= 4) // currency
+ {
+ $amount_to_convert = floatval($split_query[0]);
+ if ($amount_to_convert != 0)
+ return 1;
+ }
+ else if (strpos($query_lower, "mean") && count($split_query) >= 2) // definition
+ {
+ return 2;
+ }
+ else if (strpos($query_lower, "my") !== false)
+ {
+ if (strpos($query_lower, "ip"))
+ {
+ return 3;
+ }
+ else if (strpos($query_lower, "user agent") || strpos($query_lower, "ua"))
+ {
+ return 4;
+ }
+ }
+ else if (strpos($query_lower, "weather") !== false)
+ {
+ return 5;
+ }
+ else if ($query_lower == "tor")
+ {
+ return 6;
+ }
+ else if (3 > count(explode(" ", $query))) // wikipedia
+ {
+ return 7;
+ }
+
+ return 0;
+ }
+
+ function get_special_search_request($opts, $mh) {
+ if ($opts->page != 0)
+ return null;
+
+ $special_search = check_for_special_search($opts->query);
+ $special_request = null;
+ $url = null;
+
+ if ($special_search == 0)
+ return null;
+
+ switch ($special_search) {
+ case 1:
+ require "engines/special/currency.php";
+ $special_request = new CurrencyRequest($opts, $mh);
+ break;
+ case 2:
+ require "engines/special/definition.php";
+ $special_request = new DefinitionRequest($opts, $mh);
+ break;
+ case 3:
+ require "engines/special/ip.php";
+ $special_request = new IPRequest($opts, $mh);
+ break;
+ case 4:
+ require "engines/special/user_agent.php";
+ $special_request = new UserAgentRequest($opts, $mh);
+ break;
+ case 5:
+ require "engines/special/weather.php";
+ $special_request = new WeatherRequest($opts, $mh);
+ break;
+ case 6:
+ require "engines/special/tor.php";
+ $special_request = new TorRequest($opts, $mh);
+ break;
+ case 7:
+ require "engines/special/wikipedia.php";
+ $special_request = new WikipediaRequest($opts, $mh);
+ break;
+ }
+
+ return $special_request;
+ }
+?>
diff --git a/engines/special/tor.php b/engines/special/tor.php
@@ -1,18 +1,22 @@
<?php
- function tor_result($response)
- {
- $formatted_response = "It seems like you are not using Tor";
- if (strpos($response, $_SERVER["REMOTE_ADDR"]) !== false)
- {
- $formatted_response = "It seems like you are using Tor";
- }
+ class TorRequest extends EngineRequest {
+ public function get_request_url() {
+ return "https://check.torproject.org/torbulkexitlist";
+ }
+
+ public function get_results() {
+ $response = curl_multi_getcontent($ch);
+
+ $formatted_response = strpos($response, $_SERVER["REMOTE_ADDR"]) ? "It seems like you are using Tor" : "It seems like you are not using Tor";
$source = "https://check.torproject.org";
+
return array(
"special_response" => array(
"response" => $formatted_response,
"source" => $source
)
);
+ }
}
?>
diff --git a/engines/special/user_agent.php b/engines/special/user_agent.php
@@ -1,11 +1,12 @@
<?php
- function user_agent_result()
- {
+ class UserAgentRequest extends EngineRequest {
+ function get_results() {
return array(
"special_response" => array(
"response" => $_SERVER["HTTP_USER_AGENT"],
"source" => null
)
);
+ }
}
?>
diff --git a/engines/special/weather.php b/engines/special/weather.php
@@ -1,26 +1,31 @@
<?php
- function weather_results($response)
- {
+ class WeatherRequest extends EngineRequest {
+ public function get_request_url () {
+ return "https://wttr.in/@" . $_SERVER["REMOTE_ADDR"] . "?format=j1";
+ }
+
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
$json_response = json_decode($response, true);
- if ($json_response)
- {
- $current_weather = $json_response["current_condition"][0];
+ if (!$json_response)
+ return array();
- $temp_c = $current_weather["temp_C"];
- $temp_f = $current_weather["temp_F"];
- $description = $current_weather["weatherDesc"][0]["value"];
+ $current_weather = $json_response["current_condition"][0];
- $formatted_response = "$description - $temp_c °C | $temp_f °F";
+ $temp_c = $current_weather["temp_C"];
+ $temp_f = $current_weather["temp_F"];
+ $description = $current_weather["weatherDesc"][0]["value"];
- $source = "https://wttr.in";
- return array(
- "special_response" => array(
- "response" => htmlspecialchars($formatted_response),
- "source" => $source
- )
- );
- }
+ $formatted_response = "$description - $temp_c °C | $temp_f °F";
+ $source = "https://wttr.in";
+ return array(
+ "special_response" => array(
+ "response" => htmlspecialchars($formatted_response),
+ "source" => $source
+ )
+ );
+ }
}
?>
diff --git a/engines/special/wikipedia.php b/engines/special/wikipedia.php
@@ -1,21 +1,28 @@
<?php
- function wikipedia_results($query, $response)
- {
- global $config;
+ class WikipediaRequest extends EngineRequest {
+ public function get_request_url() {
+ $this->wikipedia_language = $this->opts->language;
+ $query_encoded = urlencode($this->query);
- $query_encoded = urlencode($query);
+ if (!in_array($this->wikipedia_language, json_decode(file_get_contents("static/misc/wikipedia_langs.json"), true)))
+ $this->wikipedia_language = "en";
- $json_response = json_decode($response, true);
+ return "https://$this->wikipedia_language.wikipedia.org/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=$query_encoded";
+ }
- $first_page = array_values($json_response["query"]["pages"])[0];
+ public function get_results() {
+ $response = curl_multi_getcontent($this->ch);
- if (!array_key_exists("missing", $first_page))
- {
- $description = substr($first_page["extract"], 0, 250) . "...";
+ $json_response = json_decode($response, true);
+
+ $first_page = array_values($json_response["query"]["pages"])[0];
- $wikipedia_language = isset($_COOKIE["wikipedia_language"]) ? trim(htmlspecialchars($_COOKIE["wikipedia_language"])) : $config->wikipedia_language;
+ if (array_key_exists("missing", $first_page))
+ return array();
+
+ $description = substr($first_page["extract"], 0, 250) . "...";
- $source = check_for_privacy_frontend("https://$wikipedia_language.wikipedia.org/wiki/$query");
+ $source = check_for_privacy_frontend("https://$this->wikipedia_language.wikipedia.org/wiki/$this->query", $this->opts);
$response = array(
"special_response" => array(
"response" => htmlspecialchars($description),
@@ -23,8 +30,7 @@
)
);
- if (array_key_exists("thumbnail", $first_page))
- {
+ if (array_key_exists("thumbnail", $first_page)) {
$image_url = $first_page["thumbnail"]["source"];
$response["special_response"]["image"] = $image_url;
}
diff --git a/engines/text/duckduckgo.php b/engines/text/duckduckgo.php
@@ -0,0 +1,64 @@
+<?php
+ class DuckDuckGoRequest extends EngineRequest {
+ function get_request_url()
+ {
+ $query_encoded = str_replace("%22", "\"", urlencode($this->query));
+ $results = array();
+
+ $domain = 'com';
+ $results_language = $this->opts->language;
+ $number_of_results = $this->opts->number_of_results;
+
+ $url = "https://html.duckduckgo.$domain/html/?q=$query_encoded&kd=-1&s=" . 3 * $this->page;
+
+ if (3 > strlen($results_language) && 0 < strlen($results_language))
+ $url .= "&lr=lang_$results_language";
+
+ if (3 > strlen($number_of_results) && 0 < strlen($number_of_results))
+ $url .= "&num=$number_of_results";
+
+ if (isset($_COOKIE["safe_search"]))
+ $url .= "&safe=medium";
+ return $url;
+ }
+
+ public function get_results() {
+ $results = array();
+ $xpath = get_xpath(curl_multi_getcontent($this->ch));
+
+ foreach($xpath->query("/html/body/div[1]/div[". count($xpath->query('/html/body/div[1]/div')) ."]/div/div/div/div") as $result)
+ {
+ $url = $xpath->evaluate(".//h2[@class='result__title']//a/@href", $result)[0];
+
+ if ($url == null)
+ continue;
+
+ if (!empty($results)) // filter duplicate results
+ {
+ if (end($results)["url"] == $url->textContent)
+ continue;
+ }
+
+ $url = $url->textContent;
+
+ $url = check_for_privacy_frontend($url, $this->opts);
+
+ $title = $xpath->evaluate(".//h2[@class='result__title']", $result)[0];
+ $description = $xpath->evaluate(".//a[@class='result__snippet']", $result)[0];
+
+ array_push($results,
+ array (
+ "title" => htmlspecialchars($title->textContent),
+ "url" => htmlspecialchars($url),
+ "base_url" => htmlspecialchars(get_base_url($url)),
+ "description" => $description == null ?
+ "No description was provided for this site." :
+ htmlspecialchars($description->textContent)
+ )
+ );
+ }
+ return $results;
+ }
+
+ }
+?>
diff --git a/engines/text/google.php b/engines/text/google.php
@@ -0,0 +1,77 @@
+<?php
+ class GoogleRequest extends EngineRequest {
+ function get_request_url()
+ {
+
+ $query_encoded = str_replace("%22", "\"", urlencode($this->query));
+ $results = array();
+
+ $domain = $this->opts->google_domain;
+ $results_language = $this->opts->language;
+ $number_of_results = $this->opts->number_of_results;
+
+ $url = "https://www.google.$domain/search?q=$query_encoded&nfpr=1&start=$this->page";
+
+ if (3 > strlen($results_language) && 0 < strlen($results_language)) {
+ $url .= "&lr=lang_$results_language";
+ $url .= "&hl=$results_language";
+ }
+
+ if (3 > strlen($number_of_results) && 0 < strlen($number_of_results))
+ $url .= "&num=$number_of_results";
+
+ if (isset($_COOKIE["safe_search"]))
+ $url .= "&safe=medium";
+
+ return $url;
+ }
+
+
+ public function get_results() {
+ $results = array();
+ $xpath = get_xpath(curl_multi_getcontent($this->ch));
+
+ if (!$xpath)
+ return $results;
+
+ $didyoumean = $xpath->query(".//a[@class='gL9Hy']")[0];
+
+ if (!is_null($didyoumean))
+ array_push($results, array(
+ "did_you_mean" => $didyoumean->textContent
+ ));
+
+ foreach($xpath->query("//div[@id='search']//div[contains(@class, 'g')]") as $result) {
+ $url = $xpath->evaluate(".//div[@class='yuRUbf']//a/@href", $result)[0];
+
+ if ($url == null)
+ continue;
+
+ if (!empty($results)) // filter duplicate results, ignore special result
+ {
+ if (end($results)["url"] == $url->textContent)
+ continue;
+ }
+
+ $url = $url->textContent;
+ $url = check_for_privacy_frontend($url, $this->opts);
+
+ $title = $xpath->evaluate(".//h3", $result)[0];
+ $description = $xpath->evaluate(".//div[contains(@class, 'VwiC3b')]", $result)[0];
+
+ array_push($results,
+ array (
+ "title" => htmlspecialchars($title->textContent),
+ "url" => htmlspecialchars($url),
+ "base_url" => htmlspecialchars(get_base_url($url)),
+ "description" => $description == null ?
+ "No description was provided for this site." :
+ htmlspecialchars($description->textContent)
+ )
+ );
+ }
+
+ return $results;
+ }
+ }
+?>
diff --git a/engines/text/text.php b/engines/text/text.php
@@ -0,0 +1,135 @@
+<?php
+ class TextSearch extends EngineRequest {
+ public function __construct($opts, $mh) {
+ $this->query = $opts->query;
+ $this->page = $opts->page;
+ $this->opts = $opts;
+
+ $engine = $opts->preferred_engines["text"] ?? "google";
+
+ $query_parts = explode(" ", $this->query);
+ $last_word_query = end($query_parts);
+ if (substr($this->query, 0, 1) == "!" || substr($last_word_query, 0, 1) == "!")
+ check_ddg_bang($this->query, $opts);
+
+ if ($engine == "google") {
+ require "engines/text/google.php";
+ $this->engine_request = new GoogleRequest($opts, $mh);
+ }
+
+ if ($engine == "duckduckgo") {
+ require "engines/text/duckduckgo.php";
+ $this->engine_request = new DuckDuckGoRequest($opts, $mh);
+ }
+
+ require "engines/special/special.php";
+ $this->special_request = get_special_search_request($opts, $mh);
+ }
+
+ public function get_results() {
+ $results = $this->engine_request->get_results();
+
+ if ($this->special_request) {
+ $special_result = $this->special_request->get_results();
+
+ if ($special_result)
+ $results = array_merge(array($special_result), $results);
+ }
+
+ return $results;
+ }
+
+ public static function print_results($results) {
+
+ if (empty($results))
+ return;
+
+ $special = $results[0];
+
+ if (array_key_exists("did_you_mean", $special))
+ {
+ $didyoumean = $special["did_you_mean"];
+ $new_url = "/search.php?q=" . urlencode($didyoumean);
+ echo "<p class=\"did-you-mean\">Did you mean ";
+ echo "<a href=\"$new_url\">$didyoumean</a>";
+ echo "?</p>";
+ }
+
+ if (array_key_exists("special_response", $special))
+ {
+ $response = $special["special_response"]["response"];
+ $source = $special["special_response"]["source"];
+
+ echo "<p class=\"special-result-container\">";
+ if (array_key_exists("image", $special["special_response"]))
+ {
+ $image_url = $special["special_response"]["image"];
+ echo "<img src=\"image_proxy.php?url=$image_url\">";
+ }
+ echo $response;
+ if ($source)
+ echo "<a href=\"$source\" target=\"_blank\">$source</a>";
+ echo "</p>";
+ }
+
+ echo "<div class=\"text-result-container\">";
+
+ foreach($results as $result)
+ {
+ if (!array_key_exists("title", $result))
+ continue;
+
+ $title = $result["title"];
+ $url = $result["url"];
+ $base_url = $result["base_url"];
+ $description = $result["description"];
+
+ echo "<div class=\"text-result-wrapper\">";
+ echo "<a href=\"$url\">";
+ echo "$base_url";
+ echo "<h2>$title</h2>";
+ echo "</a>";
+ echo "<span>$description</span>";
+ echo "</div>";
+ }
+
+ echo "</div>";
+ }
+ }
+
+ function check_ddg_bang($query, $opts)
+ {
+
+ $bangs_json = file_get_contents("static/misc/ddg_bang.json");
+ $bangs = json_decode($bangs_json, true);
+
+ if (substr($query, 0, 1) == "!")
+ $search_word = substr(explode(" ", $query)[0], 1);
+ else
+ $search_word = substr(end(explode(" ", $query)), 1);
+
+ $bang_url = null;
+
+ foreach($bangs as $bang)
+ {
+ if ($bang["t"] == $search_word)
+ {
+ $bang_url = $bang["u"];
+ break;
+ }
+ }
+
+ if ($bang_url)
+ {
+ $bang_query_array = explode("!" . $search_word, $query);
+ $bang_query = trim(implode("", $bang_query_array));
+
+ $request_url = str_replace("{{{s}}}", str_replace('%26quot%3B','%22', urlencode($bang_query)), $bang_url);
+ $request_url = check_for_privacy_frontend($request_url, $opts);
+
+ header("Location: " . $request_url);
+ die();
+ }
+ }
+
+?>
diff --git a/instances.php b/instances.php
@@ -19,7 +19,7 @@
foreach($instances as $instance) {
$hostname = parse_url($instance["clearnet"])["host"];
- $country = get_country_emote($instance["country"]) . $instnace["country"];
+ $country = get_country_emote($instance["country"]) . $instance["country"];
$is_tor = !is_null($instance["tor"]);
$is_i2p = !is_null($instance["i2p"]);
diff --git a/misc/header.php b/misc/header.php
@@ -8,9 +8,6 @@
<link rel="stylesheet" type="text/css" href="static/css/styles.css"/>
<link title="LibreY search" type="application/opensearchdescription+xml" href="opensearch.xml?method=POST" rel="search"/>
<link rel="stylesheet" type="text/css" href="<?php
- echo "static/css/";
- if (isset($_COOKIE["theme"]))
- echo htmlspecialchars($_COOKIE["theme"] . ".css");
- else
- echo "dark.css";
+$theme = $_REQUEST["theme"] ?? trim(htmlspecialchars($_COOKIE["theme"] ?? "dark"));
+ echo "static/css/" . $theme . ".css";
?>"/>
diff --git a/misc/search_engine.php b/misc/search_engine.php
@@ -0,0 +1,138 @@
+<?php
+ abstract class EngineRequest {
+ function __construct($opts, $mh) {
+ $this->query = $opts->query;
+ $this->page = $opts->page;
+ $this->opts = $opts;
+
+ $url = $this->get_request_url();
+ if (!$url)
+ return;
+
+ $this->ch = curl_init($url);
+
+ if ($opts->curl_settings)
+ curl_setopt_array($this->ch, $opts->curl_settings);
+
+ if ($mh)
+ curl_multi_add_handle($mh, $this->ch);
+ }
+
+ public function get_request_url() {
+ return "";
+ }
+
+ public function successful() {
+ return curl_getinfo($this->ch)['http_code'] == '200';
+ }
+
+ abstract function get_results();
+ static public function print_results($results){}
+ }
+
+ function load_opts() {
+ $opts = require "config.php";
+
+ $opts->query = trim($_REQUEST["q"] ?? "");
+ $opts->type = (int) ($_REQUEST["t"] ?? 0);
+ $opts->page = (int) ($_REQUEST["p"] ?? 0);
+
+ $opts->theme = $_REQUEST["theme"] ?? trim(htmlspecialchars($_COOKIE["theme"] ?? "dark"));
+
+ $opts->safe_search = (int) ($_REQUEST["safe"] ?? 0) == 1 || isset($_COOKIE["safe_search"]);
+
+ $opts->disable_special = (int) ($_REQUEST["ns"] ?? 0) == 1 || isset($_COOKIE["disable_special"]);
+
+ $opts->disable_frontends = (int) ($_REQUEST["nf"] ?? 0) == 1 || isset($_COOKIE["disable_frontends"]);
+
+ $opts->language = $_REQUEST["lang"] ?? trim(htmlspecialchars($_COOKIE["language"] ?? ""));
+
+ $opts->do_fallback = (int) ($_REQUEST["nfb"] ?? 0) == 0;
+ if (!$opts->instance_fallback) {
+ $opts->do_fallback = false;
+ }
+
+ $opts->number_of_results ??= trim(htmlspecialchars($_COOKIE["number_of_results"]));
+
+ foreach (array_keys($opts->frontends ?? array()) as $frontend) {
+ $opts->frontends[$frontend]["instance_url"] = $_COOKIE[$frontend] ?? $opts->frontends[$frontend]["instance_url"];
+ }
+ return $opts;
+ }
+
+ function opts_to_params($opts) {
+ $query = urlencode($opts->query);
+
+ $params = "";
+ $params .= "p=$opts->page";
+ $params .= "&q=$query";
+ $params .= "&t=$opts->type";
+ $params .= "&nfb=" . ($opts->do_fallback ? 0 : 1);
+ $params .= "&safe=" . ($opts->safe_search ? 1 : 0);
+ $params .= "&nf=" . ($opts->disable_frontends ? 1 : 0);
+ $params .= "&ns=" . ($opts->disable_special ? 1 : 0);
+
+ return $params;
+ }
+
+ function init_search($opts, $mh) {
+ switch ($opts->type)
+ {
+ case 1:
+ require "engines/qwant/image.php";
+ return new QwantImageSearch($opts, $mh);
+
+ case 2:
+ require "engines/invidious/video.php";
+ return new VideoSearch($opts, $mh);
+
+ case 3:
+ if ($opts->disable_bittorent_search) {
+ echo "<p class=\"text-result-container\">The host disabled this feature! :C</p>";
+ break;
+ }
+
+ require "engines/bittorrent/merge.php";
+ return new TorrentSearch($opts, $mh);
+
+ case 4:
+ if ($opts->disable_hidden_service_search) {
+ echo "<p class=\"text-result-container\">The host disabled this feature! :C</p>";
+ break;
+ }
+ require "engines/ahmia/hidden_service.php";
+ return new TorSearch($opts, $mh);
+
+ default:
+ require "engines/text/text.php";
+ return new TextSearch($opts, $mh);
+ }
+ }
+
+ function fetch_search_results($opts, $do_print) {
+ $start_time = microtime(true);
+ $mh = curl_multi_init();
+ $search_category = init_search($opts, $mh);
+
+ $running = null;
+
+ do {
+ curl_multi_exec($mh, $running);
+ } while ($running);
+
+ $results = $search_category->get_results();
+
+ if (count($results) <= 1) {
+ require "engines/librex/fallback.php";
+ $results = get_librex_results($opts);
+ }
+
+ if (!$do_print)
+ return $results;
+
+ print_elapsed_time($start_time);
+ $search_category->print_results($results);
+
+ return $results;
+ }
+?>
diff --git a/misc/tools.php b/misc/tools.php
@@ -1,69 +1,49 @@
<?php
- function get_base_url($url)
- {
+ function get_base_url($url) {
$split_url = explode("/", $url);
$base_url = $split_url[0] . "//" . $split_url[2] . "/";
return $base_url;
}
- function get_root_domain($url)
- {
+ function get_root_domain($url) {
$split_url = explode("/", $url);
$base_url = $split_url[2];
$base_url_main_split = explode(".", strrev($base_url));
$root_domain = strrev($base_url_main_split[1]) . "." . strrev($base_url_main_split[0]);
-
+
return $root_domain;
}
- function try_replace_with_frontend($url, $frontend, $original)
- {
- global $config;
- $frontends = $config->frontends;
+ function try_replace_with_frontend($url, $frontend, $original, $opts) {
+ $frontends = $opts->frontends;
- if (isset($_COOKIE[$frontend]) || !empty($frontends[$frontend]["instance_url"]))
- {
-
- if (isset($_COOKIE[$frontend]))
- $frontend = $_COOKIE[$frontend];
- else if (!empty($frontends[$frontend]["instance_url"]))
- $frontend = $frontends[$frontend]["instance_url"];
+ if (array_key_exists($frontend, $opts->frontends)) {
+ $frontend = $frontends[$frontend]["instance_url"];
if (empty(trim($frontend)))
return $url;
- if (strpos($url, "wikipedia.org") !== false)
- {
+ if (strpos($url, "wikipedia.org") !== false) {
$wiki_split = explode(".", $url);
- if (count($wiki_split) > 1)
- {
+ if (count($wiki_split) > 1) {
$lang = explode("://", $wiki_split[0])[1];
$url = $frontend . explode($original, $url)[1] . (strpos($url, "?") !== false ? "&" : "?") . "lang=" . $lang;
}
- }
- else if (strpos($url, "fandom.com") !== false)
- {
+ } else if (strpos($url, "fandom.com") !== false) {
$fandom_split = explode(".", $url);
- if (count($fandom_split) > 1)
- {
+ if (count($fandom_split) > 1) {
$wiki_name = explode("://", $fandom_split[0])[1];
$url = $frontend . "/" . $wiki_name . explode($original, $url)[1];
}
- }
- else if (strpos($url, "gist.github.com") !== false)
- {
+ } else if (strpos($url, "gist.github.com") !== false) {
$gist_path = explode("gist.github.com", $url)[1];
$url = $frontend . "/gist" . $gist_path;
- }
- else if (strpos($url, "stackexchange.com") !== false)
- {
+ } else if (strpos($url, "stackexchange.com") !== false) {
$se_domain = explode(".", explode("://", $url)[1])[0];
$se_path = explode("stackexchange.com", $url)[1];
$url = $frontend . "/exchange" . "/" . $se_domain . $se_path;
- }
- else
- {
+ } else {
$url = $frontend . explode($original, $url)[1];
}
@@ -74,26 +54,18 @@
return $url;
}
- function check_for_privacy_frontend($url)
- {
-
- global $config;
-
- if (isset($_COOKIE["disable_frontends"]))
+ function check_for_privacy_frontend($url, $opts) {
+ if ($opts->disable_frontends)
return $url;
- foreach($config->frontends as $frontend => $data)
- {
+ foreach($opts->frontends as $frontend => $data) {
$original = $data["original_url"];
- if (strpos($url, $original))
- {
- $url = try_replace_with_frontend($url, $frontend, $original);
+ if (strpos($url, $original)) {
+ $url = try_replace_with_frontend($url, $frontend, $original, $opts);
break;
- }
- else if (strpos($url, "stackexchange.com"))
- {
- $url = try_replace_with_frontend($url, "anonymousoverflow", "stackexchange.com");
+ } else if (strpos($url, "stackexchange.com")) {
+ $url = try_replace_with_frontend($url, "anonymousoverflow", "stackexchange.com", $opts);
break;
}
}
@@ -101,88 +73,10 @@
return $url;
}
- function check_ddg_bang($query)
- {
-
- $bangs_json = file_get_contents("static/misc/ddg_bang.json");
- $bangs = json_decode($bangs_json, true);
-
- if (substr($query, 0, 1) == "!")
- $search_word = substr(explode(" ", $query)[0], 1);
- else
- $search_word = substr(end(explode(" ", $query)), 1);
-
- $bang_url = null;
-
- foreach($bangs as $bang)
- {
- if ($bang["t"] == $search_word)
- {
- $bang_url = $bang["u"];
- break;
- }
- }
-
- if ($bang_url)
- {
- $bang_query_array = explode("!" . $search_word, $query);
- $bang_query = trim(implode("", $bang_query_array));
-
- $request_url = str_replace("{{{s}}}", str_replace('%26quot%3B','%22', urlencode($bang_query)), $bang_url);
- $request_url = check_for_privacy_frontend($request_url);
-
- header("Location: " . $request_url);
- die();
- }
- }
-
- function check_for_special_search($query)
- {
- if (isset($_COOKIE["disable_special"]))
- return 0;
-
- $query_lower = strtolower($query);
- $split_query = explode(" ", $query);
-
- if (strpos($query_lower, "to") && count($split_query) >= 4) // currency
- {
- $amount_to_convert = floatval($split_query[0]);
- if ($amount_to_convert != 0)
- return 1;
- }
- else if (strpos($query_lower, "mean") && count($split_query) >= 2) // definition
- {
- return 2;
- }
- else if (strpos($query_lower, "my") !== false)
- {
- if (strpos($query_lower, "ip"))
- {
- return 3;
- }
- else if (strpos($query_lower, "user agent") || strpos($query_lower, "ua"))
- {
- return 4;
- }
- }
- else if (strpos($query_lower, "weather") !== false)
- {
- return 5;
- }
- else if ($query_lower == "tor")
- {
- return 6;
- }
- else if (3 > count(explode(" ", $query))) // wikipedia
- {
- return 7;
- }
-
- return 0;
- }
+ function get_xpath($response) {
+ if (!$response)
+ return null;
- function get_xpath($response)
- {
$htmlDom = new DOMDocument;
@$htmlDom->loadHTML($response);
$xpath = new DOMXPath($htmlDom);
@@ -190,9 +84,8 @@
return $xpath;
}
- function request($url)
- {
- global $config;
+ function request($url) {
+ $config ??= require "config.php";
$ch = curl_init($url);
curl_setopt_array($ch, $config->curl_settings);
@@ -201,28 +94,24 @@
return $response;
}
- function human_filesize($bytes, $dec = 2)
- {
+ function human_filesize($bytes, $dec = 2) {
$size = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$dec}f ", $bytes / pow(1024, $factor)) . @$size[$factor];
}
- function remove_special($string)
- {
+ function remove_special($string) {
$string = preg_replace("/[\r\n]+/", "\n", $string);
return trim(preg_replace("/\s+/", ' ', $string));
}
- function print_elapsed_time($start_time)
- {
+ function print_elapsed_time($start_time) {
$end_time = number_format(microtime(true) - $start_time, 2, '.', '');
echo "<p id=\"time\">Fetched the results in $end_time seconds</p>";
}
- function print_next_page_button($text, $page, $query, $type)
- {
+ function print_next_page_button($text, $page, $query, $type) {
echo "<form class=\"page\" action=\"search.php\" target=\"_top\" method=\"get\" autocomplete=\"off\">";
echo "<input type=\"hidden\" name=\"p\" value=\"" . $page . "\" />";
echo "<input type=\"hidden\" name=\"q\" value=\"$query\" />";
@@ -231,15 +120,13 @@
echo "</form>";
}
- function copy_cookies($curl)
- {
+ function copy_cookies($curl) {
if (array_key_exists("HTTP_COOKIE", $_SERVER))
curl_setopt( $curl, CURLOPT_COOKIE, $_SERVER['HTTP_COOKIE'] );
}
- function get_country_emote($code)
- {
+ function get_country_emote($code) {
$emoji = [];
foreach(str_split($code) as $c) {
if(($o = ord($c)) > 64 && $o % 32 < 27) {
diff --git a/search.php b/search.php
@@ -1,14 +1,34 @@
-<?php
+<?php
require "misc/header.php";
- $config = require "config.php";
require "misc/tools.php";
+ require "misc/search_engine.php";
+
+ $opts = load_opts();
+
+ function print_page_buttons($type, $query, $page) {
+ if ($type > 1)
+ return;
+ echo "<div class=\"next-page-button-wrapper\">";
+
+ if ($page != 0)
+ {
+ print_next_page_button("<<", 0, $query, $type);
+ print_next_page_button("<", $page - 10, $query, $type);
+ }
+
+ for ($i=$page / 10; $page / 10 + 10 > $i; $i++)
+ print_next_page_button($i + 1, $i * 10, $query, $type);
+
+ print_next_page_button(">", $page + 10, $query, $type);
+
+ echo "</div>";
+ }
?>
<title>
<?php
- $query = trim($_REQUEST["q"]);
- echo $query;
+ echo $opts->query;
?> - LibreY</title>
</head>
<body>
@@ -16,21 +36,18 @@
<h1 class="logomobile"><a class="no-decoration" href="./">Libre<span class="Y">Y</span></a></h1>
<input type="text" name="q"
<?php
- $query_encoded = urlencode($query);
-
- if (1 > strlen($query) || strlen($query) > 256)
+ if (1 > strlen($opts->query) || strlen($opts->query) > 256)
{
header("Location: ./");
die();
}
- echo "value=\"" . htmlspecialchars($query) . "\"";
+ echo "value=\"" . htmlspecialchars($opts->query) . "\"";
?>
>
<br>
<?php
- $type = isset($_REQUEST["t"]) ? (int) $_REQUEST["t"] : 0;
- echo "<button class=\"hide\" name=\"t\" value=\"$type\"/></button>";
+ echo "<button class=\"hide\" name=\"t\" value=\"$opts->type\"/></button>";
?>
<button type="submit" class="hide"></button>
<input type="hidden" name="p" value="0">
@@ -42,13 +59,13 @@
{
$category_index = array_search($category, $categories);
- if (($config->disable_bittorent_search && $category_index == 3) ||
- ($config->disable_hidden_service_search && $category_index ==4))
+ if (($opts->disable_bittorent_search && $category_index == 3) ||
+ ($opts->disable_hidden_service_search && $category_index ==4))
{
continue;
}
- echo "<a " . (($category_index == $type) ? "class=\"active\" " : "") . "href=\"./search.php?q=" . $query . "&p=0&t=" . $category_index . "\"><img src=\"static/images/" . $category . "_result.png\" alt=\"" . $category . " result\" />" . ucfirst($category) . "</a>";
+ echo "<a " . (($category_index == $opts->type) ? "class=\"active\" " : "") . "href=\"./search.php?q=" . urlencode($opts->query) . "&p=0&t=" . $category_index . "\"><img src=\"static/images/" . $category . "_result.png\" alt=\"" . $category . " result\" />" . ucfirst($category) . "</a>";
}
?>
</div>
@@ -56,93 +73,8 @@
</form>
<?php
-
- $page = isset($_REQUEST["p"]) ? (int) $_REQUEST["p"] : 0;
- $start_time = microtime(true);
- switch ($type)
- {
- case 0:
- $engine=$config->preferred_engines['text'];
- if (is_null($engine))
- $engine = "google";
- $query_parts = explode(" ", $query);
- $last_word_query = end($query_parts);
- if (substr($query, 0, 1) == "!" || substr($last_word_query, 0, 1) == "!")
- check_ddg_bang($query);
- require "engines/$engine/text.php";
- $results = get_text_results($query, $page);
- print_elapsed_time($start_time);
- print_text_results($results);
- break;
-
- case 1:
- require "engines/qwant/image.php";
- $results = get_image_results($query_encoded, $page);
- print_elapsed_time($start_time);
- print_image_results($results);
- break;
-
- case 2:
- require "engines/invidious/video.php";
- $results = get_video_results($query_encoded);
- print_elapsed_time($start_time);
- print_video_results($results);
- break;
-
- case 3:
- if ($config->disable_bittorent_search)
- echo "<p class=\"text-result-container\">The host disabled this feature! :C</p>";
- else
- {
- require "engines/bittorrent/merge.php";
- $results = get_merged_torrent_results($query_encoded);
- print_elapsed_time($start_time);
- print_merged_torrent_results($results);
- }
- break;
-
- case 4:
- if ($config->disable_hidden_service_search)
- echo "<p class=\"text-result-container\">The host disabled this feature! :C</p>";
- else
- {
- require "engines/ahmia/hidden_service.php";
- $results = get_hidden_service_results($query_encoded);
- print_elapsed_time($start_time);
- print_hidden_service_results($results);
- }
- break;
-
- default:
- $query_parts = explode(" ", $query);
- $last_word_query = end($query_parts);
- if (substr($query, 0, 1) == "!" || substr($last_word_query, 0, 1) == "!")
- check_ddg_bang($query);
- require "engines/google/text.php";
- $results = get_text_results($query, $page);
- print_elapsed_time($start_time);
- print_text_results($results);
- break;
- }
-
-
- if (2 > $type)
- {
- echo "<div class=\"next-page-button-wrapper\">";
-
- if ($page != 0)
- {
- print_next_page_button("<<", 0, $query, $type);
- print_next_page_button("<", $page - 10, $query, $type);
- }
-
- for ($i=$page / 10; $page / 10 + 10 > $i; $i++)
- print_next_page_button($i + 1, $i * 10, $query, $type);
-
- print_next_page_button(">", $page + 10, $query, $type);
-
- echo "</div>";
- }
+ fetch_search_results($opts, true);
+ print_page_buttons($opts->type, $opts->query, $opts->page);
?>
<?php require "misc/footer.php"; ?>
diff --git a/settings.php b/settings.php
@@ -1,43 +1,35 @@
<?php
- $config = require "config.php";
+ require "misc/search_engine.php";
+ $opts = load_opts();
- // Reset all cookies when resetting, or before saving new cookies
- if (isset($_REQUEST["reset"]) || isset($_REQUEST["save"]))
- {
- if (isset($_SERVER["HTTP_COOKIE"]))
- {
- $cookies = explode(";", $_SERVER["HTTP_COOKIE"]);
- foreach($cookies as $cookie)
- {
- $parts = explode("=", $cookie);
- $name = trim($parts[0]);
- setcookie($name, "", time() - 1000);
- }
- }
+ // Reset all cookies when resetting, or before saving new cookies
+ if (isset($_REQUEST["reset"]) || isset($_REQUEST["save"])) {
+ if (isset($_SERVER["HTTP_COOKIE"])) {
+ $cookies = explode(";", $_SERVER["HTTP_COOKIE"]);
+ foreach($cookies as $cookie) {
+ $parts = explode("=", $cookie);
+ $name = trim($parts[0]);
+ setcookie($name, "", time() - 1000);
}
+ }
+ }
- if (isset($_REQUEST["save"]))
- {
- foreach($_POST as $key=>$value)
- {
- if (!empty($value))
- {
- setcookie($key, $value, time() + (86400 * 90), '/');
- }
- else
- {
- setcookie($key, "", time() - 1000);
- }
- }
+ if (isset($_REQUEST["save"])) {
+ foreach($_POST as $key=>$value) {
+ if (!empty($value)) {
+ setcookie($key, $value, time() + (86400 * 90), '/');
+ } else {
+ setcookie($key, "", time() - 1000);
}
+ }
+ }
- if (isset($_REQUEST["save"]) || isset($_REQUEST["reset"]))
- {
- header("Location: ./");
- die();
- }
+ if (isset($_REQUEST["save"]) || isset($_REQUEST["reset"])) {
+ header("Location: ./");
+ die();
+ }
- require "misc/header.php";
+ require "misc/header.php";
?>
<title>LibreY - Settings</title>
@@ -67,10 +59,9 @@
<option value=\"ubuntu\">Ubuntu</option>
<option value=\"tokyo_night\">Tokyo night</option>";
- if (isset($_COOKIE["theme"]))
- {
- $cookie_theme = $_COOKIE["theme"];
- $themes = str_replace($cookie_theme . "\"", $cookie_theme . "\" selected", $themes);
+ if (isset($_COOKIE["theme"])) {
+ $theme = $opts->theme;
+ $themes = str_replace($theme . "\"", $theme . "\" selected", $themes);
}
echo $themes;
@@ -79,19 +70,19 @@
</div>
<div>
<label>Disable special queries (e.g.: currency conversion)</label>
- <input type="checkbox" name="disable_special" <?php echo isset($_COOKIE["disable_special"]) ? "checked" : ""; ?> >
+ <input type="checkbox" name="disable_special" <?php echo $opts->disable_special ? "checked" : ""; ?> >
</div>
<h2>Privacy friendly frontends</h2>
<p>For an example if you want to view YouTube without getting spied on, click on "Invidious", find the instance that is most suitable for you then paste it in (correct format: https://example.com)</p>
<div class="settings-textbox-container">
<?php
- foreach($config->frontends as $frontend => $data)
+ foreach($opts->frontends as $frontend => $data)
{
echo "<div>";
echo "<a for=\"$frontend\" href=\"" . $data["project_url"] . "\" target=\"_blank\">" . ucfirst($frontend) . "</a>";
echo "<input type=\"text\" name=\"$frontend\" placeholder=\"Replace " . $data["original_name"] . "\" value=";
- echo isset($_COOKIE["$frontend"]) ? htmlspecialchars($_COOKIE["$frontend"]) : $data["instance_url"];
+ echo htmlspecialchars($opts->frontends["$frontend"]["instance_url"] ?? "");
echo ">";
echo "</div>";
}
@@ -99,43 +90,25 @@
</div>
<div>
<label>Disable frontends</label>
- <input type="checkbox" name="disable_frontends" <?php echo isset($_COOKIE["disable_frontends"]) ? "checked" : ""; ?> >
+ <input type="checkbox" name="disable_frontends" <?php echo $opts->disable_frontends ? "checked" : ""; ?> >
</div>
<h2>Search settings</h2>
<div class="settings-textbox-container">
<div>
- <span>Site language</span>
- <?php
- echo "<input type=\"text\" name=\"google_language_site\" placeholder=\"E.g.: en\" value=\"";
- echo isset($_COOKIE["google_language_site"]) ? htmlspecialchars($_COOKIE["google_language_site"]) : $config->google_language_site;
- ?>">
- </div>
- <div>
- <span>Results language</span>
+ <span>Language</span>
<?php
- echo "<input type=\"text\" name=\"google_language_results\" placeholder=\"E.g.: de\" value=\"";
- echo isset($_COOKIE["google_language_results"]) ? htmlspecialchars($_COOKIE["google_language_results"]) : $config->google_language_results;
- ?>">
+ // TODO make this a dropdown
+ echo "<input type=\"text\" name=\"language\" placeholder=\"any\" value=\"" . htmlspecialchars($opts->language ?? "") . "\">";
+ ?>
</div>
<div>
<label>Number of results per page</label>
- <input type="number" name="google_number_of_results" value="<?php echo isset($_COOKIE["google_number_of_results"]) ? $_COOKIE["google_number_of_results"] : $config->google_number_of_results; ?>" >
+ <input type="number" name="number_of_results" value="<?php echo htmlspecialchars($opts->number_of_results ?? "10") ?>" >
</div>
<div>
<label>Safe search</label>
- <input type="checkbox" name="safe_search" <?php echo isset($_COOKIE["safe_search"]) ? "checked" : ""; ?> >
- </div>
- </div>
-
- <h2>Wikipedia settings</h2>
- <div class="settings-textbox-container">
- <div>
- <span>Results language</span>
- <?php
- echo "<input type=\"text\" name=\"wikipedia_language\" placeholder=\"E.g.: en\" value=\"";
- echo isset($_COOKIE["wikipedia_language"]) ? htmlspecialchars($_COOKIE["wikipedia_language"]) : $config->wikipedia_language;
- ?>">
+ <input type="checkbox" name="safe_search" <?php echo $opts->safe_search ? "checked" : ""; ?> >
</div>
</div>
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |