tissue/app/MetadataResolver/PixivResolver.php

90 lines
2.9 KiB
PHP
Raw Normal View History

2019-01-14 16:01:58 +09:00
<?php
namespace App\MetadataResolver;
use GuzzleHttp\Client;
2019-01-14 16:01:58 +09:00
class PixivResolver implements Resolver
{
/**
* @var Client
*/
private $client;
/**
* @var OGPResolver
*/
private $ogpResolver;
public function __construct(Client $client, OGPResolver $ogpResolver)
{
$this->client = $client;
$this->ogpResolver = $ogpResolver;
}
/**
* 直リン可能な pixiv.cat のプロキシ URL に変換する
* HUGE THANKS TO PIXIV.CAT!
*
2019-01-14 18:34:33 +09:00
* @param string $pixivUrl i.pximg URL
*
* @return string i.pixiv.cat URL
*/
2019-01-15 00:05:01 +09:00
public function proxize(string $pixivUrl): string
{
2019-01-19 03:02:37 +09:00
return str_replace('i.pximg.net', 'i.pixiv.cat', $pixivUrl);
2019-01-14 16:01:58 +09:00
}
public function resolve(string $url): Metadata
{
if (preg_match('~www\.pixiv\.net/user/\d+/series/\d+~', $url, $matches)) {
$res = $this->client->get($url);
if ($res->getStatusCode() === 200) {
$metadata = $this->ogpResolver->parse($res->getBody());
$metadata->image = $this->proxize($metadata->image);
return $metadata;
} else {
throw new \RuntimeException("{$res->getStatusCode()}: $url");
}
}
2019-02-04 02:43:40 +09:00
parse_str(parse_url($url, PHP_URL_QUERY), $params);
$illustId = $params['illust_id'];
$page = 0;
2019-01-14 16:01:58 +09:00
2019-02-04 02:43:40 +09:00
// 漫画ページページ数はmanga_bigならあるかも
if ($params['mode'] === 'manga_big' || $params['mode'] === 'manga') {
$page = $params['page'] ?? 0;
}
2019-01-14 16:01:58 +09:00
$res = $this->client->get('https://www.pixiv.net/ajax/illust/' . $illustId);
if ($res->getStatusCode() === 200) {
$json = json_decode($res->getBody()->getContents(), true);
$metadata = new Metadata();
2019-01-14 16:01:58 +09:00
$metadata->title = $json['body']['illustTitle'] ?? '';
$metadata->description = '投稿者: ' . $json['body']['userName'] . PHP_EOL . strip_tags(str_replace('<br />', PHP_EOL, $json['body']['illustComment'] ?? ''));
$metadata->image = $this->proxize($json['body']['urls']['original'] ?? '');
2019-01-14 16:01:58 +09:00
// ページ数の指定がある場合は画像URLをそのページにする
if ($page != 0) {
$metadata->image = str_replace('_p0', '_p'.$page, $metadata->image);
}
// タグ
if (!empty($json['body']['tags']['tags'])) {
foreach ($json['body']['tags']['tags'] as $tag) {
// 一部の固定キーワードは無視
if (array_search($tag['tag'], ['R-18', 'イラスト', 'pixiv', 'ピクシブ'], true) === false) {
$metadata->tags[] = preg_replace('/\s/', '_', $tag['tag']);
}
}
}
return $metadata;
} else {
throw new \RuntimeException("{$res->getStatusCode()}: $url");
2019-01-14 16:01:58 +09:00
}
}
}