package Shapeways::Item; use Moose; use MooseX::Storage; use Shapeways; use Shapeways::Logger; with Storage(format => 'JSON'); has contents => ( 'is' => 'ro', lazy => 1, builder => '_download_item', ); has image => ( is => 'ro', lazy => 1, builder => '_download_image', ); has image_url => ( is => 'ro', ); has download_url => ( is => 'ro', default => undef ); has title => ( is => 'ro', ); has description => ( is => 'ro', ); has shapeways_id => ( is => 'ro', ); has file_ext => ( is => 'rw', default => '.zip', # will this ever be different? .stl maybe? ); sub _download_image { my $self = shift; log_info {"Downloading image"}; my $mech = Shapeways->mech; my $res = $mech->get($self->image_url); if ($res->is_success) { # TODO check headers for extension log_info {"Download successful"}; return $res->content; } else { log_error {"Failed to download: ", $res->code, " ", $res->status_line}; return undef; } } sub _download_item { my $self = shift; my $mech = Shapeways->mech(); my $base = Shapeways->base_url(); log_info {"Downloading ", $self->title, "(", $self->shapeways_id, ") ", $self->download_url}; my $res = $mech->get($base . $self->download_url); if ($res->is_success) { # TODO check headers for extension log_info {"Download successful"}; return $res->content; } else { log_error {"Failed to download: ", $res->code, " ", $res->status_line}; return undef; } } sub serialize { my $self = shift; my %opts = ( mkdir => 1, # make a directory for the files dirname => $self->title."-".$self->shapeways_id, filebase => $self->title, unpack => 0, path => './', @_ ); # Download the file, rename it via the title, save a corrosponding .txt file with the description, title and original file name log_info {"Saving to disk: ", $self->title, "(", $self->shapeways_id, ") ", $self->download_url}; my $dir = $opts{path}.'/'.$opts{dirname}.'/'; log_debug {"dir => ", $dir}; mkdir($dir) or die "Couldn't mkdir $dir => $!"; log_debug {"Saving main file"}; open(my $fh, '>', $dir.$opts{filebase}.$self->file_ext) or die "Couldn't write base file => $!"; print $fh $self->contents; close($fh); log_debug {"Saving text file"}; open(my $descfh, '>', $dir.$opts{filebase}.'.txt') or die "Coouldn't open desc file => $!"; my $header = $self->title . " - " . $self->shapeways_id; print $descfh $header, "\n"; print $descfh "="x(length($header)), "\n\n"; print $descfh $self->description; # TODO html decoding? not sure close($descfh); log_debug {"Saving image file"}; open(my $imgfh, '>', $dir."folder.jpg") or die "Couldn't save image => $!"; print $imgfh $self->image; close($imgfh); # TODO fetch images } sub new_from_url { my $self = shift; my $url = shift; my ($tree_path, $code) = Shapeways->get_url($url); my $data = { shapeways_id => ($url =~ m|/product/([^/]+)/|g)[0], description => $tree_path->findvalue('//div[contains(@class,"product-description-content")]'), title => $tree_path->findvalue('//h1[contains(@class,"product-title-header")]'), download_url => $tree_path->findvalue('//div[contains(@class,"product-page-download")]//a/@href'), image_url => ($tree_path->findvalues('//img[contains(@class, "film-strip-img")]/@src'))[0], # only get the first image }; my $obj = Shapeways::Item->new($data); return $obj; } 1;