Removed Twitter and Nitter support. It's over folks.

This commit is contained in:
flash 2023-07-06 22:53:02 +00:00
parent 4cff688057
commit d9094f0d05
9 changed files with 154 additions and 445 deletions

@ -1 +1 @@
Subproject commit bce5ba77a268ecd6338d0e3520e41ff4c40cbeda Subproject commit 1cd1695429b5a313ac357f3f3faba365e425f504

View file

@ -10,7 +10,6 @@ $ctx->registerLookup(new \Uiharu\Lookup\EEPROMLookup('eeprom', 'eeprom.flashii.n
if(UIH_DEBUG) if(UIH_DEBUG)
$ctx->registerLookup(new \Uiharu\Lookup\EEPROMLookup('devrom', 'eeprom.edgii.net', ['i.edgii.net'])); $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\YouTubeLookup);
$ctx->registerLookup(new \Uiharu\Lookup\NicoNicoLookup); $ctx->registerLookup(new \Uiharu\Lookup\NicoNicoLookup);

View file

@ -13,9 +13,6 @@ use Uiharu\MediaTypeExts;
use Uiharu\UihContext; use Uiharu\UihContext;
use Uiharu\Url; use Uiharu\Url;
use Uiharu\Lookup\EEPROMLookupResult; use Uiharu\Lookup\EEPROMLookupResult;
use Uiharu\Lookup\TwitterLookupResult;
use Uiharu\Lookup\TwitterLookupTweetResult;
use Uiharu\Lookup\TwitterLookupUserResult;
use Uiharu\Lookup\YouTubeLookupResult; use Uiharu\Lookup\YouTubeLookupResult;
use Uiharu\Lookup\NicoNicoLookupResult; use Uiharu\Lookup\NicoNicoLookupResult;
use Index\MediaType; use Index\MediaType;
@ -188,17 +185,6 @@ final class v1_0 implements \Uiharu\IApi {
if($result->hasPreviewImage()) if($result->hasPreviewImage())
$resp->image = $result->getPreviewImage(); $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) { if($result instanceof YouTubeLookupResult) {
$resp->youtube_video_id = $result->getYouTubeVideoId(); $resp->youtube_video_id = $result->getYouTubeVideoId();

View file

@ -13,298 +13,298 @@ final class Colour {
switch($input) { switch($input) {
// CSS Level 1 // CSS Level 1
case @"black": case "black":
return self::BLACK; return self::BLACK;
case @"silver": case "silver":
return self::SILVER; return self::SILVER;
case @"gray": case "gray":
case @"grey": // CSS Level 3 case "grey": // CSS Level 3
return self::GREY; return self::GREY;
case @"white": case "white":
return self::WHITE; return self::WHITE;
case @"maroon": case "maroon":
return self::MAROON; return self::MAROON;
case @"red": case "red":
return self::RED; return self::RED;
case @"purple": case "purple":
return self::PURPLE; return self::PURPLE;
case @"fuchsia": case "fuchsia":
case @"magenta": // CSS Level 3 case "magenta": // CSS Level 3
return self::MAGENTA; return self::MAGENTA;
case @"green": case "green":
return self::GREEN; return self::GREEN;
case @"lime": case "lime":
return self::LIME; return self::LIME;
case @"olive": case "olive":
return self::OLIVE; return self::OLIVE;
case @"yellow": case "yellow":
return self::YELLOW; return self::YELLOW;
case @"navy": case "navy":
return self::NAVY; return self::NAVY;
case @"blue": case "blue":
return self::BLUE; return self::BLUE;
case @"teal": case "teal":
return self::TEAL; return self::TEAL;
case @"aqua": case "aqua":
case @"cyan": // CSS Level 3 case "cyan": // CSS Level 3
return self::CYAN; return self::CYAN;
// CSS Level 2 // CSS Level 2
case @"orange": case "orange":
return self::ORANGE; return self::ORANGE;
// CSS Level 3 // CSS Level 3
case @"aliceblue": case "aliceblue":
return self::ALICEBLUE; return self::ALICEBLUE;
case @"antiquewhite": case "antiquewhite":
return self::ANTIQUEWHITE; return self::ANTIQUEWHITE;
case @"aquamarine": case "aquamarine":
return self::AQUAMARINE; return self::AQUAMARINE;
case @"azure": case "azure":
return self::AZURE; return self::AZURE;
case @"beige": case "beige":
return self::BEIGE; return self::BEIGE;
case @"bisque": case "bisque":
return self::BISQUE; return self::BISQUE;
case @"blanchedalmond": case "blanchedalmond":
return self::BLANCHEDALMOND; return self::BLANCHEDALMOND;
case @"blueviolet": case "blueviolet":
return self::BLUEVIOLET; return self::BLUEVIOLET;
case @"brown": case "brown":
return self::BROWN; return self::BROWN;
case @"burlywood": case "burlywood":
return self::BURLYWOOD; return self::BURLYWOOD;
case @"cadetblue": case "cadetblue":
return self::CADETBLUE; return self::CADETBLUE;
case @"chartreuse": case "chartreuse":
return self::CHARTREUSE; return self::CHARTREUSE;
case @"chocolate": case "chocolate":
return self::CHOCOLATE; return self::CHOCOLATE;
case @"coral": case "coral":
return self::CORAL; return self::CORAL;
case @"cornflowerblue": case "cornflowerblue":
return self::CORNFLOWERBLUE; return self::CORNFLOWERBLUE;
case @"cornsilk": case "cornsilk":
return self::CORNSILK; return self::CORNSILK;
case @"crimson": case "crimson":
return self::CRIMSON; return self::CRIMSON;
case @"darkblue": case "darkblue":
return self::DARKBLUE; return self::DARKBLUE;
case @"darkcyan": case "darkcyan":
return self::DARKCYAN; return self::DARKCYAN;
case @"darkgoldenrod": case "darkgoldenrod":
return self::DARKGOLDENROD; return self::DARKGOLDENROD;
case @"darkgrey": case "darkgrey":
case @"darkgray": case "darkgray":
return self::DARKGREY; return self::DARKGREY;
case @"darkgreen": case "darkgreen":
return self::DARKGREEN; return self::DARKGREEN;
case @"darkkhaki": case "darkkhaki":
return self::DARKKHAKI; return self::DARKKHAKI;
case @"darkmagenta": case "darkmagenta":
return self::DARKMAGENTA; return self::DARKMAGENTA;
case @"darkolivegreen": case "darkolivegreen":
return self::DARKOLIVEGREEN; return self::DARKOLIVEGREEN;
case @"darkorange": case "darkorange":
return self::DARKORANGE; return self::DARKORANGE;
case @"darkorchid": case "darkorchid":
return self::DARKORCHID; return self::DARKORCHID;
case @"darkred": case "darkred":
return self::DARKRED; return self::DARKRED;
case @"darksalmon": case "darksalmon":
return self::DARKSALMON; return self::DARKSALMON;
case @"darkseagreen": case "darkseagreen":
return self::DARKSEAGREEN; return self::DARKSEAGREEN;
case @"darkslateblue": case "darkslateblue":
return self::DARKSLATEBLUE; return self::DARKSLATEBLUE;
case @"darkslategrey": case "darkslategrey":
case @"darkslategray": case "darkslategray":
return self::DARKSLATEGREY; return self::DARKSLATEGREY;
case @"darkturquoise": case "darkturquoise":
return self::DARKTURQUOISE; return self::DARKTURQUOISE;
case @"darkviolet": case "darkviolet":
return self::DARKVIOLET; return self::DARKVIOLET;
case @"deeppink": case "deeppink":
return self::DEEPPINK; return self::DEEPPINK;
case @"deepskyblue": case "deepskyblue":
return self::DEEPSKYBLUE; return self::DEEPSKYBLUE;
case @"dimgray": case "dimgray":
case @"dimgrey": case "dimgrey":
return self::DIMGREY; return self::DIMGREY;
case @"dodgerblue": case "dodgerblue":
return DodgerBluself::DODGERBLUE; return DodgerBluself::DODGERBLUE;
case @"firebrick": case "firebrick":
return self::FIREBRICK; return self::FIREBRICK;
case @"floralwhite": case "floralwhite":
return self::FLORALWHITE; return self::FLORALWHITE;
case @"forestgreen": case "forestgreen":
return self::FORESTGREEN; return self::FORESTGREEN;
case @"gainsboro": case "gainsboro":
return self::GAINSBORO; return self::GAINSBORO;
case @"ghostwhite": case "ghostwhite":
return self::GHOSTWHITE; return self::GHOSTWHITE;
case @"gold": case "gold":
return self::GOLD; return self::GOLD;
case @"goldenrod": case "goldenrod":
return self::GOLDENROD; return self::GOLDENROD;
case @"greenyellow": case "greenyellow":
return self::GREENYELLOW; return self::GREENYELLOW;
case @"honeydew": case "honeydew":
return self::HONEYDEW; return self::HONEYDEW;
case @"hotpink": case "hotpink":
return self::HOTPINK; return self::HOTPINK;
case @"indianred": case "indianred":
return self::INDIANRED; return self::INDIANRED;
case @"indigo": case "indigo":
return self::INDIGO; return self::INDIGO;
case @"ivory": case "ivory":
return self::IVORY; return self::IVORY;
case @"khaki": case "khaki":
return self::KHAKI; return self::KHAKI;
case @"lavender": case "lavender":
return self::LAVENDER; return self::LAVENDER;
case @"lavenderblush": case "lavenderblush":
return self::LAVENDERBLUSH; return self::LAVENDERBLUSH;
case @"lawngreen": case "lawngreen":
return self::LAWNGREEN; return self::LAWNGREEN;
case @"lemonchiffon": case "lemonchiffon":
return self::LEMONCHIFFON; return self::LEMONCHIFFON;
case @"lightblue": case "lightblue":
return self::LIGHTBLUE; return self::LIGHTBLUE;
case @"lightcoral": case "lightcoral":
return self::LIGHTCORAL; return self::LIGHTCORAL;
case @"lightcyan": case "lightcyan":
return self::LIGHTCYAN; return self::LIGHTCYAN;
case @"lightgoldenrodyellow": case "lightgoldenrodyellow":
return self::LIGHTGOLDENRODYELLOW; return self::LIGHTGOLDENRODYELLOW;
case @"lightgray": case "lightgray":
case @"lightgrey": case "lightgrey":
return self::LIGHTGREY; return self::LIGHTGREY;
case @"lightgreen": case "lightgreen":
return self::LIGHTGREEN; return self::LIGHTGREEN;
case @"lightpink": case "lightpink":
return self::LIGHTPINK; return self::LIGHTPINK;
case @"lightsalmon": case "lightsalmon":
return self::LIGHTSALMON; return self::LIGHTSALMON;
case @"lightseagreen": case "lightseagreen":
return self::LIGHTSEAGREEN; return self::LIGHTSEAGREEN;
case @"lightskyblue": case "lightskyblue":
return self::LIGHTSEAGREEN; return self::LIGHTSEAGREEN;
case @"lightslategray": case "lightslategray":
case @"lightslategrey": case "lightslategrey":
return self::LIGHTSLATEGREY; return self::LIGHTSLATEGREY;
case @"lightsteelblue": case "lightsteelblue":
return self::LIGHTSTEELBLUE; return self::LIGHTSTEELBLUE;
case @"lightyellow": case "lightyellow":
return self::LIGHTYELLOW; return self::LIGHTYELLOW;
case @"limegreen": case "limegreen":
return self::LIMEGREEN; return self::LIMEGREEN;
case @"linen": case "linen":
return self::LINEN; return self::LINEN;
case @"mediumaquamarine": case "mediumaquamarine":
return self::MEDIUMAQUAMARINE; return self::MEDIUMAQUAMARINE;
case @"mediumblue": case "mediumblue":
return self::MEDIUMBLUE; return self::MEDIUMBLUE;
case @"mediumorchid": case "mediumorchid":
return self::MEDIUMORCHID; return self::MEDIUMORCHID;
case @"mediumpurple": case "mediumpurple":
return self::MEDIUMPURPLE; return self::MEDIUMPURPLE;
case @"mediumseagreen": case "mediumseagreen":
return self::MEDIUMSEAGREEN; return self::MEDIUMSEAGREEN;
case @"mediumslateblue": case "mediumslateblue":
return self::MEDIUMSLATEBLUE; return self::MEDIUMSLATEBLUE;
case @"mediumspringgreen": case "mediumspringgreen":
return self::MEDIUMSPRINGGREEN; return self::MEDIUMSPRINGGREEN;
case @"mediumturquoise": case "mediumturquoise":
return self::MEDIUMTURQUOISE; return self::MEDIUMTURQUOISE;
case @"mediumvioletred": case "mediumvioletred":
return self::MEDIUMVIOLETRED; return self::MEDIUMVIOLETRED;
case @"midnightblue": case "midnightblue":
return self::MIDNIGHTBLUE; return self::MIDNIGHTBLUE;
case @"mintcream": case "mintcream":
return self::MINTCREAM; return self::MINTCREAM;
case @"mistyrose": case "mistyrose":
return self::MISTYROSE; return self::MISTYROSE;
case @"moccasin": case "moccasin":
return self::MOCCASIN; return self::MOCCASIN;
case @"navajowhite": case "navajowhite":
return self::NAVAJOWHITE; return self::NAVAJOWHITE;
case @"oldlace": case "oldlace":
return self::OLDLACE; return self::OLDLACE;
case @"olivedrab": case "olivedrab":
return self::OLIVEDRAB; return self::OLIVEDRAB;
case @"orangered": case "orangered":
return self::ORANGERED; return self::ORANGERED;
case @"orchid": case "orchid":
return self::ORCHID; return self::ORCHID;
case @"palegoldenrod": case "palegoldenrod":
return self::PALEGOLDENROD; return self::PALEGOLDENROD;
case @"palegreen": case "palegreen":
return self::PALEGREEN; return self::PALEGREEN;
case @"paleturquoise": case "paleturquoise":
return self::PALETURQUOISE; return self::PALETURQUOISE;
case @"palevioletred": case "palevioletred":
return self::PALEVIOLETRED; return self::PALEVIOLETRED;
case @"papayawhip": case "papayawhip":
return self::PAPAYAWHIP; return self::PAPAYAWHIP;
case @"peachpuff": case "peachpuff":
return self::PEACHPUFF; return self::PEACHPUFF;
case @"peru": case "peru":
return self::PERU; return self::PERU;
case @"pink": case "pink":
return self::PINK; return self::PINK;
case @"plum": case "plum":
return self::PLUM; return self::PLUM;
case @"powderblue": case "powderblue":
return self::POWDERBLUE; return self::POWDERBLUE;
case @"rosybrown": case "rosybrown":
return self::ROSYBROWN; return self::ROSYBROWN;
case @"royalblue": case "royalblue":
return self::ROYALBLUE; return self::ROYALBLUE;
case @"saddlebrown": case "saddlebrown":
return self::SADDLEBROWN; return self::SADDLEBROWN;
case @"salmon": case "salmon":
return self::SALMON; return self::SALMON;
case @"sandybrown": case "sandybrown":
return self::SANDYBROWN; return self::SANDYBROWN;
case @"seagreen": case "seagreen":
return self::SEAGREEN; return self::SEAGREEN;
case @"seashell": case "seashell":
return self::SEASHELL; return self::SEASHELL;
case @"sienna": case "sienna":
return self::SIENNA; return self::SIENNA;
case @"skyblue": case "skyblue":
return self::SKYBLUE; return self::SKYBLUE;
case @"slateblue": case "slateblue":
return self::SLATEBLUE; return self::SLATEBLUE;
case @"slategray": case "slategray":
case @"slategrey": case "slategrey":
return self::SLATEGREY; return self::SLATEGREY;
case @"snow": case "snow":
return self::SNOW; return self::SNOW;
case @"springgreen": case "springgreen":
return self::SPRINGGREEN; return self::SPRINGGREEN;
case @"steelblue": case "steelblue":
return self::STEELBLUE; return self::STEELBLUE;
case @"tan": case "tan":
return self::TAN; return self::TAN;
case @"thistle": case "thistle":
return self::THISTLE; return self::THISTLE;
case @"tomato": case "tomato":
return self::TOMATO; return self::TOMATO;
case @"turquoise": case "turquoise":
return self::TURQUOISE; return self::TURQUOISE;
case @"violet": case "violet":
return self::VIOLET; return self::VIOLET;
case @"wheat": case "wheat":
return self::WHEAT; return self::WHEAT;
case @"whitesmoke": case "whitesmoke":
return self::WHITESMOKE; return self::WHITESMOKE;
case @"yellowgreen": case "yellowgreen":
return self::YELLOWGREEN; return self::YELLOWGREEN;
// CSS Level 4 // CSS Level 4
case @"rebeccapurple": case "rebeccapurple":
return self::REBECCAPURPLE; return self::REBECCAPURPLE;
} }

View file

@ -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.');
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -32,7 +32,7 @@ final class WebLookup implements \Uiharu\ILookup {
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_TIMEOUT => 5, CURLOPT_TIMEOUT => 5,
CURLOPT_DEFAULT_PROTOCOL => 'https', 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 => [ CURLOPT_HTTPHEADER => [
'Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8', 'Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8',
], ],
@ -200,11 +200,13 @@ final class WebLookup implements \Uiharu\ILookup {
break; break;
case 'theme-color': case 'theme-color':
$siteInfo->colour = $valueAttr; if(empty($siteInfo->colour))
$siteInfo->colour = $valueAttr;
break; break;
case 'og:type': case 'og:type':
$siteInfo->type = 'website:' . $valueAttr; if(empty($siteInfo->type))
$siteInfo->type = 'website:' . $valueAttr;
break; break;
} }
} }