tissue/app/MetadataResolver/PixivResolver.php
2019-01-19 03:02:37 +09:00

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");
}
}
}
}