[open-ils-commits] r15891 - in trunk/Open-ILS/src: perlmods/OpenILS/Utils support-scripts (erickson)

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Mar 17 20:04:03 EDT 2010


Author: erickson
Date: 2010-03-17 20:04:02 -0400 (Wed, 17 Mar 2010)
New Revision: 15891

Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm
   trunk/Open-ILS/src/support-scripts/marc_stream_importer.pl
Log:
Make GetOpts::Long and Cronscript get along

So the old Cronscript approach was to have variables declared with
the default values assigned and pass a hash of keys => var_ref, where
the var_ref's pointed to the variables.  This didn't work because of
Cronscript trying to build the clean hashes and incorporate structure
into the object.

So instead now we rely on the MyGetOptions return
value (hashref or hash), essentially the opts_clean hash.  And we
populate the local variables afterwards.  The default values are passed
in the hash now.  This works.

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm	2010-03-18 00:04:01 UTC (rev 15890)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm	2010-03-18 00:04:02 UTC (rev 15891)
@@ -24,7 +24,7 @@
 use strict;
 use warnings;
 
-use Getopt::Long;
+use Getopt::Long qw(:DEFAULT GetOptionsFromArray);
 use OpenSRF::System;
 use OpenSRF::AppSession;
 use OpenSRF::Utils::JSON;
@@ -94,32 +94,54 @@
 #  (2) provides hashspace for the rest of the arbitrary options from the command-line
 #
 # TODO: allow more options to be passed here, maybe mimic Getopt::Long::GetOptions style
+#
+# If an arrayref argument is passed, then @ARGV will NOT be touched.
+# Instead, the array will be passed to GetOptionsFromArray.
+#
 
 sub MyGetOptions {
     my $self = shift;
+    my $arrayref = @_ ? shift : undef;
+    if ($arrayref and ref($arrayref) ne 'ARRAY') {
+        carp "MyGetOptions argument is not an array ref.  Expect GetOptionsFromArray to explode";
+    }
     $self->{got_options} and carp "MyGetOptions called after options were already retrieved previously";
     my @keys = sort {is_clean($b) <=> is_clean($a)} keys %{$self->{default_opts}};
     $debug and print "KEYS: ", join(", ", @keys), "\n";
     foreach (@keys) {
         my $clean = clean($_);
-        $self->{opts_clean}->{$clean} = $self->{default_opts_clean}->{$clean};  # prepopulate default
-        $self->{opts}->{$_} = \$self->{opts_clean}->{$clean};                   # pointer for GetOptions
+        my $place = $self->{default_opts_clean}->{$clean};
+        $self->{opts_clean}->{$clean} = $place;  # prepopulate default
+        # $self->{opts}->{$_} = $self->{opts_clean}->{$clean};                 # pointer for GetOptions
+        $self->{opts}->{$_} = sub {
+            my $opt = shift;
+            my $val = shift;
+            ref ( $self->{opts_clean}->{$opt} ) and ref($self->{opts_clean}->{$opt}) eq 'SCALAR'
+            and ${$self->{opts_clean}->{$opt}} = $val;  # set the referent's value
+            $self->{opts_clean}->{$opt} = $val;     # burn the map, stick the value there
+        };                 # pointer for GetOptions
     }
-    GetOptions($self->{opts}, @keys);
+    $arrayref  ? GetOptionsFromArray($arrayref, $self->{opts}, @keys)
+               : GetOptions(                    $self->{opts}, @keys) ;
+   
     foreach (@keys) {
         delete $self->{opts}->{$_};     # now remove the mappings from (1) so we just have (2)
     }
     $self->clean_mirror('opts');        # populate clean_opts w/ cleaned versions of (2), plus everything else
 
     print $self->help() and exit if $self->{opts_clean}->{help};
+    $self->new_lockfile();
+    $self->{got_options}++;
+    return wantarray ? %{$self->{opts_clean}} : $self->{opts_clean};
+}
+
+sub new_lockfile {
+    my $self = shift;
     $debug and $OpenILS::Utils::Lockfile::debug = $debug;
-
     unless ($self->{opts_clean}->{nolockfile} || $self->{default_opts_clean}->{nolockfile}) {
         $self->{lockfile_obj} = OpenILS::Utils::Lockfile->new($self->first_defined('lock-file'));
         $self->{lockfile}     = $self->{lockfile_obj}->filename;
     }
-    $self->{got_options}++;
-    return $self;
 }
 
 sub first_defined {
@@ -155,6 +177,11 @@
     my $val  = shift;
     my $clean = clean($key);
     my @others = grep {/$clean/ and $_ ne $key} keys %{$self->{default_opts}};
+    unless (@others) {
+        $debug and print "unique key $key => $val\n";
+        $self->{default_opts}->{$key} = $val;   # no purge, just add
+        return;
+    }
     foreach (@others) {
         $debug and print "variant of $key => $_\n";
         if ($key ne $clean) {    # if it is a dirtier key, delete the clean one
@@ -172,6 +199,7 @@
 # TODO: check $opts is hashref; then check verbose/debug first.  maybe check negations e.g. "no-verbose" ?
     @extra_opts = keys %$opts;
     foreach (@extra_opts) {        # add any other keys w/ default values
+        $debug and print "init() adding option $_, default value: $opts->{$_}\n";
         $self->add_and_purge($_, $opts->{$_});
     }
     $self->clean_mirror;
@@ -179,7 +207,7 @@
 }
 
 sub usage {
-    my $self = shift;
+    # my $self = shift;
     return "\nUSAGE: $0 [OPTIONS]";
 }
 

Modified: trunk/Open-ILS/src/support-scripts/marc_stream_importer.pl
===================================================================
--- trunk/Open-ILS/src/support-scripts/marc_stream_importer.pl	2010-03-18 00:04:01 UTC (rev 15890)
+++ trunk/Open-ILS/src/support-scripts/marc_stream_importer.pl	2010-03-18 00:04:02 UTC (rev 15891)
@@ -12,63 +12,7 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-=head1 NAME
 
-marc_stream_importer.pl - Import MARC records via bare socket connection.
-
-=head1 SYNOPSIS
-
-./marc_stream_importer.pl /openils/conf/opensrf_core.xml \
-    <eg_username> <eg_password> <bib_source> --port <port> --min_servers 2 \
-    --max_servers 20 --log_file /openils/var/log/marc_net_importer.log &
-
-Note: this script has to be run in the same directory as oils_header.pl
-
-=head1 DESCRIPTION
-
-This script is a Net::Server::PreFork instance for shoving records into Evergreen from a remote system.
-
-=head2 Configuration
-
-=head3 OCLC Connexion
-
-To use this script with OCLC Connexion, configure the client as follows:
-
-Under Tools -> Options -> Export (tab)
-   Create -> Choose Connection -> OK -> Leave translation at "None" 
-       -> Create -> Create -> choose TCP/IP (internet) 
-       -> Enter hostname and Port, leave 'Use Telnet Protocol' checked 
-       -> Create/OK your way out of the dialogs
-   Record Characteristics (button) -> Choose 'UTF-8 Unicode' for the Character Set
-   
-
-OCLC and Connexion are trademark/service marks of OCLC Online Computer Library Center, Inc.
-
-=head1 CAVEATS
-
-WARNING: This script provides no inherent security layer.  Any client that has 
-access to the server+port can inject MARC records into the system.  
-Use the available options (like allow/deny) in the Net::Server config file 
-or via the command line to restrict access as necessary.
-
-=head1 EXAMPLES
-
-./marc_stream_importer.pl /openils/conf/opensrf_core.xml \
-    admin open-ils connexion --port 5555 --min_servers 2 \
-    --max_servers 20 --log_file /openils/var/log/marc_net_importer.log &
-
-=head1 SEE ALSO
-
-L<Net::Server::PreFork>, L<marc_stream_importer.conf>
-
-=head1 AUTHORS
-
-    Bill Erickson <erickson at esilibrary.com>
-    Joe Atzberger <jatzberger at esilibrary.com>
-
-
-=cut
-
 use strict; use warnings;
 use Net::Server::PreFork;
 use base qw/Net::Server::PreFork/;
@@ -76,31 +20,87 @@
 use MARC::Batch;
 use MARC::File::XML;
 use MARC::File::USMARC;
+
+use Data::Dumper;
 use File::Basename qw/fileparse/;
-use Getopt::Long;
+use Getopt::Long qw(:DEFAULT GetOptionsFromArray);
+use Pod::Usage;
 
 use OpenSRF::Utils::Logger qw/$logger/;
 use OpenILS::Utils::Cronscript;
 require 'oils_header.pl';
 use vars qw/$apputils/;
 
-# DEFAULTS
-my $bufsize       = 4096;
+my $debug = 0;
+
+my %defaults = (
+    'buffsize=i'    => 4096,
+    'source=s'      => 1,
+    'osrf-config=s' => '/openils/conf/opensrf_core.xml',
+    'user=s'        => 'admin',
+    'password=s'    => '',
+    'nolockfile'    => 1,
+);
+
+$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;
+}
+
+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);
+# GetOptionsFromArray(\@script_args, \%defaults, %defaults); # similar to
+
+my $bufsize       = $real_opts->{buffsize};
+my $bib_source    = $real_opts->{source};
+my $osrf_config   = $real_opts->{'osrf-config'};
+my $oils_username = $real_opts->{user};
+my $oils_password = $real_opts->{password};
+my $help          = $real_opts->{help};
+   $debug        += $real_opts->{debug};
+
+foreach (keys %$real_opts) {
+    print("real_opt->{$_} = ", $real_opts->{$_}, "\n") if $real_opts->{debug} or $debug;
+}
 my $wait_time     = 5;
-my $bib_source    = 'connexion';
-my $osrf_config   = '/openils/conf/opensrf_core.xml';
-my $oils_username = 'admin';
+my $authtoken     = '';
 
 # DEFAULTS for Net::Server
 my $filename   = fileparse($0, '.pl');
 my $conf_file  = (-r "$filename.conf") ? "$filename.conf" : undef;
 # $conf_file is the Net::Server config for THIS script (not EG), if it exists and is readable
 
-# $script->session('open-ils.cat') or die "No session created";
 
-my $oils_password = shift;
-my $authtoken;
+pod2usage(1) if $help;
+unless ($oils_password) {
+    print STDERR "\nERROR: password option required for session login\n\n";
+    # pod2usage(1);
+}
 
+print Dumper($o) if $debug;
+
+if ($debug) {
+    foreach my $ref (qw/bufsize bib_source osrf_config oils_username oils_password help conf_file debug/) {
+        no strict 'refs';
+        printf "%16s => %s\n", $ref, (eval("\$$ref") || '');
+    }
+}
+
 sub warning {
     return <<WARNING;
 
@@ -111,8 +111,9 @@
 }
 
 print warning();
-# $0 = 'Evergreen MARC Stream Listener';
+print Dumper($real_opts);
 
+
 sub xml_import {
     return $apputils->simplereq(
         'open-ils.cat', 
@@ -157,7 +158,7 @@
     return $index;
 }
 
-sub process_request {
+sub process_request {   # The core Net::Server method
     my $self = shift;
     my $socket = $self->{server}->{client};
     my $data = '';
@@ -183,11 +184,79 @@
 # When that happens, get a new one.
 sub new_auth_token {
     $authtoken = oils_login($oils_username, $oils_password, 'staff') 
-        or die "Unable to login to Evergreen";
+        or die "Unable to login to Evergreen as user $oils_username";
     return $authtoken;
 }
 
+##### MAIN ######
+
 osrf_connect($osrf_config);
 new_auth_token();
-__PACKAGE__->run();
+print "Calling Net::Server run ", (@ARGV ? "with options: " . join(' ', @ARGV) : ''), "\n";
+__PACKAGE__->run(conf_file => $conf_file);
 
+__END__
+
+=head1 NAME
+
+marc_stream_importer.pl - Import MARC records via bare socket connection.
+
+=head1 SYNOPSIS
+
+ ./marc_stream_importer.pl /openils/conf/opensrf_core.xml
+    --user=<eg_username>                       \
+    --pass=<eg_password> --source=<bib_source> \
+    -- --port=<port> --min_servers=2           \
+       --max_servers=20 --log_file=/openils/var/log/marc_net_importer.log &
+
+Note the extra -- to separate options for the script wrapper from options for the
+underlying Net::Server instance.  
+
+Note: this script has to be run in the same directory as oils_header.pl
+
+Run perldoc marc_stream_importer.pl for more documentation.
+
+=head1 DESCRIPTION
+
+This script is a Net::Server::PreFork instance for shoving records into Evergreen from a remote system.
+
+=head2 Configuration
+
+=head3 OCLC Connexion
+
+To use this script with OCLC Connexion, configure the client as follows:
+
+Under Tools -> Options -> Export (tab)
+   Create -> Choose Connection -> OK -> Leave translation at "None" 
+       -> Create -> Create -> choose TCP/IP (internet) 
+       -> Enter hostname and Port, leave 'Use Telnet Protocol' checked 
+       -> Create/OK your way out of the dialogs
+   Record Characteristics (button) -> Choose 'UTF-8 Unicode' for the Character Set
+   
+
+OCLC and Connexion are trademark/service marks of OCLC Online Computer Library Center, Inc.
+
+=head1 CAVEATS
+
+WARNING: This script provides no inherent security layer.  Any client that has 
+access to the server+port can inject MARC records into the system.  
+Use the available options (like allow/deny) in the Net::Server config file 
+or via the command line to restrict access as necessary.
+
+=head1 EXAMPLES
+
+./marc_stream_importer.pl /openils/conf/opensrf_core.xml \
+    admin open-ils connexion --port 5555 --min_servers 2 \
+    --max_servers 20 --log_file /openils/var/log/marc_net_importer.log &
+
+=head1 SEE ALSO
+
+L<Net::Server::PreFork>, L<marc_stream_importer.conf>
+
+=head1 AUTHORS
+
+    Bill Erickson <erickson at esilibrary.com>
+    Joe Atzberger <jatzberger at esilibrary.com>
+
+
+=cut



More information about the open-ils-commits mailing list