From 9447e65acde93fdfef315efbe0d52cf80cccb5e5 Mon Sep 17 00:00:00 2001 From: flashwave Date: Tue, 29 Dec 2020 02:40:16 +0000 Subject: [PATCH] let the patching commence --- public/index.php | 23 ++++- src/Dummy/DummyPackage.php | 64 +++----------- src/Dummy/DummyPackageFile.php | 40 +++++++++ src/Dummy/DummyPackageTarget.php | 32 +++++++ src/ErrorResponse.php | 21 +++++ src/IPackage.php | 2 + src/IPackageFile.php | 12 +++ src/IPackageTarget.php | 10 +++ src/PackageNotFoundException.php | 4 + src/Patchouli.php | 1 + src/PatchouliException.php | 4 + src/Platform.php | 144 +++++++++++++++++++++++++++++++ src/Version.php | 8 +- 13 files changed, 309 insertions(+), 56 deletions(-) create mode 100644 src/Dummy/DummyPackageFile.php create mode 100644 src/Dummy/DummyPackageTarget.php create mode 100644 src/ErrorResponse.php create mode 100644 src/IPackageFile.php create mode 100644 src/IPackageTarget.php create mode 100644 src/PackageNotFoundException.php create mode 100644 src/PatchouliException.php create mode 100644 src/Platform.php diff --git a/public/index.php b/public/index.php index b264e42..834c319 100644 --- a/public/index.php +++ b/public/index.php @@ -7,12 +7,15 @@ require_once __DIR__ . '/../startup.php'; $request = Http\HttpRequest::create(); -header('Content-Type: ' . FWIF::CONTENT_TYPE); +header('Content-Type: ' . (PAT_DEBUG ? 'text/plain; charset=us-ascii' : FWIF::CONTENT_TYPE)); + +$tPlat = Platform::getUser(); + +// ONLY EXACT MATCHES ↓ if($request->match('GET', '/packages')) { $tags = explode(';', (string)$request->getQueryParam('tags', FILTER_SANITIZE_STRING)); $packages = empty($tags) ? Patchouli::getPackages() : Patchouli::getPackagesWithTags($tags); - header('Content-Type: text/plain; charset=us-ascii'); echo FWIF::encode($packages); return; } @@ -25,5 +28,17 @@ if($request->match('GET', '/')) { return; } -http_response_code(404); -echo '{"code":404,"message":"Path not found."}'; +// REGEX MATCHES ↓ + +if($request->match('GET', '#^/packages/([a-z0-9-]+)/?$#', $args)) { + try { + $packageInfo = Patchouli::getPackage($args[0]); + } catch(PackageNotFoundException $ex) { + http_response_code(404); + $packageInfo = new ErrorResponse(404, 'Package not found.'); + } + echo FWIF::encode($packageInfo); + return; +} + +echo FWIF::encode(new ErrorResponse(404, 'Path not found.')); diff --git a/src/Dummy/DummyPackage.php b/src/Dummy/DummyPackage.php index 051322a..35451ca 100644 --- a/src/Dummy/DummyPackage.php +++ b/src/Dummy/DummyPackage.php @@ -17,6 +17,17 @@ class DummyPackage implements IPackage { return new Version; } + public function getFiles(): array { + return [ + new DummyPackageFile('filename.bin'), + new DummyPackageFile('boobs.png'), + ]; + } + + public function getTargets(): array { + return [new DummyPackageTarget]; + } + public function getDependencies(): array { return []; } @@ -25,57 +36,10 @@ class DummyPackage implements IPackage { $data = [ 'id' => $this->getId(), 'name' => $this->getName(), - 'version' => $this->getVersion(), + 'ver' => $this->getVersion(), + 'files' => $this->getFiles(), + 'targ' => $this->getTargets(), 'deps' => [], - /*'null' => null, - 'true' => true, - 'false' => false, - 'zero' => 0, - 'u8' => 0x42, - 'u16' => 0x4344, - 'u24' => 0x454647, - 'u32' => 0x58596061, - 'u40' => 0x6263646566, - 'u48' => 0x676869707172, - 'u56' => 0x73747576777879, - 'u64' => 0x7481828384858687, - 'neg32' => -12345678, - 'neg64' => -1234567890987654, - 'float' => 12345.6789, - 'float2' => 8.0, - 'floatNeg' => -12345.6789, - 'floatPi' => M_PI, - 'floatE' => M_E, - 'floatLog2E' => M_LOG2E, - 'floatLog10E' => M_LOG10E, - 'floatLn2' => M_LN2, - 'floatLn10' => M_LN10, - 'floatPi2' => M_PI_2, - 'floatPi4' => M_PI_4, - 'floatM1Pi' => M_1_PI, - 'floatM2Pi' => M_2_PI, - 'floatSqrtPi' => M_SQRTPI, - 'float2SqrtPi' => M_2_SQRTPI, - 'floatSqrt2' => M_SQRT2, - 'floatSqrt3' => M_SQRT3, - 'floatSqrt12' => M_SQRT1_2, - 'floatLnPi' => M_LNPI, - 'floatEuler' => M_EULER, - 'floatNaN' => NAN, - 'floatInf' => INF, - 'floatNegInf' => -INF, - 'floatZero' => 0.0, - 'floatNegZero' => -0.0, - 'invalid' => "\xFF\x25\x25\x02\xFF蠕。蝮F鄒守清\xFF\xFF\xFF", - 'datetime' => new \DateTime('2013-01-27 23:14:44 CET'), - 'datetimeNegative' => new \DateTime('-2013-01-27 23:14:44 CET'), - 'datetimeNow' => new \DateTime(), - 'period' => (new \DateTime())->diff(new \DateTime('2013-01-27 23:14:44 CET')), - 'periodNegative' => (new \DateTime('2013-01-27 23:14:44 CET'))->diff(new \DateTime()), - 'periodZero' => (new \DateTime())->diff(new \DateTime()), - 'array' => ['e', 'a', 0x55], - 'object' => new \stdClass, - 'misaka' => '御坂 美琴',*/ ]; foreach($this->getDependencies() as $dependency) $data['deps'][] = $dependency->getName(); diff --git a/src/Dummy/DummyPackageFile.php b/src/Dummy/DummyPackageFile.php new file mode 100644 index 0000000..55a4d13 --- /dev/null +++ b/src/Dummy/DummyPackageFile.php @@ -0,0 +1,40 @@ +filename = $filename; + } + + public function getFileName(): string { + return $this->filename;; + } + + public function getFileType(): string { + return 'application/octet-stream'; + } + + public function isRemote(): bool { + return true; + } + + public function getRemoteUrl(): string { + return 'http://flash.moe/assets/errors/404.jpg'; + } + + public function getLocalStream() { + throw new UnexpectedValueException; + } + + public function fwifSerialize(): array { + return [ + 'name' => $this->getFileName(), + 'type' => $this->getFileType(), + ]; + } +} diff --git a/src/Dummy/DummyPackageTarget.php b/src/Dummy/DummyPackageTarget.php new file mode 100644 index 0000000..2a4f0a5 --- /dev/null +++ b/src/Dummy/DummyPackageTarget.php @@ -0,0 +1,32 @@ + $this->getPlatform(), + 'files' => $this->getFiles(), + 'deps' => [], + ]; + foreach($this->getDependencies() as $pack) + $data['deps'][] = $pack->getName(); + return $data; + } +} diff --git a/src/ErrorResponse.php b/src/ErrorResponse.php new file mode 100644 index 0000000..34dd8e6 --- /dev/null +++ b/src/ErrorResponse.php @@ -0,0 +1,21 @@ +code = $code; + $this->message = $message; + } + + public function fwifSerialize() { + return [ + 'c' => $this->code, + 'm' => $this->message, + ]; + } +} diff --git a/src/IPackage.php b/src/IPackage.php index 340966d..0168b30 100644 --- a/src/IPackage.php +++ b/src/IPackage.php @@ -6,5 +6,7 @@ use FWIF\FWIFSerializable; interface IPackage extends FWIFSerializable { function getName(): string; function getVersion(): Version; + function getFiles(): array; + function getTargets(): array; function getDependencies(): array; } diff --git a/src/IPackageFile.php b/src/IPackageFile.php new file mode 100644 index 0000000..1e57c5c --- /dev/null +++ b/src/IPackageFile.php @@ -0,0 +1,12 @@ +match($other); + } + + public static function isWindows(Platform $other): bool { return self::isMatch(self::WIN_ANY, $other); } + public static function isMacOS(Platform $other) : bool { return self::isMatch(self::OSX_ANY, $other); } + public static function isLinux(Platform $other) : bool { return self::isMatch(self::LIN_ANY, $other); } + + private string $os; + private string $arch; + private ?Version $version; + + public function __construct(string $os, ?string $arch = null, ?Version $version = null) { + if($arch == null) { + if(strpos($os, '/') === true) + throw new InvalidArgumentException('$arch cannot be null if $os doesn\'t contain a slash.'); + $parts = explode('/', $os, 2); + $os = $parts[0]; + $arch = $parts[1]; + } + + $this->os = $os; + $this->arch = $arch; + $this->version = $version; + } + + public function getOperatingSystem(): string { + return $this->os; + } + + public function getArchitecture(): string { + return $this->arch; + } + + public function hasVersion(): bool { + return $this->version !== null; + } + public function getVersion(): Version { + return $this->version; + } + + public function withVersion(Version $version): self { + return new static($this->getOperatingSystem(), $this->getArchitecture(), $version); + } + + public function matchOperatingSystem(Platform $other): bool { + if($this->getOperatingSystem() === '*' + || $other->getOperatingSystem() === '*') + return true; + return $this->getOperatingSystem() === $other->getOperatingSystem(); + } + + public function matchArchitecture(Platform $other): bool { + if($this->getArchitecture() === '*' + || $other->getArchitecture() === '*') + return true; + return $this->getArchitecture() === $other->getArchitecture(); + } + + public function matchVersion(Platform $other): bool { + if(!$this->hasVersion()) + return !$other->hasVersion(); + if(!$other->hasVersion()) + return false; + return $this->getVersion()->match($other->getVersion()); + } + + public function match(Platform $other, bool $matchVersion = false): bool { + if(!$this->matchOperatingSystem($other) || !$this->matchArchitecture($other)) + return false; + if($matchVersion && !$this->matchVersion($other)) + return false; + return true; + } + + public function __toString(): string { + return sprintf('%s/%s', $this->getOperatingSystem(), $this->getArchitecture()); + } + + public function fwifSerialize() { + return (string)$this; + } +} \ No newline at end of file diff --git a/src/Version.php b/src/Version.php index 7f7436b..c8030ec 100644 --- a/src/Version.php +++ b/src/Version.php @@ -4,11 +4,15 @@ namespace Patchouli; use FWIF\FWIFSerializable; class Version implements FWIFSerializable { - public function fwifSerialize(): string { - return (string)$this; + public function match(Version $other): bool { + return true; } public function __toString(): string { return '1.0.0'; } + + public function fwifSerialize(): string { + return (string)$this; + } }