From 3aa01807741ffad103b9f6a74d878e58f2e828e8 Mon Sep 17 00:00:00 2001 From: lolcat Date: Mon, 16 Oct 2023 02:30:43 -0400 Subject: [PATCH] captcha and imgur, findthatmeme, yep imagesearch --- README.md | 20 ++- admin.php | 0 api.txt | 18 +- api/v1/ac.php | 4 +- api/v1/images.php | 6 + api/v1/music.php | 7 + api/v1/news.php | 6 + api/v1/videos.php | 6 + api/v1/web.php | 6 + captcha.php | 147 +++++++++++++++++ data/captcha/font.ttf | Bin 0 -> 125972 bytes images.php | 10 +- lib/captcha_gen.php | 325 +++++++++++++++++++++++++++++++++++++ lib/curlproxy.php | 5 + lib/frontend.php | 26 ++- lib/nextpage.php | 2 +- music.php | 10 +- news.php | 10 +- scraper/ftm.php | 148 +++++++++++++++++ scraper/imgur.php | 249 ++++++++++++++++++++++++++++ scraper/pinterest.php | 224 +++++++++++++++++++++++++ scraper/yep.php | 370 ++++++++++++++++++++++++++++++++++++++++++ settings.php | 21 ++- static/style.css | 75 ++++++++- videos.php | 10 +- web.php | 68 ++++---- 26 files changed, 1710 insertions(+), 63 deletions(-) create mode 100644 admin.php create mode 100755 captcha.php create mode 100644 data/captcha/font.ttf create mode 100644 lib/captcha_gen.php create mode 100644 scraper/ftm.php create mode 100644 scraper/imgur.php create mode 100644 scraper/pinterest.php create mode 100644 scraper/yep.php diff --git a/README.md b/README.md index 651944a..70c475e 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ https://4get.ca - Yandex - Google - Brave + - Yep + - Imgur + - FindThatMeme 3. Videos - YouTube @@ -39,6 +42,17 @@ https://4get.ca 5. Music - SoundCloud +6. Autocompleter + - Brave + - DuckDuckGo + - Yandex + - Google + - Qwant + - Yep + - Marginalia + - YouTube + - SoundCloud + More scrapers are coming soon. I currently want to add Google web/video/news search, HackerNews (durr orange site!!) and Qwant. A shopping and files tab is also in my todo list. # Setup @@ -166,7 +180,11 @@ certbot --nginx --key-type ecdsa -d www.yourdomain.com -d yourdomain.com After doing that certbot should deploy the certificate automatically into your 4get nginx config file. It should be ready to use at that point. -Ok bye!!! +## Captcha + +Right now the setup for this shit is absolutely awful. + +Edit line 190 in `lib/captcha_gen.php` and specify your image sets. You can't disable the captcha right now lol. Just use a previous commit if you want to do that. Call me a shitcoder all you want I've had no energy lately. Images must be stored in `data/captcha`. Create a folder for each category. All files in there should be named from `1.png` to `321839.png`, for example. ## Tor Setup diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..e69de29 diff --git a/api.txt b/api.txt index 40b0ed3..f3c8b17 100644 --- a/api.txt +++ b/api.txt @@ -30,12 +30,25 @@ under your own terms. Please respect the terms of use listed here so that this website may be available to all in the far future. + P.s fuck whoever botted my site for months on end, choke on my dick + lol!!!! + Get your instance running here :: https://git.lolcat.ca/lolcat/4get Thanks! ++ Passes + Depending of the instance, you may need to provide a "pass" token + in the cookies of your request. These can be obtained from solving + a captcha which will allow you to make 100 requests in the next 24 + hours. In the future, you will be able to ask the serber maintainer + for a "pass" which will allow you to bypass the captcha requirement. + + The captcha doesn't need javascript to work. + + + Decode the data All payloads returned by the API are encoded in the JSON format. If you don't know how to tackle the problem, maybe programming is not @@ -47,8 +60,11 @@ + Check if an API call was successful All API responses come with an array index named "status". If the status is something else than the string "ok", something went wrong. + You can supply the content of the "status" string back to your + application to inform the user of what went wrong. - The HTTP code will always be 200 as to not cause issues with CORS. + The HTTP code will be 429 if your pass is invalid. It is set to 200 + otherwise. + Get the next page of results diff --git a/api/v1/ac.php b/api/v1/ac.php index 0964fd9..3ee1481 100644 --- a/api/v1/ac.php +++ b/api/v1/ac.php @@ -17,7 +17,7 @@ class autocomplete{ "yep" => "https://api.yep.com/ac/?query={searchTerms}", "marginalia" => "https://search.marginalia.nu/suggest/?partial={searchTerms}", "yt" => "https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&q={searchTerms}", - "sc" => "https://api-v2.soundcloud.com/search/queries?q={searchTerms}&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=10&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en" + "sc" => "https://api-v2.soundcloud.com/search/queries?q={searchTerms}&client_id=ArYppSEotE3YiXCO4Nsgid2LLqJutiww&limit=10&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en" ]; /* @@ -100,7 +100,7 @@ class autocomplete{ foreach($js[1] as $item){ - $json[] = strip_tags($item[0]); + $json[] = htmlspecialchars_decode(strip_tags($item[0])); } echo json_encode( diff --git a/api/v1/images.php b/api/v1/images.php index 694658e..474e2dd 100644 --- a/api/v1/images.php +++ b/api/v1/images.php @@ -7,6 +7,12 @@ chdir("../../"); include "lib/frontend.php"; $frontend = new frontend(); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, false); + [$scraper, $filters] = $frontend->getscraperfilters( "images", isset($_GET["scraper"]) ? $_GET["scraper"] : null diff --git a/api/v1/music.php b/api/v1/music.php index faf2d96..7512ac0 100644 --- a/api/v1/music.php +++ b/api/v1/music.php @@ -7,6 +7,13 @@ chdir("../../"); include "lib/frontend.php"; $frontend = new frontend(); +/* + Captcha +*/ +$null = null; +include "lib/captcha_gen.php"; +new captcha($null, $null, $null, $null, false); + [$scraper, $filters] = $frontend->getscraperfilters( "music", isset($_GET["scraper"]) ? $_GET["scraper"] : null diff --git a/api/v1/news.php b/api/v1/news.php index 775ef94..97738fc 100644 --- a/api/v1/news.php +++ b/api/v1/news.php @@ -7,6 +7,12 @@ chdir("../../"); include "lib/frontend.php"; $frontend = new frontend(); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, false); + [$scraper, $filters] = $frontend->getscraperfilters( "news", isset($_GET["scraper"]) ? $_GET["scraper"] : null diff --git a/api/v1/videos.php b/api/v1/videos.php index 225611a..9277792 100644 --- a/api/v1/videos.php +++ b/api/v1/videos.php @@ -7,6 +7,12 @@ chdir("../../"); include "lib/frontend.php"; $frontend = new frontend(); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, false); + [$scraper, $filters] = $frontend->getscraperfilters( "videos", isset($_GET["scraper"]) ? $_GET["scraper"] : null diff --git a/api/v1/web.php b/api/v1/web.php index 7f6d769..c479149 100644 --- a/api/v1/web.php +++ b/api/v1/web.php @@ -7,6 +7,12 @@ chdir("../../"); include "lib/frontend.php"; $frontend = new frontend(); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, false); + [$scraper, $filters] = $frontend->getscraperfilters( "web", isset($_GET["scraper"]) ? $_GET["scraper"] : null diff --git a/captcha.php b/captcha.php new file mode 100755 index 0000000..21da034 --- /dev/null +++ b/captcha.php @@ -0,0 +1,147 @@ + "#ebdbb2", + "fg" => "#1d2021" + ]; +}else{ + + $theme = [ + "bg" => "#1d2021", + "fg" => "#ebdbb2" + ]; +} + +$im = new Imagick(); +$im->newImage(400, 400, $theme["bg"]); +$im->setImageBackgroundColor($theme["bg"]); +$im->setImageFormat("jpg"); + +$noise = [ + imagick::NOISE_GAUSSIAN, + imagick::NOISE_LAPLACIAN +]; + +$distort = [ + imagick::DISTORTION_AFFINE, + imagick::DISTORTION_SHEPARDS +]; + +$i = 0; +for($y=0; $y<4; $y++){ + + for($x=0; $x<4; $x++){ + + $tmp = new Imagick("./data/captcha/" . $grid[0][$i][0] . "/" . random_int(1, $grid[0][$i][1]) . ".png"); + + // convert transparency correctly + $tmp->setImageBackgroundColor("black"); + $tmp->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE); + + // distort $tmp + $tmp->distortImage( + $distort[random_int(0,1)], + [ + 0, 0, + random_int(-15, 15), random_int(-15, 15), + + 100, 0, + random_int(80, 120), random_int(-15, 15), + + 100, 100, + random_int(80, 120), random_int(80, 120), + + 0, 100, + random_int(-15, 15), random_int(80, 120) + ], + false + ); + + // append image + $im->compositeImage($tmp->getImage(), Imagick::COMPOSITE_DEFAULT, $x * 100, $y * 100); + + $i++; + } +} + +// add noise +$im->addNoiseImage($noise[random_int(0, 1)]); + +// expand top of image +$im->setImageGravity(Imagick::GRAVITY_SOUTH); +$im->chopImage(0, -27, 400, 400); +$im->extentImage(0, 0, 0, -27); + +// add text +$draw = new ImagickDraw(); +$draw->setFontSize(20); +$draw->setFillColor($theme["fg"]); +//$draw->setTextAntialias(false); +$draw->setFont("./data/captcha/font.ttf"); + +$text = "Pick " . $grid[1] . " images of " . str_replace("_", " ", $grid[2]); + +$pos = 200 - ($im->queryFontMetrics($draw, $text)["textWidth"] / 2); + +for($i=0; $iannotateImage( + $draw, + $pos, + 20, + random_int(-15, 15), + $text[$i] + ); + + $pos += $im->queryFontMetrics($draw, $text[$i])["textWidth"]; + +} + +$im->setFormat("jpeg"); +$im->setImageCompressionQuality(90); +$im->setImageCompression(Imagick::COMPRESSION_JPEG2000); +echo $im->getImageBlob(); diff --git a/data/captcha/font.ttf b/data/captcha/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..13f5dc7dd316bb11f555b7cceff37b8f33c50922 GIT binary patch literal 125972 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%0A)?DxkSa1)q#TE= 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, $filters); -$frontend->loadheader( - $get, - $filters, - "images" -); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, $get, $filters, "images", true); $payload = [ "images" => "", diff --git a/lib/captcha_gen.php b/lib/captcha_gen.php new file mode 100644 index 0000000..2ae824b --- /dev/null +++ b/lib/captcha_gen.php @@ -0,0 +1,325 @@ += 102){ + + // reached limit, delete and give captcha + apcu_delete($_COOKIE["pass"]); + }else{ + + // the cookie is OK! dont die() and give results + if($output === true){ + $frontend->loadheader( + $get, + $filters, + $page + ); + } + return; + } + } + } + + if($output === false){ + + echo json_encode([ + "status" => "The \"pass\" token in your cookies is missing or has expired!!" + ]); + die(); + } + + /* + Validate form data + */ + $lines = + explode( + "\r\n", + file_get_contents("php://input") + ); + + $invalid = false; + $answers = []; + $key = false; + $error = ""; + + foreach($lines as $line){ + + $line = explode("=", $line, 2); + + if(count($line) !== 2){ + + $invalid = true; + break; + } + + preg_match( + '/^c\[([0-9]+)\]$/', + $line[0], + $regex + ); + + if( + $line[1] != "on" || + !isset($regex[0][1]) + ){ + + // check if its k + if( + $line[0] == "k" && + strpos($line[1], "c.") === 0 + ){ + + $key = apcu_fetch($line[1]); + apcu_delete($line[1]); + } + break; + } + + $regex = (int)$regex[1]; + + if( + $regex >= 16 || + $regex <= -1 + ){ + + $invalid = true; + break; + } + + $answers[] = $regex; + } + + if( + !$invalid && + $key !== false + ){ + $check = $key[1]; + + // validate answer + for($i=0; $i time() + 86400, // expires in 24 hours + "samesite" => "Strict", + "path" => "/" + ] + ); + + $frontend->loadheader( + $get, + $filters, + $page + ); + return; + + }else{ + + $error = ""; + } + } + + /* + Generate random grid data to pass to captcha.php + */ + $dataset = [ + ["birds", 2263], + ["fumo_plushies", 1006], + ["minecraft", 848] + ]; + + // get the positions for the answers + // will return between 3 and 6 answer positions + $range = range(0, 15); + $answer_pos = []; + + array_splice($range, 0, 1); + + for($i=0; $i "", + "right-left" => "", + "right-right" => "", + "left" => + '
' . + '

IQ test

' . + 'Due to getting hit with 20,000 bot requests per day, I had to put this up. Sorry.

' . + 'Solving this captcha will allow you to make 100 searches today. I will add a way for legit users to bypass the captcha later. Sorry /g/tards!!' . + $error . + '
' . + '
' . + '
' . + 'Captcha image' . + '
' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '
' . + '
' . + '
' . + '' . + '' . + '
' . + '
' + ]; + + http_response_code(429); // too many reqs + $frontend->loadheader( + $get, + $filters, + "web" + ); + + echo $frontend->load("search.html", $payload); + die(); + } +} diff --git a/lib/curlproxy.php b/lib/curlproxy.php index 93cdbdc..ef9085b 100644 --- a/lib/curlproxy.php +++ b/lib/curlproxy.php @@ -127,6 +127,11 @@ class proxy{ throw new Exception("Too many redirects"); } + if($url == "https://i.imgur.com/removed.png"){ + + throw new Exception("Encountered imgur 404"); + } + // sanitize URL if($this->validateurl($url) === false){ diff --git a/lib/frontend.php b/lib/frontend.php index 4c5e232..97c8c5b 100644 --- a/lib/frontend.php +++ b/lib/frontend.php @@ -901,7 +901,11 @@ class frontend{ "ddg" => "DuckDuckGo", "yandex" => "Yandex", "brave" => "Brave", - "google" => "Google" + "google" => "Google", + "yep" => "Yep", + //"pinterest" => "Pinterest", + "imgur" => "Imgur", + "ftm" => "FindThatMeme" ] ]; break; @@ -1011,10 +1015,30 @@ class frontend{ $lib = new wiby(); break; + case "yep": + include "scraper/yep.php"; + $lib = new yep(); + break; + case "sc": include "scraper/sc.php"; $lib = new sc(); break; + + case "pinterest": + include "scraper/pinterest.php"; + $lib = new pinterest(); + break; + + case "imgur": + include "scraper/imgur.php"; + $lib = new imgur(); + break; + + case "ftm": + include "scraper/ftm.php"; + $lib = new ftm(); + break; } // set scraper on $_GET diff --git a/lib/nextpage.php b/lib/nextpage.php index 3fab855..7516667 100644 --- a/lib/nextpage.php +++ b/lib/nextpage.php @@ -26,7 +26,7 @@ class nextpage{ apcu_store( $page . "." . $this->scraper . - (string)($key), + (string)$key, gzdeflate($salt.$iv.$out.$tag), 900 // cache information for 15 minutes blaze it ); diff --git a/music.php b/music.php index 61078b9..c95fb4c 100644 --- a/music.php +++ b/music.php @@ -10,11 +10,11 @@ $frontend = new frontend(); $get = $frontend->parsegetfilters($_GET, $filters); -$frontend->loadheader( - $get, - $filters, - "music" -); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, $get, $filters, "music", true); $payload = [ "class" => "", diff --git a/news.php b/news.php index eb5817f..ff37489 100644 --- a/news.php +++ b/news.php @@ -10,11 +10,11 @@ $frontend = new frontend(); $get = $frontend->parsegetfilters($_GET, $filters); -$frontend->loadheader( - $get, - $filters, - "news" -); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, $get, $filters, "news", true); $payload = [ "class" => "", diff --git a/scraper/ftm.php b/scraper/ftm.php new file mode 100644 index 0000000..af39c12 --- /dev/null +++ b/scraper/ftm.php @@ -0,0 +1,148 @@ +nextpage = new nextpage("ftm"); + } + + public function getfilters($page){ + + return []; + } + + private function get($url, $search, $offset){ + + $curlproc = curl_init(); + + curl_setopt($curlproc, CURLOPT_URL, $url); + + $payload = + json_encode( + [ + "search" => $search, + "offset" => $offset + ] + ); + + curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding + curl_setopt($curlproc, CURLOPT_HTTPHEADER, + ["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0", + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding: gzip", + "Content-Length: " . strlen($payload), + "Content-Type: application/json", + "DNT: 1", + "Connection: keep-alive", + "Origin: https://findthatmeme.com", + "Referer: https://findthatmeme.com/?search=" . urlencode($search), + "Upgrade-Insecure-Requests: 1", + "Sec-Fetch-Dest: document", + "Sec-Fetch-Mode: navigate", + "Sec-Fetch-Site: none", + "Sec-Fetch-User: ?1", + "X-Auth-Key: undefined", + "X-CSRF-Validation-Header: true"] + ); + + curl_setopt($curlproc, CURLOPT_POST, true); + curl_setopt($curlproc, CURLOPT_POSTFIELDS, $payload); + + curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($curlproc, CURLOPT_TIMEOUT, 30); + + $data = curl_exec($curlproc); + + if(curl_errno($curlproc)){ + + throw new Exception(curl_error($curlproc)); + } + + curl_close($curlproc); + return $data; + } + + public function image($get){ + + $search = $get["s"]; + + $out = [ + "status" => "ok", + "npt" => null, + "image" => [] + ]; + + if($get["npt"]){ + + $count = (int)$this->nextpage->get($get["npt"], "images"); + }else{ + + $count = 0; + } + + try{ + $json = + json_decode( + $this->get( + "https://findthatmeme.com/api/v1/search", + $search, + $count + ), + true + ); + + }catch(Exception $error){ + + throw new Exception("Failed to fetch JSON"); + } + + if($json === null){ + + throw new Exception("Failed to decode JSON"); + } + + foreach($json as $item){ + + $count++; + + if($item["type"] == "VIDEO"){ + + $thumb = "thumb/" . $item["thumbnail"]; + }else{ + + $thumb = $item["image_path"]; + } + + $out["image"][] = [ + "title" => date("jS \of F Y @ g:ia", strtotime($item["created_at"])), + "source" => [ + [ + "url" => + "https://findthatmeme.us-southeast-1.linodeobjects.com/" . + $thumb, + "width" => null, + "height" => null + ] + ], + "url" => $item["source_page_url"] + ]; + } + + if($count === 50){ + + $out["npt"] = + $this->nextpage->store( + $count, + "images" + ); + } + + return $out; + } +} diff --git a/scraper/imgur.php b/scraper/imgur.php new file mode 100644 index 0000000..4a16de7 --- /dev/null +++ b/scraper/imgur.php @@ -0,0 +1,249 @@ +nextpage = new nextpage("imgur"); + + include "lib/fuckhtml.php"; + $this->fuckhtml = new fuckhtml(); + } + + public function getfilters($page){ + + return [ + "sort" => [ // /score/ + "display" => "Sort by", + "option" => [ + "score" => "Highest scoring", + "relevance" => "Most relevant", + "time" => "Newest first" + ] + ], + "time" => [ // /score/day/ + "display" => "Time posted", + "option" => [ + "all" => "All time", + "day" => "Today", + "week" => "This week", + "month" => "This month", + "year" => "This year" + ] + ], + "format" => [ // q_type + "display" => "Format", + "option" => [ + "any" => "Any format", + "jpg" => "JPG", + "png" => "PNG", + "gif" => "GIF", + "anigif" => "Animated GIF", + "album" => "Albums" + ] + ], + "size" => [ // q_size_px + "display" => "Size", + "option" => [ + "any" => "Any size", + "small" => "Small (500px or less)", + "med" => "Medium (500px to 2000px)", + "big" => "Big (2000px to 5000px)", + "lrg" => "Large (5000px to 10000px)", + "huge" => "Huge (10000px and above)" + ] + ] + ]; + } + + private function get($url, $get = []){ + + $curlproc = curl_init(); + + if($get !== []){ + $get = http_build_query($get); + $url .= "?scrolled&" . $get; + } + + curl_setopt($curlproc, CURLOPT_URL, $url); + + curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding + curl_setopt($curlproc, CURLOPT_HTTPHEADER, + ["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0", + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding: gzip", + "DNT: 1", + "Referer: https://imgur.com/search/", + "Connection: keep-alive", + "Sec-Fetch-Dest: empty", + "Sec-Fetch-Mode: cors", + "Sec-Fetch-Site: same-origin", + "TE: trailers", + "X-Requested-With: XMLHttpRequest"] + ); + + curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($curlproc, CURLOPT_TIMEOUT, 30); + + $data = curl_exec($curlproc); + + if(curl_errno($curlproc)){ + + throw new Exception(curl_error($curlproc)); + } + + curl_close($curlproc); + return $data; + } + + public function image($get){ + + if($get["npt"]){ + + $filter = + json_decode( + $this->nextpage->get( + $get["npt"], + "images" + ), + true + ); + + $search = $filter["s"]; + unset($filter["s"]); + + $sort = $filter["sort"]; + unset($filter["sort"]); + + $time = $filter["time"]; + unset($filter["time"]); + + $format = $filter["format"]; + unset($filter["format"]); + + $size = $filter["size"]; + unset($filter["size"]); + + $page = $filter["page"]; + unset($filter["page"]); + }else{ + + $search = $get["s"]; + $sort = $get["sort"]; + $time = $get["time"]; + $format = $get["format"]; + $size = $get["size"]; + $page = 0; + + $filter = [ + "q" => $search + ]; + + if($format != "any"){ + + $filter["q_type"] = $format; + } + + if($size != "any"){ + + $filter["q_size_px"] = $size; + $filter["q_size_is_mpx"] = "off"; + } + } + + $out = [ + "status" => "ok", + "npt" => null, + "image" => [] + ]; + + try{ + $html = + $this->get( + "https://imgur.com/search/$sort/$time/page/$page", + $filter + ); + + }catch(Exception $error){ + + throw new Exception("Failed to fetch HTML"); + } + + $this->fuckhtml->load($html); + + $posts = + $this->fuckhtml + ->getElementsByClassName( + "post", + "div" + ); + + foreach($posts as $post){ + + $this->fuckhtml->load($post); + + $image = + $this->fuckhtml + ->getElementsByTagName("img")[0]; + + $image_url = "https:" . substr($this->fuckhtml->getTextContent($image["attributes"]["src"]), 0, -5); + + $out["image"][] = [ + "title" => + $this->fuckhtml + ->getTextContent( + $image["attributes"]["alt"] + ), + "source" => [ + [ + "url" => $image_url . ".jpg", + "width" => null, + "height" => null + ], + [ + "url" => $image_url . "m.jpg", + "width" => null, + "height" => null + ] + ], + "url" => + "https://imgur.com" . + $this->fuckhtml + ->getTextContent( + $this->fuckhtml + ->getElementsByClassName( + "image-list-link", + "a" + ) + [0] + ["attributes"] + ["href"] + ) + ]; + } + + if(isset($out["image"][0])){ + + // store nextpage + $filter["s"] = $search; + $filter["sort"] = $sort; + $filter["time"] = $time; + $filter["format"] = $format; + $filter["size"] = $size; + $filter["page"] = $page + 1; + + $out["npt"] = + $this->nextpage->store( + json_encode($filter), + "images" + ); + } + + return $out; + } +} diff --git a/scraper/pinterest.php b/scraper/pinterest.php new file mode 100644 index 0000000..2bb5b71 --- /dev/null +++ b/scraper/pinterest.php @@ -0,0 +1,224 @@ +nextpage = new nextpage("pinterest"); + } + + public function getfilters($page){ + + return []; + } + + private function get($url, $get = []){ + + $curlproc = curl_init(); + + if($get !== []){ + $get = http_build_query($get); + $url .= "?" . $get; + } + + curl_setopt($curlproc, CURLOPT_URL, $url); + + curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding + curl_setopt($curlproc, CURLOPT_HTTPHEADER, + ["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0", + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding: gzip", + "DNT: 1", + "Connection: keep-alive", + "Upgrade-Insecure-Requests: 1", + "Sec-Fetch-Dest: document", + "Sec-Fetch-Mode: navigate", + "Sec-Fetch-Site: none", + "Sec-Fetch-User: ?1"] + ); + + curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($curlproc, CURLOPT_TIMEOUT, 30); + + $data = curl_exec($curlproc); + + if(curl_errno($curlproc)){ + + throw new Exception(curl_error($curlproc)); + } + + curl_close($curlproc); + return $data; + } + + public function image($get){ + + $search = $get["s"]; + + $out = [ + "status" => "ok", + "npt" => null, + "image" => [] + ]; + + $filter = [ + "source_url" => "/search/pins/?q=" . urlencode($search), + "rs" => "typed", + "data" => + json_encode( + [ + "options" => [ + "article" => null, + "applied_filters" => null, + "appliedProductFilters" => "---", + "auto_correction_disabled" => false, + "corpus" => null, + "customized_rerank_type" => null, + "filters" => null, + "query" => $search, + "query_pin_sigs" => null, + "redux_normalize_feed" => true, + "rs" => "typed", + "scope" => "pins", // pins, boards, videos, + "source_id" => null + ], + "context" => [] + ] + ), + "_" => substr(str_replace(".", "", (string)microtime(true)), 0, -1) + ]; + + try{ + $json = + json_decode( + $this->get( + "https://www.pinterest.ca/resource/BaseSearchResource/get/", + $filter + ), + true + ); + + }catch(Exception $error){ + + throw new Exception("Failed to fetch JSON"); + } + + if($json === null){ + + throw new Exception("Failed to decode JSON"); + } + + //print_r($json); + + foreach( + $json + ["resource_response"] + ["data"] + ["results"] + as $item + ){ + + switch($item["type"]){ + + case "pin": + + /* + Handle image object + */ + $images = array_values($item["images"]); + $image = &$images[count($images) - 1]; // original + $thumb = &$images[1]; // 236x + + $title = []; + + if( + isset($item["grid_title"]) && + trim($item["grid_title"]) != "" + ){ + + $title[] = $item["grid_title"]; + } + + if( + isset($item["description"]) && + trim($item["description"]) != "" + ){ + + $title[] = $item["description"]; + } + + $title = implode(": ", $title); + + if( + $title == "" && + isset($item["board"]["name"]) && + trim($item["board"]["name"]) != "" + ){ + + $title = $item["board"]["name"]; + } + + if($title == ""){ + + $title = null; + } + + $out["image"][] = [ + "title" => $title, + "source" => [ + [ + "url" => $image["url"], + "width" => (int)$image["width"], + "height" => (int)$image["height"] + ], + [ + "url" => $thumb["url"], + "width" => (int)$thumb["width"], + "height" => (int)$thumb["height"] + ] + ], + "url" => "https://www.pinterest.com/pin/" . $item["id"] + ]; + break; + + case "board": + + if(isset($item["cover_pin"]["image_url"])){ + + $image = [ + "url" => $item["cover_pin"]["image_url"], + "width" => (int)$item["cover_pin"]["size"][0], + "height" => (int)$item["cover_pin"]["size"][1] + ]; + }elseif(isset($item["image_cover_url_hd"])){ + /* + $image = [ + "url" => + "width" => null, + "height" => null + ];*/ + } + break; + } + } + + return $out; + } + + private function getfullresimage($image, $has_og){ + + $has_og = $has_og ? "1200x" : "originals"; + + return + preg_replace( + '/https:\/\/i\.pinimg\.com\/[^\/]+\//', + "https://i.pinimg.com/" . $has_og . "/", + $image + ); + } +} diff --git a/scraper/yep.php b/scraper/yep.php new file mode 100644 index 0000000..8ff4a57 --- /dev/null +++ b/scraper/yep.php @@ -0,0 +1,370 @@ +nextpage = new nextpage("yep"); + } + + public function getfilters($page){ + + return [ + "country" => [ + "display" => "Country", + "option" => [ + "all" => "All regions", + "af" => "Afghanistan", + "al" => "Albania", + "dz" => "Algeria", + "as" => "American Samoa", + "ad" => "Andorra", + "ao" => "Angola", + "ai" => "Anguilla", + "ag" => "Antigua and Barbuda", + "ar" => "Argentina", + "am" => "Armenia", + "aw" => "Aruba", + "au" => "Australia", + "at" => "Austria", + "az" => "Azerbaijan", + "bs" => "Bahamas", + "bh" => "Bahrain", + "bd" => "Bangladesh", + "bb" => "Barbados", + "by" => "Belarus", + "be" => "Belgium", + "bz" => "Belize", + "bj" => "Benin", + "bt" => "Bhutan", + "bo" => "Bolivia", + "ba" => "Bosnia and Herzegovina", + "bw" => "Botswana", + "br" => "Brazil", + "bn" => "Brunei Darussalam", + "bg" => "Bulgaria", + "bf" => "Burkina Faso", + "bi" => "Burundi", + "cv" => "Cabo Verde", + "kh" => "Cambodia", + "cm" => "Cameroon", + "ca" => "Canada", + "ky" => "Cayman Islands", + "cf" => "Central African Republic", + "td" => "Chad", + "cl" => "Chile", + "cn" => "China", + "co" => "Colombia", + "cg" => "Congo", + "cd" => "Congo, Democratic Republic", + "ck" => "Cook Islands", + "cr" => "Costa Rica", + "hr" => "Croatia", + "cu" => "Cuba", + "cy" => "Cyprus", + "cz" => "Czechia", + "ci" => "Côte d'Ivoire", + "dk" => "Denmark", + "dj" => "Djibouti", + "dm" => "Dominica", + "do" => "Dominican Republic", + "ec" => "Ecuador", + "eg" => "Egypt", + "sv" => "El Salvador", + "gq" => "Equatorial Guinea", + "ee" => "Estonia", + "et" => "Ethiopia", + "fo" => "Faroe Islands", + "fj" => "Fiji", + "fi" => "Finland", + "fr" => "France", + "gf" => "French Guiana", + "pf" => "French Polynesia", + "ga" => "Gabon", + "gm" => "Gambia", + "ge" => "Georgia", + "de" => "Germany", + "gh" => "Ghana", + "gi" => "Gibraltar", + "gr" => "Greece", + "gl" => "Greenland", + "gd" => "Grenada", + "gp" => "Guadeloupe", + "gu" => "Guam", + "gt" => "Guatemala", + "gg" => "Guernsey", + "gn" => "Guinea", + "gy" => "Guyana", + "ht" => "Haiti", + "hn" => "Honduras", + "hk" => "Hong Kong", + "hu" => "Hungary", + "is" => "Iceland", + "in" => "India", + "id" => "Indonesia", + "iq" => "Iraq", + "ie" => "Ireland", + "im" => "Isle of Man", + "il" => "Israel", + "it" => "Italy", + "jm" => "Jamaica", + "jp" => "Japan", + "je" => "Jersey", + "jo" => "Jordan", + "kz" => "Kazakhstan", + "ke" => "Kenya", + "ki" => "Kiribati", + "kw" => "Kuwait", + "kg" => "Kyrgyzstan", + "la" => "Lao People's Democratic Republic", + "lv" => "Latvia", + "lb" => "Lebanon", + "ls" => "Lesotho", + "ly" => "Libya", + "li" => "Liechtenstein", + "lt" => "Lithuania", + "lu" => "Luxembourg", + "mk" => "Macedonia", + "mg" => "Madagascar", + "mw" => "Malawi", + "my" => "Malaysia", + "mv" => "Maldives", + "ml" => "Mali", + "mt" => "Malta", + "mq" => "Martinique", + "mr" => "Mauritania", + "mu" => "Mauritius", + "yt" => "Mayotte", + "mx" => "Mexico", + "fm" => "Micronesia, Federated States of", + "md" => "Moldova", + "mc" => "Monaco", + "mn" => "Mongolia", + "me" => "Montenegro", + "ms" => "Montserrat", + "ma" => "Morocco", + "mz" => "Mozambique", + "mm" => "Myanmar", + "na" => "Namibia", + "nr" => "Nauru", + "np" => "Nepal", + "nl" => "Netherlands", + "nc" => "New Caledonia", + "nz" => "New Zealand", + "ni" => "Nicaragua", + "ne" => "Niger", + "ng" => "Nigeria", + "nu" => "Niue", + "no" => "Norway", + "om" => "Oman", + "pk" => "Pakistan", + "ps" => "Palestine, State of", + "pa" => "Panama", + "pg" => "Papua New Guinea", + "py" => "Paraguay", + "pe" => "Peru", + "ph" => "Philippines", + "pn" => "Pitcairn", + "pl" => "Poland", + "pt" => "Portugal", + "pr" => "Puerto Rico", + "qa" => "Qatar", + "ro" => "Romania", + "ru" => "Russian Federation", + "rw" => "Rwanda", + "re" => "Réunion", + "sh" => "Saint Helena", + "kn" => "Saint Kitts and Nevis", + "lc" => "Saint Lucia", + "vc" => "Saint Vincent and the Grenadines", + "ws" => "Samoa", + "sm" => "San Marino", + "st" => "Sao Tome and Principe", + "sa" => "Saudi Arabia", + "sn" => "Senegal", + "rs" => "Serbia", + "sc" => "Seychelles", + "sl" => "Sierra Leone", + "sg" => "Singapore", + "sk" => "Slovakia", + "si" => "Slovenia", + "sb" => "Solomon Islands", + "so" => "Somalia", + "kr" => "Sourth Korea", + "za" => "South Africa", + "es" => "Spain", + "lk" => "Sri Lanka", + "sr" => "Suriname", + "se" => "Sweden", + "ch" => "Switzerland", + "tw" => "Taiwan", + "tj" => "Tajikistan", + "tz" => "Tanzania", + "th" => "Thailand", + "tl" => "Timor-Leste", + "tg" => "Togo", + "tk" => "Tokelau", + "to" => "Tonga", + "tt" => "Trinidad and Tobago", + "tn" => "Tunisia", + "tr" => "Turkey", + "tm" => "Turkmenistan", + "ug" => "Uganda", + "ua" => "Ukraine", + "ae" => "United Arab Emirates", + "gb" => "United Kingdom", + "us" => "United States", + "uy" => "Uruguay", + "uz" => "Uzbekistan", + "vu" => "Vanuatu", + "ve" => "Venezuela", + "vn" => "Vietnam", + "vg" => "Virgin Islands, British", + "vi" => "Virgin Islands, U.S.", + "ye" => "Yemen", + "zm" => "Zambia", + "zw" => "Zimbabwe" + ] + ], + "nsfw" => [ + "display" => "NSFW", + "option" => [ + "yes" => "Yes", + "maybe" => "Maybe", + "no" => "No" + ] + ] + ]; + } + + private function get($url, $get = []){ + + $curlproc = curl_init(); + + if($get !== []){ + $get = http_build_query($get); + $url .= "?" . $get; + } + + curl_setopt($curlproc, CURLOPT_URL, $url); + + curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding + curl_setopt($curlproc, CURLOPT_HTTPHEADER, + ["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0", + "Accept: */*", + "Accept-Language: en-US,en;q=0.5", + "Accept-Encoding: gzip", + "DNT: 1", + "Origin: https://yep.com", + "Referer: https://yep.com/", + "Connection: keep-alive", + "Sec-Fetch-Dest: empty", + "Sec-Fetch-Mode: cors", + "Sec-Fetch-Site: same-site"] + ); + + curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($curlproc, CURLOPT_TIMEOUT, 30); + + $data = curl_exec($curlproc); + + if(curl_errno($curlproc)){ + + throw new Exception(curl_error($curlproc)); + } + + curl_close($curlproc); + return $data; + } + + public function image($get){ + + $search = $get["s"]; + $country = $get["country"]; + $nsfw = $get["nsfw"]; + + switch($nsfw){ + + case "yes": $nsfw = "off"; break; + case "maybe": $nsfw = "moderate"; break; + case "no": $nsfw = "strict"; break; + } + + $out = [ + "status" => "ok", + "npt" => null, + "image" => [] + ]; + + try{ + + $json = + json_decode( + $this->get( + "https://api.yep.com/fs/2/search", + [ + "client" => "web", + "gl" => $country == "all" ? $country : strtoupper($country), + "no_correct" => "false", + "q" => $search, + "safeSearch" => $nsfw, + "type" => "images" + ] + ), + true + ); + }catch(Exception $error){ + + throw new Exception("Failed to fetch JSON"); + } + + if($json === null){ + + throw new Exception("Failed to decode JSON"); + } + + foreach($json[1]["results"] as $item){ + + if( + $item["width"] !== 0 && + $item["height"] !== 0 + ){ + + $thumb_width = $item["width"] >= 260 ? 260 : $item["width"]; + $thumb_height = ceil($item["height"] * ($thumb_width / $item["width"])); + + $width = $item["width"]; + $height = $item["height"]; + }else{ + + $thumb_width = null; + $thumb_height = null; + $width = null; + $height = null; + } + + $out["image"][] = [ + "title" => $item["title"], + "source" => [ + [ + "url" => $item["image_id"], + "width" => $width, + "height" => $height + ], + [ + "url" => $item["src"], + "width" => $thumb_width, + "height" => $thumb_height + ] + ], + "url" => $item["host_page"] + ]; + } + + return $out; + } +} diff --git a/settings.php b/settings.php index bce3af0..98e6b49 100644 --- a/settings.php +++ b/settings.php @@ -161,6 +161,22 @@ $settings = [ [ "value" => "google", "text" => "Google" + ], + [ + "value" => "yep", + "text" => "Yep" + ], + /*[ + "value" => "pinterest", + "text" => "Pinterest" + ],*/ + [ + "value" => "imgur", + "text" => "Imgur" + ], + [ + "value" => "ftm", + "text" => "FindThatMeme" ] ] ], @@ -243,7 +259,7 @@ if($_POST){ // refresh cookie dates $loop = &$_COOKIE; } - + foreach($loop as $key => $value){ foreach($settings as $title){ @@ -262,7 +278,8 @@ foreach($loop as $key => $value){ "", [ "expires" => -1, // removes cookie - "samesite" => "Strict" + "samesite" => "Strict", + "path" => "/" ] ); diff --git a/static/style.css b/static/style.css index ec55624..fdb4951 100644 --- a/static/style.css +++ b/static/style.css @@ -283,7 +283,79 @@ h3,h4,h5,h6{ WEB */ -/* Left wrapper */ +/* Captcha */ +.captcha-wrapper{ + position:relative; + max-width:400px; + margin:17px auto 0; + border:1px solid var(--928374); +} + +.captcha{ + padding-bottom:100%; + padding-top:6.2%; +} + +.captcha-wrapper img{ + position:absolute; + top:0; + left:0; + width:100%; + height:100%; +} + +.captcha-controls{ + position:absolute; + top:0; + left:0; + bottom:0; + right:0; + top:6.3%; +} + +.captcha-wrapper img{ + display:block; + background:#282828; +} + +.captcha-wrapper input{ + display:none; +} + +.captcha-wrapper label{ + float:left; + width:25%; + height:25%; + position:relative; + cursor:pointer; +} + +.captcha-wrapper label:hover{ + background:rgba(255,255,255,0.2); +} + +.captcha-wrapper input:checked + label{ + background:rgba(0,0,0,0.5); +} + +.captcha-wrapper input:checked + label:after{ + content:""; + position:absolute; + left:39%; + top:29%; + width:20%; + height:30%; + transform:rotate(45deg); + border-right:7px solid var(--ebdbb2); + border-bottom:7px solid var(--ebdbb2); + box-sizing:border-box; +} + +.captcha-submit{ + float:right; + margin:12px 0 4px; +} + .web .left{ width:40%; float:left; @@ -294,6 +366,7 @@ h3,h4,h5,h6{ border:1px dashed var(--504945); padding:10px; margin-bottom:17px; + overflow:hidden; } .infobox .code{ diff --git a/videos.php b/videos.php index 2842703..ddc281c 100644 --- a/videos.php +++ b/videos.php @@ -10,11 +10,11 @@ $frontend = new frontend(); $get = $frontend->parsegetfilters($_GET, $filters); -$frontend->loadheader( - $get, - $filters, - "videos" -); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, $get, $filters, "videos", true); $payload = [ "class" => "", diff --git a/web.php b/web.php index e34672d..4df2609 100644 --- a/web.php +++ b/web.php @@ -10,11 +10,11 @@ $frontend = new frontend(); $get = $frontend->parsegetfilters($_GET, $filters); -$frontend->loadheader( - $get, - $filters, - "web" -); +/* + Captcha +*/ +include "lib/captcha_gen.php"; +new captcha($frontend, $get, $filters, true); $payload = [ "class" => "", @@ -44,6 +44,35 @@ try{ die(); } +/* + Prepend Oracle output, if applicable +*/ +include("oracles/encoder.php"); +include("oracles/calc.php"); +include("oracles/time.php"); +include("oracles/numerics.php"); +$oracles = [new calculator(), new encoder(), new time(), new numerics()]; +$fortune = ""; +foreach ($oracles as $oracle) { + if ($oracle->check_query($_GET["s"])) { + $resp = $oracle->generate_response($_GET["s"]); + if ($resp != "") { + $fortune .= "
"; + foreach ($resp as $title => $r) { + if ($title) { + $fortune .= "

".htmlspecialchars($title)."

".htmlspecialchars($r)."
"; + } + else { + $fortune .= "".$r."
"; + } + } + $fortune .= "Answer provided by oracle: ".$oracle->info["name"]."
"; + } + break; + } +} +$payload["left"] = $fortune; + $answerlen = 0; /* @@ -475,35 +504,6 @@ if($c !== 0){ $payload["left"] .= ''; } -/* - Prepend Oracle output, if applicable -*/ -include_once("oracles/encoder.php"); -include_once("oracles/calc.php"); -include_once("oracles/time.php"); -include_once("oracles/numerics.php"); -$oracles = [new calculator(), new encoder(), new time(), new numerics()]; -$fortune = ""; -foreach ($oracles as $oracle) { - if ($oracle->check_query($_GET["s"])) { - $resp = $oracle->generate_response($_GET["s"]); - if ($resp != "") { - $fortune .= "
"; - foreach ($resp as $title => $r) { - if ($title) { - $fortune .= "

".htmlspecialchars($title)."

".htmlspecialchars($r)."
"; - } - else { - $fortune .= "".$r."
"; - } - } - $fortune .= "Answer provided by oracle: ".$oracle->info["name"]."
"; - } - break; - } -} -$payload["left"] = $fortune . $payload["left"]; - /* Load next page */