I would like to build a small pipeline that allows the user to choose a file and then runs several scripts using this file as an input. As some of these scripts run for several minutes (exact time depends on the input file's size) I would like to show a progress bar that is based on how many scripts of this pipeline have been finished.
The problem is that I don't know how to update this progress bar based on the status of the pipeline and would appreciate some help with that. I show the files I use first and then explain the problem in more detail.
My html form:
<form action="main.pl" method="post" enctype="multipart/form-data">
<input type="file" name="fileName" />
<input type="submit" value="Analyze" />
</form>
The pipeline script main.pl:
#!/usr/bin/perl
use CGI;
use strict;
#use warnings;
my $q = CGI->new;
my $fileName = $q->param('fileName');
my $progressPerc = 0;
my $numJobs = 3; #in actual script much more
my $count = 1;
system('perl', './file1.pl', $fileName);
$progressPerc = $count/$numJobs*100;
#here I want to pass $progressPerc to the progress bar
$count += 1;
system('perl', './file2.pl', $fileName);
$progressPerc = $count/$numJobs*100;
#here I want to pass $progressPerc to the progress bar
$count += 1;
system('perl', './file3.pl', $fileName);
$progressPerc = $count/$numJobs*100;
#here I want to pass $progressPerc to the progress bar
I found a good working progress bar on http://jqueryui.com/progressbar/#label which looks as follows (I post the entire file although I would only need the .js-part):
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>http://jqueryui.com/progressbar/#label</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<style>
.ui-progressbar {
position: relative;
}
.progress-label {
position: absolute;
left: 50%;
top: 4px;
font-weight: bold;
text-shadow: 1px 1px 0 #fff;
}
</style>
<script>
$(function() {
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
progressbar.progressbar({
value: false,
change: function() {
progressLabel.text( progressbar.progressbar( "value" ) + "%" );
},
complete: function() {
progressLabel.text( "Complete!" );
}
});
function progress() {
var val = progressbar.progressbar( "value" ) || 0;
progressbar.progressbar( "value", val + 10 );
if ( val < 99 ) {
setTimeout( progress, 800 );
}
}
setTimeout( progress, 2000 );
});
</script>
</head>
<body>
<div id="progressbar"><div class="progress-label">Loading...</div></div>
</body>
</html>
Is there any easy way to pass $progressPerc from main.pl to the function progress() every time it changes its value? If there was only one call, this could be done using ajax, however, I don't know how to use ajax for several calls i.e. dynamically; by 'dynamic' I mean that once a perl script in main.pl is finished, this should be reported to the progress bar which is then updated.
If there is no easy way to do this: Can one somehow introduce an if clause that checks every x minutes (using setTimeout) whether the output files produced by these perl scripts in main.pl exist and if so, the progress bar is updated and if not one waits for longer? And if so, how would it be implemented?
Almost a month has passed since I asked this question but an answer did not appear. Therefore, I now post my one which is based on ThisSuitIsBlackNot's comment.
Although not that elaborated, it might serve as a minimal example on how one can connect Perl, HTML, Javascript/Ajax and JSON. Maybe it helps someone to get started with that topic.
If you want to run this code, just copy index.html file to your html directory (e.g. /var/www/html) and the perl scripts to your cgi-bin directory (e.g. /var/www/cgi-bin). Make sure to make these perl scripts executable! In my code below, the cgi directory is in /var/www/cgi-bin/ajax/stackCGI - please change that accordingly.
The status of the pipeline is written to a file which is then read in in 1 second intervals, the progress bar is updated and a message about the current status is displayed. The duration that the single steps in the pipeline take, is represented by the Perl's sleep function.
The files are given below.
Any comments and improvements are welcome!
index.html:
pipeline.pl:
readFromFileJson.pl: