1
0
Fork 0
mirror of https://github.com/perlbot/perlbuut-pastebin synced 2025-06-07 14:17:26 -04:00

Fix conflict and bring other stuff

This commit is contained in:
Ryan Voots 2019-09-08 01:56:16 -04:00
commit d82c4b62c3
12 changed files with 529 additions and 24 deletions

View file

@ -30,10 +30,12 @@ sub api_get_paste {
if ($row) { if ($row) {
$c->delay(sub { $c->delay(sub {
my ($delay) = @_; my ($delay) = @_;
$c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], $delay->begin(0, 1)) $c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], 0, $delay->begin(0, 1))
}, },
sub { sub {
my ($delay, $output_hr) = @_; my ($delay, $evalres) = @_;
my ($status, $output_hr) = $evalres->@{qw/status output/};
my ($output_lang) = keys %$output_hr; # grab a random output value, should be the first one since multilang support isn't working yet my ($output_lang) = keys %$output_hr; # grab a random output value, should be the first one since multilang support isn't working yet
my ($output) = $output_hr->{$output_lang}; my ($output) = $output_hr->{$output_lang};
@ -44,6 +46,7 @@ sub api_get_paste {
description => $row->{desc}, description => $row->{desc},
language => $output_lang, language => $output_lang,
output => $output, output => $output,
status => $status,
warning => "If this was multi-language paste, you just got a random language", warning => "If this was multi-language paste, you just got a random language",
}; };

View file

@ -50,21 +50,21 @@ sub api_get_paste {
if ($row) { if ($row) {
$c->delay(sub { $c->delay(sub {
my ($delay) = @_; my ($delay) = @_;
$c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], $delay->begin(0, 1)) $c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], 0, $delay->begin(0, 1))
}, },
sub { sub {
my ($delay, $output_hr) = @_; my ($delay, $evalres) = @_;
my ($status, $output_hr) = $evalres->@{qw/status output/};
my ($output_lang) = keys %$output_hr; # grab a random output value, should be the first one since multilang support isn't working yet my ($output_lang) = keys %$output_hr; # grab a random output value, should be the first one since multilang support isn't working yet
my ($output) = $output_hr->{$output_lang};
my $data = { my $data = {
paste => $row->{paste}, paste => $row->{paste},
when => $row->{when}, when => $row->{when},
username => $row->{who}, username => $row->{who},
description => $row->{desc}, description => $row->{desc},
language => $output_lang, language => $output_lang,
output => $output, output => $output_hr,
warning => "If this was multi-language paste, you just got a random language",
}; };
$c->render(json => $data); $c->render(json => $data);

View file

@ -20,8 +20,6 @@ sub run_eval {
my ($self) = @_; my ($self) = @_;
my $data = $self->req->body_params; my $data = $self->req->body_params;
$self = $self->inactivity_timeout(3600); $self = $self->inactivity_timeout(3600);
my $code = $data->param('code') // ''; my $code = $data->param('code') // '';
@ -29,13 +27,17 @@ sub run_eval {
$self->delay(sub { $self->delay(sub {
my $delay = shift; my $delay = shift;
$self->eval->get_eval(undef, $code, [$language], $delay->begin(0,1)); $self->eval->get_eval(undef, $code, [$language], 1, $delay->begin(0,1));
return 1; return 1;
}, },
sub { sub {
my $delay = shift; my $delay = shift;
my ($output) = @_; my ($evalres) = @_;
use Data::Dumper;
print Dumper("wutwut", $evalres);
my $output = $evalres->{output};
$self->render(json => {evalout => $output}); $self->render(json => {evalout => $output});
}) })

View file

@ -85,15 +85,18 @@ sub get_paste {
$c->delay(sub { $c->delay(sub {
my $delay = shift; my $delay = shift;
$c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], $delay->begin(0,1)); $c->eval->get_eval($pasteid, $row->{paste}, [$row->{language}], 0, $delay->begin(0,1));
}, sub { }, sub {
my ($delay, $evalout) = @_; my ($delay, $evalres) = @_;
my ($status, $evalout) = $evalres->@{qw/status output/};
$c->stash($row); $c->stash($row);
$c->stash({language => $c->languages->get_language_hash->{$row->{language}}}); $c->stash({language => $c->languages->get_language_hash->{$row->{language}}});
$c->stash({all_langs => $c->languages->get_language_hash}); $c->stash({all_langs => $c->languages->get_language_hash});
$c->stash({page_tmpl => 'viewer.html'}); $c->stash({page_tmpl => 'viewer.html'});
$c->stash({paste_id => $pasteid}); $c->stash({paste_id => $pasteid});
$c->stash({eval => $evalout}); $c->stash({eval => $evalout});
$c->stash({eval_status => $status});
$c->stash({perl_sort_versions => \&App::Model::Languages::perl_sort_versions}); $c->stash({perl_sort_versions => \&App::Model::Languages::perl_sort_versions});
$c->render('page'); $c->render('page');

View file

@ -29,23 +29,32 @@ sub _adopt_future {
}) })
} }
my @full_langs = qw/perl perl5.30 perl5.28 perl5.26 perl5.24 perl5.22 perl5.20 perl5.18 perl5.16 perl5.14 perl5.12 perl5.10 perl5.8 perl5.6 perl5.8.8 perl5.8.4 perl5.10.0/; sub _get_cache {
my ($key) = @_;
return unless defined $key;
return $memd->get($key);
}
my @major_langs = qw/perl perl5.30 perl5.28 perl5.26 perl5.24 perl5.22 perl5.20 perl5.18 perl5.16 perl5.14 perl5.12 perl5.10 perl5.8 perl5.6/;
my @full_langs = map {"perl$_"} '', qw/5.30.0 5.28.2 5.28.1 5.28.0 5.26.3 5.26.2 5.26.1 5.26.0 5.24.4 5.24.3 5.24.2 5.24.1 5.24.0 5.22.4 5.22.3 5.22.2 5.22.1 5.22.0 5.20.3 5.20.2 5.20.1 5.20.0 5.18.4 5.18.3 5.18.2 5.18.1 5.18.0 5.16.3 5.16.2 5.16.1 5.16.0 5.14.4 5.14.3 5.14.2 5.14.1 5.14.0 5.12.5 5.12.4 5.12.3 5.12.2 5.12.1 5.12.0 5.10.1 5.10.0 5.8.9 5.8.8 5.8.7 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.6.2 5.6.1 5.6.0/;
sub get_eval { sub get_eval {
my ($self, $paste_id, $code, $langs, $callback) = @_; my ($self, $paste_id, $code, $langs, $wait, $callback) = @_;
print "Entering\n"; print "Entering\n";
if (@$langs == 1 && $langs->[0] eq "evalall") { if (@$langs == 1 && $langs->[0] eq "evalall") {
$langs = [@full_langs]; $langs = [@major_langs];
} elsif (@$langs == 1 && $langs->[0] eq "evaltall") { } elsif (@$langs == 1 && $langs->[0] eq "evaltall") {
$langs = [map {$_."t"} @full_langs]; $langs = [map {$_."t"} @major_langs];
} elsif (@$langs == 1 && $langs->[0] eq "evalrall") { } elsif (@$langs == 1 && $langs->[0] eq "evalrall") {
$langs = [map {$_, $_."t"} @major_langs];
} elsif (@$langs == 1 && $langs->[0] eq 'evalyall') {
$langs = [map {$_, $_."t"} @full_langs]; $langs = [map {$_, $_."t"} @full_langs];
} }
use Data::Dumper; use Data::Dumper;
print "Languages! ", Dumper($langs); print "Languages! ", Dumper($langs);
if ($paste_id && (my $cached = $memd->get($paste_id))) { if ($paste_id && (my $cached = _get_cache($paste_id))) {
$callback->($cached); $callback->($cached);
} else { } else {
# connect to server # connect to server
@ -57,9 +66,16 @@ sub get_eval {
my $reader = $self->get_eval_reader($stream); my $reader = $self->get_eval_reader($stream);
my %output; my %output;
# TODO make running status messages per langs?
$memd->set($paste_id, {status => 'running', output => {}});
if (!$wait && @$langs != 1) {
$callback->({status => 'running', output => {}});
}
for my $lang (@$langs) { for my $lang (@$langs) {
if ($lang eq 'text') { if ($lang eq 'text') {
$callback->(""); $callback->({status => "ready", output => {}});
return; return;
} else { } else {
my $future = $self->async_eval($stream, $reader, $lang, $code); my $future = $self->async_eval($stream, $reader, $lang, $code);
@ -77,11 +93,13 @@ sub get_eval {
if (!keys %futures) { # I'm the last one if (!keys %futures) { # I'm the last one
print "Calling memset\n"; print "Calling memset\n";
$memd->set($paste_id, \%output) if ($paste_id); $memd->set($paste_id, {status => 'ready', output => \%output}) if ($paste_id);
print "Returning output to delay\n"; print "Returning output to delay\n";
use Data::Dumper; use Data::Dumper;
print Dumper(\%output); print Dumper(\%output);
$callback->(\%output); if ($wait || @$langs == 1) {
$callback->({status => "ready", output => \%output});
}
} }
}); });
} }

View file

@ -18,9 +18,10 @@ my @langs = (
{name => "perl", mode => "perl", description => "Perl 5 (blead/git)"}, {name => "perl", mode => "perl", description => "Perl 5 (blead/git)"},
{name => "perlt", mode => "perl", description => "Perl 5 (blead/git threaded)"}, {name => "perlt", mode => "perl", description => "Perl 5 (blead/git threaded)"},
{name => "deparse", mode => "perl", description => "Deparsed Perl"}, {name => "deparse", mode => "perl", description => "Deparsed Perl"},
{name => "evalall", mode => "perl", description => "Perl (EvalAll) (unthreaded)"}, {name => "evalall", mode => "perl", description => "Perl (EvalAll) (major unthreaded)"},
{name => "evaltall", mode => "perl", description => "Perl (EvalAll) (threaded)"}, {name => "evaltall", mode => "perl", description => "Perl (EvalAll) (major threaded)"},
{name => "evalrall", mode => "perl", description => "Perl (EvalAll) (threaded + unthreaded)"}, {name => "evalrall", mode => "perl", description => "Perl (EvalAll) (major un+threaded)"},
{name => "evalrall", mode => "perl", description => "Perl (EvalY'All) (EVERYTHING)"},
{name => "perl5.30.0", mode => "perl", description => "Perl 5.30.0"}, {name => "perl5.30.0", mode => "perl", description => "Perl 5.30.0"},
{name => "perl5.30.0t", mode => "perl", description => "Perl 5.30.0 (threaded)"}, {name => "perl5.30.0t", mode => "perl", description => "Perl 5.30.0 (threaded)"},
{name => "perl5.28.2", mode => "perl", description => "Perl 5.28.2"}, {name => "perl5.28.2", mode => "perl", description => "Perl 5.28.2"},

29
static/editor.css Normal file
View file

@ -0,0 +1,29 @@
#editor {
margin: auto;
position: relative !important;
width: 100%;
height: 500px;
display: none;
font-variant-ligatures: none;
}
#paste {
font-family: 'monospace'
}
html, body, #content {
width: 100%;
}
@font-face {
font-family: "AnonymousPro";
src: url("/static/fonts/AnonymousPro-Regular.woff2") format('woff2');
}
.options label {
padding-right: 0.5em;
}
.options label:not(:first-child) {
padding-left: 2em;
}

174
static/editor.js Normal file
View file

@ -0,0 +1,174 @@
$(function() {
var hostname = $(location).attr('hostname');
var channel = $(location).attr('hash');
// console.log("host: " + hostname + " channel: " + channel);
// fuck parsing the hostname
var servers = {
"f.perlbot.pl": "localhost:perlbot:",
"freenode.perlbot.pl": "localhost:perlbot:",
"m.perlbot.pl": "localhost:perlbot-magnet:",
"magnet.perlbot.pl": "localhost:perlbot-magnet:",
"o.perlbot.pl": "localhost:perlbot-oftc:",
"oftc.perlbot.pl": "localhost:perlbot-oftc:",
"f.perl.bot": "localhost:perlbot:",
"freenode.perl.bot": "localhost:perlbot:",
"m.perl.bot": "localhost:perlbot-magnet:",
"magnet.perl.bot": "localhost:perlbot-magnet:",
"o.perl.bot": "localhost:perlbot-oftc:",
"oftc.perl.bot": "localhost:perlbot-oftc:",
};
if (channel && servers[hostname]) { // only do this if we have a channel and a valid server
// console.log("found default channel to post: "+servers[hostname]+channel);
var option = $("option[value='"+servers[hostname]+channel+"']");
// console.log(option);
option.prop('selected', true);
}
if (servers[hostname]) {
var badoptions = $("select#channel option:not([value^='"+servers[hostname]+"'])");
console.log(badoptions);
badoptions.remove();
}
});
$(function() {
var showingmodules = 0;
var showingeval = 0;
var editor;
var use_editor = function() {
if ($("#raw_editor").is(":checked")) {
if (editor) {
$("#paste").val(editor.getValue());
}
$("#editor").hide();
$("#paste").show();
} else {
$("#paste").hide();
$("#editor").show();
if (!editor) {
$("#editor").text($("#paste").val());
} else {
editor.setValue($("#paste").val(),0);
editor.clearSelection();
}
}
};
use_editor();
$("#raw_editor").on("change", use_editor);
editor = ace.edit("editor");
//editor.setTheme("ace/theme/twilight");
//safely delete all bindings
var save_keys={};
Object.keys(editor.keyBinding.$defaultHandler.commandKeyBinding)
.filter((value) => value.match(/(?:(?:backspac|hom)e|d(?:elete|own)|(?:righ|lef)t|end|up|tab)/))
.forEach((key) => save_keys[key] = editor.keyBinding.$defaultHandler.commandKeyBinding[key]);
editor.keyBinding.$defaultHandler.commandKeyBinding = save_keys;
$("#language").on('change', function () {
var language = $('#language option').filter(':selected').attr('data-lang');
console.log("language: ", language);
editor.session.setMode("ace/mode/" + language);
});
var channel = $(location).attr('hash');
if (channel == "#perl6") {
$("#language").val("perl6").change();
} else if (channel == "#cobol") {
$("#language").val("cobol").change();
}
editor.session.setMode("ace/mode/perl");
// editor.setOptions({fontFamily: ['AnonymousPro', 'monospace', 'mono']});
function setup_columns() {
if (showingeval && showingmodules) {
$("#editors").removeClass().addClass('col-md-6');
$("#evalcol").removeClass().addClass('col-md-4');
$("#modules").removeClass().addClass('col-md-2');
} else if (showingeval) {
$("#editors").removeClass().addClass('col-md-10');
$("#evalcol").removeClass().addClass('col-md-2');
$("#modules").removeClass().addClass('hidden');
} else if (showingmodules) {
$("#editors").removeClass().addClass('col-md-10');
$("#evalcol").removeClass().addClass('hidden');
$("#modules").removeClass().addClass('col-md-2');
} else {
$("#editors").removeClass().addClass('col-md-12');
$("#evalcol").removeClass().addClass('hidden');
$("#modules").removeClass().addClass('hidden');
}
};
function resizeAce() {
var h = window.innerHeight;
if (h > 360) {
$('#editor').css('height', (h - 175).toString() + 'px');
}
};
$(window).on('resize', function () {
resizeAce();
});
resizeAce();
$("#submit").on('click', function () {
var code = $("#raw_editor").is(":checked") ?
$("#paste").val() :
editor.getValue();
$("#paste").text(code); // copy to the textarea
});
$('#evalme').on('click', function () {
showingeval = 1;
$('#eval').text("Evaluating...");
setup_columns();
var code = $("#raw_editor").is(":checked") ?
$("#paste").val() :
editor.getValue();
var language = $('#language option').filter(':selected').val();
$.ajax('/eval', {
method: 'post',
data: {code: code, language: language},
dataType: "json",
success: function(data, status) {
console.log("data out", data);
var keys = Object.keys(data.evalout);
var outputarr = [];
if (keys.length > 1) {
outputarr = $.map(data.evalout, function(output, lang) {
return "[[ "+lang+" ]]\n"+output+"\n\n";
});
} else {
outputarr = [data.evalout[keys[0]]];
}
console.log("outputarr", outputarr);
console.log(outputarr.join("\n"));
$('#eval').text(outputarr.join("\n"));
}
});
});
$("#showmodules").on('click', function() {
showingmodules = 1 - showingmodules;
setup_columns();
});
});

162
static/test.html Normal file
View file

@ -0,0 +1,162 @@
<!DOCTYPE html>
<html>
<head>
<title>Amazon Lex for JavaScript - Sample Application (BookTrip)</title>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.41.0.min.js"></script>
<style language="text/css">
input#wisdom {
padding: 4px;
font-size: 1em;
width: 400px
}
input::placeholder {
color: #ccc;
font-style: italic;
}
p.userRequest {
margin: 4px;
padding: 4px 10px 4px 10px;
border-radius: 4px;
min-width: 50%;
max-width: 85%;
float: left;
background-color: #7d7;
}
p.lexResponse {
margin: 4px;
padding: 4px 10px 4px 10px;
border-radius: 4px;
text-align: right;
min-width: 50%;
max-width: 85%;
float: right;
background-color: #bbf;
font-style: italic;
}
p.lexError {
margin: 4px;
padding: 4px 10px 4px 10px;
border-radius: 4px;
text-align: right;
min-width: 50%;
max-width: 85%;
float: right;
background-color: #f77;
}
</style>
</head>
<body>
<h1 style="text-align: left">Amazon Lex - BookTrip</h1>
<p style="width: 400px">
This little chatbot shows how easy it is to incorporate
<a href="https://aws.amazon.com/lex/" title="Amazon Lex (product)" target="_new">Amazon Lex</a> into your web pages. Try it out.
</p>
<div id="conversation" style="width: 400px; height: 400px; border: 1px solid #ccc; background-color: #eee; padding: 4px; overflow: scroll"></div>
<form id="chatform" style="margin-top: 10px" onsubmit="return pushChat();">
<input type="text" id="wisdom" size="80" value="" placeholder="I need a hotel room">
</form>
<script type="text/javascript">
// set the focus to the input box
document.getElementById("wisdom").focus();
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'us-east-1'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
// Provide your Pool Id here
IdentityPoolId: 'us-east-1:dbe1d89b-d4ed-459d-ba40-ef8f096b5e4b',
});
var lexruntime = new AWS.LexRuntime();
var lexUserId = 'chatbot-demo' + Date.now();
var sessionAttributes = {};
function pushChat() {
// if there is text to be sent...
var wisdomText = document.getElementById('wisdom');
if (wisdomText && wisdomText.value && wisdomText.value.trim().length > 0) {
// disable input to show we're sending it
var wisdom = wisdomText.value.trim();
wisdomText.value = '...';
wisdomText.locked = true;
// send it to the Lex runtime
var params = {
botAlias: '$LATEST',
botName: 'BookTrip',
inputText: wisdom,
userId: lexUserId,
sessionAttributes: sessionAttributes
};
showRequest(wisdom);
lexruntime.postText(params, function(err, data) {
if (err) {
console.log(err, err.stack);
showError('Error: ' + err.message + ' (see console for details)')
}
if (data) {
// capture the sessionAttributes for the next cycle
sessionAttributes = data.sessionAttributes;
// show response and/or error/dialog status
showResponse(data);
}
// re-enable input
wisdomText.value = '';
wisdomText.locked = false;
});
}
// we always cancel form submission
return false;
}
function showRequest(daText) {
var conversationDiv = document.getElementById('conversation');
var requestPara = document.createElement("P");
requestPara.className = 'userRequest';
requestPara.appendChild(document.createTextNode(daText));
conversationDiv.appendChild(requestPara);
conversationDiv.scrollTop = conversationDiv.scrollHeight;
}
function showError(daText) {
var conversationDiv = document.getElementById('conversation');
var errorPara = document.createElement("P");
errorPara.className = 'lexError';
errorPara.appendChild(document.createTextNode(daText));
conversationDiv.appendChild(errorPara);
conversationDiv.scrollTop = conversationDiv.scrollHeight;
}
function showResponse(lexResponse) {
var conversationDiv = document.getElementById('conversation');
var responsePara = document.createElement("P");
responsePara.className = 'lexResponse';
if (lexResponse.message) {
responsePara.appendChild(document.createTextNode(lexResponse.message));
responsePara.appendChild(document.createElement('br'));
}
if (lexResponse.dialogState === 'ReadyForFulfillment') {
responsePara.appendChild(document.createTextNode(
'Ready for fulfillment'));
// TODO: show slot values
} else {
responsePara.appendChild(document.createTextNode(
'(' + lexResponse.dialogState + ')'));
}
conversationDiv.appendChild(responsePara);
conversationDiv.scrollTop = conversationDiv.scrollHeight;
}
</script>
</body>
</html>

9
static/test2.html Normal file
View file

@ -0,0 +1,9 @@
<html>
<title>perlbot v2 api test</title>
<form action="/api/v2/add_file" method="post">
<input name="filename_1" value="foo.txt" />
<textarea name="filecontent_1">hello world</textarea>
<input type="submit"/>
</form>
</html>

101
templates/neweditor.html.tt Normal file
View file

@ -0,0 +1,101 @@
[% BLOCK body_style %]
<link rel="stylesheet" type="text/css" href="/static/editor.css" />
<script src="/static/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="/static/editor.js"></script>
[% END %]
[% BLOCK page_header %]
<div class="row">
<div class="col-md-3">
<label for="username">Who: </label>
<input size="20" name="username" placeholder="Anonymous" />
</div>
<div class="col-md-3">
<label for="channel">Where: </label>
<select name="channel" id="channel">
<option value="">-- IRC Channel --</option>
[% FOREACH channel = channels %]
<option value="[% channel.key %]">[% channel.value %]</option>
[% END %]
</select>
</div>
<div class="col-md-5">
<label for="desc">What: </label>
<input size="40" name="description" placeholder="I broke this" maxlength="40"/>
<input type="button" value="Show supported modules" id="showmodules" style="float:right"/>
</div>
<div class="col-md-1">
<a href="http://www.cafepress.com/perlbot">Perlbot Merch</a>
</div>
</div>
[% END %]
[% BLOCK body %]
<form action="/api/v1/paste" method="POST" id="form">
<input type="hidden" name="redirect" value="1" />
<div id="content" class="container">
<div class="panel">
<div class="panel-heading">
[% PROCESS page_header %]
</div>
</div>
<div class="panel-body">
<div class="row">
<div id="editors" class="col-md-12">
<div class="options">
<!-- TODO this should come from the eval server somehow -->
<label>Expire in</label>
<select name="expire">
<option value="1">1 hour</option>
<option value="8">8 hours</option>
<option value="24">24 hours</option>
<option value="48">2 days</option>
<option value="168" selected>1 week</option>
<option value="720">1 month</option>
<option value="8760">1 year</option>
<option value="">Never</option>
</select>
</div>
<!-- BEGIN LOOP -->
<div id="file_1" class="file">
<div class="fileheader col-md-12">
<label>Filename</label>
<input type="text" name="filename_1" placeholder=""/>
<label>Language</label>
<select name="filelang_1" id="filelang_1">
[% FOREACH lang IN languages %]
<option value="[% lang.name %]" data-lang="[% lang.mode %]">[% lang.description %]</option>
[% END %]
</select>
<input type="file" name="fileupload_1" />
<!-- use a hidden field when we've been rebuilt <input type="hidden" name="fileupload_1" /> -->
<input type="submit" name="filedelete_1" value="Delete File"/>
<label>Raw Editor</label>
<input type="checkbox" id="raw_editor_1"/>
</div>
<div class="filecontents col-md-12">
<textarea name="filecontents_1" id="filecontents_1" cols="80" rows="25">[% pastedata | html %]</textarea>
<pre id="editor"></pre>
</div>
</div>
<!-- END LOOP -->
</div>
<div id="evalcol" class="hidden">
<h3>Program Output:</h3>
<pre id="eval">[% eval | html %]</pre>
</div>
<div id="modules" class="hidden">
<h3>Supported modules</h3>
Under construction
</div>
</div>
<div class="panel-footer">
<input value="Submit" type="submit" id="submit" />
<input value="Check Eval" type="button" id="evalme" />
</div>
</div>
</form>
[% END %]

View file

@ -74,6 +74,9 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
[% IF eval_status == "running" %]
<div id="evalstatus">Eval still running, please refresh page after waiting</div>
[% END %]
[% IF eval.keys.size == 0 || !eval.keys.size.defined %] [% IF eval.keys.size == 0 || !eval.keys.size.defined %]
[% ELSIF eval.keys.size == 1 %] [% ELSIF eval.keys.size == 1 %]
<div id="eval" class="col-md-12"> <div id="eval" class="col-md-12">