first commit

This commit is contained in:
hnhx 2022-02-17 21:14:56 +01:00
commit 1a91e6a06a
11 changed files with 523 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# librex

13
api.php Normal file
View File

@ -0,0 +1,13 @@
<?php
header('Content-Type: application/json');
require "fetch.php";
$query = $_REQUEST["q"];
$page = (int) $_REQUEST["p"] * 10;
$type = $_REQUEST["img_search"] == "true" ? true : false;
$results = fetch_results($query, $page, $type);
echo json_encode($results, true);
?>

10
config.php Executable file
View File

@ -0,0 +1,10 @@
<?php
// This user agent will be used to access Google
$config_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36";
// e.g.: fr -> https://google.fr/
$config_google_domain = "com";
// Results will be in this language
$config_google_language = "en";
?>

26
donate.xhtml Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>LibreX - Donate</title>
<meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="A privacy respecting meta search engine."/>
<link rel="stylesheet" type="text/css" href="static/styles.css"/>
</head>
<body>
<div class="donate-container">
<h1>Donate</h1>
<p>Support the host</p>
<span>(Your donation thingy goes here...)</span>
<p>Support the creator</p>
<span>You can donate to hnhx via the XMR address found on the <a href="https://github.com/hnhx/librex/" target="_blank">GitHub repo</a></span>
</div>
<div class="info-container">
<a href="/">LibreX</a>
<a href="https://github.com/hnhx/librex/" target="_blank">Source code &amp; Other instances</a>
<a href="/donate.xhtml" id="right">Donate ❤️</a>
</div>
</body>
</html>

98
fetch.php Normal file
View File

@ -0,0 +1,98 @@
<?php
function get_base_url($url)
{
$split_url = explode("/", $url);
$base_url = $split_url[0] . "//" . $split_url[2] . "/";
return $base_url;
}
function fetch_results($query, $page, $get_images=false)
{
require("config.php");
$query_encoded = urlencode($query);
$google = "https://www.google.$config_google_domain/search?&q=$query_encoded&start=$page&hl=$config_google_language";
if ($get_images)
$google .= "&tbm=isch";
$ch = curl_init($google);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
// CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5_HOSTNAME,
// CURLOPT_PROXY => "127.0.0.1:9150",
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_ENCODING => "",
CURLOPT_USERAGENT => $config_user_agent,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_VERBOSE => 1,
]);
$response = curl_exec($ch);
$htmlDom = new DOMDocument;
@$htmlDom->loadHTML($response);
$xpath = new DOMXPath($htmlDom);
$results = array();
if ($get_images)
{
$mh = curl_multi_init();
$chs = array();
foreach($xpath->query(".//following::img") as $image)
{
$alt = $image->getAttribute("alt");
$src = $image->getAttribute("data-src");
if (!empty($src) && !empty($alt))
{
$ch = curl_init($src);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
array_push($chs, $ch);
curl_multi_add_handle($mh, $ch);
}
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
foreach($chs as $ch)
{
$img_base64 = base64_encode(curl_multi_getcontent($ch));
array_push($results,
array (
"base64" => $img_base64,
"alt" => $alt
)
);
}
}
else
{
foreach($xpath->query("//div[contains(@class, 'yuRUbf')]") as $div)
{
$title = $div->getElementsByTagName("h3")[0]->textContent;
$url = $div->getElementsByTagName("a")[0]->getAttribute("href");
$base_url = get_base_url($url);
array_push($results,
array (
"title" => $title,
"url" => $url,
"base_url" => $base_url
)
);
}
}
return $results;
}
?>

27
index.xhtml Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>LibreX</title>
<meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="A privacy respecting meta search engine."/>
<link rel="stylesheet" type="text/css" href="static/styles.css"/>
</head>
<body>
<form class="search-container" action="search.php" method="post">
<h1>LibreX</h1>
<input type="text" name="q"/>
<input type="hidden" name="p" value="0"/>
<input type="submit" style="display:none"/> <br/>
<button name="type" value="text" type="submit">Search with LibreX</button>
<button name="type" value="img" type="submit">Search images with LibreX</button>
</form>
<div class="info-container">
<a href="/">LibreX</a>
<a href="https://github.com/hnhx/librex/" target="_blank">Source code &amp; Other instances</a>
<a href="/donate.xhtml" id="right">Donate ❤️</a>
</div>
</body>
</html>

14
opensearch.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>LibreX</ShortName>
<Description>A meta search engine for Google.</Description>
<InputEncoding>UTF-8</InputEncoding>
<LongName>LibreX search</LongName>
<Url rel="results" type="text/html" method="post" template="http://localhost/search.php">
<Param name="q" value="{searchTerms}" />
</Url>
<Url type="application/opensearchdescription+xml"
rel="self"
template="/opensearch.xml?method=POST" />
</OpenSearchDescription>

66
search.php Normal file
View File

@ -0,0 +1,66 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title> <?php echo $_REQUEST["q"]; ?> - LibreX</title>
<meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="A privacy respecting meta search engine."/>
<link rel="stylesheet" type="text/css" href="static/styles.css"/>
<link title="LibreX search" type="application/opensearchdescription+xml" href="/opensearch.xml?method=POST" rel="search"/>
</head>
<body>
<form class="small-search-container" method="post">
<a href="/"><h1>LibreX</h1></a>
<input type="hidden" name="p" value="0">
<input type="text" name="q"
<?php
session_start();
$valid_query = true;
if (!isset($_REQUEST["q"]))
$valid_query = false;
else if (1 > strlen($_REQUEST["q"]) || strlen($_REQUEST["q"]) > 256)
$valid_query = false;
if ($valid_query)
{
$query = $_REQUEST["q"];
echo "value=\"$query\"";
$_SESSION["q"] = $query;
$_SESSION["p"] = $_REQUEST["p"];
$_SESSION["type"] = $_REQUEST["type"];
}
else
{
header("Location: /");
die();
}
?>
>
<br>
<?php
if (isset($_REQUEST["type"]))
if ($_REQUEST["type"] == "img")
echo "<input type=\"hidden\" name=\"type\" value=\"img\"/>";
?>
<button type="submit" style="display:none;"></button>
<div class="result_change">
<button name="type" value="text">Text results</button>
<button name="type" value="img">Image results</button>
</div>
<hr>
</form>
<iframe src="search_frame.php" frameborder="0"></iframe>
<div class="info-container">
<a href="/">LibreX</a>
<a href="https://github.com/hnhx/librex/" target="_blank">Source code &amp; Other instances</a>
<a href="/donate.xhtml" id="right">Donate ❤️</a>
</div>
</body>
</html>

83
search_frame.php Normal file
View File

@ -0,0 +1,83 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" type="text/css" href="static/styles.css"/>
</head>
<body>
<?php
function print_next_pages($page, $button_val, $q) {
echo "<form id=\"page\" action=\"search.php\" target=\"_top\" method=\"post\">";
echo "<input type=\"hidden\" name=\"p\" value=\"" . $page . "\" />";
echo "<input type=\"hidden\" name=\"q\" value=\"$q\" />";
echo "<button type=\"submit\">$button_val</button>";
echo "</form>";
}
session_start();
require("fetch.php");
$query = $_SESSION["q"];
$page = (int) htmlspecialchars($_SESSION["p"]);
$search_type = $_SESSION["type"] == "img" ? true : false;
$start_time = microtime(true);
$results = fetch_results($query, $page, $search_type);
$end_time = number_format(microtime(true) - $start_time, 2, '.', '');
echo "<p id=\"time\">Fetched the results in $end_time seconds</p>";
if ($_SESSION["type"] != "img")
{
foreach($results as $result)
{
$title = $result["title"];
$url = $result["url"];
$base_url = $result["base_url"];
echo "<div class=\"result-container\">";
echo "<a href=\"$url\" target=\"_blank\">";
echo "$base_url";
echo "<h2>$title</h2>";
echo "</a>";
echo "</div>";
}
echo "<div class=\"page-container\">";
if ($page != 0)
{
print_next_pages(0, "&lt;&lt;", $query);
print_next_pages($page - 10, "&lt;", $query);
}
for ($i=$page / 10; $page / 10 + 10>$i; $i++)
{
$page_input = $i * 10;
$page_button = $i + 1;
print_next_pages($page_input, $page_button, $query);
}
print_next_pages($page + 10, "&gt;", $query);
echo "</div>";
}
else
{
foreach($results as $result)
{
$src = $result["base64"];
$alt = $result["alt"];
echo "<a href=\"data:image/jpeg;base64,$src\" target=\"_blank\"><img src=\"data:image/jpeg;base64,$src\"></a>";
}
}
require "session_destroy.php";
?>
</body>
</html>

13
session_destroy.php Normal file
View File

@ -0,0 +1,13 @@
<?php
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
session_destroy();
?>

172
static/styles.css Normal file
View File

@ -0,0 +1,172 @@
html {
color: #e8eaed;
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
body {
background-color: #202124;
margin: 0;
padding: 0;
}
hr { margin:30px 0px 30px 0px; }
iframe {
width: 100%;
height: 100vh;
}
img { padding:15px; }
.search-container {
text-align: center;
margin-top:13%;
}
.search-container input , .small-search-container input {
padding:10px;
font-size: 16px;
border:1px solid #5f6368;
border-radius: 25px;
color: inherit;
background-color: inherit;
}
.search-container input { width: 520px; }
.small-search-container input {
width: 600px;
margin-left:-10px;
}
.search-container input:hover, .small-search-container input:hover {
background-color: #303134;
border-color: #303134;
}
.search-container input:focus , .small-search-container input:focus { outline: none; }
.search-container h1 { font-size:70px; }
.search-container button {
background-color: #303134;
border:none;
border-radius: 4px;
color:inherit;
padding:13px 10px 13px 10px;
margin-top:30px;
font-size: 14px;
margin-left:20px;
}
.search-container button:hover {
border: 1px solid #5f6368;
cursor:pointer;
}
.info-container {
position: fixed;
bottom: 0;
width: 100%;
background-color:#171717;
font-size:15px;
padding-top: 15px;
padding-bottom: 15px;
border-top:1px solid #303134;
}
.info-container a , p {
color:#999da2;
text-decoration: none;
}
.info-container a {
padding-left: 25px;
font-size:16px;
}
.info-container #right { float:right; }
.info-container a:hover { text-decoration: underline; }
.small-search-container h1, a {
display: inline;
margin-right:40px;
color:inherit;
text-decoration: none;
}
.small-search-container { margin:2%; }
.result-container, #time {
margin-left:10%;
}
.result-container a {
font-size: 14px;
color:#bdc1c6;
text-decoration: none;
}
.result-container h2 {
font-size: 20px;
color:#8ab4f8;
padding-top:5px;
margin-top:1px;
}
.result-container h2:hover { text-decoration: underline; }
.result-container {
margin-top:6px;
}
.page-container {
margin-bottom:70px;
margin-left:15%;
}
.page-container #page { display: inline; }
.page-container #page button {
padding-right: 10px;
background-color: inherit;
font-size: 16px;
color:#8ab4f8;
border: none;
}
.page-container #page button:hover {
cursor:pointer;
text-decoration: underline;
}
.result_change button {
color:#c58af9;
background-color: inherit;
border:none;
text-decoration: underline;
display: inline;
margin:20px 0px 0px 0px;
font-size: 18px;
}
.result_change { margin-left: 11%;}
.result_change button:hover { cursor: pointer; }
.donate-container {
margin-left: 25%;
margin-right: 25%;
margin-top: 13%;
border: 1px solid #bdc1c6;
border-top: none;
border-bottom: none;
text-align: center;
}
.donate-container a {
color:#8ab4f8;
text-decoration: underline;
}