Data-Downloader
view release on metacpan or search on metacpan
lib/Data/Downloader/File.pm view on Meta::CPAN
if ($self->disk && ! -d $self->disk_obj->abs_path) {
mkpath $self->disk_obj->abs_path;
}
my $tmpfile = File::Temp->new(
UNLINK => 0,
DIR => ($self->disk ? $self->disk_obj->abs_path : $root),
TEMPLATE => "download.tmp.XXXXXXX"
);
# Download it before computing the storage path, since storing uses the hash.
if ($args{fake}) {
DEBUG "faking the download";
print $tmpfile "This is a test file from ".$self->url."\n";
print $tmpfile "MD5: ".($self->md5 || "unknown before download")."\n";
print $tmpfile "Some random stuff : ".rand."\n";
$tmpfile->flush;
} else {
INFO "downloading from ".$self->url;
my $max_time = $ENV{DATA_DOWNLOADER_TIMEOUT} || $ENV{DADO_MAX_TIME_PER_FILE} || 300;
system(qw/curl -L --fail --silent --insecure --compressed --max-time/,$max_time,"-o","$tmpfile",$self->url)==0
or do {
my $info = "$?";
$info .= "${^CHILD_ERROR_NATIVE}" if defined(${^CHILD_ERROR_NATIVE});
$self->error("failed to get file: $info");
ERROR "failed to get file (error code: $info)";
unlink $tmpfile;
return;
};
}
# Compute or check the hash.
if (defined($self->md5)) {
unless ($args{fake}) {
$self->_check_hash($tmpfile) or do {
my $error = "bad md5 for ".$self->filename." ($tmpfile)";
ERROR $error;
$self->error($error);
unlink $tmpfile;
return;
};
}
} else {
$self->_store_hash($tmpfile);
}
# Now put it in place
my $destination = $self->storage_path;
my $destdir = dirname($destination);
unless (-d $destdir) {
mkpath($destdir) or do {
ERROR "couldn't make directory $destdir: $!";
unlink $tmpfile;
return;
};
}
rename $tmpfile, $destination or do {
ERROR "rename to $destination failed: $!";
unlink $tmpfile;
return;
};
chmod 0644, $destination or do {
ERROR "chmod failed: $!";
unlink $tmpfile;
return;
};
TRACE "downloaded to $destination";
$self->on_disk(1);
$self->add_log_entries( {
requested_at => $request_time,
cache_hit => 1,
completed_at => DateTime->now(),
prog => $0,
pid => $$,
uid => $<,
note => $ENV{DATA_DOWNLOADER_LOG_NOTE},
}) if $ENV{DATA_DOWNLOADER_GATHER_STATS};
my $stat = stat($destination);
$self->size( $stat->size );
$self->atime( DateTime->from_epoch(epoch => $stat->atime) );
$self->db->do_transaction(
sub {
$self->save( changes_only => 1 ) or die $self->error;
}
) or do {
WARN "errors saving file : ".$self->db->error;
return;
};
return $self if $args{skip_links};
$self->makelinks or WARN "Failed to make symlinks for file";
return $self;
}
=item decorate_tree
Put the links for a file within a single linktree.
A tree may contain multiple symlinks for a file if
there are metadata_transformations defined for this
repository which transform a set of metadata into mutltiple
sets of template parameters.
Parameters :
tree -- A DD::Linktree object
=cut
sub decorate_tree {
my $self = shift;
my $args = validate( @_, { tree => 1 } );
my $tree = $args->{tree};
$tree->load unless $tree->repository && $tree->repository_obj;
unless ($self->on_disk) {
LOGWARN "not making broken symlinks for ".$self->filename;
return;
}
# Start with a hash of template vars, but this may be transformed into multiple sets of
# template vars using metadata_transformations.
my @template_vars = ( +{ map { ( $_->name => $_->value ) } $self->metadata });
for my $t ( sort { ($a->order_key || 0) <=> ($b->order_key || 0) }
( run in 2.109 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )