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)
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
296
src/Colour.php
296
src/Colour.php
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue