diff options
Diffstat (limited to 'prog/sear.php')
-rw-r--r-- | prog/sear.php/css.css | 136 | ||||
-rw-r--r-- | prog/sear.php/favicon.ico | bin | 0 -> 1150 bytes | |||
-rw-r--r-- | prog/sear.php/index.php | 307 | ||||
-rw-r--r-- | prog/sear.php/osdd.xml | 8 |
4 files changed, 451 insertions, 0 deletions
diff --git a/prog/sear.php/css.css b/prog/sear.php/css.css new file mode 100644 index 0000000..dc78c9f --- /dev/null +++ b/prog/sear.php/css.css @@ -0,0 +1,136 @@ +:root { /* most of the styles are used on http://sijanec.eu, so there are some excess colours */ + --bgc1: black; + --bgc2: #111; + --bgc3: #222; + --fgc1: white; + --fgc2: lightgray; + --fgc3: lightblue; + --fglinkc: #ae5; + --fglinkvisitedc: #0cd; + --fglinkhoverc: cyan; + --fglinkactivec: #eff; + --fgchilite: red; + --fgdecorc: yellow; + --fgcodec: #aed; + --bgcodec: var(--bgc2); + --bgclight: darkgray; + --scheme-name: dark; +} + +@media (prefers-color-scheme: light) { + :root { + --bgc1: white; + --bgc2: lightgray; + --bgc3: darkgray; + --fgc1: black; + --fgc2: gray; + --fgc3: darkred; + --fglinkc: blue; + --fglinkvisitedc: purple; + --fglinkhoverc: darkblue; + --fglinkactivec: cyan; + --fgchilite: red; + --fgdecorc: darkmagenta; + --fgcodec: var(--bgc1); + --bgcodec: var(--fgc1); + --bgclight: darkgray; + --scheme-name: light; + } +} + +input, textarea, button { + background: var(--bgc2); + color: var(--fgc1); +} + +a { + text-decoration: underline; + cursor: pointer; + color: var(--fglinkc); +} + +a:visited { + color: var(--fglinkvisitedc); +} + +a:hover { + color: var(--fglinkhoverc); +} + +a:active { + color: var(--fglinkactivec); +} + + +@media screen and (min-width: 1000px) { + body { + margin-left: 10%; + margin-right: 10%; + } +} + +body { + background-color: var(--bgc1); + color: var(--fgc1); + scrollbar-color: var(--scheme-name); +} + +code { + color: var(--fgcodec); + background-color: var(--bgcodec); +} +input[type=text], button { + height: 1cm; + font-size: large; +} +.result:hover { + background: var(--bgc2); +} +.container { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: stretch; +} +input[name=q] { + flex-grow: 4; + width: 100%; +} +button { + flex-basis: 12.5%; +} +.SC_LOG_ERROR { + color: red; +} +.SC_LOG_WARNING { + color: orange; +} +.SC_LOG_INFO { + color: lightgreen; +} +.SC_LOG_DEBUG { + color: magenta; +} +.breadcrumb { + color: var(--fgc2); + font-size: small; /* small is relative to parent (h4) size */ +} +.result h4 { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 0.314159265358em; +} +.result p { + margin-top: 0.314159265358em; +} +.result img { + height: 10em; +} +button::after { + content: attr(value); +} +button span { /* rationale: links browser does not support CSS and emojis, therefore it'll show */ + display: none; /* basic default text instead of emojis. */ +} /* if browser does not support ::after, content or attr, but supports other CSS, button is blank */ diff --git a/prog/sear.php/favicon.ico b/prog/sear.php/favicon.ico Binary files differnew file mode 100644 index 0000000..6d3265d --- /dev/null +++ b/prog/sear.php/favicon.ico diff --git a/prog/sear.php/index.php b/prog/sear.php/index.php new file mode 100644 index 0000000..cd684b8 --- /dev/null +++ b/prog/sear.php/index.php @@ -0,0 +1,307 @@ +<?php +function find_class ($haystack, $definition) { + $pos = stripos($haystack, $definition); + if ($pos === false) + return false; + while ($haystack[$pos] != ".") + $pos--; + $endofclass = ++$pos; + while (ctype_alnum($haystack[$endofclass])) + $endofclass++; + return substr($haystack, $pos, $endofclass-$pos); +} +function fix_url ($h) { + if (str_starts_with($h, "/url?q=")) { + $h = substr($h, strlen("/url?q=")); + $h = substr($h, 0, strpos($h, "&")); + $h = urldecode($h); + } + if (strpos($h, "googleweblight.com/fp?u=") !== false) { + $h = substr($h, strpos($h, "googleweblight.com/fp?u=")+strlen("googleweblight.com/fp?u=")); + $h = substr($h, 0, strpos($h, "&")); + $h = urldecode($h); + } + return $h; +} +function only_text_content ($node) { + $r = ""; + foreach($node->childNodes as $n) + if ($n->nodeType == XML_TEXT_NODE) + $r .= $n->nodeValue; + return $r; +} +function query_google ($s, $image = false, $noredirect = false, $bindstring = false) { + $us = urlencode($s); + $a = ""; + if ($image) + $a .= "&tbm=isch"; + if ($noredirect) + $a .= "&nfpr=1"; + $url = "http://wap.google.com/search?q=$us&num=100&ie=UTF-8$a"; + $sockarr = []; + if ($bindstring) + $sockarr["bindto"] = $bindstring; + $txtdoc = file_get_contents($url, false, stream_context_create(["socket" => $sockarr, "http" => ["ignore_errors" => true, "header" => "User-Agent: Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)\r\n"]])); + if ($txtdoc == false) + return ["status" => false, "code" => "failed"]; + if (str_contains($txtdoc, "In the meantime, solving the above CAPTCHA will let you continue")) + return ["status" => false, "code" => "captcha", "url" => $url]; + $resultsforclass = find_class($txtdoc, "{color:#1967d2}"); + if ($image) { + $imageclass = find_class($txtdoc, "{font-family:Roboto,Helvetica,Arial,sans-serif}"); + if (!$imageclass) + return ["status" => false, "code" => "noimgclass"]; + } else { + $titleclass = find_class($txtdoc, "{color:#1967D2;font-size:14px;line-height:16px}"); + $descclass = find_class($txtdoc, "{word-break:break-word}"); + if (!$titleclass || !$descclass) + return ["status" => false, "code" => "noclass"]; + } + $results = []; + $x = new DOMDocument(); + $x->loadHTML($txtdoc); + if ($image) + foreach ($x->getElementsByTagName("div") as $div) { + if ($div->getAttribute("class") != $imageclass) + continue; + $hreflink = $div->getElementsByTagName("a")[0]->getAttribute("href"); + if (!$hreflink) + continue; + preg_match(",.*s?imgurl=([^&]*)&imgrefurl=([^&]*).*,", $hreflink, $matches); + $imgurl = $matches[1]; + $imgrefurl = $matches[2]; + if (!$imgurl && !$imgrefurl) + continue; + $imgurl = urldecode(fix_url($imgurl)); + $imgrefurl = urldecode(fix_url($imgrefurl)); + $results[] = ["imgsrc" => $imgurl, "url" => $imgrefurl]; + } + else + foreach ($x->getElementsByTagName("a") as $a) { + if (!$a->getAttribute("class")) + continue; + if (!str_contains($a->getAttribute("class"), $titleclass)) + continue; + $hreflink = fix_url($a->getAttribute("href")); + if (!$hreflink) + continue; + $firstspan = null; + foreach ($a->getElementsByTagName("span") as $span) { + if ($firstspan == null) + $firstspan = $span; + if ($span->getAttribute("class") == $descclass) + $breadcrumbs = $span->nodeValue; + } + foreach ($a->parentNode->parentNode->getElementsByTagName("table")[0]->getElementsByTagName("span") as $span) + if ($span->getAttribute("class") == $descclass) + $description = $span->nodeValue; + $results[] = ["url" => $hreflink, "title" => $firstspan->nodeValue, "breadcrumbs" => $breadcrumbs, "description" => $description]; + } + $suggested = []; + if ($resultsforclass) + foreach ($x->getElementsByTagName("a") as $a) + if (str_contains($a->getAttribute("class"), $resultsforclass)) + if (str_contains($a->getAttribute("href"), "&spell=1&") || (str_contains($a->getAttribute("href"), "&nfpr=1&") && sizeof($suggested) > 0)) + $suggested[] = $a->nodeValue; + if (sizeof($suggested) > 1 && !$noredirect) // aaaaaaaaaaa tukaj obstaja še ... "Skupaj z rezultati za" response!!!!!!!! + $s = $suggested[0]; + $suggestion = false; + if (sizeof($suggested) == 1 || ($noredirect && sizeof($suggested) > 0)) + $suggestion = $suggested[0]; + return ["status" => true, "query" => $s, "suggestion" => $suggestion, "results" => $results]; +} +function template ($title, $queryinfo, $body, $query = "", $additionalform = "", $imgfirst = false) { + $query = htmlspecialchars($query); + $title = htmlspecialchars($title); + $buttons = " + <button type=submit value=🔍 ><span>=></span></button> + <button accesskey=f type=submit name=f value=Ʊ ><span>1.</span></button> + <button accesskey=i type=submit name=i value=🖼><span>[^]</span></button> + "; + if ($imgfirst) { + $buttons = " + <button type=submit name=i value=🖼><span>[^]</span></button> + <button accesskey=i type=submit value=🔍 ><span>=></span></button> + <button accesskey=f type=submit name=f value=Ʊ ><span>1.</span></button> + "; + } + return " + <!DOCTYPE html> + <html lang=sl> + <head> + <meta charset=UTF-8> + <title>$title :: sear.c</title> + <meta name=viewport content=width='device-width, initial-scale=1'> + <link rel=stylesheet href=/css.css> + <link rel=icon type=image/x-icon href=favicon.ico> + <link title=sear.c rel=search type=application/opensearchdescription+xml href=/osdd.xml> + </head> + <body> + <form class=container action=.> + <input accesskey=s type=text name=q value='$query' placeholder='sear.php ...' size=50 /> + $buttons + $additionalform + </form> + <h3> + $queryinfo + </h3> + $body + <hr> + <h4 align=center> + <a href=//ni.šijanec.eu/projects/r/tree/prog/sear.php>sear.php</a> + <a href=javascript:window.external.AddSearchProvider(window.location.origin+'/osdd.xml') id=r hidden=hidden >registriraj v brskalnik</a> + </h4> + <script> + if (typeof window.external.AddSearchProvider === 'function') + document.getElementById('r').hidden = false; + </script> + </body> + "; +} +function results_html ($results, $plaintext, $limit) { + $r = ""; + $i = 0; + foreach ($results as $result) { + if ($limit && $i == $limit) + return $r; + $safeurl = htmlspecialchars($result["url"]); + if ($plaintext) + $safeurl = htmlspecialchars(str_replace("https:", "http:", $result["url"], 1)); + if (isset($result["imgsrc"])) { + $safeimgsrc = htmlspecialchars($result["imgsrc"]); + if ($plaintext) + $safeimgsrc = htmlspecialchars(str_replace("https:", "http:", $result["imgsrc"], 1)); + $r .= " + <a id=result$i class=result href='$safeurl'> + <img src='$safeimgsrc' /> + </a> + "; + } else { + $safetitle = trim(htmlspecialchars($result["title"])); + $safebreadcrumb = htmlspecialchars($result["breadcrumbs"]); + $safedesc = htmlspecialchars($result["description"]); + $r .= " + <div id=result$i class=result> + <h4> + <a href='$safeurl' accesskey=$i>$safetitle</a> + <span class=breadcrumb> + $safebreadcrumb + </span> + </h4> + <p> + $safedesc + </p> + </div> + "; + } + $i++; + } + return $r; +} +function handle_response ($query, $response, $limit, $plaintext, $horseshoe, $add_url, $add_form, $image) { + if (sizeof($response["results"]) == 0) + die(template($query, "ni rezultatov", "vaše iskanje ni obrodilo sadov.", $query, "", $image)); + if ($horseshoe) + header("Location: " . $response["results"][0]["url"]); + $queryinfo = ""; + if ($response["query"] != $query) { + $safequeryurl = urlencode($query); + $safequeryhtml = htmlspecialchars($query); + $queryinfo .= "preusmeril sem vas iz <a href='?e=e$add_url&q=$safequeryurl'>$safequeryhtml</a> | "; + } + if ($response["suggestion"] != false) { + $safequeryurl = urlencode($response["suggestion"]); + $safequeryhtml = htmlspecialchars($response["suggestion"]); + $queryinfo .= "predlagam iskanje <a href='?e=e$add_url&q=$safequeryurl'>$safequeryhtml</a> | "; + } + $queryinfo .= sizeof($response["results"]) . " zadetkov"; + $resultshtml = results_html($response["results"], $plaintext, $limit); + die(template($response["query"], $queryinfo, $resultshtml, $response["query"], $add_form, $image)); +} +$add_form = ""; +$add_url = ""; +$q = null; +if (isset($_REQUEST["q"])) + $q = $_REQUEST["q"]; +$image = false; +if (!empty($_REQUEST["i"])) + $image = true; +$exact = false; +if (!empty($_REQUEST["e"])) { + $add_url .= "&e=e"; + $exact = true; + $add_form .= "<input type=hidden name=e value=e />"; +} +if (!empty($_REQUEST["json"])) { + header("Content-Type: application/json"); + die(json_encode(query_google($q, $image, $exact))); +} +$limit = false; +if (!empty($_REQUEST["l"])) { + $limit = int($_REQUEST["l"]); + $add_url .= "&l=$limit"; + $add_form .= "<input type=hidden name=l value=$limit />"; +} +$plaintext = false; +if (!empty($_REQUEST["h"])) { + $plaintext = true; + $add_url .= "&h=h"; + $add_form .= "<input type=hidden name=h value=h />"; +} +$horseshoe = false; +if (!empty($_REQUEST["f"])) { + $horseshoe = true; + $add_url .= "&f=f"; + $add_form .= "<input type=hidden name=f value=f />"; +} +if ($q == null) { + die(template("", "iskalnik sear.php", "dobrodošli v iskalniku sear.php, naslednjiku programa sear.c. za iskanje po spletu nekaj vnesite v iskalno vrstico zgoraj in pritisnite na gumb.")); +} +$bindstrings = []; +foreach (net_get_interfaces() as $interface) + foreach ($interface["unicast"] as $unicast) { + if (!isset($unicast["address"])) + continue; + $address = $unicast["address"]; + if ($address == "::1") // tu timeouta + continue; + $bindstring = "$address:0"; + if (str_contains($address, ":")) + $bindstring = "[$address]:0"; + $bindstrings[] = $bindstring; + } +if (getenv("BINDSTRINGS")) + $bindstrings = explode(",", getenv("BINDSTRINGS")); +foreach ($bindstrings as $bindstring) { + // file_put_contents("/dev/stderr", "trying bindstring $bindstring\n"); + $response = query_google($q, $image, $exact, $bindstring); + if ($response["status"] == true) + break; + if ($response["code"] == "captcha") + continue; + if ($response["code"] == "failed") + continue; + break; +} +if ($response["status"] != true) { + if ($response["code"] == "captcha") { + foreach (["http://searc.oliwerix.com/sear.php?ref=b"] as $fallback) { + $add_url = ""; + if ($exact) + $add_url .= "&e=e"; + $json = json_decode(file_get_contents($fallback . $add_url . "&q=" . urlencode($q)), true); + if (!isset($json["status"])) + continue; + if ($json["status"] == false) { + if ($json["code"] == "captcha") + continue; + die(template("napaka", "napaka pri posredovanju zahteve", "ker je poizvedba vrnila captcho, sem jo posredoval na drug strežnik, ta pa je vrnil napako " . $json["code"] . ".", $q)); + } + handle_response($q, $json, $limit, $plaintext, $horseshoe, $add_url, $add_form, $image); + } + die(template("napaka", "iskalno zaledje omejuje iskanja", "iskalno zaledje se je odzvalo s CAPTCHO, češ, da ta instanca prehitro pošilja zahteve. obenem se je enako zgodilo tudi vsem rezervnim strežnikom. iščete lahko ročno preko spletne strani zaledne storitve: <a href='" . htmlspecialchars($response["url"]) . "'>kliknite sem</a>.", $q)); + } + die(template("napaka", "napaka pri poizvedbi", "poizvedba na iskalno zaledje je vrnila napako " . $response["code"] . ".", $q)); +} +handle_response($q, $response, $limit, $plaintext, $horseshoe, $add_url, $add_form, $image); +?> diff --git a/prog/sear.php/osdd.xml b/prog/sear.php/osdd.xml new file mode 100644 index 0000000..3b8b504 --- /dev/null +++ b/prog/sear.php/osdd.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> + percent percent. --> +<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" > + <ShortName>sear.c @ REPLACEME</ShortName> + <Description>sear.c @ REPLACEME</Description> + <Url type="text/html" method="get" template="http://REPLACEME/?q={searchTerms}" /> + <Image height="16" width="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA/wAAAP////////////////8AAAD/AAAA////////////////////////////////////////////AAAA/////////////////////////////////wAAAP8AAAD//////////////////////////////////////wAAAP//////////////////////////////////////AAAA/wAAAP//////////////////////////////////////AAAA/wAAAP////////////////////////////////8AAAD/AAAA/////////////////////////////////////////////////////////////////////////////////wAAAP8AAAD//////wAAAP8AAAD/AAAA////////////////////////////////////////////////////////////AAAA/wAAAP////////////////8AAAD//////////////////////////////////////////////////////wAAAP///////////////////////////wAAAP///////////////////////////////////////////wAAAP//////////////////////AAAA////////////AAAA/////////////////wAAAP8AAAD///////////8AAAD///////////////////////////8AAAD//////wAAAP///////////wAAAP///////////wAAAP//////AAAA//////////////////////8AAAD///////////8AAAD//////////////////////wAAAP////////////////8AAAD///////////////////////////8AAAD//////////////////////wAAAP///////////wAAAP///////////wAAAP////////////////8AAAD/////////////////////////////////AAAA/wAAAP//////////////////////AAAA/wAAAP8AAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image> +</OpenSearchDescription> |