Initial release
The first public release of Goosle.
This commit is contained in:
parent
e054b6da22
commit
6e7114a205
29 changed files with 2255 additions and 0 deletions
BIN
apple-touch-icon.png
Normal file
BIN
apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
198
assets/css/styles.css
Normal file
198
assets/css/styles.css
Normal file
|
@ -0,0 +1,198 @@
|
|||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
body { position: relative; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; color: #222; background-color: #ffffff; line-height: 1; }
|
||||
div { margin: 0; padding: 0; border: 0; font-size: 100%; vertical-align: baseline; }
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; }
|
||||
h2, h3, h4, h5, h6 { font-weight: normal; }
|
||||
h2, h3, h4, h5, h6, p, ul, ol, blockquote { padding-top: .5em; padding-bottom: .5em; }
|
||||
ol, ol > li { margin: 0; padding: 0; list-style: none; }
|
||||
input, button { outline: none; }
|
||||
button { cursor: pointer; }
|
||||
p { font-size: 18px; color: #494949; }
|
||||
a { text-decoration: none; color: #4495d4; }
|
||||
a:hover { text-decoration: underline; }
|
||||
input[type="text"]:invalid ~ input[type="submit"] { opacity: 0.5; pointer-events: none; }
|
||||
|
||||
/* Page structure */
|
||||
.wrap { min-height: 100vh; overflow: hidden; }
|
||||
.header-wrap { display: block; padding-top: 16px; width: 100%; }
|
||||
.results-wrap { position: relative; display: flex; margin: 0 158px 50px 158px; }
|
||||
.footer-wrap { position: absolute; bottom: 0; display: block; margin-top: 15px; padding: 0; width: 100%; }
|
||||
|
||||
/* Main page */
|
||||
body.main { background-color: #1f242b; color: #f0f6fc; }
|
||||
.search-box-main, .password-generator { text-align: center; margin-top: 10%; }
|
||||
.search-box-main h1 { font-size: 70px; }
|
||||
.search-box-main .search, .password-generator .password { padding: 10px 20px; width: 600px; color: #f0f6fc; background-color: #333333; font-size: 32px; font-family: sans-serif; border: 1px solid #3C4043; border-radius: 10px; }
|
||||
.search-box-buttons button { margin: 30px 20px 10px 20px; padding: 13px 10px 13px 10px; min-width: 130px; color: #f0f6fc; background-color: #333333; font-size: 14px; border: 1px solid #1c1c1c; border-radius: 6px; }
|
||||
.search-box-buttons button:hover { border: 1px solid #5f6368; }
|
||||
|
||||
.password-generator { margin: 30px auto; padding: 0; }
|
||||
.password-generator .password { margin: 10px auto; width: 300px; text-align: center; font-size: 14px; }
|
||||
|
||||
/* Search Results - Header */
|
||||
.header-wrap { background-color: #1f242b; color: #f0f6fc; border-bottom: 2px solid #1fa4d1; }
|
||||
.header-wrap .search { position: relative; margin: 28px 0 28px 158px; padding: 5px 5px 5px 15px; height: 30px; width: 580px; color: #f0f6fc; background-color: #1f242b; font-size: 100%; font-weight: 400; border: 1px solid #303842; border-radius: 10px 0 0 10px; }
|
||||
.header-wrap .button { position: relative; margin: 28px 10px 28px 0; padding: 5px 20px 5px 15px; height: 40px; color: #f0f6fc; background-color: #1fa4d1; font-size: 100%; font-weight: 400; border: none; border-radius: 0 10px 10px 0; }
|
||||
|
||||
/* Search results - Header Navigation */
|
||||
.navigation-header { margin-left: 165px; margin-bottom: 10px; }
|
||||
.navigation-header img { margin-right: 5px; height: 16px; vertical-align: middle; }
|
||||
.navigation-header a { margin-right: 20px; border: none; font-size: 16px; cursor: pointer; text-decoration: none; }
|
||||
.navigation-header a:hover { color: #ebf3fa; }
|
||||
.navigation-header a:visited { color: #1fa4d1; }
|
||||
.navigation-header .active { padding-bottom: 8px; border-bottom: 4px #1fa4d1 solid; }
|
||||
|
||||
/* Search results - Main column */
|
||||
.main-column { width: 100%; }
|
||||
.main-column ol .result { margin: .50rem 0 .50rem 0; padding: 0; }
|
||||
.main-column ol .special-result, .main-column ol .meta-time, .main-column ol .meta-error, .main-column ol .meta-did-you-mean { margin: .75rem 0 .75rem 0; padding: .5rem 10px; }
|
||||
|
||||
.main-column ol li article { padding: .5rem 10px; border: 1px solid #fefefe; border-radius: 8px; }
|
||||
.main-column ol li article div.url:first-child, .main-column ol li.special-result article div.source:first-child { flex-grow: 0; }
|
||||
.main-column ol li article div.url { display: inline-block; margin: 0; max-width: 100%; color: #666; font-size: 1rem; line-height: 1.6; letter-spacing: .2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.main-column ol li article div.url a { margin: 0; color: #3f6e35; cursor: pointer; text-decoration: none; }
|
||||
.main-column ol li article div.title, .main-column ol li.special-result article div.title { margin-top: .146rem; margin-bottom: .28451rem; }
|
||||
.main-column ol li article div.title h2 { margin: 0; padding: 0; position: relative; font-size: 1.46rem; letter-spacing: -.01px; }
|
||||
.main-column ol li article div.title h2:hover { text-decoration: underline; }
|
||||
.main-column ol li article div.title a { margin: 0; display: block; cursor: pointer; }
|
||||
.main-column ol li article div.title a:visited { color: #6d59a3; }
|
||||
.main-column ol li article div.description { margin: 0; line-height: 1.4; font-size: 1rem; color: #494949; }
|
||||
.main-column ol li article div.description .seeders { color: #518257; }
|
||||
.main-column ol li article div.description .leechers { color: #c00; }
|
||||
|
||||
/* Image results - Main column */
|
||||
.main-column .image-wrapper { width: 100%; margin: .75rem 0 .75rem 0; }
|
||||
@supports not (display: grid) {
|
||||
.image-grid > * { max-width: 8rem; margin-left: auto; margin-right: auto; }
|
||||
.image-grid li.result { display: inline-block; margin: .75rem; width: 12.5%; }
|
||||
.image-grid > * + * { margin-top: 1rem; }
|
||||
}
|
||||
@supports (display: grid) {
|
||||
.main-column ol.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); grid-gap: 1rem; }
|
||||
}
|
||||
.main-column ol.image-grid .result .image-box { position: relative; }
|
||||
.main-column ol.image-grid .result .image-box::after { display: block; padding-bottom: 100%; content: ""; }
|
||||
.main-column ol.image-grid .result .image-box img { position: absolute; object-fit: cover; width: 100%; height: 100%; }
|
||||
|
||||
/* Special results - Main column */
|
||||
.main-column ol .special-result { background-color: #fefefe; }
|
||||
.main-column ol li.special-result article { padding: .5rem 10px; position: relative; overflow: hidden; border: 1px solid #aeaeae; border-radius: 8px; color: #222; }
|
||||
.main-column ol li.special-result article div.title h2 { margin: 0; padding: 0; font-size: 1.5rem; font-weight: 600; word-wrap: break-word; color: #222; }
|
||||
.main-column ol li.special-result article div.title h2:hover { text-decoration: none; }
|
||||
.main-column ol li.special-result article div.title a { margin: 0; display: block; color: #6c00a2; cursor: pointer; }
|
||||
.main-column ol li.special-result article div.title a:visited { color: #6d59a3; }
|
||||
.main-column ol li.special-result article div.text, .main-column ol li article div.source { padding-top: 10px; position: relative; font-style: normal; }
|
||||
.main-column ol li.special-result article div.text img { padding: 0 0 10px 10px; }
|
||||
.main-column ol li.special-result article div.source { display: inline-block; margin: 0; max-width: 100%; color: #666; font-size: 1rem; line-height: 1.6; letter-spacing: .2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: inherit; }
|
||||
.main-column ol li.special-result article div.source a { margin: 0; color: #3f6e35; text-decoration: none; }
|
||||
|
||||
/* Misc */
|
||||
.logo { position: absolute; margin: 28px 18px; }
|
||||
.logo a { color: #f0f6fc; cursor: pointer; }
|
||||
.no-decoration, .no-decoration:hover { text-decoration: none; }
|
||||
.hide { display: none; }
|
||||
.G { color: #1fa4d1; }
|
||||
.meta-error { position: relative; overflow: hidden; color: #c00; background-color: #ffebe8; border: 1px solid #c00; border-radius: 8px; }
|
||||
.auth-error { margin-top: 15%; font-size: 32px; text-align: center; color: #eaeaea; }
|
||||
|
||||
/* Footer bar */
|
||||
.footer-wrap { background-color: #161616; color: #f0f6fc; border-top: 2px solid #303134; }
|
||||
.footer { padding: 10px; }
|
||||
.footer a { color: #f0f6fc; }
|
||||
|
||||
@media only screen and (max-width:960px) { /* tablet, landscape iPad, lo-res laptops ands desktops */
|
||||
/* Page structure */
|
||||
.results-wrap { position: relative; display: flex; margin: 0 48px 20px 48px; }
|
||||
|
||||
/* Main page */
|
||||
.search-box-main { margin-top: 10%; }
|
||||
.search-box-main input { width: 80%; }
|
||||
.search-box-buttons button { display: table-row; margin: 30px 0px 0px 0px; width: 80%; }
|
||||
|
||||
/* Search Results - Header */
|
||||
.header-wrap { margin-left: auto; margin-right: auto; text-align: center; }
|
||||
.header-wrap .search { margin: 10px 0px 28px 48px; width: 400px; }
|
||||
.header-wrap .search, .header-wrap .button { margin: 10px 0px 28px 0px; }
|
||||
|
||||
/* Search results - Header Navigation */
|
||||
.navigation-header { display: flex; margin: 0; padding: 0; align-items: baseline; }
|
||||
.navigation-header a { margin: 0 auto; padding: 0; }
|
||||
|
||||
/* Misc */
|
||||
.logo { position: relative; display: block;margin: 0 auto; float: none; padding: 10px; font-size: 28px; }
|
||||
}
|
||||
|
||||
@media only screen and (max-width:640px) { /* portrait tablets, portrait iPad, landscape e-readers, landscape 800x480 or 854x480 phones */
|
||||
/* Page structure */
|
||||
.results-wrap { position: relative; display: flex; margin: 0 10px 10px 10px; }
|
||||
|
||||
/* Main page */
|
||||
.search-box-main { margin-top: 10%; }
|
||||
.search-box-main input { width: 80%; }
|
||||
.search-box-buttons button { display: table-row; margin: 30px 0px 0px 0px; width: 80%; }
|
||||
|
||||
/* Search Results - Header */
|
||||
.header-wrap { margin-left: auto; margin-right: auto; text-align: center; }
|
||||
.header-wrap .search, .header-wrap .button { margin: 0px 0px 10px 0px; width: 80%; border-radius: 25px; }
|
||||
|
||||
/* Search results - Header Navigation */
|
||||
.navigation-header { display: flex; margin: 0; padding: 0; align-items: baseline; }
|
||||
.navigation-header a { margin: 0 auto; padding: 0; }
|
||||
|
||||
/* Misc */
|
||||
.logo { position: relative; display: block; float: none; margin: 0 auto; padding: 10px; font-size: 28px; }
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) { /* portrait e-readers (Nook/Kindle), smaller tablets @ 600 or @ 640 wide. */
|
||||
/* Page structure */
|
||||
.results-wrap { position: relative; display: flex; margin: 0 10px 10px 10px; }
|
||||
|
||||
/* Main page */
|
||||
.search-box-main { margin-top: 10%; }
|
||||
.search-box-main input { width: 80%; }
|
||||
.search-box-main h1 { font-size: 45px; }
|
||||
.search-box-buttons button { display: table-row; margin: 30px 0px 0px 0px; width: 80%; }
|
||||
|
||||
/* Search Results - Header */
|
||||
.header-wrap { margin-left: auto; margin-right: auto; text-align: center; }
|
||||
.header-wrap .search, .header-wrap .button { margin: 0px 0px 10px 0px; width: 80%; border-radius: 25px; }
|
||||
|
||||
/* Search results - Header Navigation */
|
||||
.navigation-header { display: flex; margin: 0; padding: 0; align-items: baseline; }
|
||||
.navigation-header a { margin: 0 auto; padding: 0; }
|
||||
|
||||
/* Misc */
|
||||
.logo { position: relative; display: block; float: none; margin: 0 auto; padding: 10px; font-size: 28px; }
|
||||
}
|
||||
|
||||
@media only screen and (max-width:320px) { /* smartphones, iPhone, portrait 480x320 phones */
|
||||
/* Page structure */
|
||||
.results-wrap { position: relative; display: flex; margin: 0 10px 10px 10px; }
|
||||
|
||||
/* Main page */
|
||||
.search-box-main { margin-top: 40px; }
|
||||
.search-box-main input { width: 80%; }
|
||||
.search-box-main h1 { font-size: 45px; }
|
||||
.search-box-buttons button { display: table-row; margin: 20px 0px 0px 0px; width: 80%; }
|
||||
|
||||
/* Search Results - Header */
|
||||
.header-wrap { margin-left: auto; margin-right: auto; text-align: center; }
|
||||
.header-wrap .search, .header-wrap .button { margin: 0px 0px 10px 0px; width: 80%; border-radius: 25px; }
|
||||
|
||||
/* Search results - Header Navigation */
|
||||
.navigation-header { display: flex; margin: 0; padding: 0; align-items: baseline; }
|
||||
.navigation-header a { margin: 0 auto; padding: 0; }
|
||||
|
||||
/* Misc */
|
||||
.logo { position: relative; float: none; display: block; margin: 0 auto; padding: 10px; font-size: 28px; }
|
||||
}
|
BIN
assets/images/image.png
Normal file
BIN
assets/images/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/images/search.png
Normal file
BIN
assets/images/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/images/torrent.png
Normal file
BIN
assets/images/torrent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
114
config.php
Normal file
114
config.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
/* ------------------------------------------------------------------------------------
|
||||
HASH:
|
||||
A simple lowercase passphrase (something simple like: j9fg-i2du-er6m or 1846) used for caching results. This helps to differentiate between instances on the same server.
|
||||
You can also add it to your url/bookmark as a simple passphrase to keep unwanted users out.
|
||||
|
||||
CACHE:
|
||||
If you have ACPu it is highly recommended to enable caching as it'll speed up repeatable searched by a lot.
|
||||
"on" (Recommended) for active sites, requires APCu
|
||||
"off" Disables cache, useful for testing or if your server lacks APCu support
|
||||
|
||||
CACHE_TIME:
|
||||
Minutes the result should be cached in ACPu.
|
||||
|
||||
HASH AUTH:
|
||||
Use the above hash as a simple passphrase.
|
||||
Using it as a passphrase lets you host Goosle on a public server without providing a public service.
|
||||
|
||||
Usage: https://example.com/?a=1234567890
|
||||
Disclaimer: This is not meant to 'hack proof' or truly secure the setup. Just a simple token to keep surface level prying eyes out.
|
||||
|
||||
RAW OUTPUT:
|
||||
"off" (Recommended) for active sites
|
||||
"on" Output the search results as an array instead of formatted with HTML
|
||||
|
||||
ENABLE TORRENT SEARCH:
|
||||
Enable or disable searching for torrent downloads.
|
||||
"on" (Default)
|
||||
"off"
|
||||
|
||||
ENABLE IMAGE SEARCH:
|
||||
Enable or disable image searches - Search results are provided by Qwant.
|
||||
"on" (Default)
|
||||
"off"
|
||||
|
||||
SPECIAL:
|
||||
Enable or disable special searches that show up before search results.
|
||||
"on" (Default)
|
||||
"off" Disable this special search
|
||||
|
||||
USER AGENTS:
|
||||
Add more or less user agents to the list. Keep at least one.
|
||||
On every search Goosle picks one at random to identify as.
|
||||
Keep them generic to prevent profiling, but also so that the request comes off as a generic boring browser and not a server/script.
|
||||
|
||||
Safari and Internet Explorer may be a limiting factor on results as they are lesser supported browsers. But should otherwise be fine.
|
||||
Chrome may attract attention because of the lack of Chrome information (tracking) aside from the user agent.
|
||||
Opera/Edge/Brave and many others use Chrome under the hood and are not a good pick for that reason.
|
||||
|
||||
BLOCK 1337x CATEGORIES:
|
||||
Add category IDs of 1337x categories, check /engines/torrent/1337x.php for a list of known categories.
|
||||
|
||||
BLOCK PIRATEBAY CATEGORIES:
|
||||
Add category IDs of Pirate Bay categories, check /engines/torrent/thepiratebay.php for a list of known categories.
|
||||
|
||||
BLOCK YTS CATEGORIES:
|
||||
Add category names as keywords, eg; "thriller", "war".
|
||||
Movies can be in multiple categories, if a movie is in 5 categories it only has to match one to be filtered out.
|
||||
|
||||
TORRENT TRACKERS:
|
||||
Only used for The Pirate Bay and YTS.
|
||||
These are added to the magnet links Goosle creates. You can add more or replace the existing ones.
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
return (object) array(
|
||||
"hash" => "blja-3jaq-34eg",
|
||||
"cache" => "off",
|
||||
"cache_time" => 30, // (Default: 30)
|
||||
"hash_auth" => "off", // Default: off)
|
||||
"raw_output" => "off", // (Default: off)
|
||||
|
||||
"enable_torrent_search" => "on", // (Default: on)
|
||||
"enable_image_search" => "on", // (Default: on)
|
||||
|
||||
"special" => array(
|
||||
"currency" => "on", // Currency converter
|
||||
"definition" => "on", // Word dictionary
|
||||
"wikipedia" => "on", // Wikipedia highlight
|
||||
"phpnet" => "on", // PHP-dot-net highlight
|
||||
"password_generator" => "on" // Password generator on homepage
|
||||
),
|
||||
|
||||
"user_agents" => array(
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15) Gecko/20100101 Firefox/119.0", // macOS 10.15, FF 119
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/116.0", // Windows 10, FF 116
|
||||
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64) Gecko/20100101 Firefox/83.0", // Linux Ubuntu, FF 83
|
||||
"Mozilla/5.0 (X11; Linux i686) Gecko/20100101 Firefox/119.0", // Linux Generic, FF 119
|
||||
),
|
||||
|
||||
"leetx_categories_blocked" => array(3, 7, 47), // Default: 3, 7, 47
|
||||
"piratebay_categories_blocked" => array(206, 210), // Default: 206, 210
|
||||
"yts_categories_blocked" => array("horror"), // Default: "horror"
|
||||
"torrent_trackers" => array(
|
||||
"http://nyaa.tracker.wf:7777/announce",
|
||||
"udp://open.stealth.si:80/announce",
|
||||
"udp://tracker.opentrackr.org:1337/announce",
|
||||
"udp://exodus.desync.com:6969/announce",
|
||||
"udp://tracker.torrent.eu.org:451/announce",
|
||||
),
|
||||
"version" => "1.0",
|
||||
"released" => "Nov 28, 2023"
|
||||
);
|
||||
?>
|
93
engines/duckduckgo.php
Normal file
93
engines/duckduckgo.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class DuckDuckGoRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
$results = array();
|
||||
|
||||
// Split the query
|
||||
$query_terms = explode(" ", strtolower($this->query));
|
||||
|
||||
// Safe search override
|
||||
$safe = "-1";
|
||||
if(strpos($query_terms[0], "safe") !== false) {
|
||||
$switch = explode(":", $query_terms[0]);
|
||||
|
||||
if(!is_numeric($switch[1])) {
|
||||
$safe = ($switch[1] == "on") ? "1" : "-2";
|
||||
|
||||
$this->query = implode(" ", array_slice($query_terms, 1));
|
||||
}
|
||||
}
|
||||
|
||||
// q = query
|
||||
// kz = Instant answers (1 = on, -1 = off)
|
||||
// kc = Autoload images (1 = on, -1 = off)
|
||||
// kav = Autoload results (1 = on, -1 = off)
|
||||
// kf = Favicons (1 = on, -1 = off)
|
||||
// kaf = Full URLs (1 = on, -1 = off)
|
||||
// kac = Auto suggest (1 = on, -1 = off)
|
||||
// kd = Redirects (1 = on, -1 = off)
|
||||
// kh = HTTPS (1 = on, -1 = off)
|
||||
// kg = Get/Post (g = GET, p = POST)
|
||||
// kp = Safe search (1 = on, -1 = moderate, -2 = off (may include nsfw/illegal content))
|
||||
// k1 = Ads (1 = on, -1 = off)
|
||||
// More here: https://duckduckgo.com/duckduckgo-help-pages/settings/params/
|
||||
|
||||
$args = array("q" => $this->query, "kz" => "-1", "kc" => "-1", "kav" => "-1", "kf" => "-1", "kaf" => "1", "kac" => "-1", "kd" => "-1", "kh" => "1", "kg" => "g", "kp" => $safe, "k1" => "-1");
|
||||
$url = "https://html.duckduckgo.com/html/?".http_build_query($args);
|
||||
|
||||
unset($query_terms, $switch, $args, $safe);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
if(!$xpath) return $results;
|
||||
|
||||
$didyoumean = $xpath->query(".//div[@id='did_you_mean']/a[1]")[0];
|
||||
if(!is_null($didyoumean)) {
|
||||
array_push($results, array("did_you_mean" => $didyoumean->textContent));
|
||||
}
|
||||
$search_specific = $xpath->query(".//div[@id='did_you_mean']/a[2]")[0];
|
||||
if(!is_null($search_specific)) {
|
||||
array_push($results, array("search_specific" => $search_specific->textContent));
|
||||
}
|
||||
|
||||
foreach($xpath->query("/html/body/div[1]/div[". count($xpath->query('/html/body/div[1]/div')) ."]/div/div/div[contains(@class, 'web-result')]/div") as $result) {
|
||||
$url = $xpath->evaluate(".//h2[@class='result__title']//a/@href", $result)[0];
|
||||
if($url == null) continue;
|
||||
|
||||
if(!empty($results)) { // filter duplicate urls/results
|
||||
$result_urls = array_column($results, "url");
|
||||
if(in_array($url->textContent, $result_urls) || in_array(get_base_url($url->textContent), $result_urls)) continue;
|
||||
}
|
||||
|
||||
$title = $xpath->evaluate(".//h2[@class='result__title']", $result)[0];
|
||||
if($title == null) continue;
|
||||
|
||||
$description = $xpath->evaluate(".//a[@class='result__snippet']", $result)[0];
|
||||
|
||||
array_push($results, array (
|
||||
"title" => htmlspecialchars($title->textContent),
|
||||
"url" => htmlspecialchars($url->textContent),
|
||||
"description" => $description == null ? 'No description was provided for this site.' : htmlspecialchars($description->textContent)
|
||||
));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
112
engines/google.php
Normal file
112
engines/google.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class GoogleRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
$results = array();
|
||||
|
||||
// Split the query
|
||||
$query_terms = explode(" ", strtolower($this->query));
|
||||
|
||||
// Category search
|
||||
$cat = null;
|
||||
if($query_terms[0] == 'app') {
|
||||
$cat = 'app';
|
||||
} else if($query_terms[0] == 'book') {
|
||||
$cat = 'bks';
|
||||
} else if($query_terms[0] == 'news') {
|
||||
$cat = 'nws';
|
||||
} else if($query_terms[0] == 'shop') {
|
||||
$cat = 'shop';
|
||||
} else if($query_terms[0] == 'patent') {
|
||||
$cat = 'pts';
|
||||
}
|
||||
|
||||
// Language override
|
||||
$lang = null;
|
||||
if(strpos($query_terms[0], "lang") !== false) {
|
||||
$switch = explode(":", $query_terms[0]);
|
||||
|
||||
if(strlen($switch[1]) == 2 && !is_numeric($switch[1])) {
|
||||
$lang = "lang_".$switch[1];
|
||||
|
||||
$this->query = implode(" ", array_slice($query_terms, 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Safe search override
|
||||
$safe = 1;
|
||||
if(strpos($query_terms[0], "safe") !== false) {
|
||||
$switch = explode(":", $query_terms[0]);
|
||||
|
||||
if(!is_numeric($switch[1])) {
|
||||
$safe = ($switch[1] == "on") ? "2" : "0";
|
||||
|
||||
$this->query = implode(" ", array_slice($query_terms, 1));
|
||||
}
|
||||
}
|
||||
|
||||
// q = query
|
||||
// safe = Safe search (Default 1) 0 = off (may include nsfw/illegal content), 1 = moderate, 2 = on/strict
|
||||
// lr = Language (lang_XX, optional)
|
||||
// tbm = Category search (app, bks (books), isch (images), vid, nws (News), shop, pts (Patents))
|
||||
// pws = Personal search results on|off (Default 0, off)
|
||||
// num = Number of results per page (number, multiple on 10 usually)
|
||||
// start = Start position in search (Kind of like pages) (number, multiple on 10|15 usually)
|
||||
|
||||
$args = array("q" => $this->query, "safe" => $safe, "lr" => (!is_null($lang)) ? $lang : '', "tbm" => (!is_null($cat)) ? $cat : '', "pws" => 0, "num" => 20, "start" => 0);
|
||||
$url = "https://www.google.com/search?".http_build_query($args);
|
||||
|
||||
unset($query_terms, $switch, $args, $cat, $lang, $safe);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
if(!$xpath) return $results;
|
||||
|
||||
$didyoumean = $xpath->query(".//a[@class='gL9Hy']")[0];
|
||||
if(!is_null($didyoumean)) {
|
||||
array_push($results, array("did_you_mean" => $didyoumean->textContent));
|
||||
}
|
||||
$search_specific = $xpath->query(".//a[@class='spell_orig']")[0];
|
||||
if(!is_null($search_specific)) {
|
||||
array_push($results, array("search_specific" => $search_specific->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 urls/results
|
||||
$result_urls = array_column($results, "url");
|
||||
if(in_array($url->textContent, $result_urls) OR in_array(get_base_url($url->textContent), $result_urls)) continue;
|
||||
}
|
||||
|
||||
$title = $xpath->evaluate(".//h3", $result)[0];
|
||||
if($title == null) continue;
|
||||
|
||||
$description = $xpath->evaluate(".//div[contains(@class, 'VwiC3b')]", $result)[0];
|
||||
|
||||
array_push($results, array (
|
||||
"title" => htmlspecialchars($title->textContent),
|
||||
"url" => htmlspecialchars($url->textContent),
|
||||
"description" => $description == null ? 'No description was provided for this site.' : htmlspecialchars($description->textContent)
|
||||
));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
?>
|
117
engines/search-image.php
Normal file
117
engines/search-image.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
class ImageSearch extends EngineRequest {
|
||||
|
||||
public function get_request_url() {
|
||||
$results = array();
|
||||
|
||||
// Split the query
|
||||
$query_terms = explode(" ", strtolower($this->query));
|
||||
|
||||
// Size override
|
||||
$size = "";
|
||||
if($query_terms[0] == 'size') {
|
||||
$switch = explode(":", $query_terms[0]);
|
||||
|
||||
if((strlen($switch[1]) >= 3 && strlen($switch[1]) <= 6) && !is_numeric($switch[1])) {
|
||||
if($switch[1] == "med") $switch[1] = "medium";
|
||||
if($switch[1] == "lrg") $switch[1] = "large";
|
||||
|
||||
if($switch[1] == "small" || $switch[1] == "medium" || $switch[1] == "large") {
|
||||
$size = $switch[1];
|
||||
}
|
||||
|
||||
$this->query = implode(" ", array_slice($query_terms, 1));
|
||||
}
|
||||
}
|
||||
|
||||
// q = query
|
||||
// t = Search type (images)
|
||||
// size = Preferred image size (small|medium|large)
|
||||
|
||||
$args = array("q" => $this->query, "t" => "images", "size" => $size);
|
||||
$url = "https://lite.qwant.com?".http_build_query($args);
|
||||
|
||||
unset($query_terms, $switch, $args, $size);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array("search" => array());
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
if(!$xpath) return $results;
|
||||
|
||||
foreach($xpath->query("//a[@rel='noopener']") as $result) {
|
||||
$meta = $xpath->evaluate(".//img", $result)[0];
|
||||
|
||||
if($meta) {
|
||||
$encoded_url = explode("?position", explode("==/", $result->getAttribute("href"))[1])[0];
|
||||
|
||||
$url = htmlspecialchars(urldecode(base64_decode($encoded_url)));
|
||||
$alt_text = get_base_url($url)." - ".htmlspecialchars($meta->getAttribute("alt"));
|
||||
$image = urldecode(htmlspecialchars(urlencode($meta->getAttribute("src"))));
|
||||
|
||||
// filter duplicate urls/results
|
||||
if(!empty($results)) {
|
||||
$result_urls = array_column($results, "url");
|
||||
if(in_array($url, $result_urls) || in_array(get_base_url($url), $result_urls)) continue;
|
||||
}
|
||||
|
||||
array_push($results["search"], array (
|
||||
"alt" => $alt_text,
|
||||
"image" => $image,
|
||||
"url" => $url,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Add warning if there are no results, or a text if there is no search query.
|
||||
if(empty($results['search'])) {
|
||||
$results["error"] = array(
|
||||
"message" => "No results found. Please try with less or different keywords!"
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function print_results($results, $opts) {
|
||||
if($opts->raw_output == "on") {
|
||||
echo '<pre>Results: ';
|
||||
print_r($results);
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
echo "<section class=\"main-column\">";
|
||||
echo "<ol>";
|
||||
|
||||
// Elapsed time
|
||||
if(array_key_exists("search", $results)) {
|
||||
echo "<li class=\"meta-time\">Fetched the results in ".$results['time']." seconds.</li>";
|
||||
}
|
||||
|
||||
echo "</ol>";
|
||||
|
||||
echo "<div class=\"image-wrapper\">";
|
||||
echo "<ol class=\"image-grid\">";
|
||||
|
||||
// Search results
|
||||
if(array_key_exists("search", $results)) {
|
||||
foreach($results['search'] as $result) {
|
||||
if(!array_key_exists("url", $result) || !array_key_exists("alt", $result)) continue;
|
||||
|
||||
// Put result together
|
||||
echo "<li class=\"result\"><div class=\"image-box\">";
|
||||
echo "<a href=\"".$result["url"]."\" target=\"_blank\" title=\"".$result["alt"]."\"><img src=\"".$result["image"]."\" alt=\"".$result["alt"]."\" /></a>";
|
||||
echo "</div></li>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</ol>";
|
||||
echo "</div>";
|
||||
echo "<center><small>Not what you're looking for? Try <a href=\"https://duckduckgo.com/?q=".urlencode($opts->query)."&iax=images&ia=images\" target=\"_blank\">DuckDuckGo</a> or <a href=\"https://www.google.com/search?q=".urlencode($opts->query)."&tbm=isch&pws=0\" target=\"_blank\">Google Images</a>.</small></center>";
|
||||
echo "</section>";
|
||||
}
|
||||
}
|
||||
?>
|
109
engines/search-torrent.php
Normal file
109
engines/search-torrent.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class TorrentSearch extends EngineRequest {
|
||||
protected $requests;
|
||||
|
||||
public function __construct($opts, $mh) {
|
||||
$this->opts = $opts;
|
||||
$this->url = 'torrent'; // Dummy value to satisfy EngineRequest::get_results()
|
||||
|
||||
require "engines/torrent/1337x.php";
|
||||
require "engines/torrent/nyaa.php";
|
||||
require "engines/torrent/thepiratebay.php";
|
||||
require "engines/torrent/yts.php";
|
||||
|
||||
$this->requests = array(
|
||||
new LeetxRequest($opts, $mh), // 1337x
|
||||
new NyaaRequest($opts, $mh),
|
||||
new PirateBayRequest($opts, $mh),
|
||||
new YTSRequest($opts, $mh)
|
||||
);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = $results_temp = array();
|
||||
|
||||
foreach ($this->requests as $request) {
|
||||
if($request->request_successful()) {
|
||||
$results_temp = array_merge($results_temp, $request->get_results());
|
||||
}
|
||||
}
|
||||
|
||||
if(count($results_temp) > 0) {
|
||||
// Ensure highest seeders are shown first
|
||||
$seeders = array_column($results_temp, "seeders");
|
||||
array_multisort($seeders, SORT_DESC, $results_temp);
|
||||
|
||||
// Cap results
|
||||
$results['search'] = array_slice($results_temp, 0, 50);
|
||||
unset($results_temp);
|
||||
}
|
||||
|
||||
// Add warning if there are no results
|
||||
if(empty($results)) {
|
||||
$results["error"] = array(
|
||||
"message" => "No results found. Please try with less or different keywords!"
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function print_results($results, $opts) {
|
||||
if($opts->raw_output == "on") {
|
||||
echo '<pre>Results: ';
|
||||
print_r($results);
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
echo "<section class=\"main-column\">";
|
||||
echo "<ol>";
|
||||
|
||||
// Elapsed time
|
||||
echo "<li class=\"meta-time\">Fetched the results in ".$results['time']." seconds.</li>";
|
||||
|
||||
// No results found
|
||||
if(array_key_exists("error", $results)) {
|
||||
echo "<li class=\"meta-error\">".$results['error']['message']."</li>";
|
||||
}
|
||||
|
||||
// Search results
|
||||
if(array_key_exists("search", $results)) {
|
||||
foreach($results['search'] as $result) {
|
||||
$meta = array();
|
||||
// Optional data
|
||||
if(array_key_exists('quality', $result)) $meta[] = "<strong>Quality:</strong> ".$result['quality'];
|
||||
if(array_key_exists('year', $result)) $meta[] = "<strong>Year:</strong> ".$result['year'];
|
||||
if(array_key_exists('category', $result)) $meta[] = "<strong>Category:</strong> ".$result['category'];
|
||||
if(array_key_exists('runtime', $result)) $meta[] = "<strong>Runtime:</strong> ".date('H:i', mktime(0, $result['runtime']));
|
||||
if(array_key_exists('date_added', $result)) $meta[] = "<strong>Added:</strong> ".date('M d, Y', $result['date_added']);
|
||||
if(array_key_exists('url', $result)) $meta[] = "<a href=\"".$result["url"]."\" target=\"_blank\" title=\"Careful - Site may contain intrusive popup ads and malware!\">Torrent page</a>";
|
||||
|
||||
// Put result together
|
||||
echo "<li class=\"result\"><article>";
|
||||
echo "<div class=\"url\"><a href=\"".$result["magnet"]."\" target=\"_blank\">".$result["source"]."</a></div>";
|
||||
echo "<div class=\"title\"><a href=\"".$result["magnet"]."\" target=\"_blank\"><h2>".stripslashes($result["name"])."</h2></a></div>";
|
||||
echo "<div class=\"description\"><strong>Seeds:</strong> <span class=\"seeders\">".$result['seeders']."</span> - <strong>Peers:</strong> <span class=\"leechers\">".$result['leechers']."</span> - <strong>Size:</strong> ".$result['size']."<br />".implode(" - ", $meta)."</div>";
|
||||
echo "</article></li>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "<li class=\"result\"><article>";
|
||||
echo "<small>Goosle does not store, index, offer or distribute torrent files.</small>";
|
||||
echo "</article></li>";
|
||||
|
||||
echo "</ol>";
|
||||
echo "<center><small>Showing 50 results, sorted by most seeders.</small></center>";
|
||||
echo "</section>";
|
||||
}
|
||||
}
|
||||
?>
|
164
engines/search.php
Normal file
164
engines/search.php
Normal file
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class TextSearch extends EngineRequest {
|
||||
protected $engine, $engine_request, $special_request;
|
||||
|
||||
public function __construct($opts, $mh) {
|
||||
$this->query = $opts->query;
|
||||
$this->opts = $opts;
|
||||
|
||||
if($this->opts->type == 0) {
|
||||
require "engines/duckduckgo.php";
|
||||
$this->engine_request = new DuckDuckGoRequest($opts, $mh);
|
||||
}
|
||||
|
||||
if($this->opts->type == 1) {
|
||||
require "engines/google.php";
|
||||
$this->engine_request = new GoogleRequest($opts, $mh);
|
||||
}
|
||||
|
||||
// Special search
|
||||
$this->special_request = special_search_request($opts);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
|
||||
// Abort if no results from search engine
|
||||
if(!isset($this->engine_request)) return $results;
|
||||
|
||||
// Add search results
|
||||
$success = $this->engine_request->request_successful();
|
||||
if($success == "ok") {
|
||||
$search_result = $this->engine_request->get_results();
|
||||
|
||||
if($search_result) {
|
||||
$results['search'] = $search_result;
|
||||
}
|
||||
unset($search_result);
|
||||
} else {
|
||||
$results["error"] = array(
|
||||
"message" => $success
|
||||
);
|
||||
}
|
||||
|
||||
// Check for Special result
|
||||
if($this->special_request) {
|
||||
$special_result = $this->special_request->get_results();
|
||||
|
||||
if($special_result) {
|
||||
$results['special'] = $special_result;
|
||||
}
|
||||
unset($special_result);
|
||||
}
|
||||
|
||||
// Add warning if there are no results, or a text if there is no search query.
|
||||
if(empty($results)) {
|
||||
$results["error"] = array(
|
||||
"message" => "No results found. Please try with less or different keywords!"
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function print_results($results, $opts) {
|
||||
if($opts->raw_output == "on") {
|
||||
echo '<pre>Results: ';
|
||||
print_r($results);
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
echo "<section class=\"main-column\">";
|
||||
echo "<ol>";
|
||||
|
||||
// Elapsed time
|
||||
if(array_key_exists("search", $results)) {
|
||||
$number_of_results = count($results['search']);
|
||||
echo "<li class=\"meta-time\">Fetched ".$number_of_results." results in ".$results['time']." seconds.</li>";
|
||||
}
|
||||
|
||||
// No results found
|
||||
if(array_key_exists("error", $results)) {
|
||||
echo "<li class=\"meta-error\">".$results['error']['message']."</li>";
|
||||
}
|
||||
|
||||
// Did you mean/Search suggestion
|
||||
if(array_key_exists("search", $results)) {
|
||||
$specific_result = "";
|
||||
|
||||
if(array_key_exists("did_you_mean", $results['search'][0])) {
|
||||
if(array_key_exists("search_specific", $results['search'][1])) {
|
||||
// Add double quotes to Google search
|
||||
$search_specific = ($opts->type == 1) ? "\"".$results['search'][1]['search_specific']."\"" : $results['search'][1]['search_specific'];
|
||||
$search_specific_url = "./results.php?q=" . urlencode($search_specific)."&t=".$opts->type."&a=".$opts->hash;
|
||||
$specific_result = "<br /><small>Or instead search for <a href=\"$search_specific_url\">$search_specific</a>.</small>";
|
||||
|
||||
unset($results['search'][1], $search_specific, $search_specific_url);
|
||||
}
|
||||
|
||||
$didyoumean = $results['search'][0]['did_you_mean'];
|
||||
$didyoumean_url = "./results.php?q=" . urlencode($didyoumean)."&t=".$opts->type."&a=".$opts->hash;
|
||||
|
||||
echo "<li class=\"meta-did-you-mean\">Did you mean <a href=\"$didyoumean_url\">$didyoumean</a>?$specific_result</li>";
|
||||
|
||||
unset($results['search'][0], $didyoumean, $didyoumean_url, $specific_result);
|
||||
}
|
||||
}
|
||||
|
||||
// Special result
|
||||
if(array_key_exists("special", $results)) {
|
||||
echo "<li class=\"special-result\"><article>";
|
||||
// Maybe shorten text
|
||||
if(strlen($results['special']['text']) > 1250) {
|
||||
$results['special']['text'] = substr($results['special']['text'], 0, strrpos(substr($results['special']['text'], 0, 1300), ". "));
|
||||
$results['special']['text'] .= '. <a href="'.$results['special']['source'].'" target="_blank">[...]</a>';
|
||||
}
|
||||
|
||||
// Add image to text
|
||||
if(array_key_exists("image", $results['special'])) {
|
||||
$image_specs = getimagesize($results['special']['image']);
|
||||
$width = $image_specs[0] / 2;
|
||||
$height = $image_specs[1] / 2;
|
||||
|
||||
$special_image = "<img src=\"".$results['special']['image']."\" align=\"right\" width=\"".$width."\" height=\"".$height."\" />";
|
||||
$results['special']['text'] = $special_image.$results['special']['text'];
|
||||
|
||||
unset($image_specs, $width, $height, $special_image);
|
||||
}
|
||||
echo "<div class=\"title\"><h2>".$results['special']['title']."</h2></div>";
|
||||
echo "<div class=\"text\">".$results['special']['text']."</div>";
|
||||
if(array_key_exists("source", $results['special'])) {
|
||||
echo "<div class=\"source\"><a href=\"".$results['special']['source']."\" target=\"_blank\">".$results['special']['source']."</a></div>";
|
||||
}
|
||||
echo "</article></li>";
|
||||
}
|
||||
|
||||
// Search results
|
||||
if(array_key_exists("search", $results)) {
|
||||
foreach($results['search'] as $result) {
|
||||
if(array_key_exists("did_you_mean", $result)) continue;
|
||||
|
||||
// Put result together
|
||||
echo "<li class=\"result\"><article>";
|
||||
echo "<div class=\"url\"><a href=\"".$result["url"]."\" target=\"_blank\">".get_formatted_url($result["url"])."</a></div>";
|
||||
echo "<div class=\"title\"><a href=\"".$result["url"]."\" target=\"_blank\"><h2>".$result["title"]."</h2></a></div>";
|
||||
echo "<div class=\"description\">".$result["description"]."</div>";
|
||||
echo "</article></li>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</ol>";
|
||||
echo "</section>";
|
||||
}
|
||||
}
|
||||
?>
|
55
engines/special/currency.php
Normal file
55
engines/special/currency.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class CurrencyRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
return "https://cdn.moneyconvert.net/api/latest.json";
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$json_response = json_decode($response, true);
|
||||
|
||||
if(!empty($json_response)) {
|
||||
$result = $json_response["rates"];
|
||||
|
||||
// Process query
|
||||
// [0] = AMOUNT
|
||||
// [1] = FROM CURRENCY
|
||||
// [2] = (to|in)
|
||||
// [3] = TO CURRENCY
|
||||
|
||||
$query_terms = explode(" ", $this->query);
|
||||
$amount = floatval($query_terms[0]);
|
||||
$amount_currency = strtoupper($query_terms[1]);
|
||||
$conversion_currency = strtoupper($query_terms[3]);
|
||||
|
||||
// Unknown/misspelled currencies
|
||||
if (!array_key_exists($amount_currency, $result) || !array_key_exists($conversion_currency, $result)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Calculate exchange rate
|
||||
$conversion = round(($result[$conversion_currency] / $result[$amount_currency]) * $amount, 4);
|
||||
|
||||
return array(
|
||||
"title" => "Currency conversion:",
|
||||
"text" => "$amount $amount_currency = $conversion $conversion_currency",
|
||||
"source" => "https://moneyconvert.net/"
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
"title" => "Uh-oh...",
|
||||
"text" => "No exchange rates could be loaded. Try again later."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
58
engines/special/definition.php
Normal file
58
engines/special/definition.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class DefinitionRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
$query_terms = explode(" ", $this->query);
|
||||
|
||||
// [0] = (define|d|mean|meaning)
|
||||
// [1] = WORD
|
||||
|
||||
return "https://api.dictionaryapi.dev/api/v2/entries/en/".$query_terms[1];
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$json_response = json_decode($response, true);
|
||||
|
||||
if(!empty($json_response)) {
|
||||
// Word not found
|
||||
if (array_key_exists("title", $json_response)) {
|
||||
return array(
|
||||
"title" => strip_tags(trim($json_response['title'])),
|
||||
"text" => strip_tags(trim($json_response['message']))
|
||||
);
|
||||
}
|
||||
|
||||
// Grab first result if there are multiple
|
||||
$result = $json_response[0];
|
||||
$definitions = array_slice($result['meanings'][0]['definitions'], 0, 3);
|
||||
|
||||
// Word found
|
||||
$formatted_response = strip_tags(trim($result['meanings'][0]['partOfSpeech']))."<br /><ol class=\"word-definitions\">";
|
||||
foreach($definitions as $key => $def) {
|
||||
$formatted_response .= "<li>".strip_tags(trim($def['definition']))."</li>";
|
||||
}
|
||||
$formatted_response .= "</ol>";
|
||||
|
||||
return array(
|
||||
"title" => strip_tags(trim($result['word']))." <span>[".strip_tags(trim($result['phonetic']))."]</span>",
|
||||
"text" => $formatted_response,
|
||||
"source" => strip_tags(trim($result['sourceUrls'][0]))
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
"title" => "Whoops...",
|
||||
"text" => "No definitions could be loaded. Try again later."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
47
engines/special/php.php
Normal file
47
engines/special/php.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class PHPnetRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
$this->query = str_replace("_", "-", str_replace("php ", "", $this->query));
|
||||
|
||||
return "https://www.php.net/manual/function.".urlencode($this->query);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
if($xpath) {
|
||||
// Scrape the page
|
||||
$title = $xpath->query("//div/section/div[@class='refentry']/div/h1[@class='refname']")[0]->textContent;
|
||||
if(is_null($title)) return array();
|
||||
$php_versions = $xpath->query("//div/section/div[@class='refentry']/div/p[@class='verinfo']")[0]->textContent;
|
||||
$purpose = $xpath->query("//div/section/div[@class='refentry']/div/p[@class='refpurpose']")[0]->textContent;
|
||||
$usage = $xpath->query("//div/section/div[@class='refentry']/div[@class='refsect1 description']/div[@class='methodsynopsis dc-description']")[0]->textContent;
|
||||
|
||||
$response = array (
|
||||
// Required
|
||||
"title" => sanitize($title),
|
||||
"text" => "<p>".$purpose." <em><small>".$php_versions."</small></em></p><p>".highlight_string("<?php ".trim($usage)." ?>", 1)."</p>",
|
||||
"source" => "https://www.php.net/manual/function.".urlencode($this->query)
|
||||
);
|
||||
|
||||
return $response;
|
||||
} else {
|
||||
return array(
|
||||
"title" => "Oof...",
|
||||
"text" => "PHP.net didn't provide any answers. Try again later."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
66
engines/special/wikipedia.php
Normal file
66
engines/special/wikipedia.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class WikipediaRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
$query_terms = explode(" ", $this->query);
|
||||
|
||||
// [0] = (wiki|w)
|
||||
// [1] = SEARCH TERM
|
||||
|
||||
unset($query_terms[0]); // Remove first item (w or wiki) from array and encode the rest for Wikipedia
|
||||
$this->query = implode(" ", $query_terms);
|
||||
|
||||
return "https://wikipedia.org/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=".urlencode($this->query);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$json_response = json_decode($response, true);
|
||||
|
||||
if(!empty($json_response)) {
|
||||
$result = $json_response['query']['pages'];
|
||||
|
||||
// Abort on invalid response
|
||||
if (!is_array($result)) return array();
|
||||
|
||||
// Grab first result if there are multiple
|
||||
$result = $result[array_key_first($result)];
|
||||
|
||||
// Page not found
|
||||
if (array_key_exists("missing", $result)) {
|
||||
return array(
|
||||
"title" => "Wiki page not found",
|
||||
"text" => "Maybe the page doesn't exist. Try searching on Wikipedia with the link below or search for something else.",
|
||||
"source" => "https://wikipedia.org/wiki/Special:Search?go=Go&search=".urlencode($this->query)
|
||||
);
|
||||
}
|
||||
|
||||
// Page found
|
||||
$response = array(
|
||||
"title" => strip_tags(trim($result['title'])),
|
||||
"text" => strip_tags(trim($result['extract'])),
|
||||
"source" => "https://wikipedia.org/wiki/".urlencode($this->query)
|
||||
);
|
||||
|
||||
if (array_key_exists("thumbnail", $result)) {
|
||||
$response["image"] = strip_tags(trim($result["thumbnail"]["source"]));
|
||||
}
|
||||
|
||||
return $response;
|
||||
} else {
|
||||
return array(
|
||||
"title" => "Sigh...",
|
||||
"text" => "Wikipedia could not be loaded. Try again later."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
142
engines/torrent/1337x.php
Normal file
142
engines/torrent/1337x.php
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class LeetxRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
return "https://1337x.to/search/".urlencode($this->query)."/1/";
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
// Failted to load page
|
||||
if(!$xpath) return $results;
|
||||
|
||||
$categories = array(
|
||||
1 => "DVD",
|
||||
2 => "Divx/Xvid",
|
||||
3 => "SVCD/VCD",
|
||||
4 => "Dubs/Dual Audio",
|
||||
5 => "DVD",
|
||||
6 => "Divx/Xvid",
|
||||
7 => "SVCD/VCD",
|
||||
9 => "Documentary",
|
||||
|
||||
10 => "PC Game",
|
||||
11 => "PS2",
|
||||
12 => "PSP",
|
||||
13 => "Xbox",
|
||||
14 => "Xbox360",
|
||||
15 => "PS1",
|
||||
16 => "Dreamcast",
|
||||
17 => "Other (Gaming)",
|
||||
18 => "PC Software",
|
||||
19 => "Mac Software",
|
||||
|
||||
20 => "Linux Software",
|
||||
21 => "Other (Software)",
|
||||
22 => "MP3",
|
||||
23 => "Lossless Audio",
|
||||
24 => "DVD (Music)",
|
||||
25 => "Music Video",
|
||||
26 => "Radio",
|
||||
27 => "Other (Audio)",
|
||||
28 => "Anime",
|
||||
|
||||
33 => "Emulation",
|
||||
34 => "Tutorials",
|
||||
35 => "Sounds",
|
||||
36 => "E-Books",
|
||||
37 => "Images",
|
||||
38 => "Mobile Phone",
|
||||
39 => "Comics",
|
||||
|
||||
40 => "Other",
|
||||
41 => "HD (Video)",
|
||||
42 => "HD (Video)",
|
||||
43 => "PS3",
|
||||
44 => "Wii",
|
||||
45 => "DS",
|
||||
46 => "GameCube",
|
||||
47 => "Nulled Script",
|
||||
48 => "Video",
|
||||
49 => "Picture",
|
||||
|
||||
50 => "Magazine",
|
||||
51 => "Hentai",
|
||||
52 => "Audiobook",
|
||||
53 => "Album (Music)",
|
||||
54 => "h.264/x264",
|
||||
55 => "Mp4",
|
||||
56 => "Android",
|
||||
57 => "iOS",
|
||||
58 => "Box Set (Music)",
|
||||
59 => "Discography",
|
||||
|
||||
60 => "Single (Music)",
|
||||
66 => "3D",
|
||||
67 => "Games",
|
||||
68 => "Concerts",
|
||||
69 => "AAC (Music)",
|
||||
|
||||
70 => "HEVC/x265",
|
||||
71 => "HEVC/x265",
|
||||
72 => "3DS",
|
||||
73 => "Bollywood",
|
||||
74 => "Cartoon",
|
||||
75 => "SD (Video)",
|
||||
76 => "UHD",
|
||||
77 => "PS4",
|
||||
78 => "Dual Audio (Video)",
|
||||
79 => "Dubbed (Video)",
|
||||
|
||||
80 => "Subbed",
|
||||
81 => "Raw",
|
||||
82 => "Switch",
|
||||
);
|
||||
|
||||
// Scrape the page
|
||||
foreach($xpath->query("//table/tbody/tr") as $result) {
|
||||
$category = $xpath->evaluate(".//td[@class='coll-1 name']/a/@href", $result)[0]->textContent;
|
||||
$category = explode("/", trim($category));
|
||||
|
||||
// Block these categories
|
||||
if(in_array($category[2], $this->opts->leetx_categories_blocked)) continue;
|
||||
|
||||
$name = $xpath->evaluate(".//td[@class='coll-1 name']/a", $result)[1]->textContent;
|
||||
$seeders = $xpath->evaluate(".//td[@class='coll-2 seeds']", $result)[0]->textContent;
|
||||
$leechers = $xpath->evaluate(".//td[@class='coll-3 leeches']", $result)[0]->textContent;
|
||||
$date_added = explode(" ", sanitize($xpath->evaluate(".//td[@class='coll-date']", $result)[0]->textContent));
|
||||
$date_added = mktime(0, 0, 0, date("m", strtotime($date_added[0])), preg_replace('/[^\d.]+/', '', $date_added[1]), intval('20'.preg_replace('/[^\d.]+/', '', $date_added[2])));
|
||||
$url = "https://1337x.to".sanitize($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]);
|
||||
|
||||
array_push($results, array (
|
||||
// Required
|
||||
"source" => "1337x.to",
|
||||
"name" => sanitize($name),
|
||||
"magnet" => "./engines/torrent/magnetize_1337x.php?url=".$url,
|
||||
"seeders" => sanitize($seeders),
|
||||
"leechers" => sanitize($leechers),
|
||||
"size" => sanitize($size),
|
||||
// Optional values
|
||||
"category" => $categories[sanitize($category[2])],
|
||||
"url" => $url,
|
||||
"date_added" => $date_added
|
||||
));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
?>
|
49
engines/torrent/magnetize_1337x.php
Normal file
49
engines/torrent/magnetize_1337x.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
require "../../misc/tools.php";
|
||||
$opts = require "../../config.php";
|
||||
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($this->ch, CURLOPT_URL, $_REQUEST["url"]);
|
||||
curl_setopt($this->ch, CURLOPT_HTTPGET, 1); // Redundant? Probably...
|
||||
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($this->ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($this->ch, CURLOPT_USERAGENT, $opts->user_agents[array_rand($opts->user_agents)]);
|
||||
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array(
|
||||
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Language: en-US,en;q=0.5',
|
||||
'Upgrade-Insecure-Requests: 1'
|
||||
));
|
||||
curl_setopt($this->ch, CURLOPT_ENCODING, "gzip,deflate");
|
||||
curl_setopt($this->ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
|
||||
curl_setopt($this->ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
|
||||
curl_setopt($this->ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
|
||||
curl_setopt($this->ch, CURLOPT_MAXREDIRS, 5);
|
||||
curl_setopt($this->ch, CURLOPT_TIMEOUT, 3);
|
||||
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
// No results
|
||||
if(!$xpath) die();
|
||||
|
||||
$magnet = $xpath->query("//main/div/div/div/div/div/ul/li/a/@href")[0]->textContent;
|
||||
$magnet = trim($magnet);
|
||||
|
||||
header("Location: $magnet")
|
||||
?>
|
56
engines/torrent/nyaa.php
Normal file
56
engines/torrent/nyaa.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class NyaaRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
return "https://nyaa.si/?q=".urlencode($this->query);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$xpath = get_xpath($response);
|
||||
|
||||
// Failted to load page
|
||||
if(!$xpath) return $results;
|
||||
|
||||
// Scrape the page
|
||||
foreach($xpath->query("//tbody/tr") as $result) {
|
||||
$category = $xpath->evaluate(".//td[1]//a/@title", $result)[0]->textContent;
|
||||
$name = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result)[0]->textContent;
|
||||
$url = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@href", $result)[0]->textContent;
|
||||
$meta = $xpath->evaluate(".//td[@class='text-center']", $result);
|
||||
$seeders = $meta[3]->textContent;
|
||||
$leechers = $meta[4]->textContent;
|
||||
$size = $meta[1]->textContent;
|
||||
$date_added = $meta[2]->textContent;
|
||||
$date_added = explode("-", substr(sanitize($date_added), 0, 10));
|
||||
$date_added = mktime(0, 0, 0, $date_added[1], $date_added[2], $date_added[0]);
|
||||
$magnet = $xpath->evaluate(".//a[2]/@href", $meta[0])[0]->textContent;
|
||||
|
||||
array_push($results, array (
|
||||
// Required
|
||||
"source" => "nyaa.si",
|
||||
"name" => sanitize($name),
|
||||
"magnet" => sanitize($magnet),
|
||||
"seeders" => sanitize($seeders),
|
||||
"leechers" => sanitize($leechers),
|
||||
"size" => sanitize($size),
|
||||
// Optional values
|
||||
"category" => str_replace(" - ", "/", sanitize($category)),
|
||||
"url" => "https://nyaa.si".sanitize($url),
|
||||
"date_added" => $date_added
|
||||
));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
?>
|
115
engines/torrent/thepiratebay.php
Normal file
115
engines/torrent/thepiratebay.php
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
class PirateBayRequest extends EngineRequest {
|
||||
public function get_request_url() {
|
||||
return "https://apibay.org/q.php?q=".urlencode($this->query);
|
||||
}
|
||||
|
||||
public function parse_results($response) {
|
||||
$results = array();
|
||||
$json_response = json_decode($response, true);
|
||||
|
||||
// No response
|
||||
if(empty($json_response)) return $results;
|
||||
|
||||
$categories = array(
|
||||
100 => "Audio",
|
||||
101 => "Music",
|
||||
102 => "Audio Book",
|
||||
103 => "Sound Clips",
|
||||
104 => "Audio FLAC",
|
||||
199 => "Audio Other",
|
||||
|
||||
200 => "Video",
|
||||
201 => "Movie",
|
||||
202 => "Movie DVDr",
|
||||
203 => "Music Video",
|
||||
204 => "Movie Clip",
|
||||
205 => "TV Show",
|
||||
206 => "Handheld",
|
||||
207 => "HD Movie",
|
||||
208 => "HD TV Show",
|
||||
209 => "3D Movie",
|
||||
210 => "CAM/TS",
|
||||
211 => "UHD/4K Movie",
|
||||
212 => "UHD/4K TV Show",
|
||||
299 => "Video Other",
|
||||
|
||||
300 => "Applications",
|
||||
301 => "Apps Windows",
|
||||
302 => "Apps Apple",
|
||||
303 => "Apps Unix",
|
||||
304 => "Apps Handheld",
|
||||
305 => "Apps iOS",
|
||||
306 => "Apps Android",
|
||||
399 => "Apps Other OS",
|
||||
|
||||
400 => "Games",
|
||||
401 => "Games PC",
|
||||
402 => "Games Apple",
|
||||
403 => "Games PSx",
|
||||
404 => "Games XBOX360",
|
||||
405 => "Games Wii",
|
||||
406 => "Games Handheld",
|
||||
407 => "Games iOS",
|
||||
408 => "Games Android",
|
||||
499 => "Games Other OS",
|
||||
|
||||
500 => "Porn",
|
||||
501 => "Porn Movie",
|
||||
502 => "Porn Movie DVDr",
|
||||
503 => "Porn Pictures",
|
||||
504 => "Porn Games",
|
||||
505 => "Porn HD Movie",
|
||||
506 => "Porn Movie Clip",
|
||||
507 => "Porn UHD/4K Movie",
|
||||
599 => "Porn Other",
|
||||
|
||||
600 => "Other",
|
||||
601 => "Other E-Book",
|
||||
602 => "Other Comic",
|
||||
603 => "Other Pictures",
|
||||
604 => "Other Covers",
|
||||
605 => "Other Physibles",
|
||||
699 => "Other Other"
|
||||
);
|
||||
|
||||
// Use API result
|
||||
foreach($json_response as $response) {
|
||||
// Nothing found
|
||||
if($response["name"] == "No results returned") break;
|
||||
|
||||
// Block these categories
|
||||
if(in_array($response["category"], $this->opts->piratebay_categories_blocked)) continue;
|
||||
|
||||
$name = sanitize($response["name"]);
|
||||
$magnet = "magnet:?xt=urn:btih:".sanitize($response["info_hash"])."&dn=".$name."&tr=".implode("&tr=", $this->opts->torrent_trackers);
|
||||
|
||||
array_push($results, array (
|
||||
// Required
|
||||
"source" => "thepiratebay.org",
|
||||
"name" => $name,
|
||||
"magnet" => $magnet,
|
||||
"seeders" => sanitize($response["seeders"]),
|
||||
"leechers" => sanitize($response["leechers"]),
|
||||
"size" => human_filesize(sanitize($response["size"])),
|
||||
// Optional
|
||||
"category" => $categories[sanitize($response["category"])],
|
||||
"url" => "https://thepiratebay.org/description.php?id=".sanitize($response["id"]),
|
||||
"date_added" => sanitize($response["added"]),
|
||||
));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
?>
|
66
engines/torrent/yts.php
Normal file
66
engines/torrent/yts.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
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 parse_results($response) {
|
||||
$results = array();
|
||||
$response = curl_multi_getcontent($this->ch);
|
||||
$json_response = json_decode($response, true);
|
||||
|
||||
// No response
|
||||
if(empty($json_response)) return $results;
|
||||
|
||||
// Nothing found
|
||||
if($json_response["status"] != "ok" || $json_response["data"]["movie_count"] == 0) return $results;
|
||||
|
||||
// Use API result
|
||||
foreach ($json_response["data"]["movies"] as $movie) {
|
||||
// Prevent gaps
|
||||
if(!array_key_exists("year", $movie)) $movie['year'] = 0;
|
||||
if(!array_key_exists("genres", $movie)) $movie['genres'] = array();
|
||||
if(!array_key_exists("runtime", $movie)) $movie['runtime'] = 0;
|
||||
if(!array_key_exists("url", $movie)) $movie['url'] = '';
|
||||
|
||||
// Block these categories
|
||||
if(array_intersect($movie["genres"], $this->opts->yts_categories_blocked)) continue;
|
||||
|
||||
$name = sanitize($movie["title"]);
|
||||
|
||||
foreach ($movie["torrents"] as $torrent) {
|
||||
$magnet = "magnet:?xt=urn:btih:".sanitize($torrent["hash"])."&dn=".urlencode($name)."&tr=".implode("&tr=", $this->opts->torrent_trackers);
|
||||
|
||||
array_push($results, array (
|
||||
// Required
|
||||
"source" => "yts.mx",
|
||||
"name" => $name,
|
||||
"magnet" => $magnet,
|
||||
"seeders" => sanitize($torrent["seeds"]),
|
||||
"leechers" => sanitize($torrent["peers"]),
|
||||
"size" => sanitize($torrent["size"]),
|
||||
// Optional
|
||||
"quality" => sanitize($torrent["quality"]),
|
||||
"year" => sanitize($movie["year"]),
|
||||
"category" => sanitize(implode(', ', $movie["genres"])),
|
||||
"runtime" => sanitize($movie["runtime"]),
|
||||
"url" => sanitize($movie["url"]),
|
||||
"date_added" => sanitize($movie["date_uploaded_unix"])
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
?>
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
188
functions/search_engine.php
Normal file
188
functions/search_engine.php
Normal file
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
abstract class EngineRequest {
|
||||
protected $url, $query, $opts, $mh, $ch;
|
||||
|
||||
function __construct($opts, $mh) {
|
||||
$this->query = $opts->query;
|
||||
$this->mh = $mh;
|
||||
// Must be in this order :-/
|
||||
$this->opts = $opts;
|
||||
$this->url = $this->get_request_url();
|
||||
|
||||
// No search engine url
|
||||
if(!$this->url) return;
|
||||
|
||||
// Skip if there is a cached result (from earlier search)
|
||||
if($this->opts->cache == "on" && has_cached_results($this->url, $this->opts->hash)) return;
|
||||
|
||||
// Curl
|
||||
$this->ch = curl_init();
|
||||
|
||||
curl_setopt($this->ch, CURLOPT_URL, $this->url);
|
||||
curl_setopt($this->ch, CURLOPT_HTTPGET, 1); // Redundant? Probably...
|
||||
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($this->ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($this->ch, CURLOPT_USERAGENT, $this->opts->user_agents[array_rand($this->opts->user_agents)]);
|
||||
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array(
|
||||
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Language: en-US,en;q=0.5',
|
||||
'Upgrade-Insecure-Requests: 1'
|
||||
));
|
||||
curl_setopt($this->ch, CURLOPT_ENCODING, "gzip,deflate");
|
||||
curl_setopt($this->ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
|
||||
curl_setopt($this->ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
|
||||
curl_setopt($this->ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
|
||||
curl_setopt($this->ch, CURLOPT_MAXREDIRS, 5);
|
||||
curl_setopt($this->ch, CURLOPT_TIMEOUT, 3);
|
||||
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
|
||||
if($mh) curl_multi_add_handle($mh, $this->ch);
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Get search engine url
|
||||
--------------------------------------*/
|
||||
public function get_request_url() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Check if a request to a search engine was successful
|
||||
--------------------------------------*/
|
||||
public function request_successful() {
|
||||
if((isset($this->ch) && curl_getinfo($this->ch)['http_code'] == '200') || has_cached_results($this->url, $this->opts->hash)) {
|
||||
$return = "ok";
|
||||
} else {
|
||||
$return = "Error code ".curl_getinfo($this->ch)['http_code']." for ".curl_getinfo($this->ch)['url'].". <a href=\"".curl_getinfo($this->ch)['url']."\" target=\"_blank\">Go there now</a>.";
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
abstract function parse_results($response);
|
||||
|
||||
/*--------------------------------------
|
||||
// Load search results
|
||||
--------------------------------------*/
|
||||
public function get_results() {
|
||||
|
||||
if(!isset($this->url)) return $this->parse_results(null);
|
||||
|
||||
// Skip if there is a cached result (from earlier search)
|
||||
if($this->opts->cache == "on" && has_cached_results($this->url, $this->opts->hash)) return fetch_cached_results($this->url, $this->opts->hash);
|
||||
|
||||
if(!isset($this->ch)) return $this->parse_results(null);
|
||||
$response = ($this->mh) ? curl_multi_getcontent($this->ch) : curl_exec($this->ch);
|
||||
|
||||
$results = $this->parse_results($response) ?? array();
|
||||
|
||||
// Cache last request
|
||||
if($this->opts->cache == "on" && !empty($results)) store_cached_results($this->url, $this->opts->hash, $results, ($this->opts->cache_time * 60));
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function print_results($results, $opts) {}
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Load and make config available, pass around variables
|
||||
--------------------------------------*/
|
||||
function load_opts() {
|
||||
$opts = require "config.php";
|
||||
|
||||
$opts->query = (isset($_REQUEST['q'])) ? sanitize($_REQUEST["q"]) : "";
|
||||
$opts->type = (isset($_REQUEST['t'])) ? sanitize($_REQUEST["t"]) : 0;
|
||||
$opts->user_auth = (isset($_REQUEST['a'])) ? sanitize($_REQUEST["a"]) : "";
|
||||
|
||||
// Remove ! at the start of queries to prevent DDG Bangs (!g, !c and crap like that)
|
||||
$has_exclamation_mark = substr($opts->query, 0, 1);
|
||||
if($has_exclamation_mark == "!") $opts->query = ltrim($opts->query, "!");
|
||||
|
||||
return $opts;
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Try to get some search results
|
||||
--------------------------------------*/
|
||||
function fetch_search_results($opts) {
|
||||
$start_time = microtime(true);
|
||||
|
||||
// Curl
|
||||
$mh = curl_multi_init();
|
||||
|
||||
// Load search script
|
||||
if($opts->type == 0 || $opts->type == 1) {
|
||||
require "engines/search.php";
|
||||
$search = new TextSearch($opts, $mh);
|
||||
} else if($opts->type == 2) {
|
||||
require "engines/search-image.php";
|
||||
$search = new ImageSearch($opts, $mh);
|
||||
} else if($opts->type == 9) {
|
||||
require "engines/search-torrent.php";
|
||||
$search = new TorrentSearch($opts, $mh);
|
||||
}
|
||||
|
||||
$running = null;
|
||||
|
||||
do {
|
||||
curl_multi_exec($mh, $running);
|
||||
} while ($running);
|
||||
|
||||
$results = $search->get_results();
|
||||
|
||||
curl_multi_close($mh);
|
||||
|
||||
// Add elapsed time to results
|
||||
$results['time'] = number_format(microtime(true) - $start_time, 5, '.', '');
|
||||
|
||||
$search->print_results($results, $opts);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Process special searches
|
||||
--------------------------------------*/
|
||||
function special_search_request($opts) {
|
||||
$special_request = null;
|
||||
$query_terms = explode(" ", $opts->query);
|
||||
|
||||
// Currency converter
|
||||
if($opts->special['currency'] == "on" && is_numeric($query_terms[0]) && ($query_terms[2] == 'to' || $query_terms[2] == 'in')) {
|
||||
require "engines/special/currency.php";
|
||||
$special_request = new CurrencyRequest($opts, null);
|
||||
}
|
||||
|
||||
// Dictionary
|
||||
if($opts->special['definition'] == "on" && count($query_terms) == 2 && ($query_terms[0] == 'define' || $query_terms[0] == 'd' || $query_terms[0] == 'mean' || $query_terms[0] == 'meaning')) {
|
||||
require "engines/special/definition.php";
|
||||
$special_request = new DefinitionRequest($opts, null);
|
||||
}
|
||||
|
||||
// Wikipedia search
|
||||
if($opts->special['wikipedia'] == "on" && count($query_terms) >= 2 && ($query_terms[0] == 'wiki' || $query_terms[0] == 'w')) {
|
||||
require "engines/special/wikipedia.php";
|
||||
$special_request = new WikipediaRequest($opts, null);
|
||||
}
|
||||
|
||||
// php.net search
|
||||
if($opts->special['phpnet'] == "on" && count($query_terms) == 2 && $query_terms[0] == 'php') {
|
||||
require "engines/special/php.php";
|
||||
$special_request = new PHPnetRequest($opts, null);
|
||||
}
|
||||
|
||||
return $special_request;
|
||||
}
|
||||
?>
|
127
functions/tools.php
Normal file
127
functions/tools.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
/*--------------------------------------
|
||||
// Verify the hash, or not, and let people in, or not
|
||||
--------------------------------------*/
|
||||
function verify_hash($opts, $auth) {
|
||||
if(($opts->hash_auth == "on" && strtolower($opts->hash) === strtolower($auth)) || $opts->hash_auth == "off") return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Strip all extras from an url
|
||||
--------------------------------------*/
|
||||
function get_base_url($url) {
|
||||
$parsed = parse_url($url);
|
||||
|
||||
return $parsed["scheme"] . "://" . $parsed["host"] . "/";
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Format search result urls
|
||||
--------------------------------------*/
|
||||
function get_formatted_url($url) {
|
||||
$parsed = parse_url($url);
|
||||
|
||||
return $parsed["scheme"] . "://" . $parsed["host"] . str_replace('/', ' › ', str_replace('%20', ' ', rtrim($parsed['path'], '/')));
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Load pages into a DOM
|
||||
--------------------------------------*/
|
||||
function get_xpath($response) {
|
||||
if(!$response)
|
||||
return null;
|
||||
|
||||
$htmlDom = new DOMDocument;
|
||||
@$htmlDom->loadHTML($response);
|
||||
$xpath = new DOMXPath($htmlDom);
|
||||
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// APCu Caching
|
||||
--------------------------------------*/
|
||||
function has_cached_results($url, $hash) {
|
||||
if(function_exists("apcu_exists")) {
|
||||
return apcu_exists("$hash:$url");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function store_cached_results($url, $hash, $results, $ttl = 0) {
|
||||
if(function_exists("apcu_store") && !empty($results)) {
|
||||
return apcu_store("$hash:$url", $results, $ttl);
|
||||
}
|
||||
}
|
||||
|
||||
function fetch_cached_results($url, $hash) {
|
||||
if(function_exists("apcu_fetch")) {
|
||||
return apcu_fetch("$hash:$url");
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Sanitize variables
|
||||
--------------------------------------*/
|
||||
function sanitize($thing) {
|
||||
switch(gettype($thing)) {
|
||||
case 'string':
|
||||
$thing = stripslashes(strip_tags(trim($thing)));
|
||||
break;
|
||||
case 'boolean':
|
||||
$thing = ($thing === FALSE) ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
$thing = ($thing === NULL) ? 'NULL' : strip_tags(trim($thing));
|
||||
break;
|
||||
}
|
||||
|
||||
return $thing;
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Human readable file sizes
|
||||
--------------------------------------*/
|
||||
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];
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
// Generate random strings for passwords
|
||||
--------------------------------------*/
|
||||
function string_generator() {
|
||||
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
$password = array();
|
||||
$length = strlen($characters) - 1;
|
||||
|
||||
for ($i = 0; $i < 24; $i++) {
|
||||
$n = rand(0, $length);
|
||||
$password[] = $characters[$n];
|
||||
}
|
||||
|
||||
array_splice($password, 6, 0, '-');
|
||||
array_splice($password, 13, 0, '-');
|
||||
array_splice($password, 20, 0, '-');
|
||||
|
||||
return implode($password);
|
||||
}
|
||||
?>
|
44
goosle.htaccess
Normal file
44
goosle.htaccess
Normal file
|
@ -0,0 +1,44 @@
|
|||
# mod_rewrite
|
||||
RewriteEngine on
|
||||
|
||||
# FORCE SSL
|
||||
RewriteCond %{HTTPS} !=on
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
|
||||
|
||||
# Redirect 404 to homepage
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . / [L,R=301]
|
||||
|
||||
# Use UTF-8 encoding for anything served text/plain or text/html
|
||||
AddDefaultCharset UTF-8
|
||||
AddCharset UTF-8 .css .js
|
||||
|
||||
# Cache Control
|
||||
ExpiresByType image/webp "access plus 1 year"
|
||||
ExpiresByType image/x-icon "access plus 1 year"
|
||||
ExpiresByType font/woff "access plus 1 year"
|
||||
ExpiresByType font/woff2 "access plus 1 year"
|
||||
ExpiresByType application/font-woff "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 year"
|
||||
ExpiresByType text/javascript "access plus 1 year"
|
||||
ExpiresByType application/javascript "access plus 1 year"
|
||||
# Failsaves
|
||||
ExpiresByType application/octet-stream "access plus 1 year"
|
||||
ExpiresByType text/plain "access plus 1 year"
|
||||
ExpiresDefault "access 30 days"
|
||||
|
||||
# Gzip compression
|
||||
SetOutputFilter DEFLATE
|
||||
|
||||
# Don’t compress images and other uncompressible content
|
||||
SetEnvIfNoCase Request_URI \
|
||||
\.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g|mp4|webm|webp)$ no-gzip dont-vary
|
||||
|
||||
# Compress all output labeled with one of the following MIME-types
|
||||
AddOutputFilterByType DEFLATE application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/xhtml+xml application/xml font/ttf font/otf font/opentype image/svg+xml image/x-icon text/css text/html text/plain text/x-component text/xml
|
||||
Header append Vary: Accept-Encoding
|
||||
|
||||
# Force deflate for mangled headers
|
||||
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
|
||||
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
|
129
help.php
Normal file
129
help.php
Normal file
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
require "functions/tools.php";
|
||||
require "functions/search_engine.php";
|
||||
|
||||
$opts = load_opts();
|
||||
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
?>
|
||||
<!DOCTYPE html >
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="description" content="A private meta search engine!"/>
|
||||
<meta name="referrer" content="no-referrer"/>
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/styles.css"/>
|
||||
<title><?php echo $opts->query; ?> - Goosle Search</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
if(verify_hash($opts, $auth)) {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="header-wrap">
|
||||
<form action="results.php" method="get" autocomplete="off">
|
||||
<h1 class="logo"><a class="no-decoration" href="./?a=<?php echo $opts->hash; ?>"><span class="G">G</span>oosle</a></h1>
|
||||
<input tabindex="1" class="search" type="text" value="<?php echo (strlen($opts->query) > 0) ? htmlspecialchars($opts->query) : "" ; ?>" name="q" required /><input tabindex="2" class="button" type="submit" value="Search" />
|
||||
|
||||
<input type="hidden" name="t" value="<?php echo $opts->type; ?>"/>
|
||||
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>">
|
||||
|
||||
<div class="navigation-header">
|
||||
<a <?php echo ($opts->type == "0") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=0"><img src="assets/images/search.png" alt="DuckDuckGo results" />DuckDuckGo</a>
|
||||
<a <?php echo ($opts->type == "1") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=1"><img src="assets/images/search.png" alt="Google results" />Google</a>
|
||||
<?php if($opts->enable_image_search == "on") { ?>
|
||||
<a <?php echo ($opts->type == "2") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=2"><img src="assets/images/image.png" alt="Image results" />Image</a>
|
||||
<?php } ?>
|
||||
<?php if($opts->enable_torrent_search == "on") { ?>
|
||||
<a <?php echo ($opts->type == "9") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=9"><img src="assets/images/torrent.png" alt="Torrent results" />Torrent</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="results-wrap">
|
||||
<section class="main-column">
|
||||
<h2>DuckDuckGo features</h2>
|
||||
<p>DuckDuckGo is mostly language agnostic and will try to figure out on it's own what language to use.</p>
|
||||
<p>Searching defaults to Moderate Safe mode. To override the safe mode prefix your search with <strong>safe:on</strong> or <strong>safe:off</strong>.<br /><strong>On</strong> will use 'Strict' mode, while <strong>off</strong> will disable safe searching, this may yield results that are unsuitable for work or minors.</p>
|
||||
<p><em><strong>Note:</strong> Search bangs are not supported and the <strong>!</strong> to trigger them is stripped out to prevent issues.</em></p>
|
||||
|
||||
<h2>Google features</h2>
|
||||
<p>Searching defaults to Moderate Safe mode. You can override safe mode by adding the prefix <strong>safe:on</strong> or <strong>safe:off</strong> to your search query.<br /><strong>On</strong> will use 'Strict' mode, while <strong>off</strong> will disable safe searching. this may yield results that are unsuitable for work or minors.</p>
|
||||
<p>Google results are not personalized by default, using Google's option for it.</p>
|
||||
<p>Google search is language agnostic and Google will try to figure out on it's own what language to use. To search in a specific language prefix your search with <strong>lang fr</strong> for French or <strong>lang:es</strong> for Spanish. Any language that google supports will work as long as you use the ISO639-1:2002 language code. Commonly these are the 2 letter abbreviations for the language such as; en, fr, es, de, sk, and so on.</p>
|
||||
<p>To do a category search, prefix your search with one of the following keywords; <strong>app</strong>, <strong>book</strong>, <strong>news</strong>, <strong>shop</strong> or <strong>patent</strong>. This will tell Google to look for results in that specific category.<br />For example: Searching for <strong>book trainspotting</strong> will (or should) show results related to the book Trainspotting.</p>
|
||||
|
||||
<?php if($opts->enable_image_search == "on") { ?>
|
||||
<h2>Image Search</h2>
|
||||
<p>Search for images through Qwant Image Search.<br />The number of results is limited to 50.</p>
|
||||
<p>Contrary to Google Image Search which opens a popup/slider with more information. Goosle Image Search links directly to the page where the image is hosted.</p>
|
||||
<p>You can search for images in a general size by adding <strong>size:small</strong>, <strong>size:medium</strong> or <strong>size:large</strong> to your search query.</p>
|
||||
<?php } ?>
|
||||
|
||||
<h2>Special Searches</h2>
|
||||
<?php if($opts->special['currency'] == "on") { ?>
|
||||
<h3>Currency converter</h3>
|
||||
<p>Convert currency with a simple query.<br />
|
||||
For example: Search for <strong>20 EUR in HKD</strong> or <strong>20 USD to MXN</strong> and DuckDuckGo or Google will search for it, but also a local conversion is done in a highlighted result.</p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($opts->special['wikipedia'] == "on") { ?>
|
||||
<h3>Wikipedia Search</h3>
|
||||
<p>Prefix your search with <strong>w</strong> or <strong>wiki</strong> to search on Wikipedia for a page match. This works best for English searches as Wikipedia defaults to English.<br />
|
||||
For example: Searching for <strong>wiki beach ball</strong> will show you a excerpt from that page above the search results or suggest the most likely alternative if Wikipedia knows what your search query means.</p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($opts->special['phpnet'] == "on") { ?>
|
||||
<h3>PHP.net Search</h3>
|
||||
<p>Prefix your search with <strong>php</strong> to search on php.net for a PHP function.<br />
|
||||
For example: Searching for <strong>php in_array</strong> or <strong>php trim</strong> will show you a brief description, compatible PHP versions and a usage example for that function.</p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($opts->special['definition'] == "on") { ?>
|
||||
<h3>Word Definition</h3>
|
||||
<p>You can easily look up the meaning of single words. Prefix the word you want to look up with any of the following keywords; <strong>d</strong>, <strong>define</strong>, <strong>mean</strong>, <strong>meaning</strong>.<br />
|
||||
For example: Searching for <strong>define search</strong> will search for that on Google or DuckDuckGo, but also show the definition highlighted above the search results.</p>
|
||||
<p><em><strong>Note:</strong> Special Searches do not work for torrent searches.</em></p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($opts->enable_torrent_search == "on") { ?>
|
||||
<h2>Torrent Search</h2>
|
||||
<p>Search for anything torrent sites have on offer the direct search result should give you the magnet link.<br />Results are gathered from 1337x, Nyaa, The Pirate Bay and YTS and are sorted by Seeders, highest first. The number of results is limited to 50.</p>
|
||||
<p>The search scripts will try to provide useful data which may include; Seeders/Leechers, A link to the torrent page, Download Category, Release year, Movie quality (720p, 4K etc.), Movie Runtime and the Download Size. Not every website makes this available and all results take a best effort approach.</p>
|
||||
<p><em><strong>Disclaimer:</strong> If you like, or found a use for, what you downloaded, you should probably buy a legal copy of it.</em></p>
|
||||
<?php } ?>
|
||||
|
||||
<p><small><strong>Acknowledgements:</strong><br />Goosle started as a fork of LibreY, and takes some design cues from DuckDuckGo.com. Goosle is created by <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>.</small></p>
|
||||
|
||||
<p><small><strong>Version:</strong> <?php echo $opts->version; ?> / <strong>Released:</strong> <?php echo $opts->released; ?></small></p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-wrap">
|
||||
<div class="footer">
|
||||
© <?php echo date('Y'); ?> <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>. All rights reserved.
|
||||
<span style="float:right;"><a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> - Your IP: <?php echo $_SERVER["REMOTE_ADDR"]; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
} else {
|
||||
echo "<div class=\"auth-error\">Nope, go away!</div>";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
72
index.php
Normal file
72
index.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
require "functions/tools.php";
|
||||
require "functions/search_engine.php";
|
||||
|
||||
$opts = load_opts();
|
||||
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
?>
|
||||
<!DOCTYPE html >
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="description" content="Goosle - A meta search engine for private and fast internet fun!"/>
|
||||
<meta name="referrer" content="no-referrer"/>
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/styles.css"/>
|
||||
<title>Goosle Search</title>
|
||||
</head>
|
||||
<body class="main">
|
||||
<?php
|
||||
if(verify_hash($opts, $auth)) {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="search-box-main">
|
||||
<form action="results.php" method="get" autocomplete="off">
|
||||
<h1><span class="G">G</span>oosle</h1>
|
||||
|
||||
<input tabindex="10" type="text" class="search" name="q" autofocus required />
|
||||
|
||||
<input type="hidden" name="t" value="0"/>
|
||||
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>"/>
|
||||
|
||||
<div class="search-box-buttons">
|
||||
<button tabindex="20" name="t" value="0" type="submit">DuckDuckGo</button>
|
||||
<button tabindex="30" name="t" value="1" type="submit">Google</button>
|
||||
<?php if($opts->enable_image_search == "on") { ?>
|
||||
<button tabindex="40" name="t" value="2" type="submit">Image</button>
|
||||
<?php } ?>
|
||||
<?php if($opts->enable_torrent_search == "on") { ?>
|
||||
<button tabindex="50" name="t" value="9" type="submit">Torrent</button>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if($opts->special['password_generator'] == "on") { ?>
|
||||
<div class="password-generator">
|
||||
<form method="get" action="./" autocomplete="off">
|
||||
Password Generator:<br/><input class="password" type="text" name="pw" maxlength="27" value="<?php echo string_generator(); ?>" autocomplete="0" />
|
||||
</form>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
echo "<div class=\"auth-error\">Nope, go away!</div>";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
58
readme.md
Normal file
58
readme.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Goosle
|
||||
A fast, privacy oriented meta search engine that just works.
|
||||
Kept simple so everyone can use it and to make sure it works on most (basic) webservers.
|
||||
|
||||
Host for yourself and friends, with a access hash key. Or set up a public search website.
|
||||
|
||||
After-all, finding things should be easy and not turn into a chore.
|
||||
|
||||
## Features
|
||||
- Search on DuckDuckGo
|
||||
- Search on Google.com
|
||||
- Image search through Qwant
|
||||
- Search for magnet links on popular Torrent sites
|
||||
- Special searches for; Currency conversion, Dictionary, Wikipedia and php.net
|
||||
- Instant password generator on the home page
|
||||
- Randomized user-agents for to prevent profiling by search providers
|
||||
- Works on *any* hosting package that does PHP7.4 or newer
|
||||
- Optional: Access key as a very basic way to keep your server to yourself
|
||||
- Optional: Speed up repeat searches with APCu cache if your server has it
|
||||
|
||||
What Goosle does *not* have.
|
||||
- Trackers and Cookies
|
||||
- User profiles or user controllable settings
|
||||
- Javascripts or Frameworks
|
||||
|
||||
And yet it just works...
|
||||
|
||||
## Requirements
|
||||
Any basic webserver/webhosting package with PHP7.4 or newer.
|
||||
Tested to work on Apache with PHP8.2.
|
||||
|
||||
## Installation
|
||||
1. Unzip the download.
|
||||
2. Edit the config.php file with your preferences.
|
||||
3. Upload all files to your webserver, for example to the root folder of a subdomain (eg. search.example.com) or a sub-folder on your main site (eg. example.com/search/)
|
||||
4. Rename goosle.htaccess to .htaccess
|
||||
5. Load the site in your browser. If you've enabled the access hash add ?a=YOURHASH to the url.
|
||||
|
||||
### Notes:
|
||||
- The .htaccess file has a redirect to force HTTPS as well as browser caching instructions ready to go.
|
||||
- The robots.txt has a rule to prevent all crawlers from crawling Goosle. But keep in mind that not every crawler obeys this file.
|
||||
- The access hash is NOT meant as a super secure measure and only works for surface level prying eyes.
|
||||
|
||||
Have fun finding things!
|
||||
|
||||
|
||||
## Disclaimer
|
||||
Goosle started as a fork of LibreY, and ended up as a rewrite and something different completely. While the code structure remains largely the same, most functions have been rewritten or altered to work as I need it to.
|
||||
Search results take design cues from DuckDuckGo and the torrent search has been modified to show more useful information where possible.
|
||||
|
||||
Goosle does not index, store or distribute torrent files. If you like, or found a use for, what you downloaded, you should probably buy a legal copy of it.
|
||||
|
||||
## Support
|
||||
Goosle comes with limited support. You can post your questions on Github or on my support forum on [ajdg.solutions](https://ajdg.solutions/support/).
|
||||
|
||||
## Changelog
|
||||
1.0 - December 5, 2023
|
||||
- Initial release
|
74
results.php
Normal file
74
results.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
require "functions/tools.php";
|
||||
require "functions/search_engine.php";
|
||||
|
||||
$opts = load_opts();
|
||||
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
|
||||
/* ------------------------------------------------------------------------------------
|
||||
* Goosle - A meta search engine for private and fast internet fun.
|
||||
*
|
||||
* COPYRIGHT NOTICE
|
||||
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
|
||||
*
|
||||
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Arnan de Gans from any
|
||||
* liability that might arise from its use.
|
||||
------------------------------------------------------------------------------------ */
|
||||
?>
|
||||
<!DOCTYPE html >
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="description" content="A private meta search engine!"/>
|
||||
<meta name="referrer" content="no-referrer"/>
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/styles.css"/>
|
||||
<title><?php echo $opts->query; ?> - Goosle Search</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
if(verify_hash($opts, $auth)) {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="header-wrap">
|
||||
<form action="results.php" method="get" autocomplete="off">
|
||||
<h1 class="logo"><a class="no-decoration" href="./?a=<?php echo $opts->hash; ?>"><span class="G">G</span>oosle</a></h1>
|
||||
<input tabindex="1" class="search" type="text" value="<?php echo (strlen($opts->query) > 0) ? htmlspecialchars($opts->query) : "" ; ?>" name="q" required /><input tabindex="2" class="button" type="submit" value="Search" />
|
||||
|
||||
<input type="hidden" name="t" value="<?php echo $opts->type; ?>"/>
|
||||
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>">
|
||||
|
||||
<div class="navigation-header">
|
||||
<a <?php echo ($opts->type == "0") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=0"><img src="assets/images/search.png" alt="DuckDuckGo results" />DuckDuckGo</a>
|
||||
<a <?php echo ($opts->type == "1") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=1"><img src="assets/images/search.png" alt="Google results" />Google</a>
|
||||
<?php if($opts->enable_image_search == "on") { ?>
|
||||
<a <?php echo ($opts->type == "2") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=2"><img src="assets/images/image.png" alt="Image results" />Image</a>
|
||||
<?php } ?>
|
||||
<?php if($opts->enable_torrent_search == "on") { ?>
|
||||
<a <?php echo ($opts->type == "9") ? "class=\"active\" " : ""; ?> href="./results.php?q=<?php echo urlencode($opts->query); ?>&a=<?php echo $opts->hash; ?>&t=9"><img src="assets/images/torrent.png" alt="Torrent results" />Torrent</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="results-wrap">
|
||||
<?php fetch_search_results($opts); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-wrap">
|
||||
<div class="footer">
|
||||
© <?php echo date('Y'); ?> <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>. All rights reserved.
|
||||
<span style="float:right;"><a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> - Your IP: <?php echo $_SERVER["REMOTE_ADDR"]; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
} else {
|
||||
echo "<div class=\"auth-error\">Nope, go away!</div>";
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
2
robots.txt
Normal file
2
robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
Loading…
Reference in a new issue