64 lines
2.3 KiB
PHP
64 lines
2.3 KiB
PHP
<?php
|
|
namespace Uiharu\Lookup;
|
|
|
|
use DOMDocument;
|
|
use RuntimeException;
|
|
use Uiharu\Url;
|
|
|
|
final class NicoNicoLookup implements \Uiharu\ILookup {
|
|
public function match(Url $url): bool {
|
|
if(!$url->isWeb() || ($url->getHost() !== 'www.nicovideo.jp' && $url->getHost() !== 'nicovideo.jp'))
|
|
return false;
|
|
|
|
if(str_starts_with($url->getPath(), '/watch/sm'))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public function lookup(Url $url): NicoNicoLookupResult {
|
|
$videoId = explode('/', trim($url->getPath(), '/'))[1] ?? '';
|
|
if(empty($videoId))
|
|
throw new RuntimeException('Nico Nico Douga video id missing.');
|
|
|
|
$thumbDoc = self::lookupThumbInfo($videoId);
|
|
|
|
$thumbResp = $thumbDoc->getElementsByTagName('nicovideo_thumb_response')[0] ?? null;
|
|
if(empty($thumbResp) || !$thumbResp->hasAttribute('status') || $thumbResp->getAttribute('status') !== 'ok')
|
|
throw new RuntimeException('Nico Nico Douga video with the given id could not be found.');
|
|
|
|
$thumbInfo = $thumbResp->getElementsByTagName('thumb')[0] ?? null;
|
|
if(empty($thumbInfo))
|
|
throw new RuntimeException('Nico Nico Douga thumb info missing from API result????');
|
|
|
|
return new NicoNicoLookupResult($url, $videoId, $thumbInfo);
|
|
}
|
|
|
|
private static function lookupThumbInfo(string $videoId): DOMDocument {
|
|
$curl = curl_init("https://ext.nicovideo.jp/api/getthumbinfo/{$videoId}");
|
|
curl_setopt_array($curl, [
|
|
CURLOPT_AUTOREFERER => false,
|
|
CURLOPT_CERTINFO => false,
|
|
CURLOPT_FAILONERROR => false,
|
|
CURLOPT_FOLLOWLOCATION => false,
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TCP_FASTOPEN => true,
|
|
CURLOPT_CONNECTTIMEOUT => 2,
|
|
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
|
|
CURLOPT_TIMEOUT => 5,
|
|
CURLOPT_USERAGENT => 'Uiharu/' . UIH_VERSION,
|
|
]);
|
|
$resp = curl_exec($curl);
|
|
curl_close($curl);
|
|
|
|
if(empty($resp))
|
|
throw new RuntimeException('Nico Nico Douga API request failed.');
|
|
|
|
$doc = new DOMDocument;
|
|
if(!$doc->loadXML($resp))
|
|
throw new RuntimeException('Failed to parse Nico Nico Douga API response.');
|
|
|
|
return $doc;
|
|
}
|
|
}
|