uiharu/src/Lookup/EEPROMLookup.php

78 lines
2.7 KiB
PHP

<?php
namespace Uiharu\Lookup;
use RuntimeException;
use Uiharu\FFMPEG;
use Uiharu\MediaTypeExts;
use Uiharu\Url;
use Index\MediaType;
final class EEPROMLookup implements \Uiharu\ILookup {
public function __construct(
private string $protocol,
private string $apiDomain,
private array $shortDomains
) {}
public function match(Url $url): bool {
return $url->getScheme() === $this->protocol || (
$url->isWeb() && (
in_array($url->getHost(), $this->shortDomains) || (
$url->getHost() === $this->apiDomain && str_starts_with($url->getPath(), '/uploads')
)
)
);
}
private function rawLookup(string $fileId): ?object {
$curl = curl_init("https://{$this->apiDomain}/uploads/{$fileId}.json");
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,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
],
]);
$resp = curl_exec($curl);
curl_close($curl);
return json_decode($resp);
}
public function lookup(Url $url): EEPROMLookupResult {
if($url->getScheme() === $this->protocol) {
$fileId = $url->getPath();
} elseif($url->isWeb()) {
if($url->getHost() === $this->apiDomain) {
if(preg_match('#^/uploads/([A-Za-z0-9-_]+)/?$#', $url->getPath(), $matches))
$fileId = $matches[1];
} else {
$fileId = substr($url->getPath(), 1);
}
}
if(!isset($fileId))
throw new RuntimeException('Was unable to find EEPROM file id.');
if(!preg_match('#^([A-Za-z0-9-_]+)$#', $fileId))
throw new RuntimeException('Invalid EEPROM file id format.');
$fileInfo = $this->rawLookup($fileId);
if($fileInfo === null)
throw new RuntimeException('EEPROM file does not exist: ' . $fileId);
$url = Url::parse('https://' . $this->shortDomains[0] . '/' . $fileId);
$mediaType = MediaType::parse($fileInfo->type);
$isMedia = MediaTypeExts::isMedia($mediaType);
$mediaInfo = $isMedia ? FFMPEG::cleanProbe($url) : null;
return new EEPROMLookupResult($url, $mediaType, $fileInfo, $mediaInfo);
}
}