ProgressBar::run and now Asset->www_copy has a bar

This commit is contained in:
Paul Driver 2010-05-10 11:40:39 -07:00
parent 67a66647ec
commit 503a378756
6 changed files with 394 additions and 31 deletions

View file

@ -145,20 +145,27 @@ A message to be displayed in the status bar.
=cut
{
# Keep the sprintf string short and don't recompute buffer breaker every time
# update is called
my $prefix = '<script type="text/javascript">
/* ' . 'BUFFER BREAKER ' x 1000 . ' */
updateWgProgressBar(';
my $format = q"'%dpx', '%s'";
my $suffix = ');
</script>
';
sub update {
my $self = shift;
my $message = shift;
$message =~ s/'/\\'/g; ##Encode single quotes for JSON;
$self->session->log->preventDebugOutput;
$self->{_counter} += 1;
my $counter = $self->{_counter} += 1;
my $modproxy_buffer_breaker = 'BUFFER BREAKER ' x 1000;
my $text = sprintf(<<EOJS, $self->{_counter}, $message);
<script type="text/javascript">
/* $modproxy_buffer_breaker */
updateWgProgressBar('%dpx', '%s');
</script>
EOJS
my $text = $prefix . sprintf($format, $counter, $message) . $suffix;
local $| = 1; # Tell modperl not to buffer the output
$self->session->output->print($text, 1); #skipMacros
if ($self->{_counter} > 600) {
@ -167,5 +174,92 @@ EOJS
return '';
}
1;
}
#-------------------------------------------------------------------
=head2 run ( options )
starts and finishes a progress bar, running some code in the middle. It
returns 'chunked' for convenience - if you don't use the return value, you
should return 'chunked' yourself.
The following keyword arguments are accepted (either as a bare hash or a
hashref).
=head3 code
A coderef to run in between starting and stopping the progress bar. It is
passed the progress bar instance as its first and only argument. It should
return the url to redirect to with finish(), or a false value.
=head3 arg
An argument (just one) to be passed to code when it is called.
=head3 title
See start().
=head3 icon
See start().
=head3 wrap
A hashref of subroutine names to code references. While code is being called,
these subroutines will be wrapped with the provided code references, which
will be passed the progress bar instance, the original code reference, and any
arguments it would have received, similiar to a Moose 'around' method, e.g.
wrap => {
'WebGUI::Asset::update' => sub {
my $bar = shift;
my $original = shift;
$bar->update('some message');
$original->(@_);
}
}
=cut
sub run {
my $self = shift;
my $args = $_[0];
$args = { @_ } unless ref $args eq 'HASH';
my %original;
my $wrap = $args->{wrap};
$self->start($args->{title}, $args->{icon});
my $url = eval {
for my $name (keys %$wrap) {
my $original = $original{$name} = do { no strict 'refs'; \&$name };
my $wrapper = $wrap->{$name};
no strict 'refs';
*$name = sub {
unshift(@_, $self, $original);
goto &$wrapper;
};
}
$args->{code}->($self, $args->{arg});
};
my $e = $@;
# Always, always restore coderefs
for my $name (keys %original) {
my $c = $original{$name};
if (ref $c eq 'CODE') {
no strict 'refs';
*$name = $c;
}
}
die $e if $e;
return $self->finish($url || $self->session->url->page);
}
1;