summaryrefslogblamecommitdiff
path: root/index.php
blob: 7ef5fb650ec65aaf1ae18ecaa54036b0516954db (plain) (tree)











































































































































                                                                                                                                       
                                                                     




                     
<?php

// find_expr runs nutrimatic's find-expr, calling $match_fn for each match.
// if $match_fn returns a non-false value, the search will stop
function find_expr($index, $expr, $match_fn, $error_fn) {
	$cmd = implode(' ', array_map('escapeshellarg', [
		"./nutrimatic/bin/find-expr",
		$index,
		$expr,
	]));
	$cmd = "ulimit -t 30; exec $cmd";
	$descriptorspec = [
		0 => ['pipe', 'r'],
		1 => ['pipe', 'w'],
		2 => ['pipe', 'w'],
	];
	$proc = proc_open($cmd, $descriptorspec, $pipes);
	list($stdin, $stdout, $stderr) = $pipes;
	fclose($stdin);
	// assumption: anything written to stderr will fit in the pipe buffer
	// nutrimatic only appears to write-then-exit, so It's Probably Fine
	while ($line = fscanf($stdout, "%s %[^\n]s\n")) {
		list($score, $text) = $line;
		if ($match_fn($score, $text)) {
			break;
		}
	}
	fclose($stdout);
	proc_terminate($proc);
	while ($err = fgets($stderr)) {
		$error_fn($err);
	}
	fclose($stderr);
	$retval = proc_close($proc);
	return $retval;
}

function index_name($file) {
	return preg_replace('/\.index$/', '', $file);
}

$index_files = glob("*.index");
$default_index = "enwiki-latest.index";
$selected_index = $default_index;
foreach ($index_files as $file) {
	if (index_name($file) == $_GET['idx']) {
		$selected_index = $file;
	}
}
$q = $_GET['q'] ?: "";
$more = 1;
$autofocus = ' autofocus';
if ($_GET['more']) {
	$more = (int)($_GET['more']);
	$autofocus = '';
}
$max_more = 10;

?>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0">
	<title><?php
	if ($q) {
		echo htmlspecialchars($q);
		echo ' &raquo; ';
	}
	if ($selected_index != $default_index) {
		echo htmlspecialchars(index_name($selected_index));
		echo ' ';
	}
	echo "nut";
	?></title>
<style>

</style>
</head>
<body>
	<form>
		<fieldset>
			<legend><a href=".">nut</a></legend>
			<select name="idx">
				<?php
				foreach ($index_files as $file) {
					$name = index_name($file);
					$attrs = '';
					if ($file == $selected_index) {
						$attrs .= ' selected';
					}
					?>
					<option<?= $attrs ?> value="<?=htmlspecialchars($name)?>"><?=htmlspecialchars($name)?></option>
					<?php
				}
				?>
			</select>
			<input type="text" name="q" value="<?=htmlspecialchars($q)?>" <?=$autofocus?>/>
			<input type="submit" />
		</fieldset>
	</form>
	<?php
	if ($more > $max_more) {
		echo "no";
	} else if ($q) {
		?>
		<ol>
			<?php
			$depth = 0;
			$anchor = '';
			find_expr($selected_index, $q, function($score, $text) use (&$depth, &$anchor, $more) {
				if ($score == '#') {
					$depth++;
					if ($depth == $more) {
						$anchor .= ' id="more"';
					}
					return $depth > $more;
				}
				?>
				<li class="match" value="<?=(int)(float)($score)?>"<?=$anchor?>><?=htmlspecialchars($text)?></li>
				<?php
				$anchor = '';
			}, function($err) {
				?>
				<li class="error" value="0"><?=htmlspecialchars($err)?></li>
				<?php
			});
			?>
		</ol>
		<?php
		if ($depth > $more && $more != $max_more) {
			?>
			<a<?=$anchor?> class="more" href="?<?=http_build_query([
				'idx' => index_name($selected_index),
				'q' => $q,
				'more' => $depth,
			])?>#more">MORE</a>
			<?php
		}
	} else {
		?>
		<p>Hi I'm a <a href="//nutrimatic.org/">Nutrimatic</a></p>
		<p><a href="https://git.doof.net/nut/">Source</a></p>
		<?php
	}
	?>
</body>
</html>