1
0

yep.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. <?php
  2. class yep{
  3. public function __construct(){
  4. include "lib/backend.php";
  5. $this->backend = new backend("yep");
  6. include "lib/fuckhtml.php";
  7. $this->fuckhtml = new fuckhtml();
  8. }
  9. public function getfilters($page){
  10. return [
  11. "lang" => [
  12. "display" => "Language",
  13. "option" => [
  14. "any" => "Any language",
  15. "aa" => "Afar",
  16. "ab" => "Abkhazian",
  17. "ae" => "Avestan",
  18. "af" => "Afrikaans",
  19. "ak" => "Akan",
  20. "am" => "Amharic",
  21. "an" => "Aragonese",
  22. "ar" => "Arabic",
  23. "as" => "Assamese",
  24. "av" => "Avaric",
  25. "ay" => "Aymara",
  26. "az" => "Azerbaijani",
  27. "ba" => "Bashkir",
  28. "be" => "Belarusian",
  29. "bg" => "Bulgarian",
  30. "bh" => "Bihari",
  31. "bi" => "Bislama",
  32. "bm" => "Bambara",
  33. "bn" => "Bengali",
  34. "bo" => "Tibetan",
  35. "br" => "Breton",
  36. "bs" => "Bosnian",
  37. "ca" => "Catalan",
  38. "ce" => "Chechen",
  39. "ch" => "Chamorro",
  40. "co" => "Corsican",
  41. "cr" => "Cree",
  42. "cs" => "Czech",
  43. "cu" => "Church Slavic",
  44. "cv" => "Chuvash",
  45. "cy" => "Welsh",
  46. "da" => "Danish",
  47. "de" => "German",
  48. "dv" => "Divehi",
  49. "dz" => "Dzongkha",
  50. "ee" => "Ewe",
  51. "el" => "Greek",
  52. "en" => "English",
  53. "eo" => "Esperanto",
  54. "es" => "Spanish",
  55. "et" => "Estonian",
  56. "eu" => "Basque",
  57. "fa" => "Persian",
  58. "ff" => "Fulah",
  59. "fi" => "Finnish",
  60. "fj" => "Fijian",
  61. "fo" => "Faroese",
  62. "fr" => "French",
  63. "fy" => "Western Frisian",
  64. "ga" => "Irish",
  65. "gd" => "Scottish Gaelic",
  66. "gl" => "Galician",
  67. "gn" => "Guarani",
  68. "gu" => "Gujarati",
  69. "gv" => "Manx",
  70. "ha" => "Hausa",
  71. "he" => "Hebrew",
  72. "hi" => "Hindi",
  73. "ho" => "Hiri Motu",
  74. "hr" => "Croatian",
  75. "ht" => "Haitian",
  76. "hu" => "Hungarian",
  77. "hy" => "Armenian",
  78. "hz" => "Herero",
  79. "ia" => "Interlingua",
  80. "id" => "Indonesian",
  81. "ie" => "Interlingue",
  82. "ig" => "Igbo",
  83. "ii" => "Sichuan Yi",
  84. "ik" => "Inupiaq",
  85. "io" => "Ido",
  86. "is" => "Icelandic",
  87. "it" => "Italian",
  88. "iu" => "Inuktitut",
  89. "ja" => "Japanese",
  90. "jv" => "Javanese",
  91. "ka" => "Georgian",
  92. "kg" => "Kongo",
  93. "ki" => "Kikuyu",
  94. "kj" => "Kuanyama",
  95. "kk" => "Kazakh",
  96. "kl" => "Kalaallisut",
  97. "km" => "Central Khmer",
  98. "kn" => "Kannada",
  99. "ko" => "Korean",
  100. "kr" => "Kanuri",
  101. "ks" => "Kashmiri",
  102. "ku" => "Kurdish",
  103. "kv" => "Komi",
  104. "kw" => "Cornish",
  105. "ky" => "Kyrgyz",
  106. "la" => "Latin",
  107. "lb" => "Luxembourgish",
  108. "lg" => "Ganda",
  109. "li" => "Limburgish",
  110. "ln" => "Lingala",
  111. "lo" => "Lao",
  112. "lt" => "Lithuanian",
  113. "lu" => "Luba-Katanga",
  114. "lv" => "Latvian",
  115. "mg" => "Malagasy",
  116. "mh" => "Marshallese",
  117. "mi" => "Maori",
  118. "mk" => "Macedonian",
  119. "ml" => "Malayalam",
  120. "mn" => "Mongolian",
  121. "mr" => "Marathi",
  122. "ms" => "Malay",
  123. "mt" => "Maltese",
  124. "my" => "Burmese",
  125. "na" => "Nauru",
  126. "nb" => "Norwegian Bokmål",
  127. "nd" => "North Ndebele",
  128. "ne" => "Nepali",
  129. "ng" => "Ndonga",
  130. "nl" => "Dutch",
  131. "nn" => "Norwegian Nynorsk",
  132. "no" => "Norwegian",
  133. "nr" => "South Ndebele",
  134. "nv" => "Navajo",
  135. "ny" => "Chichewa",
  136. "oc" => "Occitan",
  137. "oj" => "Ojibwa",
  138. "om" => "Oromo",
  139. "or" => "Oriya",
  140. "os" => "Ossetian",
  141. "pa" => "Punjabi",
  142. "pi" => "Pali",
  143. "pl" => "Polish",
  144. "ps" => "Pashto",
  145. "pt" => "Portuguese",
  146. "qu" => "Quechua",
  147. "rm" => "Romansh",
  148. "rn" => "Rundi",
  149. "ro" => "Romanian",
  150. "ru" => "Russian",
  151. "rw" => "Kinyarwanda",
  152. "sa" => "Sanskrit",
  153. "sc" => "Sardinian",
  154. "sd" => "Sindhi",
  155. "se" => "Northern Sami",
  156. "sg" => "Sango",
  157. "si" => "Sinhala",
  158. "sk" => "Slovak",
  159. "sl" => "Slovenian",
  160. "sm" => "Samoan",
  161. "sn" => "Shona",
  162. "so" => "Somali",
  163. "sq" => "Albanian",
  164. "sr" => "Serbian",
  165. "ss" => "Swati",
  166. "st" => "Southern Sotho",
  167. "su" => "Sundanese",
  168. "sv" => "Swedish",
  169. "sw" => "Swahili",
  170. "ta" => "Tamil",
  171. "te" => "Telugu",
  172. "tg" => "Tajik",
  173. "th" => "Thai",
  174. "ti" => "Tigrinya",
  175. "tk" => "Turkmen",
  176. "tl" => "Tagalog",
  177. "tn" => "Tswana",
  178. "to" => "Tonga",
  179. "tr" => "Turkish",
  180. "ts" => "Tsonga",
  181. "tt" => "Tatar",
  182. "tw" => "Twi",
  183. "ty" => "Tahitian",
  184. "ug" => "Uyghur",
  185. "uk" => "Ukrainian",
  186. "ur" => "Urdu",
  187. "uz" => "Uzbek",
  188. "ve" => "Venda",
  189. "vi" => "Vietnamese",
  190. "vo" => "Volapük",
  191. "wa" => "Walloon",
  192. "wo" => "Wolof",
  193. "xh" => "Xhosa",
  194. "yi" => "Yiddish",
  195. "yo" => "Yoruba",
  196. "za" => "Zhuang",
  197. "zh" => "Chinese",
  198. "zh-cn" => "Chinese (Simplified)",
  199. "zh-tw" => "Chinese (Traditional)",
  200. "zu" => "Zulu"
  201. ]
  202. ]
  203. ];
  204. }
  205. private function get($proxy, $url, $get = [], $use_api = false, $post_data = null, $bearer = null){
  206. $curlproc = curl_init();
  207. if($get !== []){
  208. $get = http_build_query($get);
  209. $url .= "?" . $get;
  210. }
  211. curl_setopt($curlproc, CURLOPT_URL, $url);
  212. // use http1 lol
  213. curl_setopt($curlproc, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  214. curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
  215. if($use_api){
  216. $post_data = json_encode($post_data);
  217. curl_setopt($curlproc, CURLOPT_HTTPHEADER,
  218. ["Content-Type: application/json",
  219. "Authorization: Bearer $bearer",
  220. "Content-Length: " . strlen($post_data)]
  221. );
  222. curl_setopt($curlproc, CURLOPT_POST, true);
  223. curl_setopt($curlproc, CURLOPT_POSTFIELDS, $post_data);
  224. }else{
  225. curl_setopt($curlproc, CURLOPT_HTTPHEADER,
  226. ["User-Agent: " . config::USER_AGENT,
  227. "Accept: */*",
  228. "Accept-Language: en-US,en;q=0.9",
  229. "Accept-Encoding: gzip, deflate, br, zstd",
  230. "Referer: https://yep.com/",
  231. "Origin: https://yep.com",
  232. "DNT: 1",
  233. "Connection: keep-alive",
  234. "Sec-Fetch-Dest: empty",
  235. "Sec-Fetch-Mode: cors",
  236. "Sec-Fetch-Site: same-site",
  237. "Priority: u=4",
  238. "Pragma: no-cache",
  239. "Cache-Control: no-cache",
  240. "TE: trailers"]
  241. );
  242. }
  243. curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
  244. curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
  245. curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
  246. curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
  247. curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
  248. $this->backend->assign_proxy($curlproc, $proxy);
  249. $data = curl_exec($curlproc);
  250. if(curl_errno($curlproc)){
  251. throw new Exception(curl_error($curlproc));
  252. }
  253. curl_close($curlproc);
  254. return $data;
  255. }
  256. public function web($get){
  257. if(config::YEP_USE_API){
  258. return $this->web_api($get);
  259. }
  260. $search = $get["s"];
  261. if(strlen($search) === 0){
  262. throw new Exception("Search term is empty!");
  263. }
  264. $out = [
  265. "status" => "ok",
  266. "spelling" => [
  267. "type" => "no_correction",
  268. "using" => null,
  269. "correction" => null
  270. ],
  271. "npt" => null,
  272. "answer" => [],
  273. "web" => [],
  274. "image" => [],
  275. "video" => [],
  276. "news" => [],
  277. "related" => []
  278. ];
  279. // parse filters
  280. $filters = [
  281. "q" => $search,
  282. "limit" => 10 // no fun allowed
  283. ];
  284. if($get["lang"] != "any"){
  285. $filters["language"] = $get["lang"];
  286. $filters["lang"] = $get["lang"];
  287. }
  288. try{
  289. // https://yep.com/web/v1/search?q=asmr&limit=10
  290. $json =
  291. $this->get(
  292. $this->backend->get_ip(),
  293. "https://yep.com/web/v1/search",
  294. $filters
  295. );
  296. }catch(Exception $error){
  297. throw new Exception("Failed to fetch JSON");
  298. }
  299. $this->detect_cf($json);
  300. $json = json_decode($json, true);
  301. //$json = json_decode(file_get_contents("scraper/yep.json"), true);
  302. if($json === null){
  303. throw new Exception("Failed to decode JSON");
  304. }
  305. if(isset($json["code"])){
  306. if(isset($json["reason"])){
  307. throw new Exception("Yep returned an API error: [{$json["code"]}] {$json["reason"]}");
  308. }
  309. throw new Exception("Yep returned an unknown error");
  310. }
  311. if(isset($json["results"])){
  312. foreach($json["results"] as $item){
  313. $out["web"][] = [
  314. "title" => $item["title"],
  315. "description" => str_replace("\n", " ", $item["description"]),
  316. "url" => $item["url"],
  317. "date" => null,
  318. "type" => "web",
  319. "thumb" => [
  320. "url" => null,
  321. "ratio" => null
  322. ],
  323. "sublink" => [],
  324. "table" => []
  325. ];
  326. }
  327. }
  328. return $out;
  329. }
  330. private function web_api($get){
  331. $search = $get["s"];
  332. if(strlen($search) === 0){
  333. throw new Exception("Search term is empty!");
  334. }
  335. $out = [
  336. "status" => "ok",
  337. "spelling" => [
  338. "type" => "no_correction",
  339. "using" => null,
  340. "correction" => null
  341. ],
  342. "npt" => null,
  343. "answer" => [],
  344. "web" => [],
  345. "image" => [],
  346. "video" => [],
  347. "news" => [],
  348. "related" => []
  349. ];
  350. // parse filters
  351. $filters = [
  352. "query" => $search,
  353. "limit" => 99 // for some reason they dont show anything sometimes at 100 results
  354. ];
  355. if($get["lang"] != "any"){ $filters["language"] = [ $get["lang"] ]; }
  356. // add api key
  357. $key_data = $this->backend->get_key();
  358. try{
  359. $json =
  360. $this->get(
  361. $this->backend->get_ip($key_data["increment"]),
  362. "https://platform.yep.com/api/search",
  363. [],
  364. true,
  365. $filters,
  366. $key_data["key"]
  367. );
  368. }catch(Exception $error){
  369. throw new Exception("Failed to fetch JSON");
  370. }
  371. // should never happen
  372. //$this->detect_cf($json);
  373. $json = json_decode($json, true);
  374. //$json = json_decode(file_get_contents("scraper/yep.json"), true);
  375. if($json === null){
  376. throw new Exception("Failed to decode JSON");
  377. }
  378. if(isset($json["error"])){
  379. throw new Exception("Yep API returned an error: " . $json["error"]);
  380. }
  381. if(isset($json["errors"])){
  382. throw new Exception("Yep API returned the following errors: {$json["message"]}");
  383. }
  384. if(
  385. isset($json["success"]) &&
  386. $json["success"] !== true
  387. ){
  388. throw new Exception("Yep API returned a false-y success value");
  389. }
  390. if(!isset($json["results"])){
  391. throw new Exception("Yep API did not return a results object");
  392. }
  393. foreach($json["results"] as $item){
  394. if(
  395. $item["url"] === null ||
  396. $item["url"] == ""
  397. ){
  398. // sometimes API fucks up
  399. continue;
  400. }
  401. $out["web"][] = [
  402. "title" => $item["title"],
  403. "description" => $item["description"],
  404. "url" => $item["url"],
  405. "date" => null,
  406. "type" => "web",
  407. "thumb" => [
  408. "url" => null,
  409. "ratio" => null
  410. ],
  411. "sublink" => [],
  412. "table" => []
  413. ];
  414. }
  415. return $out;
  416. }
  417. private function detect_cf($payload){
  418. // detect cloudflare page
  419. $this->fuckhtml->load($payload);
  420. if(
  421. count(
  422. $this->fuckhtml
  423. ->getElementsByClassName(
  424. "cf-wrapper",
  425. "div"
  426. )
  427. ) !== 0
  428. ){
  429. throw new Exception("Blocked by Cloudflare. Please follow curl-impersonate installation instructions");
  430. }
  431. }
  432. private function titledots($title){
  433. $substr = substr($title, -4);
  434. if(
  435. strpos($substr, "...") !== false ||
  436. strpos($substr, "…") !== false
  437. ){
  438. return trim(substr($title, 0, -4));
  439. }
  440. return trim($title);
  441. }
  442. private function unshiturl($url){
  443. $newurl = parse_url($url, PHP_URL_QUERY);
  444. parse_str($newurl, $newurl);
  445. if(isset($newurl["url"])){
  446. return $newurl["url"];
  447. }
  448. return $url;
  449. }
  450. }