-<!doctype html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>Replicator</title>
- <link rel="stylesheet" href="concise/css/concise.min.css">
- <link href="//fonts.googleapis.com/css?family=Droid+Sans" rel="stylesheet" type="text/css">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <style>
- body {
- padding-bottom: 4em;
- }
- .footer {
- bottom: 0;
- position: fixed;
- width: 100%;
- text-align: center;
- }
- .header, .footer {
- background: #62B3E7;
- padding: 1em 0;
- }
- .header h1 {
- font-weight: bold;
- }
- .header h1 a, .footer a:hover {
- text-decoration: none;
- }
- .header h1 a:hover {
- text-decoration: underline;
- }
- .header h1 big , .footer, .footer a {
- color: #fdfdfd;
- text-shadow: grey 0 0 .1em;
- }
- .header h1 small {
- color: #666;
- text-shadow: white 0 0 .2em;
- }
- li {
- list-style-type: circle;
+<?php
+
+use http\Env\Request;
+use http\Env\Response;
+use http\Header;
+
+const UNITS = ["Bytes", "KB", "MB"];
+const SIGS = ["rsa" => "sig", "gpg" => "asc"];
+
+function human_size($s) {
+ $l = floor(log10($s));
+ return sprintf("%1.1F %s", $s/pow(10,$l-($l%3)), UNITS[$l/3]);
+}
+
+function human_date($t) {
+ $d = date_create("@".$_SERVER["REQUEST_TIME"]);
+ for ($i = 1; $i < 7; ++$i) {
+ if ($t > $d->modify("-$i days")->format("U")) {
+ switch ($i) {
+ case 1:
+ return "today";
+ case 2:
+ return "yesterday";
+ default:
+ return "$i days ago";
}
- </style>
- </head>
- <body>
- <div class="header">
- <header>
- <h1 class="container">
- <a href="?"><big>Replicator</big></a><br>
- <small>Replicating PECL releases as pharext packages since 2015</small>
- </h1>
- <a href="https://github.com/m6w6/replicator"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
- </header>
- </div>
- <div class="container">
- <?php $packages = array_map("basename", glob("phars/*")); ?>
-
- <?php if ($_SERVER["QUERY_STRING"] && in_array($_SERVER["QUERY_STRING"], $packages, true)) : ?>
+ }
+ }
+ return gmdate("Y-m-d", $t);
+}
- <h2><?= $package = $_SERVER["QUERY_STRING"]; ?></h2>
- <table class="table table-full">
- <thead>
- <tr>
- <th class="text-left">Package</th>
- <th class="text-left">Date</th>
- <th class="text-right">Size</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach (array_reverse(glob("phars/$package/*.ext.phar*")) as $phar) : ?>
+function sigof($phar, $typ) {
+ return str_replace("phars/", "sigs/", $phar) . ".$typ";
+}
- <tr>
- <td class="text-left">
- <a href="<?= htmlspecialchars($phar) ?>"
- ><?= htmlspecialchars(basename($phar)) ?></a>
- </td>
- <td class="text-left">
- <?php
+function package_versions($package) {
+ $versions = [];
+ foreach (glob("phars/$package/*.ext.phar") as $phar) {
+ $name = basename($phar, ".ext.phar");
+ $data = new Phar($phar);
+ $meta = $data->getMetadata();
+ unset($data);
- $time = time();
- $dsec = 86400;
- $lmod = filemtime($phar);
- $days = [1 => "today", "yesterday"];
- do {
- for ($i = 1; $i < 7; ++$i) {
- if ($lmod > $time - $dsec * $i) {
- switch ($i) {
- case 1:
- echo "today";
- break 3;
- case 2:
- echo "yesterday";
- break 3;
- default:
- echo "$i days ago";
- break 3;
- }
- }
- }
- echo date("Y-m-d", $lmod);
- } while (false);
-
- ?>
+ if ($meta) {
+ $release = $meta["release"];
+ } else {
+ $release = substr($name, strlen($package)+1);
+ }
- </td>
- <td class="text-right">
- <?php
+ foreach (["", ".gz", ".bz2"] as $enc) {
+ $file = $phar . $enc;
+ if (!is_file($file)) {
+ continue;
+ }
- $u = ["Bytes", "KB", "MB"];
- $s = filesize($phar);
- $l = floor(log10($s));
- printf("%1.1F %s\n", $s/pow(10,$l-($l%3)), $u[$l/3]);
+ foreach (SIGS as $sigtyp => $sigext) {
+ if (file_exists($sigdat = sigof($file, $sigext))) {
+ $sigs[$sigtyp] = $sigdat;
+ }
+ }
+ $size = filesize($file);
+ $date = isset($meta["date"]) ? strtotime($meta["date"]) : filemtime($file);
+ $pharext = isset($meta["version"]) ? $meta["version"] : "2.0.1";
+ $versions[$release][$enc] = ["phar" => $file] + compact("date", "size", "pharext", "sigs");
+ }
+ uksort($versions[$release], function($a, $b) {
+ $al = strlen($a);
+ $bl = strlen($b);
+ if ($al < $bl) return -1;
+ if ($al > $bl) return 1;
+ return 0;
+ });
+ }
+ uksort($versions, "version_compare");
+ return $versions;
+}
- ?>
- </td>
- </tr>
- <?php endforeach; ?>
+function package_info($package) {
+ if (($xml = simplexml_load_file("phars/$package/info.xml"))) {
+ return [
+ "title" => (string) $xml->s,
+ "description" => (string) $xml->d,
+ "license" => (string) $xml->l
+ ];
+ }
+}
- </tbody>
- </table>
- <?php else: ?>
+$packages = array_map("basename", glob("phars/*", GLOB_NOSORT|GLOB_ONLYDIR));
+sort($packages, SORT_NATURAL|SORT_FLAG_CASE);
- <h2>Available Packages</h2>
- <ul class="list-inline">
- <?php foreach (array_map("htmlspecialchars", $packages) as $index => $package) : ?>
- <?php $next = strtolower($package{0}); ?>
- <?php if (isset($prev) && $next != $prev) : ?>
-
- </ul>
- <ul class="list-inline">
- <?php endif; ?>
+if (in_array($_SERVER["QUERY_STRING"], $packages, true)) {
+ $package = $_SERVER["QUERY_STRING"];
+}
- <li><a href="?<?= $package ?>"><?= $package ?></a></li>
- <?php $prev = $next; ?>
- <?php endforeach; ?>
-
- </ul>
- <?php endif; ?>
+$res = new Response;
+$req = new Request;
- </div>
- <div class="footer">
- <footer>
- © 2015 m6w6, Michael Wallner
- </footer>
- </div>
- </body>
-</html>
+if (!defined("INCLUDED")) {
+ if (($acc = $req->getHeader("Accept", Header::class))) {
+ $neg = basename($acc->negotiate(["text/html", "application/json"]));
+ } else {
+ $neg = "html";
+ }
+ include_once "$neg.php";
+}