tissue/app/MetadataResolver/PixivResolver.php
2019-02-04 02:43:40 +09:00

93 lines
3.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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
{
parse_str(parse_url($url, PHP_URL_QUERY), $params);
$illustId = $params['illust_id'];
// 漫画ページページ数はmanga_bigならあるかも
if ($params['mode'] === 'manga_big' || $params['mode'] === 'manga') {
$page = $params['page'] ?? 0;
// 未ログインでは漫画ページを開けないため、URL を作品ページに変換する
$url = preg_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 ($params['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");
}
}
}
}