From: Bill Erickson Date: Mon, 23 Jul 2012 16:14:52 +0000 (-0400) Subject: acq order reader; continuing X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=dd97e1f35f72b725ebb9e81b8e58ace8248aaa51;p=evergreen%2Fequinox.git acq order reader; continuing Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example index f1a4dab048..05891ae2d1 100644 --- a/Open-ILS/examples/opensrf.xml.example +++ b/Open-ILS/examples/opensrf.xml.example @@ -282,16 +282,21 @@ vim:et:ts=4:sw=4: - BAB - CONS - BAB + BAB + CONS + CONS-BAB + BR1 + false + + true + + + diff --git a/Open-ILS/src/support-scripts/acq_order_reader.pl b/Open-ILS/src/support-scripts/acq_order_reader.pl index 70f93d3d3c..0a24f2bb84 100755 --- a/Open-ILS/src/support-scripts/acq_order_reader.pl +++ b/Open-ILS/src/support-scripts/acq_order_reader.pl @@ -22,6 +22,7 @@ use Data::Dumper; use File::Temp; use Getopt::Long qw(:DEFAULT GetOptionsFromArray); use Pod::Usage; +use File::Spec; use OpenSRF::Utils::Logger qw/$logger/; use OpenSRF::AppSession; @@ -30,12 +31,18 @@ use OpenSRF::Utils::SettingsClient; use OpenSRF::Utils::Cache; use OpenILS::Utils::Cronscript; use OpenILS::Utils::CStoreEditor; +use OpenILS::Utils::Fieldmapper; require 'oils_header.pl'; use vars qw/$apputils/; my $acq_ses; my $authtoken; - +my $conf; +my $cache; +my $editor; +my $base_dir; +my $share_dir; +my $providers; my $debug = 0; my %defaults = ( @@ -89,7 +96,7 @@ unless ($oils_password) { print STDERR "\nERROR: password option required for session login\n\n"; } -print Dumper($o) if $debug; +$debug and print Dumper($o); if ($debug) { foreach my $ref (qw/osrf_config oils_username oils_password help debug/) { @@ -120,7 +127,7 @@ sub push_file_to_acq { my $file = shift; my $args = shift; - print "Pushing file '$file' to provider " . $args->{provider} . "\n"; + $logger->info("acq-or: pushing file '$file' to provider " . $args->{provider}); # Cache the file name like Vandelay does. ACQ will # read contents of the cache and then delete them. @@ -128,6 +135,12 @@ sub push_file_to_acq { my $key = $$ . time . rand(); $cache->put_cache("vandelay_import_spool_$key", {path => $file}); + # some arguments are not optional + $args->{create_po} = 1; + + # don't send our internal args to the service + my $local = delete $args->{_local}; + my $req = $acq_ses->request( 'open-ils.acq.process_upload_records', $authtoken, @@ -137,38 +150,121 @@ sub push_file_to_acq { while (my $resp = $req->recv(timeout => 600)) { if(my $content = $resp->content) { - print Dumper($content) if $debug; + $debug and print Dumper($content); } else { warn "Request returned no data: " . Dumper($resp) . "\n"; } } -} + # TODO: delete tmp queue? +} -open-ils.acq open-ils.acq.process_upload_records "ce5ab1499cf019c0b52bf9eab87335fc", "f15791c2bcea4296c0d2c955c5204125", {"picklist":null,"provider":"1","ordering_agency":"4","create_po":false,"activate_po":"on","vandelay":{"import_no_match":"on","auto_overlay_exact":"on","auto_overlay_1match":false,"auto_overlay_best_match":false,"match_quality_ratio":"0.0","queue_name":"acq.bt.2","create_assets":false,"match_set":"","bib_source":"","merge_profile":"1","fall_through_merge_profile":"","existing_queue":""}} +sub org_from_sn { + my $sn = shift; + my $org = $editor->search_actor_org_unit({shortname => $sn})->[0]; + if (!$org) { + warn "No such org unit in acq_order_reader config: '$sn'\n"; + return undef; + } + return $org; +} sub args_from_provider_conf { my $conf = shift; + my %args; my $pcode = $conf->{code}; my $orgsn = $conf->{owner}; - my $org = $editor->search_actor_org_unit(shortname => $orgsn)->[0]; - if (!$org) { - warn "No such org unit in acq_order_reader config: '$orgsn'\n"; - next; - } + $debug and print "Extracting request args for provider $pcode at $orgsn\n"; + + my $org = org_from_sn($conf->{owner}) or return undef; my $provider = $editor->search_acq_provider({ code => $pcode, owner => $org->id - }); + })->[0]; if (!$provider) { warn "No such provider in acq_order_reader config: '$pcode'\n"; - next; + return undef; + } + + my $oa = org_from_sn($conf->{ordering_agency}) or return undef; + + $args{provider} = $provider->id; + $args{ordering_agency} = $oa->id; + $args{activate_po} = ($conf->{activate_po} || '') =~ /true/i; + + # vandelay import options + my $vconf = $conf->{vandelay} || {}; + $args{vandelay} = {}; + + # value options + for my $opt ( + qw/ + match_quality_ratio + match_set + bib_source + merge_profile / ) { + + $args{vandelay}->{$opt} = $vconf->{$opt} } + # boolean options + for my $opt ( + qw/ + create_assets + import_no_match + auto_overlay_exact + auto_overlay_1match + auto_overlay_best_match/ ) { + + $args{vandelay}->{$opt} = 1 if ($vconf->{$opt} || '') =~ /true/i; + } + + if ($vconf->{queue}) { + $args{vandelay}->{queue_name} = $vconf->{queue}; + $args{vandelay}->{existing_queue} = $vconf->{queue}; + + } else { + + # create a temporary queue + $args{vandelay}->{queue_name} = sprintf("acq-order-reader-%s-%s-%s", + $org->shortname, $provider->code, $apputils->epoch2ISO8601(time)); + } + + $args{_local} = { + provider_code => $pcode, # good for debugging + dirname => File::Spec->catfile($base_dir, $conf->{subdir}) + }; + + return \%args; +} + +# returns the list of new order record files that +# need to be processed for this vendor +sub check_provider_files { + my $args = shift; + my $dirname = $args->{_local}->{dirname}; + my $dh; + my @files; + + $debug and print "Searching for new files at $dirname\n"; + + if ( !opendir($dh, $dirname) ) { + warn "Couldn't open dir '$dirname': $!"; + return @files; + } + + @files = readdir $dh; + # ignore '.', '..', and hidden files + @files = grep {$_ !~ /^\./} @files; + + $logger->info("acq-or: found " . scalar(@files) . " ACQ order files at $dirname"); + + # return the file names w/ full path + return map {File::Spec->catfile($dirname, $_)} @files; } # ----------------------------------------------------- @@ -177,40 +273,51 @@ sub args_from_provider_conf { osrf_connect($osrf_config); -my $conf = OpenSRF::Utils::SettingsClient->new; -my $base_dir = $conf->config_value(acq_order_reader => 'base_dir'); -my $share_dir = $conf->config_value(acq_order_reader => 'shared_subdir'); -my $providers = $conf->config_value(acq_order_reader => 'provider'); +$conf = OpenSRF::Utils::SettingsClient->new; +$cache = OpenSRF::Utils::Cache->new; +$editor = OpenILS::Utils::CStoreEditor->new; +$acq_ses = OpenSRF::AppSession->create('open-ils.acq'); -print Dumper($providers) if $debug; +my $user = $editor->search_actor_user({usrname => $oils_username})->[0]; +if (!$user) { + warn "Invalid user: $oils_username\n"; + exit; +} -$acq_ses = OpenSRF::AppSession->create('open-ils.acq'); -my $cache = OpenSRF::Utils::Cache->new; -my $editor = OpenILS::Utils::CStoreEditor->new; +# read configs +$base_dir = $conf->config_value(acq_order_reader => 'base_dir'); +$share_dir = $conf->config_value(acq_order_reader => 'shared_subdir'); +$providers = $conf->config_value(acq_order_reader => 'provider'); +$providers = [$providers] unless ref $providers eq 'ARRAY'; +$debug and print Dumper($providers); + +# ----------------------------------------------------- # main loop # for each provider directory, plus the shared directory, check # to see if there are any files pending. For any files found, push # them up to the ACQ service, then delete the file - while (1) { - new_auth_token(); + my $processed = 0; # explicit providers for my $provider_conf (@$providers) { my $args = args_from_provider_conf($provider_conf) or next; my @files = check_provider_files($args); - push_file_to_acq($_, $args) @files; + push_file_to_acq($_, $args) for @files; + $processed += scalar(@files); } # shared directory + # TODO clear_auth_token(); - print "Sleeping for $poll_time seconds...\n" if $debug; - sleep $poll_time; + $logger->info("acq-or: loop processed $processed files"); + $debug and print "Sleeping for $poll_interval seconds...\n"; + sleep $poll_interval; } warn "Exiting main acq_order_reader loop!\n";