tags:

views:

115

answers:

2

I am using File::Fetch in a Perl script. How can I get File::Fetch to store a file to be downloaded in a specified file?

I have tried:

    use File::Fetch;
    my $ff    = File::Fetch->new( uri => 'http://stackoverflow.com/users/63550');
    #my $where = $ff->fetch() or die $ff->error; #Creates a file named "63550".
    my $where = $ff->fetch( to => 'SO.html' );  #Creates a subfolder named SO.html with a file named "63550" in it.

A work-around would be to rename the file after download, but I wonder if it is possible to specify the file name immediately.

Test platform: ActiveState Perl 64 bit. Windows XP. From perl -v: v5.10.0 built for MSWin32-x64-multi-thread Binary build 1004 [287188] provided by ActiveState.

+2  A: 

Looking at the source code, the only way seems to be making a subclass and overriding the output_file method. I guess the author would accept a patch that makes output_file a read/write property, so that it can be changed at run-time.

Lukáš Lalinský
Thanks. I think I will use the work-around instead, then.
Peter Mortensen
Which routine specifically? There are only two uses of the method. One of them uses it to construct the final path (it has no impact on the original URL), the other one uses it as the target file name for the FTP GET command (also, no impact on the original URL). Making output_file return something that is not derived from file is just fine.
Lukáš Lalinský
Well, you are wrong. `_lwp_fetch` runs `$ua->mirror($uri, $to)` and guess where `$to` comes from? :)
Lukáš Lalinský
File::Fetch has a subclass bug that prevents this from working (really, please try what you suggest before you suggest it). I've filed the bug as https://rt.cpan.org/Ticket/Display.html?id=53427
brian d foy
A: 

I looked at the File::Fetch 0.22 code to see what you would need to do for this. There's a bug that prevents you from subclassing (unless you want to override new() and create() to fix it). Update The File::Fetch developers have applied my patch and a new release should be out shortly.

The easiest thing is probably to fetch the file to a temporary directory, discover the name with output_file, and rename it to its final location.

Lukáš thinks I'm wrong, but I don't think he's actually tried it like I had. Creating a subclass and overriding output_file has no effect:

#!perl

use strict;
use warnings;

BEGIN {
package File::Fetch::MyOutput;
use parent qw(File::Fetch);

sub output_file { die "I was called!" }
}

my $ff = File::Fetch::MyOutput->new( 
     uri => 'http://search.cpan.org/~bingos/File-Fetch-0.22/lib/File/Fetch.pm' 
     );

$ff->fetch( to => '.' );

When I run this, I end up with Fetch.pm in the current directory. The script does not die because it never invoked my output_file because the object is not actually in my subclass. This is a bug in File::Fetch which I've filed as RT 53427.

brian d foy
I have to vote -1, because it's just wrong. There is nothing in the source code that would "mess up" if you change the output of `output_file`.
Lukáš Lalinský
All of them use either the `$to` parameter (which uses `output_file` indirectly) or the `output_file` method directly. It will work just fine, but I'm not going to argue with you.
Lukáš Lalinský
File::Fetch has a bug in that it fails the null subclass test. It doesn't care what you do in a subclass because it will never see it unless you override new() to fix the bug. I think that's to much work.
brian d foy
So you delete the old discussion, to hide that all you cliamed was wrong. Yeah, that's the way to go.
Lukáš Lalinský
Indeed, I was wrong, and I realize that and removed my wrong information. I was misled by another bug in File::Fetch. However, your answer does not solve the problem either and I don't think you ever tried it. I've explained it in my answer.
brian d foy
@brian d foy: I got the same result as you when I used '.'. Thanks for filing the bug.
Peter Mortensen
No, I've not tried, because I was confident about what I was saying (and I was right). I give people suggestions, not working code. I never suggested how to subclass it (TMTOWTDI applies even to Perl module writing, you know). Removing comments from the middle of a discussion is just wrong though. You can delete a wrong answer, but don't delete parts of a discussion.
Lukáš Lalinský
Okay, you think it's wrong to remove comments. I think it's right to remove distracting or wrong information. Stackoverflow is based on editing and refining. That's why we can delete comments. I think the world would be better off if we both admitted we messed up and moved on. I was wrong, I admitted it, and I fixed it. Now it's your turn.
brian d foy
I consider everything I said here correct, so I have no reason to fix anything.
Lukáš Lalinský