#! /usr/bin/perl # get_coverart downloads coverart, and is released # under the terms of the GPL version 2, or any later version, at your # option. See the file README and COPYING for more information. # Copyright 2011 by Don Armstrong . use warnings; use strict; use Getopt::Long; use Pod::Usage; =head1 NAME get_coverart -- download coverart =head1 SYNOPSIS get_coverart --asin B000NIIUX8 --cover cover.jpg [options] Options: --asin Amazon image ID --cover file name to save cover to --debug, -d debugging level (Default 0) --help, -h display this help --man, -m display manual =head1 OPTIONS =over =item B<--debug, -d> Debug verbosity. (Default 0) =item B<--help, -h> Display brief usage information. =item B<--man, -m> Display this manual. =back =head1 EXAMPLES get_coverart --asin B000NIIUX8 --cover cover.jpg get_coverart --asin B000NIIUX8 > cover.jpg =cut use URI::Escape; use WWW::Mechanize; use HTTP::Cookies; use IO::Dir; use IO::File; use vars qw($DEBUG); my %options = (debug => 0, help => 0, man => 0, ); GetOptions(\%options, 'asin=s', 'artist=s', 'album=s', 'cover=s', 'debug|d+','help|h|?','man|m'); pod2usage() if $options{help}; pod2usage({verbose=>2}) if $options{man}; $DEBUG = $options{debug}; my @USAGE_ERRORS; if (not exists $options{asin}) { push @USAGE_ERRORS,"You must give an ASIN."; } pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS; my $wfh = \*STDOUT; if (exists $options{cover}) { $wfh = IO::File->new($options{cover},O_WRONLY|O_CREAT|O_EXCL) or die "Unable to create file: $options{cover}: $!"; } my $m = WWW::Mechanize->new(); my $content; my $parser; my $token; if (not length $options{asin}) { my ($artist,$album) = map {s/_/ /g; $_} @options{qw(artist album)}; my $url_end = uri_escape("$artist $album"); mm_get($m,"http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dpopular&field-keywords=$url_end"); $content = $m->content(); $parser = HTML::TokeParser->new(\$content); while ($token = $parser->get_tag('div')) { if (exists $token->[1]{class} and $token->[1]{class} eq 'productImage') { $token= $parser->get_token(); ($options{asin}) = $token->[2]{href} =~ m{^http://[^/]+/[^/]+/dp/([^/]+)$}; next unless defined $options{asin}; } } if (not length $options{asin}) { print STDERR "Unable to find cover for artist $options{artist} and album $options{album}\n" unless exit 1; } } mm_get($m,"http://www.amazon.com/gp/product/$options{asin}"); if ($m->status() != 200) { print STDERR "Unable to get product for asin $options{asin}\n"; exit 1; } $content = $m->content(); $parser = HTML::TokeParser->new(\$content); my $image; while ($token = $parser->get_tag('img')) { if (exists $token->[1]{id} and $token->[1]{id} eq 'prodImage') { $image = $token->[1]{src}; } } mm_get($m,$image); print {$wfh} $m->content; sub mm_get{ my ($m,$url) = @_; my $rerun = 8; my $return; do { eval { $return = $m->get($url); }; } while ($@ and ($rerun-- > 0) and sleep 5); return $return; } __END__