Advertisement
NokitaKaze

Качалка бурятников

Jul 3rd, 2015
387
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.76 KB | None | 0 0
  1. <?php
  2.     $domain = strtolower($_GET['domain']);
  3.     $id = (int) $_GET['id'];
  4.     $additional = array();
  5.     $hash = $id;
  6.     $mode = isset($_GET['mode']) ? $_GET['mode'] : 'normal';
  7.     foreach ($_GET as $key => $value) {
  8.         if (!preg_match('|^add_([a-z0-9_-]+)$|i', strtolower($key), $a)) {
  9.             continue;
  10.         }
  11.         $additional[$a[1]] = $value;
  12.         $hash .= '&'.$a[1].'='.$value;
  13.     }
  14.     $current_hash = sha1($hash);
  15.  
  16.     if (($id == 0) and (count($additional) == 0)) {
  17.         AscetCMSEngine::$http_status = 400;
  18.         echo 'domain or id is malformed';
  19.  
  20.         return;
  21.     }
  22.     AscetCMSEngine::error_reporting(0);
  23.  
  24.     /* */
  25.  
  26.     abstract class aBooru {
  27.         var $ch;
  28.         var $status = -1;
  29.         var $image_url;
  30.         var $page_url;
  31.         const user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36';
  32.  
  33.         function get_header_list($referer = null) {
  34.             if ($referer === null) {
  35.                 $referer = 'http://'.$this->get_main_domain().'/';
  36.             }
  37.  
  38.             return array(
  39.                 'Cache-Control: max-age=0',
  40.                 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  41.                 'User-agent: '.self::user_agent,
  42.                 'Referer: '.$referer,
  43.                 'Accept-Language: ru,en;q=0.8',
  44.             );
  45.         }
  46.  
  47.         function get_image($id, $additional) {
  48.             $url = $this->get_url($id, $additional);
  49.             $this->page_url = $url;
  50.             $this->ch = curl_init($url);
  51.             curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
  52.             curl_setopt($this->ch, CURLOPT_AUTOREFERER, true);
  53.             curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
  54.             curl_setopt($this->ch, CURLOPT_HEADER, true);
  55.             curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, false);
  56.             curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 20);
  57.             curl_setopt($this->ch, CURLOPT_TIMEOUT, 20);
  58.             curl_setopt($this->ch, CURLOPT_HTTPHEADER, $this->get_header_list());
  59.             $http_status = -1;
  60.             for ($try_count = 0; $try_count < 3; $try_count++) {
  61.                 $raw_buf = curl_exec($this->ch);
  62.                 list($header, $buf) = explode("\r\n\r\n", $raw_buf, 2);
  63.                 if (curl_errno($this->ch) != 0) {
  64.                     header('X-raw-page-'.$try_count.'-errno: '.curl_errno($this->ch));
  65.                     continue;
  66.                 }
  67.                 $http_status = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
  68.                 header('X-raw-page-'.$try_count.'-http-status: '.$http_status);
  69.                 if ($http_status == 200) {
  70.                     // обрабатываем полученное
  71.                     // $r = mt_rand(1, 1000000);
  72.                     // file_put_contents('/dev/shm/care-'.$r.'.html', $buf, LOCK_EX);
  73.                     // header('X-saved-raw-file-'.$r.': /dev/shm/care-'.$r.'.html');
  74.                     $img_src = $this->parse_text_for_image($buf);
  75.                     if ($img_src === null) {
  76.                         sleep(10);
  77.                         continue;
  78.                     }
  79.                     $this->image_url = $img_src;
  80.  
  81.                     break;
  82.                 } elseif ($http_status == 403) {
  83.                     sleep(10);
  84.                     continue;
  85.                 }
  86.             }
  87.             if (curl_errno($this->ch) != 0) {
  88.                 $this->status = 1000 + curl_errno($this->ch);
  89.  
  90.                 return null;
  91.             }
  92.             if ($http_status != 200) {
  93.                 $this->status = 3000 + $http_status;
  94.  
  95.                 return null;
  96.             }
  97.             /** @noinspection PhpUndefinedVariableInspection */
  98.             if ($img_src === null) {
  99.                 $this->status = 1;
  100.  
  101.                 return null;
  102.             }
  103.  
  104.  
  105.             // Теперь получаем изображение
  106.             curl_setopt($this->ch, CURLOPT_URL, $this->image_url);
  107.             curl_setopt($this->ch, CURLOPT_HTTPHEADER, $this->get_header_list($this->page_url));
  108.             $buf = '';
  109.             for ($try_count = 0; $try_count < 3; $try_count++) {
  110.                 $raw_buf = curl_exec($this->ch);
  111.                 list($header, $buf) = explode("\r\n\r\n", $raw_buf, 2);
  112.                 if (curl_errno($this->ch) != 0) {
  113.                     header('X-image-'.$try_count.'-errno: '.curl_errno($this->ch));
  114.                     continue;
  115.                 }
  116.                 $http_status = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
  117.                 header('X-image-'.$try_count.'-http-status: '.$http_status);
  118.                 if ($http_status == 200) {
  119.                     break;
  120.                 } elseif ($http_status == 403) {
  121.                     sleep(10);
  122.                     continue;
  123.                 }
  124.             }
  125.             if (curl_errno($this->ch) != 0) {
  126.                 $this->status = 2000 + curl_errno($this->ch);
  127.  
  128.                 return null;
  129.             }
  130.             if ($http_status !== 200) {
  131.                 $this->status = 4000 + $http_status;
  132.  
  133.                 return null;
  134.             }
  135.  
  136.             $this->status = 0;
  137.  
  138.             // Сохраняем thumb изображения
  139.             $content_type = curl_getinfo($this->ch, CURLINFO_CONTENT_TYPE);
  140.             header('X-content-type: '.$content_type);
  141.             $thumb_buf = '';
  142.             if (preg_match('|^image/|', $content_type)) {
  143.                 $rnd = mt_rand(1, 10000000000);
  144.                 switch (strtolower(preg_replace('|(;.*)?$|', '', $content_type))) {
  145.                     case 'image/gif':
  146.                         $extension = 'gif';
  147.                         $additional = '-alpha on -coalesce';
  148.                         break;
  149.                     case 'image/png':
  150.                         $extension = 'png';
  151.                         $additional = '';
  152.                         break;
  153.                     default:
  154.                         $extension = 'jpg';
  155.                         $additional = '';
  156.                 }
  157.                 file_put_contents('/dev/shm/booru_tmp_'.$rnd.'.'.$extension, $buf, LOCK_EX);
  158.                 system('convert /dev/shm/booru_tmp_'.$rnd.'.'.$extension.' '.
  159.                        $additional.' -resize x300 /dev/shm/booru_tmp_'.$rnd.'.out.'.$extension);
  160.                 $thumb_buf = file_get_contents('/dev/shm/booru_tmp_'.$rnd.'.out.'.$extension);
  161.                 @unlink('/dev/shm/booru_tmp_'.$rnd.'.'.$extension);
  162.                 @unlink('/dev/shm/booru_tmp_'.$rnd.'.out.'.$extension);
  163.             }
  164.  
  165.             return (object) array(
  166.                 'status' => 0,
  167.                 'url' => $img_src,
  168.                 'page_url' => $url,
  169.  
  170.                 'img' => $buf,
  171.                 'thumb' => $thumb_buf,
  172.                 'content_type' => $content_type,
  173.             );
  174.         }
  175.  
  176.         abstract function parse_text_for_image($text);
  177.  
  178.         abstract function get_url($id, $additional);
  179.  
  180.         abstract function get_main_domain();
  181.     }
  182.  
  183.  
  184. // Danbooru
  185.     class aBooru_danbooru extends aBooru {
  186.         function get_url($id, $additional) {
  187.             return 'http://danbooru.donmai.us/posts/'.$id;
  188.         }
  189.  
  190.         function parse_text_for_image($text) {
  191.             if (preg_match('#http\\://danbooru\\.donmai\\.us/data/(.+?)\\.(jpg|bmp|png|gif|jpeg|webm)#', $text, $a)) {
  192.                 return $a[0];
  193.             }
  194.  
  195.             if (preg_match('#Size\\: +<a +href\\="/data/([a-f0-9]+)\\.(jpg|bmp|png|gif|jpeg|webm)"#', $text, $a)) {
  196.                 return 'http://danbooru.donmai.us/data/'.$a[1].'.'.$a[2];
  197.             }
  198.  
  199.             return null;
  200.         }
  201.  
  202.         function get_main_domain() {
  203.             return 'danbooru.donmai.us';
  204.         }
  205.  
  206.     }
  207.  
  208. // Gelbooru
  209.     class aBooru_gelbooru extends aBooru {
  210.         function get_url($id, $additional) {
  211. //   return 'http://gelbooru.com/index.php?page=post&s=view&id='.$id;
  212.             return 'http://gelbooru.com/index.php?page=dapi&s=post&q=index&id='.$id;
  213.         }
  214.  
  215.         function parse_text_for_image($text) {
  216.             if (!preg_match('#file_url="(.+?)"#', $text, $a)) {
  217.                 return null;
  218.             }
  219.  
  220.             return $a[1];
  221.         }
  222.  
  223.         function get_main_domain() {
  224.             return 'gelbooru.com';
  225.         }
  226.     }
  227.  
  228. // Safebooru
  229.     class aBooru_safebooru extends aBooru {
  230.         function get_url($id, $additional) {
  231.             return 'http://safebooru.org/index.php?page=post&s=view&id='.$id;
  232.         }
  233.  
  234.         function parse_text_for_image($text) {
  235.             if (!preg_match('#http\\://(([0-9a-z]+?)\\.)?safebooru\\.org//images/(.+?)\\.'.
  236.                             '(jpg|bmp|png|gif|jpeg|webm)#', $text, $a)
  237.             ) {
  238.                 return null;
  239.             }
  240.  
  241.             return $a[0];
  242.         }
  243.  
  244.         function get_main_domain() {
  245.             return 'safebooru.org';
  246.         }
  247.     }
  248.  
  249. // Deviantart
  250.     class aBooru_deviantart extends aBooru {
  251.         function get_url($id, $additional) {
  252.             return 'http://www.deviantart.com/art/a-'.$id;
  253.         }
  254.  
  255.         function parse_text_for_image($text) {
  256.             if (!preg_match('#(name|property)\\="og\\:image" content="(https?\\://[^"]+?)"#', $text, $a)) {
  257.                 return null;
  258.             }
  259.  
  260.             return $a[2];
  261.         }
  262.  
  263.         function get_main_domain() {
  264.             return 'www.deviantart.com';
  265.         }
  266.     }
  267.  
  268. // E621
  269.     class aBooru_e621 extends aBooru {
  270.         function get_url($id, $additional) {
  271.             return 'https://e621.net/post/show/'.$id.'/';
  272.         }
  273.  
  274.         function parse_text_for_image($text) {
  275.             if (!preg_match('#(https?://static[0-9]+\\.e621\\.net\\/data\\/.+?.(jpg|bmp|png|gif|jpeg|))">Download<\\/a>#i',
  276.                 $text, $a)
  277.             ) {
  278.                 return null;
  279.             }
  280.  
  281.             return $a[1];
  282.         }
  283.  
  284.         function get_main_domain() {
  285.             return 'e621.net';
  286.         }
  287.     }
  288.  
  289. //
  290.     class aBooru_derpibooru extends aBooru {
  291.         function get_url($id, $additional) {
  292.             return 'https://derpiboo.ru/'.$id;
  293.         }
  294.  
  295.         function parse_text_for_image($text) {
  296.             if (!preg_match('#data\\-download\\-uri\\="(https?\\:)?\\/\\/(derpicdn\\.net\\/.+?\\.(jpg|bmp|png|gif|jpeg|webm))"#i',
  297.                 $text, $a)
  298.             ) {
  299.                 return null;
  300.             }
  301.  
  302.             return 'https://'.$a[2];
  303.         }
  304.  
  305.         function get_main_domain() {
  306.             return 'derpiboo.ru';
  307.         }
  308.     }
  309.  
  310. //
  311.     class aBooru_tumblr extends aBooru {
  312.         function get_url($id, $additional) {
  313.             return 'http://'.($additional['username']).'.tumblr.com/image/'.$id;
  314.         }
  315.  
  316.         function parse_text_for_image($text) {
  317.             if (!preg_match('#data-src="(https?:\\/\\/[0-9]+.media.tumblr.com/.+?\\.(jpg|bmp|png|gif|jpeg|webm))"#i', $text, $a)
  318.             ) {
  319.                 return null;
  320.             }
  321.  
  322.             return $a[1];
  323.         }
  324.  
  325.         function get_main_domain() {
  326.             return 'tumblr.com';
  327.         }
  328.     }
  329.  
  330. //
  331.     class aBooru_konachancom extends aBooru {
  332.         function get_url($id, $additional) {
  333.             return 'http://konachan.com/post/show/'.$id;
  334.         }
  335.  
  336.         function parse_text_for_image($text) {
  337.             if (!preg_match('#content\\="(http\\:\\/\\/konachan\\.com\\/.+?\\.(jpg|bmp|png|gif|jpeg|webm))" +property\\="og\\:image"#i',
  338.                 $text, $a)
  339.             ) {
  340.                 return null;
  341.             }
  342.  
  343.             return $a[1];
  344.         }
  345.  
  346.         function get_main_domain() {
  347.             return 'konachan.com';
  348.         }
  349.     }
  350.  
  351. //
  352.     class aBooru_pixiv extends aBooru {
  353.         function get_url($id, $additional) {
  354.             return 'http://www.pixiv.net/member_illust.php?mode=medium&illust_id='.$id;
  355.         }
  356.  
  357.         function parse_text_for_image($text) {
  358.             if (preg_match('|"(https?://[a-z0-9.-]*?pixiv\\.net/img\\-original/.+?)"|', $text, $a)) {
  359.                 return $a[1];
  360.             }
  361.  
  362.             preg_match_all('|"(https?://[a-z0-9.-]*?pixiv\\.net/c/([0-9]+)x[0-9]+/img\\-master/img/.+?)"|',
  363.                 $text, $a, PREG_SET_ORDER);
  364.             $url = null;
  365.             $max = 0;
  366.             foreach ($a as $set) {
  367.                 if ($set[2] > $max) {
  368.                     $max = (int) $set[2];
  369.                     $url = $set[1];
  370.                 }
  371.             }
  372.  
  373.             return $url;
  374.         }
  375.  
  376.         function get_main_domain() {
  377.             return 'pixiv.com';
  378.         }
  379.  
  380.         function get_header_list() {
  381.             $r = parent::get_header_list();
  382.             $r[] = 'Cookie: PHPSESSID=10566162_9e6e80b6f3ba259832c056d813c56dc2; ';
  383.  
  384.             return $r;
  385.         }
  386.     }
  387.  
  388. //
  389.     class aBooru_animepicturesnet extends aBooru {
  390.         function get_url($id, $additional) {
  391.             return 'https://anime-pictures.net/pictures/view_post/'.$id;
  392.         }
  393.  
  394.         function parse_text_for_image($text) {
  395.             if (!preg_match('#"/pictures/download_image/(.+\\.(jpg|bmp|png|gif|jpeg|webm))?"#i',
  396.                 $text, $a)
  397.             ) {
  398.                 return null;
  399.             }
  400.  
  401.             return 'https://anime-pictures.net/pictures/download_image/'.$a[1];
  402.         }
  403.  
  404.         function get_main_domain() {
  405.             return 'anime-pictures.net';
  406.         }
  407.     }
  408.  
  409. // Yandere
  410.     class aBooru_yandere extends aBooru {
  411.         function get_url($id, $additional) {
  412.             return 'https://yande.re/post/show/'.$id;
  413.         }
  414.  
  415.         function parse_text_for_image($text) {
  416.             if (!preg_match('#files.yande.re/(image/.+?)"#i',
  417.                 $text, $a)
  418.             ) {
  419.                 return null;
  420.             }
  421.  
  422.             return 'https://files.yande.re/'.$a[1];
  423.         }
  424.  
  425.         function get_main_domain() {
  426.             return 'yande.re';
  427.         }
  428.     }
  429.  
  430. // Sankakucomples
  431.     class aBooru_sankakucomplex extends aBooru {
  432.         function get_url($id, $additional) {
  433.             return 'https://chan.sankakucomplex.com/post/show/'.$id;
  434.         }
  435.  
  436.         function parse_text_for_image($text) {
  437.             if (!preg_match('#cs\\.sankakucomplex\\.com\\/data\\/(.+?)(\\?[0-9]*)?"#i', $text, $a)) {
  438.                 return null;
  439.             }
  440.  
  441.             return 'https://cs.sankakucomplex.com/data/'.$a[1].$a[2];
  442.         }
  443.  
  444.         function get_main_domain() {
  445.             return 'chan.sankakucomplex.com';
  446.         }
  447.     }
  448.  
  449.     /* */
  450.     $classname = 'aBooru_'.$domain;
  451.     if (!class_exists($classname)) {
  452.         AscetCMSEngine::$http_status = 400;
  453.         echo 'domain not found';
  454.  
  455.         return;
  456.     }
  457.  
  458.     $folder = '/dev/shm';
  459.     $storage = new KeyValueStorageFile((object) array(
  460.         'folder' => $folder,
  461.         'prefix' => 'booru_pic_'
  462.     ));
  463.     $image_value_key = 'pic_'.$domain.'_'.$current_hash;//Название ключа этого изображения
  464.  
  465.     // Создаём мьютекс
  466.     $mutex_get = new SmartMutex('get_booru_'.$image_value_key);
  467.     if (!$mutex_get->get_lock(-1)) {
  468.         AscetCMSEngine::$http_status = 503;
  469.         echo 'Wtf? Can not acq lock';
  470.  
  471.         return;
  472.     }
  473.  
  474.     // Получаем значение кеша
  475.     $value = $storage->get_value_full($image_value_key);
  476.     if ($value === null) {
  477.         $mutex = new SmartMutex('booru_get_'.$domain);
  478.         if (!$mutex->get_lock(-1)) {
  479.             AscetCMSEngine::$http_status = 503;
  480.             echo 'Wtf? Can not acq lock';
  481.  
  482.             return;
  483.         }
  484.  
  485.         $inst = new $classname();
  486.         unset($mutex, $classname);
  487.         $a = $inst->get_image($id, $additional);
  488.         if ($a === null) {
  489.             $this->http_status = 503;
  490.             echo 'Can not get image. Status: '.$inst->status.'; image url: '.$inst->image_url.'; page url: '.$inst->page_url;
  491.  
  492.             return;
  493.         }
  494.  
  495.         $hash = sha1($a->img);
  496.         $value = (object) array(
  497.             'value' => (object) array(
  498.                 'hash' => $hash,
  499.                 'page_url' => $a->page_url,
  500.                 'img_url' => $a->url,
  501.                 'get_create' => time(),//Хотя эта инфа есть в контейнере
  502.                 'get_last_time' => time(),
  503.                 'get_ip' => array($_SERVER['REMOTE_ADDR']),
  504.                 'get_count' => 1,
  505.  
  506.                 'img' => $a->img,
  507.                 'thumb' => $a->thumb,
  508.                 'content_type' => $a->content_type
  509.             ));
  510.         AscetCMSEngine::$header_time_last_modified = time();
  511.         AscetCMSEngine::$header_time_expires = (time() + 31 * 24 * 3600);
  512.         unset($a);
  513.     } else {
  514.         AscetCMSEngine::$header_time_last_modified = $value->time_create;
  515.         AscetCMSEngine::$header_time_expires = $value->time_create + 31 * 24 * 3600;
  516.         $value->value->get_last_time = time();
  517.         $value->value->get_ip[] = $_SERVER['REMOTE_ADDR'];
  518.         $value->value->get_ip = array_unique($value->value->get_ip);
  519.         $value->value->get_count++;
  520.     }
  521.     $storage->set_value($image_value_key, $value->value, 31 * 24 * 3600);
  522.     unset($mutex_get);
  523.  
  524.     header('Access-Control-Allow-Origin: *');
  525.     if ($mode == 'mime') {
  526.         $sad_contype = 'application/javascript;';
  527.         echo json_encode(array(
  528.             'status' => 0,
  529.             'content_type' => $value->value->content_type
  530.         ));
  531.     } else {
  532.         $sad_contype = $value->value->content_type;
  533.         if (($mode == 'thumb') and preg_match('|^image/|', $value->value->content_type)) {
  534.             AscetCMSEngine::$etag_hash = $value->value->hash.'-thumb';
  535.             echo $value->value->thumb;
  536.         } else {
  537.             AscetCMSEngine::$etag_hash = $value->value->hash;
  538.             echo $value->value->img;
  539.         }
  540.     }
  541. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement