view release on metacpan or search on metacpan
lib/Amazon/MWS/Routines.pm view on Meta::CPAN
$request->method('GET');
$self->sign_request($request);
$response = $self->agent->request($request);
$content = $response->content;
}
if ($self->{debug}) {
open LOG, ">>$self->{logfile}";
print LOG Dumper($response);
}
my $xs = XML::Simple->new( KeepRoot => 1 );
if ($response->code == 400 || $response->code == 403) {
my $hash = $xs->xml_in($content);
my $root = $hash->{ErrorResponse};
force_array($root, 'Error');
lib/Amazon/MWS/Routines.pm view on Meta::CPAN
if (-r $opts{configfile} ) {
my $xmlconfig = XML::Simple::XMLin("$opts{configfile}");
$opts{access_key_id} ||= $xmlconfig->{access_key_id};
$opts{secret_key} ||= $xmlconfig->{secret_key};
$opts{merchant_id} ||= $xmlconfig->{merchant_id};
$opts{marketplace_id} ||= $xmlconfig->{marketplace_id};
$opts{endpoint} ||= $xmlconfig->{endpoint};
$opts{debug} ||= $xmlconfig->{debug};
$opts{logfile} ||= $xmlconfig->{logfile};
}
my $attr = $opts->{agent_attributes};
$attr->{Language} = 'Perl';
my $attr_str = join ';', map { "$_=$attr->{$_}" } keys %$attr;
my $appname = $opts{Application} || 'Amazon::MWS::Client';
my $version = $opts{Version} || 0.5;
my $agent_string = "$appname/$version ($attr_str)";
die 'No access key id' unless $opts{access_key_id};
die 'No secret key' unless $opts{secret_key};
die 'No merchant id' unless $opts{merchant_id};
die 'No marketplace id' unless $opts{marketplace_id};
if ($opts{debug}) {
open LOG, ">$opts{logfile}" or die "Cannot open logfile.";
print LOG DateTime->now();
print LOG "\nNew instance created. \n";
print LOG Dumper(\%opts);
close LOG;
}
# https://github.com/interchange/Amazon-MWS/issues/9
$opts{endpoint} ||= 'https://mws.amazonaws.com';
# strip the trailing slashes
$opts{endpoint} =~ s/\/+\z//;
bless {
package => "$pkg",
agent => LWP::UserAgent->new(agent => $agent_string),
endpoint => $opts{endpoint},
access_key_id => $opts{access_key_id},
secret_key => $opts{secret_key},
merchant_id => $opts{merchant_id},
marketplace_id => $opts{marketplace_id},
debug => $opts{debug},
logfile => $opts{logfile},
}, $pkg;
}
1;
# Local Variables:
# tab-width: 8
# End:
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
unless is_Int($days);
die "$days is out of range 1-30"
unless $days > 0 && $days < 31;
});
=item shop_id
You can pass an arbitrary identifier to the constructor which will be
used to keep the database records separated if you have multiple
amazon accounts. If not provided, the merchant id will be used, which
will work, but it's harder (for the humans) to spot and debug.
=cut
has shop_id => (is => 'ro');
has _unique_shop_id => (is => 'lazy');
sub _build__unique_shop_id {
my $self = shift;
if (my $id = $self->shop_id) {
return $id;
}
else {
return $self->merchant_id;
}
}
=item debug
Print out additional information.
=item logfile
Passed to L<Amazon::MWS::Client> constructor.
=cut
has debug => (is => 'ro');
has logfile => (is => 'ro');
=item quiet
Boolean. Do not warn on timeouts and aborts (just print) if set to
true.
=cut
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
return [] unless $product_arrayref && @$product_arrayref;
my @products = @$product_arrayref;
my $existing = $self->existing_products;
my @todo;
foreach my $product (@products) {
my $sku = $product->sku;
if (my $exists = $existing->{$sku}) {
# mark the item as visited
$exists->{_examined} = 1;
}
print "Checking $sku\n" if $self->debug;
next unless $self->product_needs_upload($product->sku, $product->timestamp_string);
print "Scheduling product " . $product->sku . " for upload\n";
if (my $limit = $self->limit_inventory) {
my $real = $product->inventory;
if ($real > $limit) {
print "Limiting the $sku inventory from $real to $limit\n" if $self->debug;
$product->inventory($limit);
}
}
if (my $children = $product->children) {
my @good_children;
foreach my $child (@$children) {
# skip failed children, but if the current status of
# parent is failed, and we reached this point, retry.
if (! exists $self->_force_hashref->{$child} and
$existing->{$child} and
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
=cut
has client => (is => 'lazy');
sub _build_client {
my $self = shift;
my %mws_args = map { $_ => $self->$_ } (qw/merchant_id
marketplace_id
access_key_id
secret_key
debug
logfile
endpoint/);
return Amazon::MWS::Client->new(%mws_args);
}
has _mismatch_patterns => (is => 'lazy', isa => HashRef);
sub _build__mismatch_patterns {
my $self = shift;
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
=head2 product_needs_upload($sku, $timestamp)
Lookup the product $sku with timestamp $timestamp and return the sku
if the product needs to be uploaded or can be safely skipped. This
method is stateless and doesn't alter anything.
=cut
sub product_needs_upload {
my ($self, $sku, $timestamp) = @_;
my $debug = $self->debug;
return unless $sku;
my $forced = $self->_force_hashref;
# if it's forced, we have nothing to check, just pass it.
if ($forced->{$sku}) {
print "Forcing $sku as requested\n" if $debug;
return $sku;
}
$timestamp ||= 0;
my $existing = $self->existing_products;
if (exists $existing->{$sku}) {
if (my $exists = $existing->{$sku}) {
my $status = $exists->{status} || '';
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
if ($self->reset_all_errors) {
return $sku;
}
elsif (my $reset = $self->_reset_error_structure) {
# option for this error was passed.
my $error = $exists->{error_code};
my $match = $reset->{codes}->{$error};
if (($match && $reset->{negate}) or
(!$match && !$reset->{negate})) {
# was passed !this error or !random , so do not reset
print "Skipping failed item $sku with error code $error\n" if $debug;
return;
}
else {
# otherwise reset
print "Resetting error for $sku with error code $error\n" if $debug;
return $sku;
}
}
else {
print "Skipping failed item $sku\n" if $debug;
return;
}
}
elsif ($status eq 'pending') {
print "Skipping pending item $sku\n" if $debug;
return;
}
die "I shouldn't have reached this point with status <$status>";
}
}
print "$sku wasn't uploaded so far, scheduling it\n" if $debug;
return $sku;
}
=head2 orders_in_shipping_job($job_id)
Lookup the C<amazon_mws_orders> table and return a list of
C<amazon_order_id> for the given shipping confirmation job. INTERNAL.
=cut
lib/Amazon/MWS/XML/Feed.pm view on Meta::CPAN
Relationship => 'as_variants_hash',
);
my $method = $methods{$operation} or die "$operation is not supported";
my @messages;
my $message_counter = 1;
my @products = @{ $self->products };
for (my $i = 0; $i < @products; $i++) {
my $data = $products[$i]->$method;
print Dumper($data) if $self->debug;
# unclear if it's the right thing to do
if (ref($data) eq 'ARRAY') {
foreach my $msg (@$data) {
push @messages, {
MessageID => $message_counter++,
OperationType => 'Update',
$operation => $msg,
};
}
}
lib/Amazon/MWS/XML/GenericFeed.pm view on Meta::CPAN
The L<XML::Compile::Schema> writer object. You can pass this to build
this object manually (usually it's the Uploader who builds the writer).
my $writer = XML::Compile::Schema->new([glob '*.xsd'])
->compile(WRITER => 'AmazonEnvelope');
=head2 merchant_id
Required. The merchant id provided by Amazon.
=head2 debug
Whether to enable debugging or not.
=cut
has xml_writer => (is => 'ro', required => 1);
has debug => (is => 'rw');
has merchant_id => (is => 'ro',
required => 1,
isa => sub {
die "the merchant id must be a string" unless $_[0];
});
=head1 METHODS
=head2 create_feed($operation, \@messages, %options)
lib/Amazon/MWS/amazon.xml view on Meta::CPAN
<amazon>
<access_key_id>ACCESS KET HERE</access_key_id>
<secret_key>SECRET KEY HERE</secret_key>
<merchant_id>MERCHANT ID HERE</merchant_id>
<marketplace_id>HOME MARKETPLACE HERE</marketplace_id>
<endpoint>ENDPOINT HERE </endpoint>
<debug>0</debug>
<logfile>LOG FILE PATH HERE</logfile>
</amazon>
t/product-filtering.t view on Meta::CPAN
my %constructor = (
merchant_id => '__MERCHANT_ID__',
access_key_id => '12341234',
secret_key => '123412341234',
marketplace_id => '123412341234',
endpoint => 'https://mws-eu.amazonservices.com',
feed_dir => 't/feeds',
schema_dir => 'schemas',
existing_products => $existing_products,
products => \@products,
debug => 1,
);
my $uploader = Amazon::MWS::Uploader->new(%constructor);
ok($uploader, "object created");
is_deeply ($uploader->existing_products, $existing_products,
"lazy attribute passed at constructor");
ok(scalar(@{ $uploader->products_to_upload }), "Found the product to upload");