initial import

This commit is contained in:
www-data
2026-05-25 13:47:46 +02:00
parent 3e7f238cf4
commit 97f23260ed
32 changed files with 8898 additions and 0 deletions
+187
View File
@@ -0,0 +1,187 @@
<?php
/*
* rktpkgs.php
*
* Maakt een volledige HTML-index van de Racket package catalogus.
*
* Bron:
* https://pkgs.racket-lang.org/pkgs-all
*
* Output:
* Alleen HTML.
*
* Package-links:
* /package?name=<pkg-name>&next=<id>
*
* Regels:
* - Geen filterveld.
* - Geen git-adressen tonen.
* - Geen package-details tonen.
* - Geen package-downloads implementeren in dit script.
* - De package-naam zelf is de link.
* - Eén next-id per gegenereerde HTML-pagina.
*
* .htaccess:
*
* Options -MultiViews
* RewriteEngine On
* RewriteRule ^racket-pkg-index$ rktpkgs.php [L,QSA]
*/
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
ini_set('log_errors', '1');
error_reporting(E_ALL);
require_once __DIR__ . '/nexttoken.php';
require_once __DIR__ . '/lib/catalog-http.php';
require_once __DIR__ . '/lib/racket-data.php';
$TOKENS = new NextTokenStore(__DIR__ . '/data/racket-sandbox.sqlite');
@set_time_limit(180);
ignore_user_abort(false);
define('CATALOG_PKGS_ALL', 'https://pkgs.racket-lang.org/pkgs-all');
define('CACHE_DIR', __DIR__ . '/data');
define('CACHE_FILE', CACHE_DIR . '/pkgs-all.rktd');
define('CACHE_META_FILE', CACHE_DIR . '/pkgs-all.meta.json');
define('CACHE_TTL', 3600);
/*
* Eén next-id voor alle package-links op deze pagina.
*/
$NEXT_ID = $TOKENS->create();
function h($s)
{
return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
function current_scheme()
{
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
return strtolower(trim(explode(',', $_SERVER['HTTP_X_FORWARDED_PROTO'])[0]));
}
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
function current_host()
{
return $_SERVER['HTTP_HOST'] ?? 'localhost';
}
function make_url($path, $query = array())
{
global $NEXT_ID;
$query['next'] = $NEXT_ID;
return current_scheme() . '://' . current_host() . $path . '?' . http_build_query($query);
}
function html_response($html, $status = 200)
{
http_response_code($status);
header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
echo $html;
exit;
}
function fail_html($message, $status = 500)
{
html_response(
'<!doctype html>' .
'<html><head><meta charset="utf-8"><title>Error</title></head>' .
'<body><h1>Error</h1><pre>' . h($message) . '</pre></body></html>',
$status
);
}
function get_pkgs_all_text()
{
try {
return catalog_http_fetch_cached(
CATALOG_PKGS_ALL,
CACHE_FILE,
CACHE_META_FILE,
CACHE_TTL,
'rktsndbx-rktpkgs/1.0',
180
);
} catch (Throwable $e) {
fail_html($e->getMessage());
}
}
function serve_index()
{
global $NEXT_ID;
$text = get_pkgs_all_text();
$names = rktd_extract_top_level_package_names($text);
if (count($names) === 0) {
fail_html('Geen package-namen gevonden in pkgs-all.');
}
$rows = '';
foreach ($names as $i => $name) {
$url = make_url('/package', array('name' => $name));
$rows .=
'<tr id="pkg-' . h($name) . '">' .
'<td>' . h((string)($i + 1)) . '</td>' .
'<td class="pkg-name">' .
'<a class="pkg-link" href="' . h($url) . '">' . h($name) . '</a>' .
'</td>' .
'</tr>' . "\n";
}
html_response('<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8">
<title>Racket package index</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body class="simple-doc package-index-page">
<h1>Racket package index</h1>
<p>
Volledige HTML-index van de Racket package catalogus op basis van
<code>pkgs-all</code>. De package-naam is de ophaallink via
<code>rktsndbx.dijkewijk.nl</code>.
</p>
<p>
Aantal packages: <code>' . h((string)count($names)) . '</code><br>
next-id voor alle package-links op deze pagina:
<code>' . h($NEXT_ID) . '</code>
</p>
<table>
<thead>
<tr>
<th>#</th>
<th>package</th>
</tr>
</thead>
<tbody>
' . $rows . '
</tbody>
</table>
</body>
</html>');
}
$TOKENS->check_valid_next('html');
serve_index();