From: Bill Erickson Date: Mon, 23 Jul 2012 14:44:41 +0000 (-0400) Subject: acq order reader; getting started X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=b1b1604949f86a9e4a1ca3204c107cfce2701543;p=evergreen%2Fequinox.git acq order reader; getting started Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example index ea6f18b397..f1a4dab048 100644 --- a/Open-ILS/examples/opensrf.xml.example +++ b/Open-ILS/examples/opensrf.xml.example @@ -271,6 +271,30 @@ vim:et:ts=4:sw=4: + + + /openils/var/data/acq_orders/ + + + ALL + + + + BAB + CONS + BAB + + + + ABC + BR1 + ABC + + + + diff --git a/Open-ILS/src/support-scripts/acq_order_reader.pl b/Open-ILS/src/support-scripts/acq_order_reader.pl new file mode 100755 index 0000000000..70f93d3d3c --- /dev/null +++ b/Open-ILS/src/support-scripts/acq_order_reader.pl @@ -0,0 +1,259 @@ +#!/usr/bin/perl +# Copyright (C) 2012 Equinox Software, Inc. +# Author: Bill Erickson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +use strict; use warnings; +use MARC::Record; +use MARC::Batch; +use MARC::File::XML ( BinaryEncoding => 'UTF-8' ); +use MARC::File::USMARC; + +use Data::Dumper; +use File::Temp; +use Getopt::Long qw(:DEFAULT GetOptionsFromArray); +use Pod::Usage; + +use OpenSRF::Utils::Logger qw/$logger/; +use OpenSRF::AppSession; +use OpenSRF::EX qw/:try/; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Cache; +use OpenILS::Utils::Cronscript; +use OpenILS::Utils::CStoreEditor; +require 'oils_header.pl'; +use vars qw/$apputils/; + +my $acq_ses; +my $authtoken; + +my $debug = 0; + +my %defaults = ( + 'osrf-config=s' => '/openils/conf/opensrf_core.xml', + 'user=s' => 'admin', + 'password=s' => '', + 'nodaemon' => 0, + 'poll-interval=i' => 10 +); + +$OpenILS::Utils::Cronscript::debug=1 if $debug; +$Getopt::Long::debug=1 if $debug > 1; +my $o = OpenILS::Utils::Cronscript->new(\%defaults); + +my @script_args = (); + +if (grep {$_ eq '--'} @ARGV) { + print "Splitting options into groups\n" if $debug; + while (@ARGV) { + $_ = shift @ARGV; + $_ eq '--' and last; # stop at the first -- + push @script_args, $_; + } +} else { + @script_args = @ARGV; + @ARGV = (); +} + +print "Calling MyGetOptions ", + (@script_args ? "with options: " . join(' ', @script_args) : 'without options from command line'), + "\n" if $debug; + +my $real_opts = $o->MyGetOptions(\@script_args); +$o->bootstrap; + +my $osrf_config = $real_opts->{'osrf-config'}; +my $oils_username = $real_opts->{user}; +my $oils_password = $real_opts->{password}; +my $help = $real_opts->{help}; +my $poll_interval = $real_opts->{'poll-interval'}; + $debug += $real_opts->{debug}; + +foreach (keys %$real_opts) { + print("real_opt->{$_} = ", $real_opts->{$_}, "\n") if $real_opts->{debug} or $debug; +} + +# FEEDBACK + +pod2usage(1) if $help; +unless ($oils_password) { + print STDERR "\nERROR: password option required for session login\n\n"; +} + +print Dumper($o) if $debug; + +if ($debug) { + foreach my $ref (qw/osrf_config oils_username oils_password help debug/) { + no strict 'refs'; + printf "%16s => %s\n", $ref, (eval("\$$ref") || ''); + } +} + +print Dumper($real_opts); + +# log in +sub new_auth_token { + $authtoken = oils_login($oils_username, $oils_password, 'staff') + or die "Unable to login to Evergreen as user $oils_username"; + return $authtoken; +} + +# log out +sub clear_auth_token { + $apputils->simplereq( + 'open-ils.auth', + 'open-ils.auth.session.delete', + $authtoken + ); +} + +sub push_file_to_acq { + my $file = shift; + my $args = shift; + + print "Pushing file '$file' to provider " . $args->{provider} . "\n"; + + # Cache the file name like Vandelay does. ACQ will + # read contents of the cache and then delete them. + # The key can be any unique value. + my $key = $$ . time . rand(); + $cache->put_cache("vandelay_import_spool_$key", {path => $file}); + + my $req = $acq_ses->request( + 'open-ils.acq.process_upload_records', + $authtoken, + $key, + $args + ); + + while (my $resp = $req->recv(timeout => 600)) { + if(my $content = $resp->content) { + print Dumper($content) if $debug; + } else { + warn "Request returned no data: " . Dumper($resp) . "\n"; + } + } +} + + +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 args_from_provider_conf { + my $conf = shift; + + 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; + } + + my $provider = $editor->search_acq_provider({ + code => $pcode, + owner => $org->id + }); + + if (!$provider) { + warn "No such provider in acq_order_reader config: '$pcode'\n"; + next; + } + +} + +# ----------------------------------------------------- +# Main script +# ----------------------------------------------------- + +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'); + +print Dumper($providers) if $debug; + +$acq_ses = OpenSRF::AppSession->create('open-ils.acq'); +my $cache = OpenSRF::Utils::Cache->new; +my $editor = OpenILS::Utils::CStoreEditor->new; + +# 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(); + + # 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; + } + + # shared directory + + clear_auth_token(); + + print "Sleeping for $poll_time seconds...\n" if $debug; + sleep $poll_time; +} + +warn "Exiting main acq_order_reader loop!\n"; + + +__END__ + +=head1 NAME + +acq_order_reader.pl - Collect MARC order record files and pass them onto the ACQ service + +=head1 SYNOPSIS + +./acq_order_reader.pl [script opts ...] + +This script uses the EG common options from B. See --help output for those. + +Run C for full documentation. + +Note: this script has to be run in the same directory as B. + +Typical server-style execution will include a trailing C<&> to run in the background. + +=head1 OPTIONS + +The only required option is --password + + --password = + --user = default: admin + --nodaemon default: OFF When used with --spoolfile, turns off Net::Server mode and runs this utility in the foreground + + +=head2 Old style: --noqueue and associated options + +=head1 EXAMPLES + +./acq_order_reader.pl --user admin --password demo123 + +./acq_order_reader.pl --user admin --password demo123 -poll-interval 3 --debug --nodaemon + +=head1 AUTHORS + + Bill Erickson + Code liberally copied from marc_stream_importer.pl + +=cut