batch of scripts for handling the processing of offline content
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 22 Mar 2006 23:22:29 +0000 (23:22 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 22 Mar 2006 23:22:29 +0000 (23:22 +0000)
so far, they just handle the loading and unloading of scripts
and making sure they are in the right place, etc.

git-svn-id: svn://svn.open-ils.org/ILS/trunk@3412 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/offline/offline-config.pl [new file with mode: 0755]
Open-ILS/src/offline/offline-execute.pl [new file with mode: 0755]
Open-ILS/src/offline/offline-lib.pl [new file with mode: 0755]
Open-ILS/src/offline/offline-upload.pl [new file with mode: 0755]

diff --git a/Open-ILS/src/offline/offline-config.pl b/Open-ILS/src/offline/offline-config.pl
new file mode 100755 (executable)
index 0000000..674583e
--- /dev/null
@@ -0,0 +1,2 @@
+$main::config{base_dir} = '/openils/var/data/offline/';
+$main::config{bootstrap} = '/openils/conf/bootstrap.conf';
diff --git a/Open-ILS/src/offline/offline-execute.pl b/Open-ILS/src/offline/offline-execute.pl
new file mode 100755 (executable)
index 0000000..93ba225
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+use strict; use warnings;
+
+# --------------------------------------------------------------------
+# Loads the offline script files for a given org, sorts and runs the 
+# scripts, and returns the exception list
+# --------------------------------------------------------------------
+
+our $U;
+our %config;
+our $cgi;
+our $base_dir;
+our $logger;
+my @data;
+require 'offline-lib.pl';
+
+my $org        = $cgi->param('org');
+my $resp = &process_data( &sort_data( &collect_data() ) );
+&archive_files();
+handle_success("Scripts for org $org processed successfully <br/>" . JSON->perl2JSON($resp) );
+
+
+
+# --------------------------------------------------------------------
+# Collects all of the script logs into an in-memory structure that
+# can be sorted, etc.
+# --------------------------------------------------------------------
+sub collect_data {
+
+       handle_error("Org is not defined") unless $org;
+       my $dir = get_pending_dir($org);
+       handle_error("Batch from org $org is already in process") if (-e "$dir/lock");
+
+       # Lock the pending directory
+       system(("touch",  "$dir/lock")) == 0 or handle_error("Unable to create lock file");
+
+       # Load the data from the files
+       my $file;
+       my @data;
+
+       while( ($file = <$dir/*.log>) ) {
+               $logger->debug("offline: Loading script file $file");
+               open(F, $file) or handle_error("Unable to open script file $file");
+               push(@data, <F>);
+       }
+
+       return \@data;
+}
+
+
+# --------------------------------------------------------------------
+# Sorts the commands
+# --------------------------------------------------------------------
+sub sort_data {
+       my $data = shift;
+       $logger->debug("offline: Sorting data");
+       return $data;
+}
+
+
+# --------------------------------------------------------------------
+# Runs the commands and returns the list of errors
+# --------------------------------------------------------------------
+sub process_data {
+       my $data = shift;
+       my $resp = [];
+       for my $d (@$data) {
+               $logger->activity("offline: Executing command $d");
+       }
+       return $resp;
+}
+
+# --------------------------------------------------------------------
+# Moves the script files from the pending directory to the archive dir
+# --------------------------------------------------------------------
+sub archive_files {
+       my $archivedir = create_archive_dir($org);
+       my $pendingdir = get_pending_dir($org);
+       my $err = "Error moving offline logs from $pendingdir to $archivedir";
+       my @files = <$pendingdir/*.log>;
+
+       system( ("rm", "$pendingdir/lock") ) == 0 or handle_error($err);
+       system( ("mv", "@files", "$archivedir") ) == 0 or handle_error($err);
+       system( ("rmdir", "$pendingdir") ) == 0 or handle_error($err);
+       $logger->debug("offline: Archiving files to $archivedir");
+}
+
+
diff --git a/Open-ILS/src/offline/offline-lib.pl b/Open-ILS/src/offline/offline-lib.pl
new file mode 100755 (executable)
index 0000000..78b617f
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+use strict; use warnings;
+use CGI;
+use OpenSRF::System;
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Application::AppUtils;
+use JSON;
+
+
+our $U = "OpenILS::Application::AppUtils";
+our %config;
+#do '##CONFIG##/upload-server.pl';
+do 'offline-config.pl';
+our $cgi = new CGI;
+our $base_dir = $config{base_dir};
+my $bsconfig = $config{bootstrap};
+
+
+# --------------------------------------------------------------------
+# Connect to OpenSRF
+# --------------------------------------------------------------------
+OpenSRF::System->bootstrap_client(config_file => $bsconfig);
+
+
+
+
+# --------------------------------------------------------------------
+# Prints out an error message to the client
+# --------------------------------------------------------------------
+sub handle_error {
+       my $err = shift;
+       $logger->error("offline: $err");
+       print "content-type: text/html\n\n";
+       print <<"       HTML";
+       <html>
+               <head>
+                       <title>Offline Upload Failed</title>
+               </head>
+               <body>
+                       <div style='margin-top: 50px; text-align: center;'>
+                               <b style='color:red;'>Offline Upload Failed</b><br/>
+                               <span> $err </span>
+                       </div>
+               </body>
+       </html>
+       HTML
+       exit(1);
+}
+
+
+# --------------------------------------------------------------------
+# Prints out a success message to the client
+# --------------------------------------------------------------------
+sub handle_success {
+       my $msg = shift;
+       $logger->info("offline: returned success message: $msg");
+       print "content-type: text/html\n\n";
+       print <<"       HTML";
+       <html>
+               <head>
+                       <title>Success</title>
+               </head>
+               <body>
+                       <div style='margin-top: 50px; text-align: center;'>
+                               <b style='color:blue;'> $msg </b><br/>
+                       </div>
+               </body>
+       </html>
+       HTML
+}
+
+
+
+# --------------------------------------------------------------------
+# Fetches and creates if necessary the pending directory
+# --------------------------------------------------------------------
+sub get_pending_dir {
+       my $org = shift;
+       my $dir = "$base_dir/pending/$org/";
+       system( ('mkdir', '-p', "$dir") ) == 0 
+               or handle_error("Unable to create directory $dir");
+       $logger->debug("offline: created/fetched pending directory $dir");      
+       return $dir;
+}
+
+# --------------------------------------------------------------------
+# Fetches and creates if necessary the archive directory
+# --------------------------------------------------------------------
+sub create_archive_dir {
+       my $org = shift;
+       my (undef,$min,$hour,$mday,$mon,$year) = localtime(time);
+
+       $mon++;
+       $year           += 1900;
+       $min            = "0$min"       unless $min             =~ /\d{2}/o;
+       $hour           = "0$hour"      unless $hour    =~ /\d{2}/o;
+       $mday           = "0$mday"      unless $mday    =~ /\d{2}/o;
+       $mon            = "0$mon"       unless $mon             =~ /\d{2}/o;
+
+       my $dir = "$base_dir/archive/$org/$year$mon$mday$hour$min/";
+       system( ('mkdir', '-p', "$dir") ) == 0 
+               or handle_error("Unable to create archive directory $dir");
+       $logger->debug("offline: Created archive directory $dir");
+       return $dir;
+}
+
+
+
+# --------------------------------------------------------------------
+# Fetches the workstation object by name
+# --------------------------------------------------------------------
+sub fetch_workstation {
+       my $name = shift;
+       $logger->debug("offline: Fetching workstation $name");
+       my $ws = $U->storagereq(
+               'open-ils.storage.direct.actor.workstation.search.name', $name);
+       handle_error("Workstation $name does not exists") unless $ws;
+       return $ws;
+}
+
+
diff --git a/Open-ILS/src/offline/offline-upload.pl b/Open-ILS/src/offline/offline-upload.pl
new file mode 100755 (executable)
index 0000000..f1b321b
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+use strict; use warnings;
+
+# --------------------------------------------------------------------
+#  Uploads offline action files
+#      pending files go into $base_dir/pending/<org>/<ws>.log
+#      completed transactions go into $base_dir/archive/<org>/YYYMMDDHHMM/<ws>.log
+# --------------------------------------------------------------------
+
+our $U;
+our %config;
+our $cgi;
+our $base_dir;
+our $logger;
+my $org;
+require 'offline-lib.pl';
+
+if( $cgi->param('file') ) { 
+       &load_file(); 
+       &handle_success("File Upload Succeeded<br/><br/>".
+       "<a href='offline-execute.pl?org=$org'>Execute Scripts for org $org</a>");
+} else {
+       &display_upload(); 
+}
+
+
+# --------------------------------------------------------------------
+# Use this for testing manual uploads
+# --------------------------------------------------------------------
+sub display_upload {
+
+       my $ws  = $cgi->param('ws');
+       my $ses = $cgi->param('ses');
+
+       handle_error("Missing data in upload.  We need ws and ses") 
+               unless ($ws and $ses);
+
+       print "content-type: text/html\n\n";
+       print <<"       HTML";
+       <html>
+               <head>
+                       <title>Offline Upload Server</title>
+                       <style type='text/css'>
+                               input { margin: 5px;' }
+                       </style>
+               </head>
+               <body>
+                       <div style='margin-top: 50px; text-align: center;'>
+                               <form action='offline-upload.pl' method='post' enctype='multipart/form-data'>
+                                       <b>Testing</b><br/><br/>
+                                       <b> - Select an offline file to upload - </b><br/><br/>
+                                       <input type='file' name='file'> </input>
+                                       <input type='submit' name='Submit' value='Upload'> </input>
+                                       <input type='hidden' name='ws' value='$ws'> </input>
+                                       <input type='hidden' name='ses' value='$ses'> </input>
+                               </form>
+                       </div>
+               </body>
+       </html>
+       HTML
+}
+
+
+
+sub load_file() {
+
+       my $wsname      = $cgi->param('ws');
+       my $ses         = $cgi->param('ses');
+       my $filehandle = $cgi->upload('file');
+
+       my $ws = fetch_workstation($wsname);
+       $org = $ws->owning_lib;
+       my $dir = get_pending_dir($org);
+       my $output = "$dir/$wsname.log";
+       my $lock = "$dir/lock";
+
+       handle_error("Offline batch in process for this location.  Please try again later." ) if( -e $lock );
+       handle_error("File $output already exists" ) if( -e $output );
+
+       $logger->debug("offline: Writing log file $output");
+       open(FILE, ">$output");
+       while( <$filehandle> ) { print FILE; }
+}
+
+
+
+
+