diff options
Diffstat (limited to 'index.php')
-rw-r--r-- | index.php | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/index.php b/index.php new file mode 100644 index 0000000..5ac793f --- /dev/null +++ b/index.php @@ -0,0 +1,145 @@ +<?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 ' » '; + } + 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> + <?php + } + ?> +</body> +</html> |