When downloading a file from Perl, there’s many ways to go about it. You can use LWP, libcurl, wget, curl the program, etc. My shell hoster doesn’t include many perl bindings so I can’t use LWP or libcurl. I use `curl -s $url` to download urls. The only problem with using any of the above mentioned methods is that they all block Irssi until the page is downloaded. That means the client freezes and doesn’t respond to pings during this time. To remedy this, fork can be used. But fork is rather screwy in Irssi; if you use it wrong, it will create 2 instances of Irssi.
The fix? Use someone else’s code that works. Here’s mine, released under the GNU GPL. It can easily be adapted, and should be, to use LWP or libcurl if your client supports those.
use strict; use Irssi; use POSIX; sub async_curl ($$$) { my ($geturl, $callback, $argref) = @_; my ($reader, $writer); pipe($reader, $writer); my $pid = fork(); if ($pid > 0) { close($writer); Irssi::pidwait_add($pid); my $pipetag; my @pargs = ($reader, \$pipetag, $callback, $argref); $pipetag = Irssi::input_add(fileno($reader), INPUT_READ, \&pipe_input, \@pargs); } else { my $content; eval { my $data = `curl -s "$geturl"`; print($writer $data); close($writer); }; POSIX::_exit(1); } } sub pipe_input ($$$$) { my ($reader, $pipetag, $callback, $argref) = @{$_[0]}; my @lines = <$reader>; close($reader); Irssi::input_remove($$pipetag); my $text = join("", @lines); $callback->($text, $argref); }
Using this code is very simple. Here’s a quick example:
sub callback_method { my ($content, $argref) = @_; my ($arg1, $arg2) = @{$argref}; # Here we have the $content from the url # and the two args we wanted back } # Gather up any arguments we want to piggy-back onto the callback my @args = ('test1', 'test2'); # Call async_curl with a reference to our callback method # and a reference to our piggy-back args async_curl("http://www.google.com/", \&callback_method, \@args);
This really helped me with my web intensive irssi scripts. The solution you posted worked instantly and without much trouble. Thanks a lot!