Removed Twitter and Nitter support. It's over folks.
This commit is contained in:
parent
4cff688057
commit
d9094f0d05
9 changed files with 154 additions and 445 deletions
|
@ -1 +1 @@
|
|||
Subproject commit bce5ba77a268ecd6338d0e3520e41ff4c40cbeda
|
||||
Subproject commit 1cd1695429b5a313ac357f3f3faba365e425f504
|
|
@ -10,7 +10,6 @@ $ctx->registerLookup(new \Uiharu\Lookup\EEPROMLookup('eeprom', 'eeprom.flashii.n
|
|||
if(UIH_DEBUG)
|
||||
$ctx->registerLookup(new \Uiharu\Lookup\EEPROMLookup('devrom', 'eeprom.edgii.net', ['i.edgii.net']));
|
||||
|
||||
$ctx->registerLookup(new \Uiharu\Lookup\TwitterLookup);
|
||||
$ctx->registerLookup(new \Uiharu\Lookup\YouTubeLookup);
|
||||
$ctx->registerLookup(new \Uiharu\Lookup\NicoNicoLookup);
|
||||
|
||||
|
|
|
@ -13,9 +13,6 @@ use Uiharu\MediaTypeExts;
|
|||
use Uiharu\UihContext;
|
||||
use Uiharu\Url;
|
||||
use Uiharu\Lookup\EEPROMLookupResult;
|
||||
use Uiharu\Lookup\TwitterLookupResult;
|
||||
use Uiharu\Lookup\TwitterLookupTweetResult;
|
||||
use Uiharu\Lookup\TwitterLookupUserResult;
|
||||
use Uiharu\Lookup\YouTubeLookupResult;
|
||||
use Uiharu\Lookup\NicoNicoLookupResult;
|
||||
use Index\MediaType;
|
||||
|
@ -188,17 +185,6 @@ final class v1_0 implements \Uiharu\IApi {
|
|||
if($result->hasPreviewImage())
|
||||
$resp->image = $result->getPreviewImage();
|
||||
|
||||
if($result instanceof TwitterLookupResult) {
|
||||
if($result instanceof TwitterLookupTweetResult)
|
||||
$resp->tweet_id = $result->getTwitterTweetId();
|
||||
|
||||
if($result instanceof TwitterLookupUserResult)
|
||||
$resp->twitter_user_name = $result->getTwitterUserName();
|
||||
|
||||
if(UIH_DEBUG)
|
||||
$resp->dbg_twitter_info = $result->getTwitterResult();
|
||||
}
|
||||
|
||||
if($result instanceof YouTubeLookupResult) {
|
||||
$resp->youtube_video_id = $result->getYouTubeVideoId();
|
||||
|
||||
|
|
296
src/Colour.php
296
src/Colour.php
|
@ -13,298 +13,298 @@ final class Colour {
|
|||
|
||||
switch($input) {
|
||||
// CSS Level 1
|
||||
case @"black":
|
||||
case "black":
|
||||
return self::BLACK;
|
||||
case @"silver":
|
||||
case "silver":
|
||||
return self::SILVER;
|
||||
case @"gray":
|
||||
case @"grey": // CSS Level 3
|
||||
case "gray":
|
||||
case "grey": // CSS Level 3
|
||||
return self::GREY;
|
||||
case @"white":
|
||||
case "white":
|
||||
return self::WHITE;
|
||||
case @"maroon":
|
||||
case "maroon":
|
||||
return self::MAROON;
|
||||
case @"red":
|
||||
case "red":
|
||||
return self::RED;
|
||||
case @"purple":
|
||||
case "purple":
|
||||
return self::PURPLE;
|
||||
case @"fuchsia":
|
||||
case @"magenta": // CSS Level 3
|
||||
case "fuchsia":
|
||||
case "magenta": // CSS Level 3
|
||||
return self::MAGENTA;
|
||||
case @"green":
|
||||
case "green":
|
||||
return self::GREEN;
|
||||
case @"lime":
|
||||
case "lime":
|
||||
return self::LIME;
|
||||
case @"olive":
|
||||
case "olive":
|
||||
return self::OLIVE;
|
||||
case @"yellow":
|
||||
case "yellow":
|
||||
return self::YELLOW;
|
||||
case @"navy":
|
||||
case "navy":
|
||||
return self::NAVY;
|
||||
case @"blue":
|
||||
case "blue":
|
||||
return self::BLUE;
|
||||
case @"teal":
|
||||
case "teal":
|
||||
return self::TEAL;
|
||||
case @"aqua":
|
||||
case @"cyan": // CSS Level 3
|
||||
case "aqua":
|
||||
case "cyan": // CSS Level 3
|
||||
return self::CYAN;
|
||||
|
||||
// CSS Level 2
|
||||
case @"orange":
|
||||
case "orange":
|
||||
return self::ORANGE;
|
||||
|
||||
// CSS Level 3
|
||||
case @"aliceblue":
|
||||
case "aliceblue":
|
||||
return self::ALICEBLUE;
|
||||
case @"antiquewhite":
|
||||
case "antiquewhite":
|
||||
return self::ANTIQUEWHITE;
|
||||
case @"aquamarine":
|
||||
case "aquamarine":
|
||||
return self::AQUAMARINE;
|
||||
case @"azure":
|
||||
case "azure":
|
||||
return self::AZURE;
|
||||
case @"beige":
|
||||
case "beige":
|
||||
return self::BEIGE;
|
||||
case @"bisque":
|
||||
case "bisque":
|
||||
return self::BISQUE;
|
||||
case @"blanchedalmond":
|
||||
case "blanchedalmond":
|
||||
return self::BLANCHEDALMOND;
|
||||
case @"blueviolet":
|
||||
case "blueviolet":
|
||||
return self::BLUEVIOLET;
|
||||
case @"brown":
|
||||
case "brown":
|
||||
return self::BROWN;
|
||||
case @"burlywood":
|
||||
case "burlywood":
|
||||
return self::BURLYWOOD;
|
||||
case @"cadetblue":
|
||||
case "cadetblue":
|
||||
return self::CADETBLUE;
|
||||
case @"chartreuse":
|
||||
case "chartreuse":
|
||||
return self::CHARTREUSE;
|
||||
case @"chocolate":
|
||||
case "chocolate":
|
||||
return self::CHOCOLATE;
|
||||
case @"coral":
|
||||
case "coral":
|
||||
return self::CORAL;
|
||||
case @"cornflowerblue":
|
||||
case "cornflowerblue":
|
||||
return self::CORNFLOWERBLUE;
|
||||
case @"cornsilk":
|
||||
case "cornsilk":
|
||||
return self::CORNSILK;
|
||||
case @"crimson":
|
||||
case "crimson":
|
||||
return self::CRIMSON;
|
||||
case @"darkblue":
|
||||
case "darkblue":
|
||||
return self::DARKBLUE;
|
||||
case @"darkcyan":
|
||||
case "darkcyan":
|
||||
return self::DARKCYAN;
|
||||
case @"darkgoldenrod":
|
||||
case "darkgoldenrod":
|
||||
return self::DARKGOLDENROD;
|
||||
case @"darkgrey":
|
||||
case @"darkgray":
|
||||
case "darkgrey":
|
||||
case "darkgray":
|
||||
return self::DARKGREY;
|
||||
case @"darkgreen":
|
||||
case "darkgreen":
|
||||
return self::DARKGREEN;
|
||||
case @"darkkhaki":
|
||||
case "darkkhaki":
|
||||
return self::DARKKHAKI;
|
||||
case @"darkmagenta":
|
||||
case "darkmagenta":
|
||||
return self::DARKMAGENTA;
|
||||
case @"darkolivegreen":
|
||||
case "darkolivegreen":
|
||||
return self::DARKOLIVEGREEN;
|
||||
case @"darkorange":
|
||||
case "darkorange":
|
||||
return self::DARKORANGE;
|
||||
case @"darkorchid":
|
||||
case "darkorchid":
|
||||
return self::DARKORCHID;
|
||||
case @"darkred":
|
||||
case "darkred":
|
||||
return self::DARKRED;
|
||||
case @"darksalmon":
|
||||
case "darksalmon":
|
||||
return self::DARKSALMON;
|
||||
case @"darkseagreen":
|
||||
case "darkseagreen":
|
||||
return self::DARKSEAGREEN;
|
||||
case @"darkslateblue":
|
||||
case "darkslateblue":
|
||||
return self::DARKSLATEBLUE;
|
||||
case @"darkslategrey":
|
||||
case @"darkslategray":
|
||||
case "darkslategrey":
|
||||
case "darkslategray":
|
||||
return self::DARKSLATEGREY;
|
||||
case @"darkturquoise":
|
||||
case "darkturquoise":
|
||||
return self::DARKTURQUOISE;
|
||||
case @"darkviolet":
|
||||
case "darkviolet":
|
||||
return self::DARKVIOLET;
|
||||
case @"deeppink":
|
||||
case "deeppink":
|
||||
return self::DEEPPINK;
|
||||
case @"deepskyblue":
|
||||
case "deepskyblue":
|
||||
return self::DEEPSKYBLUE;
|
||||
case @"dimgray":
|
||||
case @"dimgrey":
|
||||
case "dimgray":
|
||||
case "dimgrey":
|
||||
return self::DIMGREY;
|
||||
case @"dodgerblue":
|
||||
case "dodgerblue":
|
||||
return DodgerBluself::DODGERBLUE;
|
||||
case @"firebrick":
|
||||
case "firebrick":
|
||||
return self::FIREBRICK;
|
||||
case @"floralwhite":
|
||||
case "floralwhite":
|
||||
return self::FLORALWHITE;
|
||||
case @"forestgreen":
|
||||
case "forestgreen":
|
||||
return self::FORESTGREEN;
|
||||
case @"gainsboro":
|
||||
case "gainsboro":
|
||||
return self::GAINSBORO;
|
||||
case @"ghostwhite":
|
||||
case "ghostwhite":
|
||||
return self::GHOSTWHITE;
|
||||
case @"gold":
|
||||
case "gold":
|
||||
return self::GOLD;
|
||||
case @"goldenrod":
|
||||
case "goldenrod":
|
||||
return self::GOLDENROD;
|
||||
case @"greenyellow":
|
||||
case "greenyellow":
|
||||
return self::GREENYELLOW;
|
||||
case @"honeydew":
|
||||
case "honeydew":
|
||||
return self::HONEYDEW;
|
||||
case @"hotpink":
|
||||
case "hotpink":
|
||||
return self::HOTPINK;
|
||||
case @"indianred":
|
||||
case "indianred":
|
||||
return self::INDIANRED;
|
||||
case @"indigo":
|
||||
case "indigo":
|
||||
return self::INDIGO;
|
||||
case @"ivory":
|
||||
case "ivory":
|
||||
return self::IVORY;
|
||||
case @"khaki":
|
||||
case "khaki":
|
||||
return self::KHAKI;
|
||||
case @"lavender":
|
||||
case "lavender":
|
||||
return self::LAVENDER;
|
||||
case @"lavenderblush":
|
||||
case "lavenderblush":
|
||||
return self::LAVENDERBLUSH;
|
||||
case @"lawngreen":
|
||||
case "lawngreen":
|
||||
return self::LAWNGREEN;
|
||||
case @"lemonchiffon":
|
||||
case "lemonchiffon":
|
||||
return self::LEMONCHIFFON;
|
||||
case @"lightblue":
|
||||
case "lightblue":
|
||||
return self::LIGHTBLUE;
|
||||
case @"lightcoral":
|
||||
case "lightcoral":
|
||||
return self::LIGHTCORAL;
|
||||
case @"lightcyan":
|
||||
case "lightcyan":
|
||||
return self::LIGHTCYAN;
|
||||
case @"lightgoldenrodyellow":
|
||||
case "lightgoldenrodyellow":
|
||||
return self::LIGHTGOLDENRODYELLOW;
|
||||
case @"lightgray":
|
||||
case @"lightgrey":
|
||||
case "lightgray":
|
||||
case "lightgrey":
|
||||
return self::LIGHTGREY;
|
||||
case @"lightgreen":
|
||||
case "lightgreen":
|
||||
return self::LIGHTGREEN;
|
||||
case @"lightpink":
|
||||
case "lightpink":
|
||||
return self::LIGHTPINK;
|
||||
case @"lightsalmon":
|
||||
case "lightsalmon":
|
||||
return self::LIGHTSALMON;
|
||||
case @"lightseagreen":
|
||||
case "lightseagreen":
|
||||
return self::LIGHTSEAGREEN;
|
||||
case @"lightskyblue":
|
||||
case "lightskyblue":
|
||||
return self::LIGHTSEAGREEN;
|
||||
case @"lightslategray":
|
||||
case @"lightslategrey":
|
||||
case "lightslategray":
|
||||
case "lightslategrey":
|
||||
return self::LIGHTSLATEGREY;
|
||||
case @"lightsteelblue":
|
||||
case "lightsteelblue":
|
||||
return self::LIGHTSTEELBLUE;
|
||||
case @"lightyellow":
|
||||
case "lightyellow":
|
||||
return self::LIGHTYELLOW;
|
||||
case @"limegreen":
|
||||
case "limegreen":
|
||||
return self::LIMEGREEN;
|
||||
case @"linen":
|
||||
case "linen":
|
||||
return self::LINEN;
|
||||
case @"mediumaquamarine":
|
||||
case "mediumaquamarine":
|
||||
return self::MEDIUMAQUAMARINE;
|
||||
case @"mediumblue":
|
||||
case "mediumblue":
|
||||
return self::MEDIUMBLUE;
|
||||
case @"mediumorchid":
|
||||
case "mediumorchid":
|
||||
return self::MEDIUMORCHID;
|
||||
case @"mediumpurple":
|
||||
case "mediumpurple":
|
||||
return self::MEDIUMPURPLE;
|
||||
case @"mediumseagreen":
|
||||
case "mediumseagreen":
|
||||
return self::MEDIUMSEAGREEN;
|
||||
case @"mediumslateblue":
|
||||
case "mediumslateblue":
|
||||
return self::MEDIUMSLATEBLUE;
|
||||
case @"mediumspringgreen":
|
||||
case "mediumspringgreen":
|
||||
return self::MEDIUMSPRINGGREEN;
|
||||
case @"mediumturquoise":
|
||||
case "mediumturquoise":
|
||||
return self::MEDIUMTURQUOISE;
|
||||
case @"mediumvioletred":
|
||||
case "mediumvioletred":
|
||||
return self::MEDIUMVIOLETRED;
|
||||
case @"midnightblue":
|
||||
case "midnightblue":
|
||||
return self::MIDNIGHTBLUE;
|
||||
case @"mintcream":
|
||||
case "mintcream":
|
||||
return self::MINTCREAM;
|
||||
case @"mistyrose":
|
||||
case "mistyrose":
|
||||
return self::MISTYROSE;
|
||||
case @"moccasin":
|
||||
case "moccasin":
|
||||
return self::MOCCASIN;
|
||||
case @"navajowhite":
|
||||
case "navajowhite":
|
||||
return self::NAVAJOWHITE;
|
||||
case @"oldlace":
|
||||
case "oldlace":
|
||||
return self::OLDLACE;
|
||||
case @"olivedrab":
|
||||
case "olivedrab":
|
||||
return self::OLIVEDRAB;
|
||||
case @"orangered":
|
||||
case "orangered":
|
||||
return self::ORANGERED;
|
||||
case @"orchid":
|
||||
case "orchid":
|
||||
return self::ORCHID;
|
||||
case @"palegoldenrod":
|
||||
case "palegoldenrod":
|
||||
return self::PALEGOLDENROD;
|
||||
case @"palegreen":
|
||||
case "palegreen":
|
||||
return self::PALEGREEN;
|
||||
case @"paleturquoise":
|
||||
case "paleturquoise":
|
||||
return self::PALETURQUOISE;
|
||||
case @"palevioletred":
|
||||
case "palevioletred":
|
||||
return self::PALEVIOLETRED;
|
||||
case @"papayawhip":
|
||||
case "papayawhip":
|
||||
return self::PAPAYAWHIP;
|
||||
case @"peachpuff":
|
||||
case "peachpuff":
|
||||
return self::PEACHPUFF;
|
||||
case @"peru":
|
||||
case "peru":
|
||||
return self::PERU;
|
||||
case @"pink":
|
||||
case "pink":
|
||||
return self::PINK;
|
||||
case @"plum":
|
||||
case "plum":
|
||||
return self::PLUM;
|
||||
case @"powderblue":
|
||||
case "powderblue":
|
||||
return self::POWDERBLUE;
|
||||
case @"rosybrown":
|
||||
case "rosybrown":
|
||||
return self::ROSYBROWN;
|
||||
case @"royalblue":
|
||||
case "royalblue":
|
||||
return self::ROYALBLUE;
|
||||
case @"saddlebrown":
|
||||
case "saddlebrown":
|
||||
return self::SADDLEBROWN;
|
||||
case @"salmon":
|
||||
case "salmon":
|
||||
return self::SALMON;
|
||||
case @"sandybrown":
|
||||
case "sandybrown":
|
||||
return self::SANDYBROWN;
|
||||
case @"seagreen":
|
||||
case "seagreen":
|
||||
return self::SEAGREEN;
|
||||
case @"seashell":
|
||||
case "seashell":
|
||||
return self::SEASHELL;
|
||||
case @"sienna":
|
||||
case "sienna":
|
||||
return self::SIENNA;
|
||||
case @"skyblue":
|
||||
case "skyblue":
|
||||
return self::SKYBLUE;
|
||||
case @"slateblue":
|
||||
case "slateblue":
|
||||
return self::SLATEBLUE;
|
||||
case @"slategray":
|
||||
case @"slategrey":
|
||||
case "slategray":
|
||||
case "slategrey":
|
||||
return self::SLATEGREY;
|
||||
case @"snow":
|
||||
case "snow":
|
||||
return self::SNOW;
|
||||
case @"springgreen":
|
||||
case "springgreen":
|
||||
return self::SPRINGGREEN;
|
||||
case @"steelblue":
|
||||
case "steelblue":
|
||||
return self::STEELBLUE;
|
||||
case @"tan":
|
||||
case "tan":
|
||||
return self::TAN;
|
||||
case @"thistle":
|
||||
case "thistle":
|
||||
return self::THISTLE;
|
||||
case @"tomato":
|
||||
case "tomato":
|
||||
return self::TOMATO;
|
||||
case @"turquoise":
|
||||
case "turquoise":
|
||||
return self::TURQUOISE;
|
||||
case @"violet":
|
||||
case "violet":
|
||||
return self::VIOLET;
|
||||
case @"wheat":
|
||||
case "wheat":
|
||||
return self::WHEAT;
|
||||
case @"whitesmoke":
|
||||
case "whitesmoke":
|
||||
return self::WHITESMOKE;
|
||||
case @"yellowgreen":
|
||||
case "yellowgreen":
|
||||
return self::YELLOWGREEN;
|
||||
|
||||
// CSS Level 4
|
||||
case @"rebeccapurple":
|
||||
case "rebeccapurple":
|
||||
return self::REBECCAPURPLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
<?php
|
||||
namespace Uiharu\Lookup;
|
||||
|
||||
use stdClass;
|
||||
use DOMDocument;
|
||||
use DOMXpath;
|
||||
use RuntimeException;
|
||||
use Uiharu\Config;
|
||||
use Uiharu\Url;
|
||||
use Index\MediaType;
|
||||
use Masterminds\HTML5;
|
||||
|
||||
final class TwitterLookup implements \Uiharu\ILookup {
|
||||
private const TWITTER_DOMAINS = [
|
||||
'twitter.com', 'www.twitter.com',
|
||||
'm.twitter.com', 'mobile.twitter.com',
|
||||
'nitter.net', 'www.nitter.net',
|
||||
];
|
||||
|
||||
public function match(Url $url): bool {
|
||||
if(!$url->isWeb() || !in_array(strtolower($url->getHost()), self::TWITTER_DOMAINS))
|
||||
return false;
|
||||
|
||||
return preg_match('#^/@?(?:[A-Za-z0-9_]{1,20})/status(?:es)?/([0-9]+)/?$#', $url->getPath())
|
||||
|| preg_match('#^/@?([A-Za-z0-9_]{1,20})/?$#', $url->getPath());
|
||||
}
|
||||
|
||||
private function getString(string $path): string {
|
||||
$curl = curl_init(Config::get('Nitter', 'endpoint') . $path);
|
||||
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);
|
||||
return $resp;
|
||||
}
|
||||
|
||||
private function getDocument(string $path): DOMDocument {
|
||||
$string = $this->getString($path);
|
||||
if(empty($string))
|
||||
throw new RuntimeException('Failed to download Nitter page.');
|
||||
|
||||
return (new HTML5)->loadHTML($string);
|
||||
}
|
||||
|
||||
private static function convertNitterMediaURL(string $path): string {
|
||||
if($path === '')
|
||||
return $path;
|
||||
|
||||
[,,$url] = explode('/', $path);
|
||||
$url = rawurldecode($url);
|
||||
|
||||
if(!str_starts_with($url, 'pbs.twimg.com'))
|
||||
$url = 'pbs.twimg.com/' . str_replace('_bigger', '', $url);
|
||||
|
||||
return 'https://' . $url;
|
||||
}
|
||||
|
||||
private function lookupUser(string $userName): ?object {
|
||||
$document = $this->getDocument("/{$userName}");
|
||||
$xpath = new DOMXpath($document);
|
||||
|
||||
$out = new stdClass;
|
||||
|
||||
$userNameElems = $xpath->query('//*[@class="profile-card-username"]');
|
||||
$out->userName = $userNameElems->length < 1 ? '' : trim($userNameElems[0]->textContent);
|
||||
|
||||
$profileNameElems = $xpath->query('//*[@class="profile-card-fullname"]');
|
||||
$out->profileName = $profileNameElems->length < 1 ? '' : trim($profileNameElems[0]->textContent);
|
||||
|
||||
$profileBioElems = $xpath->query('//*[@class="profile-bio"]/*');
|
||||
$out->profileBio = $profileBioElems->length < 1 ? '' : trim($profileBioElems[0]->textContent);
|
||||
|
||||
$profilePictureElems = $xpath->query('//*[@class="profile-card-avatar"]');
|
||||
$out->profilePicture = $profilePictureElems->length < 1 ? '' : $profilePictureElems[0]->getAttribute('href');
|
||||
$out->profilePicture = self::convertNitterMediaURL($out->profilePicture);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function lookupTweet(string $tweetId): ?object {
|
||||
$document = $this->getDocument("/i/status/{$tweetId}");
|
||||
$xpath = new DOMXpath($document);
|
||||
|
||||
$out = new stdClass;
|
||||
|
||||
$tweetDateElems = $xpath->query('//*[@class="tweet-date"]/*');
|
||||
$out->tweetId = $tweetDateElems->length < 1 ? '' : trim($tweetDateElems[0]->getAttribute('href'));
|
||||
if($out->tweetId !== '') {
|
||||
[,,,$out->tweetId] = explode('/', $out->tweetId);
|
||||
[$out->tweetId] = explode('#', $out->tweetId);
|
||||
}
|
||||
|
||||
$tweetTextElems = $xpath->query('//*[@class="tweet-content media-body"]');
|
||||
$out->tweetText = $tweetTextElems->length < 1 ? '' : trim($tweetTextElems[0]->textContent);
|
||||
|
||||
$profileNameElems = $xpath->query('//*[@class="fullname"]');
|
||||
$out->profileName = $profileNameElems->length < 1 ? '' : trim($profileNameElems[0]->textContent);
|
||||
|
||||
$profilePictureElems = $xpath->query('//*[@class="tweet-avatar"]/*');
|
||||
$out->profilePicture = $profilePictureElems->length < 1 ? '' : $profilePictureElems[0]->getAttribute('src');
|
||||
$out->profilePicture = self::convertNitterMediaURL($out->profilePicture);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function lookup(Url $url): TwitterLookupResult {
|
||||
if(preg_match('#^/@?(?:[A-Za-z0-9_]{1,20})/status(?:es)?/([0-9]+)/?$#', $url->getPath(), $matches)) {
|
||||
$tweetId = strval($matches[1] ?? '0');
|
||||
$tweetInfo = $this->lookupTweet($tweetId);
|
||||
if($tweetInfo === null)
|
||||
throw new RuntimeException('Tweet lookup failed.');
|
||||
return new TwitterLookupTweetResult($url, $tweetInfo);
|
||||
}
|
||||
|
||||
if(preg_match('#^/@?([A-Za-z0-9_]{1,20})/?$#', $url->getPath(), $matches)) {
|
||||
$userName = strval($matches[1] ?? '');
|
||||
$userInfo = $this->lookupUser($userName);
|
||||
if($userInfo === null)
|
||||
throw new RuntimeException('Twitter user lookup failed.');
|
||||
return new TwitterLookupUserResult($url, $userInfo);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Unknown Twitter URL format.');
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
namespace Uiharu\Lookup;
|
||||
|
||||
use RuntimeException;
|
||||
use Uiharu\Url;
|
||||
use Index\MediaType;
|
||||
|
||||
abstract class TwitterLookupResult implements \Uiharu\ILookupResult {
|
||||
private Url $url;
|
||||
|
||||
public function __construct(Url $url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function getUrl(): Url {
|
||||
return $this->url;
|
||||
}
|
||||
public abstract function getObjectType(): string;
|
||||
|
||||
public function hasMediaType(): bool {
|
||||
return false;
|
||||
}
|
||||
public function getMediaType(): MediaType {
|
||||
throw new RuntimeException('Unsupported');
|
||||
}
|
||||
|
||||
public function hasColour(): bool {
|
||||
return true;
|
||||
}
|
||||
public function getColour(): int {
|
||||
return 0x1DA1F2;
|
||||
}
|
||||
|
||||
public abstract function hasTitle(): bool;
|
||||
public abstract function getTitle(): string;
|
||||
|
||||
public function hasSiteName(): bool {
|
||||
return true;
|
||||
}
|
||||
public function getSiteName(): string {
|
||||
return 'Twitter';
|
||||
}
|
||||
|
||||
public abstract function hasDescription(): bool;
|
||||
public abstract function getDescription(): string;
|
||||
|
||||
public abstract function hasPreviewImage(): bool;
|
||||
public abstract function getPreviewImage(): string;
|
||||
|
||||
public abstract function getTwitterResult(): object;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
namespace Uiharu\Lookup;
|
||||
|
||||
use Uiharu\Url;
|
||||
|
||||
class TwitterLookupTweetResult extends TwitterLookupResult {
|
||||
private object $tweetInfo;
|
||||
|
||||
public function __construct(Url $url, object $tweetInfo) {
|
||||
parent::__construct($url);
|
||||
$this->tweetInfo = $tweetInfo;
|
||||
}
|
||||
|
||||
public function getObjectType(): string {
|
||||
return 'twitter:tweet';
|
||||
}
|
||||
|
||||
public function getTwitterTweetId(): string {
|
||||
return $this->tweetInfo->tweetId;
|
||||
}
|
||||
|
||||
public function hasTitle(): bool {
|
||||
return $this->tweetInfo->profileName !== '';
|
||||
}
|
||||
public function getTitle(): string {
|
||||
return $this->tweetInfo->profileName;
|
||||
}
|
||||
|
||||
public function hasDescription(): bool {
|
||||
return $this->tweetInfo->tweetText !== '';
|
||||
}
|
||||
public function getDescription(): string {
|
||||
return $this->tweetInfo->tweetText;
|
||||
}
|
||||
|
||||
public function hasPreviewImage(): bool {
|
||||
return $this->tweetInfo->profilePicture !== '';
|
||||
}
|
||||
public function getPreviewImage(): string {
|
||||
return $this->tweetInfo->profilePicture;
|
||||
}
|
||||
|
||||
public function getTwitterResult(): object {
|
||||
return $this->tweetInfo;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
namespace Uiharu\Lookup;
|
||||
|
||||
use Uiharu\Url;
|
||||
|
||||
class TwitterLookupUserResult extends TwitterLookupResult {
|
||||
private object $userInfo;
|
||||
|
||||
public function __construct(Url $url, object $userInfo) {
|
||||
parent::__construct($url);
|
||||
$this->userInfo = $userInfo;
|
||||
}
|
||||
|
||||
public function getObjectType(): string {
|
||||
return 'twitter:user';
|
||||
}
|
||||
|
||||
public function getTwitterUserName(): string {
|
||||
return $this->userInfo->userName;
|
||||
}
|
||||
|
||||
public function hasTitle(): bool {
|
||||
return $this->userInfo->profileName !== '';
|
||||
}
|
||||
public function getTitle(): string {
|
||||
return $this->userInfo->profileName;
|
||||
}
|
||||
|
||||
public function hasDescription(): bool {
|
||||
return $this->userInfo->profileBio !== '';
|
||||
}
|
||||
public function getDescription(): string {
|
||||
return $this->userInfo->profileBio;
|
||||
}
|
||||
|
||||
public function hasPreviewImage(): bool {
|
||||
return $this->userInfo->profilePicture !== '';
|
||||
}
|
||||
public function getPreviewImage(): string {
|
||||
return $this->userInfo->profilePicture;
|
||||
}
|
||||
|
||||
public function getTwitterResult(): object {
|
||||
return $this->userInfo;
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ final class WebLookup implements \Uiharu\ILookup {
|
|||
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
|
||||
CURLOPT_TIMEOUT => 5,
|
||||
CURLOPT_DEFAULT_PROTOCOL => 'https',
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible) Uiharu/' . UIH_VERSION,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; FlashiiBot/2.5; Uiharu/' . UIH_VERSION . '; +http://fii.moe/uiharu)',
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8',
|
||||
],
|
||||
|
@ -200,10 +200,12 @@ final class WebLookup implements \Uiharu\ILookup {
|
|||
break;
|
||||
|
||||
case 'theme-color':
|
||||
if(empty($siteInfo->colour))
|
||||
$siteInfo->colour = $valueAttr;
|
||||
break;
|
||||
|
||||
case 'og:type':
|
||||
if(empty($siteInfo->type))
|
||||
$siteInfo->type = 'website:' . $valueAttr;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue