fishmonger has asked for the wisdom of the Perl Monks concerning the following question:
EDIT: Issue resolved. As suggested in my cross post thread, I switched to using promises instead of delays.
get '/titles' => sub ($c) { $c->render_later; my $tx = $c->tx; my @promises = map { $ua->get_p($_) } @urls; Mojo::Promise->all(@promises)->then(sub { my @results = @_; my $titles = []; foreach my $result (@results) { my $tx = $result->[0]; my $title = trim($tx->res->dom->at('title')->text); my $status = $tx->res->is_success ? 'Connected' : $tx->err +or->{message}; push @$titles, {host => $tx->req->url->host, status => $st +atus, title => $title}; } $c->render(titles => $titles); })->catch(sub { $c->reply->exception(pop); undef $tx }); } => 'titles';
I'm brand new to Mojolicious and working on a lite script that goes to 75 urls and retrieves text in an h3 tag. I've worked up a working test script that outputs to console and now I'm working on adjusting it to be a web app but I can't seem to get the correct syntax to store/retrieve the data.
Here's the working cli script
#!/usr/bin/perl use Mojolicious::Lite; my @urls = ( 'https://mojolicious.org', 'https://metacpan.org', 'https://perlmonks.org', 'http://www.google.com', ); my $ua = Mojo::UserAgent->new; my $async = Mojo::IOLoop::Delay->new; $async->steps( sub { my $self = shift; $ua->get($_, $self->begin) for @urls; }, sub { my ($self, @tx) = @_; foreach (@tx) { my $title = ''; my $status = $_->res->is_success ? 'Connected' : $_->error +->{message}; if ( $_->res->is_success ) { $title = $_->res->dom->at('title')->text; $title =~ s/^\s+|\s+$//g; # couldn't get Mojo::Util tr +im function to work } printf("Host: %-20s Status: %-15s Title: %s\n", $_->req->u +rl->host, $status, $title); } } ); $async->wait unless $async->ioloop->is_running;
Output:
$ ./titles_cli.pl Host: mojolicious.org Status: Connected Title: Mojolicious +- Perl real-time web framework Host: metacpan.org Status: Connected Title: Search the C +PAN - metacpan.org Host: perlmonks.org Status: Connected Title: PerlMonks - +The Monastery Gates Host: www.google.com Status: Connected Title: Google
Here's the adjusted web version and its output
#!/usr/bin/perl use Mojolicious::Lite; my @urls = ( 'https://mojolicious.org', 'https://metacpan.org', 'https://perlmonks.org', 'http://www.google.com', ); get '/titles' => sub { my $ua = Mojo::UserAgent->new; my $async = Mojo::IOLoop::Delay->new; $async->steps( sub { my $self = shift; $ua->get($_, $self->begin) for @urls; }, sub { my ($self, @tx) = @_; my $titles = []; foreach (@tx) { my $title = ''; my $status = $_->res->is_success ? 'Connected' : $_->error +->{message}; if ( $_->res->is_success ) { $title = $_->res->dom->at('title')->text; $title =~ s/^\s+|\s+$//g; # couldn't get Mojo::Uti +l trim function to work } push @$titles, {host => $_->req->url->host, status => $status, + title => $title}; } $self->stash(titles => $titles); } ); } => 'titles'; app->start; __DATA__ @@ titles.html.ep % layout 'titles'; %= dumper stash('titles') <table border=1> <tr> <th>Host</th> <th>Status</th> <th>Title</th> </tr> <!-- % for my $server ( @{ stash('titles') } ) { --> % for my $server ( stash('titles') ) { <tr> <td><%= $server->{host} %></td> <td><%= $server->{status} %></td> <td><%= $server->{title} =%></td> </tr> % } </table> @@ layouts/titles.html.ep <!doctype html> <html> <head> <title>Titles</title> </head> <body> <h1>Titles</h1> <%= content =%> </body> </html>
Output:
$ ./titles_web.pl get /titles [Thu Feb 7 08:58:06 2019] [debug] GET "/titles" (842f1ec4) [Thu Feb 7 08:58:06 2019] [debug] Routing to a callback [Thu Feb 7 08:58:06 2019] [debug] Rendering template "titles.html.ep" + from DATA section [Thu Feb 7 08:58:06 2019] [debug] Rendering template "layouts/titles. +html.ep" from DATA section [Thu Feb 7 08:58:06 2019] [debug] 200 OK (0.002744s, 364.431/s) <!doctype html> <html> <head> <title>Titles</title> </head> <body> <h1>Titles</h1> undef <table border=1> <tr> <th>Host</th> <th>Status</th> <th>Title</th> </tr> <!-- % for my $server ( @{ stash('titles') } ) { --> <tr> <td></td> <td></td> <td></td> </tr> </table> </body> </html>
What am I doing wrong?
EDIT: I cross posted this question at https://groups.google.com/forum/#!topic/mojolicious/5P86eh7Mqu8
|
|---|