Browse Source

first commit

hnhx 3 years ago
commit
1a91e6a06a
11 changed files with 523 additions and 0 deletions
  1. 1 0
      README.md
  2. 13 0
      api.php
  3. 10 0
      config.php
  4. 26 0
      donate.xhtml
  5. 98 0
      fetch.php
  6. 27 0
      index.xhtml
  7. 14 0
      opensearch.xml
  8. 66 0
      search.php
  9. 83 0
      search_frame.php
  10. 13 0
      session_destroy.php
  11. 172 0
      static/styles.css

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# librex

+ 13 - 0
api.php

@@ -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 - 0
config.php

@@ -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 - 0
donate.xhtml

@@ -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 - 0
fetch.php

@@ -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 - 0
index.xhtml

@@ -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 - 0
opensearch.xml

@@ -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 - 0
search.php

@@ -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 - 0
search_frame.php

@@ -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 - 0
session_destroy.php

@@ -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 - 0
static/styles.css

@@ -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;
+}