use strict; use warnings; package Footprintless::Resource::UrlProvider; $Footprintless::Resource::UrlProvider::VERSION = '1.05'; # ABSTRACT: A resource provider for resources retrieved by URL # PODNAME: Footprintless::Resource::UrlProvider use parent qw(Footprintless::Resource::Provider); use Carp; use File::Temp; use Footprintless::Resource::Url; use URI; sub _download { my ( $self, $resource, %options ) = @_; my $file; if ( $options{to} ) { $file = $options{to}; if ( -d $file ) { my @segments = $resource->get_uri()->path_segments(); $file = File::Spec->catfile( $file, $segments[$#segments] ); } } else { $file = Footprintless::Resource::UrlProvider::DownloadedFile->new(); } my $response = $self->{agent}->get( $resource->get_uri(), ':content_file' => "$file" ); croak( 'download failed: ', $response->message() ) unless ( $response->is_success() ); return $file; } sub _init { my ( $self, $agent ) = @_; $self->Footprintless::Resource::Provider::_init(); $self->{agent} = $agent; return $self; } sub resource { my ( $self, $spec ) = @_; return $spec if ( UNIVERSAL::isa( $spec, 'Footprintless::Resource::Url' ) ); return Footprintless::Resource::Url->new( ref($spec) ? $spec->{url} : $spec ); } sub supports { my ( $self, $resource ) = @_; return 1; } package Footprintless::Resource::UrlProvider::DownloadedFile; $Footprintless::Resource::UrlProvider::DownloadedFile::VERSION = '1.05'; # Wraps a temp file to hold a reference so as to keep the destructor from # getting called. It will provide the filename when used as a string. use overload q{""} => 'filename', fallback => 1; sub new { my $self = bless( {}, shift ); my $file = File::Temp->new(); $self->{handle} = $file; $self->{name} = $file->filename(); return $self; } sub filename { return $_[0]->{name}; } 1; __END__ =pod =head1 NAME Footprintless::Resource::UrlProvider - A resource provider for resources retrieved by URL =head1 VERSION version 1.05 =head1 CONSTRUCTORS =head2 new($agent) Creates a new C<Footprintless::Resource::UrlProvider> that will use C<$agent> to retrieve the resources. C<$agent> should be an instance of C<LWP::UserAgent>. =head1 METHODS =head2 download($resource, \%options) Downloads C<$resource> and returns the filename it downloaded to. The returned filename may be an object which overrides the C<""> operator so that when used in string context, you will get the actual filename. The supported options are: =over 4 =item to The path of a directory or filename to download to. =back =head2 resource($spec) Returns the C<Footprintless::Resource::Url> indicated by C<$spec>. =head2 supports($spec) Returns C<1>. This provider will attempt to support any spec string. If C<$spec> is missing the scheme part, it will be set to C<file://>. For example, C</foo/bar> would result in the URL C<file:///foo/bar>. =head1 AUTHOR Lucas Theisen <lucastheisen@pastdev.com> =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2016 by Lucas Theisen. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 SEE ALSO Please see those modules/websites for more information related to this module. =over 4 =item * L<Footprintless|Footprintless> =item * L<Footprintless::Resource::Provider|Footprintless::Resource::Provider> =item * L<Footprintless::Resource::Url|Footprintless::Resource::Url> =item * L<Footprintless::ResourceManager|Footprintless::ResourceManager> =item * L<Footprintless|Footprintless> =item * L<URI|URI> =back =cut