Skip to content

Instantly share code, notes, and snippets.

@dex4er
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dex4er/bda2e33145d4e27d6a63 to your computer and use it in GitHub Desktop.
Save dex4er/bda2e33145d4e27d6a63 to your computer and use it in GitHub Desktop.
wxPerl
#!/usr/bin/env perl
use v5.14;
package MyApp {
use Moo;
use Wx ':everything';
has url => is => 'ro';
has q => is => 'ro';
has wx => is => 'rw';
has frame => is => 'rw';
has pd => is => 'rw';
sub start {
my ($self) = @_;
my $wx = Wx::SimpleApp->new;
$self->wx($wx);
my $frame = Wx::Frame->new( undef, -1, 'wxPerl', wxDefaultPosition, [ 200, 100 ] );
$frame->{TXT} = Wx::TextCtrl->new($frame , -1, '');
$frame->Show(1);
$self->frame($frame);
$self->start_progress($self->q->dequeue);
}
sub start_progress {
my ($self, $last) = @_;
my $url = $self->url;
my $pd = Wx::ProgressDialog->new( "Downloading $url", '', $last, $self->{frame},
wxPD_CAN_ABORT | wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME |
wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME );
$self->pd($pd);
}
sub update_progress {
my ($self, $current) = @_;
return $self->pd->Update($current, "Downloaded $current bytes");
}
sub destroy_progress {
my ($self) = @_;
$self->pd->Destroy;
}
sub work {
my ($self) = @_;
$self->start;
while (my $n = $self->q->dequeue) {
$self->update_progress($n) or last;
}
$self->destroy_progress;
$self->frame->{TXT}->SetValue("Thank you!");
}
}
package Mojo::Asset::Null {
use Mojo::Base 'Mojo::Asset';
has size => 0;
sub add_chunk {
my ($self, $chunk) = @_;
$self->{size} += length($chunk);
return $self;
}
}
package Worker {
local $ENV{MOJO_MAX_MEMORY_SIZE} = 100 * 1024 * 1024;
use Moo;
use Mojo::UserAgent;
use Time::HiRes qw(time);
use List::Util qw(sum);
# Mojo does not allow to run this so we need monkey patching
BEGIN { no warnings 'redefine'; *Mojo::Reactor::EV::CLONE = sub {} }
has q => is => 'ro';
has url => is => 'ro';
my $n = $ARGV[1] || 1;
my $ua = Mojo::UserAgent->new;
my @speeds;
sub BUILD {
my ($self) = @_;
$SIG{INT} = sub {
$self->q->end;
sleep 1;
threads->exit;
}
}
sub work {
my ($self) = @_;
my $t0 = time;
my $size = 0;
my $tx = $ua->build_tx(GET => $self->url);
$tx->res->content->asset(Mojo::Asset::Null->new);
$tx->res->max_message_size(0);
my $seen;
$tx->res->on(progress => sub {
my ($res) = @_;
$self->q->enqueue($res->headers->content_length) unless $seen++;
$size = $res->content->progress;
$self->q->enqueue($size);
});
$ua->start($tx, sub {
$size = $tx->res->content->body_size;
$self->q->enqueue($size);
$self->q->end;
});
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
}
}
use threads;
use Thread::Queue;
my $url = $ARGV[0] || 'http://www.cpan.org/src/5.0/perl-5.20.0.tar.gz';
my $q = Thread::Queue->new();
my $app = MyApp->new(q => $q, url => $url);
my $thr = threads->create(sub{
my $worker = Worker->new(q => $q, url => $url);
$worker->work;
});
$app->work;
$thr->kill('SIGINT');
$app->wx->MainLoop;
$thr->join;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment