wiby.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. class wiby{
  3. public function __construct(){
  4. include "lib/backend.php";
  5. $this->backend = new backend("wiby");
  6. }
  7. public function getfilters($page){
  8. if($page != "web"){
  9. return [];
  10. }
  11. return [
  12. "nsfw" => [
  13. "display" => "NSFW",
  14. "option" => [
  15. "yes" => "Yes",
  16. "no" => "No"
  17. ]
  18. ],
  19. "date" => [
  20. "display" => "Time posted",
  21. "option" => [
  22. "any" => "Any time",
  23. "day" => "Past day",
  24. "week" => "Past week",
  25. "month" => "Past month",
  26. "year" => "Past year",
  27. ]
  28. ]
  29. ];
  30. }
  31. private function get($proxy, $url, $get = [], $nsfw){
  32. $curlproc = curl_init();
  33. if($get !== []){
  34. $get = http_build_query($get);
  35. $url .= "?" . $get;
  36. }
  37. curl_setopt($curlproc, CURLOPT_URL, $url);
  38. curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
  39. curl_setopt($curlproc, CURLOPT_HTTPHEADER,
  40. ["User-Agent: " . config::USER_AGENT,
  41. "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
  42. "Accept-Language: en-US,en;q=0.5",
  43. "Accept-Encoding: gzip",
  44. "Cookie: ws={$nsfw}",
  45. "DNT: 1",
  46. "Connection: keep-alive",
  47. "Upgrade-Insecure-Requests: 1",
  48. "Sec-Fetch-Dest: document",
  49. "Sec-Fetch-Mode: navigate",
  50. "Sec-Fetch-Site: none",
  51. "Sec-Fetch-User: ?1"]
  52. );
  53. curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
  54. curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
  55. curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
  56. curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
  57. curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
  58. $this->backend->assign_proxy($curlproc, $proxy);
  59. $data = curl_exec($curlproc);
  60. if(curl_errno($curlproc)){
  61. throw new Exception(curl_error($curlproc));
  62. }
  63. curl_close($curlproc);
  64. return $data;
  65. }
  66. public function web($get){
  67. if($get["npt"]){
  68. [$q, $proxy] = $this->backend->get($get["npt"], "web");
  69. $q = json_decode($q, true);
  70. $nsfw = $q["nsfw"];
  71. unset($q["nsfw"]);
  72. }else{
  73. $search = $get["s"];
  74. if(strlen($search) === 0){
  75. throw new Exception("Search term is empty!");
  76. }
  77. $proxy = $this->backend->get_ip();
  78. $date = $get["date"];
  79. $nsfw = $get["nsfw"] == "yes" ? "0" : "1";
  80. $search =
  81. str_replace(
  82. [
  83. "!g",
  84. "!gi",
  85. "!gv",
  86. "!gm",
  87. "!b",
  88. "!bi",
  89. "!bv",
  90. "!bm",
  91. "!td",
  92. "!tw",
  93. "!tm",
  94. "!ty",
  95. "&g",
  96. "&gi",
  97. "&gv",
  98. "&gm",
  99. "&b",
  100. "&bi",
  101. "&bv",
  102. "&bm",
  103. "&td",
  104. "&tw",
  105. "&tm",
  106. "&ty",
  107. ],
  108. "",
  109. $search
  110. );
  111. switch($date){
  112. case "day": $search = "!td " . $search; break;
  113. case "week": $search = "!tw " . $search; break;
  114. case "month": $search = "!tm " . $search; break;
  115. case "year": $search = "!ty " . $search; break;
  116. }
  117. $q = [
  118. "q" => $search
  119. ];
  120. }
  121. try{
  122. $html = $this->get(
  123. $proxy,
  124. "https://wiby.me/",
  125. $q,
  126. $nsfw
  127. );
  128. }catch(Exception $error){
  129. throw new Exception("Failed to fetch search page");
  130. }
  131. preg_match(
  132. '/<p class="pin"><blockquote>(?:<\/p>)?<br><a class="more" href="\/\?q=[^"]+&p=([0-9]+)">Find more\.\.\.<\/a><\/blockquote>/',
  133. $html,
  134. $nextpage
  135. );
  136. if(count($nextpage) === 0){
  137. $nextpage = null;
  138. }else{
  139. $nextpage =
  140. $this->backend->store(
  141. json_encode([
  142. "q" => $q["q"],
  143. "p" => (int)$nextpage[1],
  144. "nsfw" => $nsfw
  145. ]),
  146. "web",
  147. $proxy
  148. );
  149. }
  150. $out = [
  151. "status" => "ok",
  152. "spelling" => [
  153. "type" => "no_correction",
  154. "using" => null,
  155. "correction" => null
  156. ],
  157. "npt" => $nextpage,
  158. "answer" => [],
  159. "web" => [],
  160. "image" => [],
  161. "video" => [],
  162. "news" => [],
  163. "related" => []
  164. ];
  165. preg_match_all(
  166. '/<blockquote>[\s]*<a .* href="(.*)">(.*)<\/a>.*<p>(.*)<\/p>[\s]*<\/blockquote>/Ui',
  167. $html,
  168. $links
  169. );
  170. for($i=0; $i<count($links[0]); $i++){
  171. $out["web"][] = [
  172. "title" => $this->unescapehtml(trim($links[2][$i])),
  173. "description" => $this->unescapehtml(trim(strip_tags($links[3][$i]), ".\n\r ")),
  174. "url" => trim($links[1][$i]),
  175. "date" => null,
  176. "type" => "web",
  177. "thumb" => [
  178. "url" => null,
  179. "ratio" => null
  180. ],
  181. "sublink" => [],
  182. "table" => []
  183. ];
  184. }
  185. return $out;
  186. }
  187. private function unescapehtml($str){
  188. return html_entity_decode(
  189. str_replace(
  190. [
  191. "<br>",
  192. "<br/>",
  193. "</br>",
  194. "<BR>",
  195. "<BR/>",
  196. "</BR>",
  197. ],
  198. "\n",
  199. $str
  200. ),
  201. ENT_QUOTES | ENT_XML1, 'UTF-8'
  202. );
  203. }
  204. }