jQuery 和 Perl:基于“管道文件”状态的进度条,动态 ajax

2024-03-05

我想构建一个小型管道,允许用户选择一个文件,然后使用该文件作为输入运行多个脚本。由于其中一些脚本运行了几分钟(确切的时间取决于输入文件的大小),我想显示一个基于该管道已完成的脚本数量的进度条。

问题是我不知道如何根据管道的状态更新此进度条,并且希望获得一些帮助。我首先展示我使用的文件,然后更详细地解释问题。

我的 HTML 表单:

<form action="main.pl" method="post" enctype="multipart/form-data">
        <input type="file" name="fileName" />
        <input type="submit" value="Analyze" />
</form>

管道脚本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

我发现了一个很好的工作进度条http://jqueryui.com/progressbar/#label http://jqueryui.com/progressbar/#label如下所示(我发布了整个文件,尽管我只需要 .js 部分):

<!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>

每次更改其值时,是否有任何简单的方法可以将 $progressPerc 从 main.pl 传递到函数 Progress() ?如果只有一个调用,可以使用 ajax 来完成,但是,我不知道如何使用 ajax 进行多个调用,即动态调用;我所说的“动态”是指一旦 main.pl 中的 perl 脚本完成,就应该将其报告给进度条,然后进度条会更新。

如果没有简单的方法来做到这一点:可以以某种方式引入一个 if 子句,每隔 x 分钟(使用 setTimeout)检查 main.pl 中这些 perl 脚本生成的输出文件是否存在,如果存在,则更新进度条并如果没有人等待更长的时间?如果是的话,将如何实施?


自从我问这个问题以来已经过去了快一个月了,但没有出现答案。因此,我现在发布我的基于 ThisSuitIsBlackNot 评论的文章。

虽然没有那么详细,但它可以作为一个关于如何连接 Perl、HTML、Javascript/Ajax 和 JSON 的最小示例。也许它可以帮助某人开始该主题。

如果您想运行此代码,只需将index.html 文件复制到您的html 目录(例如/var/www/html)并将perl 脚本复制到您的cgi-bin 目录(例如/var/www/cgi-bin)。确保使这些 perl 脚本可执行!在我下面的代码中,cgi 目录位于 /var/www/cgi-bin/ajax/stackCGI - 请相应地更改它。

管道的状态被写入一个文件,然后以 1 秒的间隔读取该文件,更新进度条并显示有关当前状态的消息。管道中单个步骤所花费的持续时间由 Perl 的 sleep 函数表示。

这些文件如下。

欢迎任何意见和改进!

索引.html:

<!DOCTYPE html>
 <html>
    <head>
        <title>Test</title> 
        <meta charset='utf-8' />
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
        <style>
           .ui-progressbar {
               position: relative;
           }
           .progress-label {
              position: absolute;
              left: 50%;

              font-weight: bold;
              text-shadow: 1px 1px 0 #fff;
           }
        </style>
<script>
        var progressVal = 0;

        function get_progress() //get_progress();
        {   

            $.ajax({
                    type: 'POST',
                    url: '/cgi-bin/ajax/stackCGI/readFromFileJson.pl',

                    success: function( res ) {

                                                $('#progressPerc').append(' ' + res.progressSummary.progress);
                                                $('#progressMessage').html('status of pipeline: ' + res.progressSummary.progressMessage);
                                                $('.progress-label').html(res.progressSummary.progress + '%');
                                                progressVal = parseFloat(res.progressSummary.progress);
                                                $( "#progressbar" ).progressbar({
                                                    value: progressVal

                                                });

                                            }
            }); 
            if (progressVal < 100){ //pipeline has not finished yet
                setTimeout(get_progress, 1000); //call the function each second every second to get a status update
            }
            else { //pipeline has finished
                $('.progress-label').html('100%');
                alert("pipeline has finished! your results can be found in path/to/files. an e-mail has been sent to [email protected] /cdn-cgi/l/email-protection");
            }

        }
        function start_pipeline()
        {
            $.ajax({
                    type: 'POST',
                    url: '/cgi-bin/ajax/stackCGI/pipeline.pl',
                    data: { 'fileAnalysis': $('#myFile').val() },
                    success: function(res) {
                                                //add your success function here

                                            },
                    error: function() {alert("pipeline has not started!");}
            });


        }

    </script>
</head>
<body>

    file name: <input type='text' id='myFile'/>
    <button onclick='start_pipeline();get_progress();' >Analyze now</button>
    <div id="progressbar"><div class="progress-label"></div></div>
    <div id="progressMessage"></div>
    <div id="progressPerc">status of pipeline in percent (in this example the function get_progress is called every second): </div>

</body>

管道.pl:

#!/usr/bin/perl

use strict;
use warnings;

use CGI;
my $q = new CGI;

print $q->header('text/plain'); #needed! otherwise the ajax call in start_pipeline returns the error message

my $fileForAnalysis = $q -> param('fileAnalysis'); 

#create a file where the progress is reported to
#make sure you have the appropriate permissions to do this
my $filename = '/var/www/cgi-bin/ajax/stackCGI/progressReport.txt'; #change the directory!
my $fh; #file handler
my $number; #progress of pipeline in percent
my $message; #progress of pipeline

$number = 0;
$message = 'pipeline has startet successfully! Your file '.$fileForAnalysis.' is now processed.';
open($fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $number."\t".$message;
close $fh;

sleep(3); #first program is running
$number = 10; #progress of pipeline in percent. as we have 4 programs in this pipeline it could also be 25 or whatever
$message = 'first program has finished';
open($fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $number."\t".$message;
close $fh;

sleep(5); #second program is running
$number = 20;
$message = 'second program has finished';
open($fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $number."\t".$message;
close $fh;

sleep(5); #third program is running
$number = 42;
$message = 'third program has finished';
open($fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $number."\t".$message;
close $fh;

sleep(5); #fourth program is running
$number = 100;
$message = 'pipeline has finished';
open($fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh $number."\t".$message;
close $fh;

readFromFileJson.pl:

#!/usr/bin/perl

use strict;
use warnings;

use JSON;
use CGI;
my $q = new CGI;

#create a file where the progress is reported to
#make sure you have the appropriate permissions to do this 
my $filename = '/var/www/cgi-bin/ajax/stackCGI/progressReport.txt'; #change the directory!
open(my $fh, '<:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!";

print $q->header('application/json;charset=UTF-8'); #output will be returned in JSON format

my @progressReport = split(/\t/,<$fh>); #file is tab separated
my %progressHash;
$progressHash{"progress"} = $progressReport[0]; 
$progressHash{"progressMessage"} = $progressReport[1];

#convert hash to JSON format
my $op = JSON -> new -> utf8 -> pretty(1);
my $output = $op -> encode({
    progressSummary => \%progressHash
});
print $output;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jQuery 和 Perl:基于“管道文件”状态的进度条,动态 ajax 的相关文章

随机推荐

  • 使用 Q Promise 进行串行执行

    我想我误解了如何Q https github com kriskowal q承诺工作 我希望我的第一个承诺在下一个承诺开始之前得到解决 但这并没有发生 这是我的代码 var Q require q function doWork taskN
  • Apache Common CLI:如何添加参数?

    我正在将 Common CLI 用于个人项目 我从文档中没有找到的一件事是如何强制呈现某个参数 为了澄清我的问题 我可以定义参数和选项之间的区别 命令 mycommand file txt b 2 mycommand is the comm
  • Windows Phone 7 图像按钮

    我需要为我的应用程序创建一个图像按钮 例如面向网络的风格 我有一个 20x20 像素的图像 并且想要一个与图像尺寸相同的图像按钮 我尝试在我的 xaml 中设置它 但它不起作用
  • 使用 LLVM 将 x86 代码重新编译为更快的 x86

    是否可以输入 x86 32 位代码来运行 LLVM 编译器 有一个巨大的算法 我没有源代码 我想让它在相同的硬件上运行得更快 我可以通过优化将其从 x86 转换回 x86 吗 这段代码运行时间很长 所以我想对其进行静态重新编译 另外 我可以
  • Android——如何允许水平和垂直滚动

    ScrollView 只允许垂直滚动 Horizo ntalScrollView 只允许水平滚动 但两者都没有类 这似乎是 Android 用户界面中一个相当大的缺陷 有什么技巧可以实现这一点吗 Try this
  • 当我们有阻塞调用时,我们应该使用像 spring webflux 这样的反应式堆栈 Web 框架吗?

    我试图了解什么时候我们会使用像 webflux 这样的反应式堆栈框架 我读过的文章似乎表明 当我们有许多阻塞调用时 我们将从反应式方法中受益 例如 如果我们有一个 Webhook 服务 需要调用客户端服务器来更新信息 但我也在这里读过htt
  • 如何使用 jQuery 的锚点设置文本框的值?

    我有一个文本框 我想根据锚标记的内部文本设置其值 换句话说 当有人点击这个锚点时 a href class clickable Blah a 我希望我的文本框填充文本 Blah 这是我当前使用的代码 在我的 html 中 有一个带有 cli
  • Mac (UNIX) 系统上的 PATH 是什么?

    我正在尝试从 git 设置一个项目 Storm https github com nathanmarz storm wiki Setting up development environment https github com natha
  • 使用gdb进行JDK9 Hotspot调试,导致eclipse / Ubuntu终端中出现SIGSEGV分段错误

    我正在尝试调试 JDK9 我想跟踪源代码并查看JDK Hotspot代码的控制流程 我使用 gdb 和 Eclipse 但有一个问题SIGSEGV Segmentation fault 我按照JDK官方文档中的Buildme md来配置JD
  • 在 Symfony 中为 @Route 注释创建自定义需求验证器

    正如你在下面看到的 我的 Route gt requirements下面的正则表达式 我在许多其他控制器 方法中使用它 有点长 看起来不太好并且最重要的是 在语法更新的情况下可能很难维护将来的问题是 我们能做下面这样的事情吗 我见过许多类似
  • 是否可以在 Mac 中构建 UWP 应用程序?

    是否可以在Mac平台上构建UWP应用程序 就像我有 Mac PC 和新的 Visual Studio Code 可以用来编写代码 但是可以安装适用于 Windows 10 UWP 的模拟器和 SDK 吗 我想为 Windows 平台构建应用
  • Asp.net 未从 C# 变量中的 javascript 函数获取值

    这个问题浪费了我很多时间 我已经编写了一个 javascript 函数并为 asp 隐藏字段分配了值 但是当我运行我的应用程序时 我没有获得 c 变量中的值 如果我遗漏了什么 请纠正我 提前致谢 这是我的代码 JavaScript 函数 f
  • 解析工作项查询上的“AssignedTo”中的用户组成员身份

    我将工作项分配给 TFS 中的用户组 比方说 我有一项任务分配给了 Devlopers 组 现在我想设置团队查询 我的任务 以便 开发人员 的每个成员都能看到该任务 我在查询编辑器中尝试了以下运算符 值组合 出于视觉原因添加方括号 分配给
  • 如何在 Spring Boot 应用程序中配置 HikariCP 和 Dropwizard/Coda-Hale 指标

    Reading 说明 https github com brettwooldridge HikariCP wiki Dropwizard Metrics在 HikariCP wiki 上关于如何启用 Dropwizard 指标的信息中 它说
  • 有没有办法使 before_save 有条件?

    我试图在 Rails 应用程序中进行有条件的 before save 操作 但它似乎不起作用 before save method call to run if self related model some method that ret
  • VirtualBox 导入错误 无法注册 DVD 映像

    我正在运行 v 4 2 6 从今天早上开始 我无法导入某些虚拟机 并且我现有的一些虚拟机显示为无法访问 并且 UI 中显示以下错误 当我将虚拟机带到另一台电脑并尝试使用虚拟盒 v 5 0 10 打开它时 也出现同样的错误 无法注册 DVD
  • 从 log4j.Logger 获取 Logger 的通用方法

    而不是在每个类上指定类名 log Logger getLogger Foo class log Logger getLogger Bar class log Logger getLogger Test class 使用可以吗 log Log
  • Spark Dataframe.cache() 更改源的行为

    我的用例 从 cassandra 表创建数据框 通过过滤列并修改该列的值来创建输出数据框 将输出数据帧写入带有 TTL 设置的 cassandra 因此所有修改的记录会在短时间内 2 秒 后被删除 将输出数据帧返回给调用者 在一段时间后将其
  • 安全提供程序会导致 Java 中的类加载器泄漏吗?

    在我的 Java EE Glassfish 3 1 1 应用程序中 我注册了一个安全提供程序 public static final class XoauthProvider extends Provider public XoauthPr
  • jQuery 和 Perl:基于“管道文件”状态的进度条,动态 ajax

    我想构建一个小型管道 允许用户选择一个文件 然后使用该文件作为输入运行多个脚本 由于其中一些脚本运行了几分钟 确切的时间取决于输入文件的大小 我想显示一个基于该管道已完成的脚本数量的进度条 问题是我不知道如何根据管道的状态更新此进度条 并且