94 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace App\MetadataResolver;
 | 
						|
 | 
						|
class PixivResolver implements Resolver
 | 
						|
{
 | 
						|
 | 
						|
    /**
 | 
						|
     * サムネイル画像 URL から最大長辺 1200px の画像 URL に変換する
 | 
						|
     *
 | 
						|
     * @param string $thumbnailUrl サムネイル画像 URL
 | 
						|
     * @return string 1200px の画像 URL
 | 
						|
     */
 | 
						|
    public function thumbnailToMasterUrl(string $thumbnailUrl):string
 | 
						|
    {
 | 
						|
        $temp = str_replace("/c/128x128", "", $thumbnailUrl);
 | 
						|
        $largeUrl = str_replace("square1200.jpg", "master1200.jpg", $temp);
 | 
						|
        return $largeUrl;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 直リン可能な pixiv.cat のプロキシ URL に変換する
 | 
						|
     * HUGE THANKS TO PIXIV.CAT!
 | 
						|
     *
 | 
						|
     * @param string $pixivUrl i.pximg URL
 | 
						|
     * @return string i.pixiv.cat URL
 | 
						|
     */
 | 
						|
    public function proxize(string $pixivUrl):string
 | 
						|
    {
 | 
						|
        return str_replace("i.pximg.net", "i.pixiv.cat", $pixivUrl);
 | 
						|
    }
 | 
						|
 | 
						|
    public function resolve(string $url): Metadata
 | 
						|
    {
 | 
						|
        preg_match("~illust_id=(\d+)~", parse_url($url)["query"], $match);
 | 
						|
        $illustId = $match[1];
 | 
						|
 | 
						|
        // 漫画ページかつページ数あり
 | 
						|
        if (strpos(parse_url($url)["query"], "mode=manga_big") && strpos(parse_url($url)["query"], "page=")) {
 | 
						|
            preg_match("~page=(\d+)~", parse_url($url)["query"], $match);
 | 
						|
            $page = $match[1];
 | 
						|
 | 
						|
            // 未ログインでは漫画ページを開けないため、URL を作品ページに変換する
 | 
						|
            $url = str_replace("mode=manga_big", "mode=medium", $url);
 | 
						|
 | 
						|
            $client = new \GuzzleHttp\Client();
 | 
						|
            $res = $client->get($url);
 | 
						|
            if ($res->getStatusCode() === 200) {
 | 
						|
                $ogpResolver = new OGPResolver();
 | 
						|
                $metadata = $ogpResolver->parse($res->getBody());
 | 
						|
 | 
						|
                preg_match("~https://i\.pximg\.net/c/128x128/img-master/img/\d{4}/\d{2}/\d{2}/\d{2}/\d{2}/\d{2}/{$illustId}_p0_square1200\.jpg~", $res->getBody(), $match);
 | 
						|
                $illustThumbnailUrl = $match[0];
 | 
						|
 | 
						|
                $illustUrl = $this->thumbnailToMasterUrl($illustThumbnailUrl);
 | 
						|
 | 
						|
                // 指定ページに変換
 | 
						|
                $illustUrl = str_replace("p0_master", "p{$page}_master", $illustUrl);
 | 
						|
 | 
						|
                $metadata->image =  $this->proxize($illustUrl);
 | 
						|
 | 
						|
                return $metadata;
 | 
						|
            } else {
 | 
						|
                throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            $client = new \GuzzleHttp\Client();
 | 
						|
            $res = $client->get($url);
 | 
						|
            if ($res->getStatusCode() === 200) {
 | 
						|
                $ogpResolver = new OGPResolver();
 | 
						|
                $metadata = $ogpResolver->parse($res->getBody());
 | 
						|
 | 
						|
                // OGP がデフォルト画像であるようならなんとかして画像を取得する
 | 
						|
                if (strpos($metadata->image, "pixiv_logo.gif") || strpos($metadata->image, "pictures.jpg")) {
 | 
						|
 | 
						|
                    // 作品ページの場合のみ対応
 | 
						|
                    if (strpos(parse_url($url)["query"], "mode=medium")) {
 | 
						|
                        preg_match("~https://i\.pximg\.net/c/128x128/img-master/img/\d{4}/\d{2}/\d{2}/\d{2}/\d{2}/\d{2}/{$illustId}(_p0)?_square1200\.jpg~", $res->getBody(), $match);
 | 
						|
                        $illustThumbnailUrl = $match[0];
 | 
						|
 | 
						|
                        $illustUrl = $this->thumbnailToMasterUrl($illustThumbnailUrl);
 | 
						|
 | 
						|
                        $metadata->image =  $this->proxize($illustUrl);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                return $metadata;
 | 
						|
            } else {
 | 
						|
                throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |