0

この投稿では、www :: mechanize Perlスクリプトによってダウンロードされているファイルの割合を計算することにより、プログレスバーを介してユーザーに通知する方法について説明します。

www :: mechanizeスクリプトの進行状況をユーザーに通知する必要がありますが、必ずしも残りのパーセンテージで通知する必要はありません。スクリプトはユーザーのアカウントを介して移行し、データを取得します。データのサイズは大幅に異なる可能性があるため、パーセンテージ係数は不明です。

js DOM divの書き込み(perlスクリプトの実行中に「ローダー」イメージを表示するダイアログで)を介して「進行状況」を表示できる場合は、それで十分です。

次のようなjsスクリプトを挿入できますか?

<script>
$('#formboxtext').html('Logging into account ...');
</script>

Perlスクリプトに挿入して、ユーザーに進行状況を表示しますか?または、DOMが更新される前にPerlスクリプトを返す必要がありますか?(答えは「いいえ」のようです。)

JavaScript::SpiderMonkeyおよびWWW::Scripterモジュールはこれを実現するために必要ですか、それともソリ​​ューションはより単純ですか?

編集:

PHPベースのCMSを拡張しています。Perlとモジュールwww::Mechanizeを使用して画面スクレイピングスクリプトを作成しました。このスクリプトは、mySQLデータベースに取得するために別のサイトのユーザーアカウントのいくつかのページをトラバースします。収集したコンテンツをphp形式で表示し、Perlスクリプトが完了したらユーザーが保存できるようにします。収集プロセスの範囲は10秒から1分です。スクリプトが情報を収集するユーザーのアカウントページをナビゲートするときの進行状況を表示したいと思います。

まず、ユーザーの個人アカウントにログインするために使用するjQueryモーダルダイアログ(phpファイルを呼び出してその内容をユーザー名とパスワードの入力の形式で入力する)をユーザーに提供します。このダイアログにローダーの画像と忍耐を求める文を表示しますが、Perlスクリプトがページをナビゲートし、進行状況を表示に戻すときに、jQueryを使用してこの文(div)を書き直したいと思います。「私は今ここにいます。今私はここにいます。」など。エラーが発生した場合(つまり、ログイン不良)、モーダルダイアログを書き直して、通常どおりに解決策を提供できます。成功した場合は、ダイアログを閉じて、収集した情報をフォーム入力に表示し、データベースに保存できるようにします。モーダルダイアログを生成したphpページに表示します。

これらすべてに複数のDOMが含まれ、プロセスをフォークし、あるスクリプト実行から別のスクリプト実行に制御を戻す必要がある場合、私は間違いなく頭を悩ませています。しかし、私はそれを学びたいです。:)私は何を読んで学ぶべきかについての概要をいただければ幸いです。それが実際に私が理解しているよりもはるかに単純であるならば、私もその答えをいただければ幸いです。

daximとreinierpostの忍耐とアドバイスに感謝します。助けてくれてありがとう。

回答: 要約:私にとっては、進行状況を示すプログレスバーを、所要時間を見積もって偽造することにしました。それはうまくいきました。この投稿では、perlスクリプトからの出力を呼び出し元のphpスクリプトに複製する方法を示していますが、その情報を元のDOMにフィードバックすることは、価値がないほど複雑になりました。進行と出力を変更するperlスクリプトに渡されるさまざまなパラメーターによって、より複雑になりました。「それを偽造する」ことは素晴らしい解決策を証明しました。ねえ、今私は私のガールフレンドがそれをする理由がわかります!:)

PS。daximに緑色のチェックマークを付けたのは、彼が私の他の質問に答えてくれて、暗闇の中で撮影していたにもかかわらず、私を大いに助けてくれたからです。

4

1 に答える 1

1

https://stackoverflow.com/a/1938448のように進行状況を STDOUT に出力する代わりに、数値を Web サービスとして公開します。これで十分です:

sub {
    return [200, [Content_Type => 'text/plain'], [$PROGRESS]]
}

クライアント側では、jQuery getを使用して 0.5 秒ごとに Web サービスをポーリングし、jQuery Progressbarを使用してそれを表示します。


編集:コード例

use 5.010;
use strictures;
use DBI qw();
use Plack::Request qw();
use POSIX qw(floor);
use Forks::Super qw(fork);
use WWW::Mechanize qw();

sub db_connect {
    return DBI->connect('dbi:SQLite:dbname=/var/tmp/progress.db');
}

sub {
    my ($env) = @_;
    my $req = Plack::Request->new($env);
    if ('/progress' eq $req->path_info) {
        return [200,
            [Content_Type => 'text/html'],
            [db_connect->selectrow_array('select progress from progress')]
        ]
    } else {
        fork(sub => sub {
            state $total = 0;
            my $dbh = db_connect;
            $dbh->do('delete from progress');
            $dbh->do('insert into progress (progress) values (0)');
            WWW::Mechanize->new->get(
                'http://localhost:5000/VBoxGuestAdditions_4.0.4.iso', # large-ish file
                ':read_size_hint' => 1024**2,
                ':content_cb' => sub {
                    my ($data, $response, $proto) = @_;
                    $total += length($data);
                    my $size = $response->header('Content-Length');
                    $dbh->do(
                        'update progress set progress = ?', {}, floor(($total/$size)*100)
                    );
sleep 1;
                },
            );
        }) unless defined db_connect->selectrow_array('select progress from progress');
        return [200,
            [Content_Type => 'text/html'],
            [q~<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.8.18/themes/base/jquery-ui.css" />
<style>
#progress { width: 80em; height: 5em; border: 1px solid black; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script>
jQuery(document).ready(function() {
    // TODO: stop the timer if progress == 100 or no response
    var timer = setInterval(function() {
        jQuery.ajax({ async: false, cache: false, dataType: 'html', url: 'http://localhost:5001/progress' }).done(function(progress) {
            jQuery('#progress').progressbar({ value: parseInt(progress) });
        });
    }, 500);
});
</script>
</head>
<body>
<h1>downloading your stuff</h1>
<div id="progress"><div>
</body>
</html>~]
        ]
    }
};
于 2012-04-12T16:21:34.507 に答える