2 use strict; use warnings;
5 use OpenSRF::Utils::Logger qw/$logger/;
6 use OpenILS::Application::AppUtils;
8 use OpenSRF::EX qw/:try/;
11 use OpenILS::Utils::Fieldmapper;
12 use Digest::MD5 qw/md5_hex/;
13 use OpenSRF::Utils qw/:daemon/;
14 our $U = "OpenILS::Application::AppUtils";
18 # --------------------------------------------------------------------
19 # Load the config options
20 # --------------------------------------------------------------------
31 # --------------------------------------------------------------------
32 # Define accessors for all of the shared vars
33 # --------------------------------------------------------------------
34 sub offline_requestor { return $requestor; }
35 sub offline_authtoken { return $authtoken; }
36 sub offline_workstation { return $workstation; }
37 sub offline_org { return $org; }
38 sub offline_org_unit { return $org_unit;}
39 sub offline_meta_file { return &offline_pending_dir . '/meta'; }
40 sub offline_lock_file { return &offline_pending_dir . '/lock'; }
41 sub offline_result_file { return &offline_pending_dir . '/results'; }
42 sub offline_archive_meta_file { return &offline_archive_dir . '/meta'; }
43 sub offline_archive_result_file { return &offline_archive_dir . '/results'; }
44 sub offline_base_dir { return $base_dir; }
45 sub offline_time_delta { return $time_delta; }
46 sub offline_config { return %config; }
47 sub offline_cgi { return $cgi; }
48 sub offline_seskey { return $seskey; }
49 sub offline_base_pending_dir { return $base_dir .'/pending/'; }
50 sub offline_base_archive_dir { return $base_dir .'/archive/'; }
54 # --------------------------------------------------------------------
56 # --------------------------------------------------------------------
57 #do '##CONFIG##/upload-server.pl';
58 do 'offline-config.pl';
61 # --------------------------------------------------------------------
63 # --------------------------------------------------------------------
71 # --------------------------------------------------------------------
72 # Loads the necessary CGI params, connects to OpenSRF, and verifies
74 # --------------------------------------------------------------------
77 $base_dir = $config{base_dir};
78 my $bsconfig = $config{bootstrap};
81 # --------------------------------------------------------------------
83 # --------------------------------------------------------------------
84 OpenSRF::System->bootstrap_client(config_file => $bsconfig);
87 # --------------------------------------------------------------------
88 # Load the required CGI params
89 # --------------------------------------------------------------------
92 $authtoken = $cgi->param('ses')
93 or handle_event(OpenILS::Event->new('NO_SESSION'));
95 $org = $cgi->param('org') || "";
97 if(my $ws = $cgi->param('ws')) {
98 $workstation = fetch_workstation($ws);
99 $org = $workstation->owning_lib if $workstation;
104 ($org_unit, $evt) = $U->fetch_org_unit($org);
105 handle_event($evt) if $evt;
108 ($requestor, $evt) = $U->checkses($authtoken);
109 handle_event($evt) if $evt;
111 $time_delta = $cgi->param('delta') || "0";
113 $seskey = $cgi->param('seskey') || time . "_$$";
115 if( $cgi->param('createses') ) {
116 if( -e &offline_pending_dir || -e &offline_archive_dir ) {
117 &handle_event(OpenILS::Event->new('OFFLINE_SESSION_EXISTS'));
119 handle_event(OpenILS::Event->new('OFFLINE_INVALID_SESSION')) unless $seskey =~ /^\w+$/;
120 &offline_pending_dir(1);
125 # --------------------------------------------------------------------
126 # Print out a full HTML page and exits
127 # --------------------------------------------------------------------
131 my $body = $args{body} || "";
132 my $res = $args{result} || "";
133 my $on = ($org_unit) ? $org_unit->name : "";
139 my $html = <<" HTML";
142 <script src='/opac/common/js/JSON.js'> </script>
144 function offline_complete(obj) {
147 xulG.handle_event(obj);
155 div { margin: 10px; text-align: center; }
158 <body onload='offline_complete($res);'>
160 <div style='margin: 5px;'><b>$on</b></div>
161 <a href='offline-upload.pl?ses=$authtoken&org=$org'>Upload More Files</a>
162 <a href='offline-status.pl?ses=$authtoken&org=$org&seskey=$seskey'>Status Page</a>
163 <a href='offline-execute.pl?ses=$authtoken&org=$org&seskey=$seskey'>Execute Batch</a>
171 if( &offline_cgi->param('raw') ) {
172 print "content-type: text/plain\n\n";
176 print "content-type: text/html\n\n";
184 # --------------------------------------------------------------------
185 # Prints the JSON form of the event out to the client
186 # --------------------------------------------------------------------
187 sub handle_event { &offline_handle_json(@_); }
189 sub offline_handle_json {
193 print_html(result => JSON->perl2JSON($obj)) unless $ischild;
194 append_result($obj) and exit;
199 sub handle_error { warn shift() . "\n"; }
202 # --------------------------------------------------------------------
203 # Fetches (and creates if necessary) the pending directory
204 # --------------------------------------------------------------------
205 sub offline_pending_dir {
207 my $dir = "$base_dir/pending/$org/$seskey/";
209 if( $create and ! -e $dir ) {
210 $logger->debug("offline: creating pending directory $dir");
211 qx/mkdir -p $dir/ and handle_error("Unable to create directory $dir");
218 my (undef,undef, undef, $mday,$mon,$year) = localtime(time);
219 $mon++; $year += 1900;
220 $mday = "0$mday" unless $mday =~ /\d{2}/o;
221 $mon = "0$mon" unless $mon =~ /\d{2}/o;
222 return ($year, $mon, $mday);
225 # --------------------------------------------------------------------
226 # Fetches and creates if necessary the archive directory
227 # --------------------------------------------------------------------
228 sub offline_archive_dir { return create_archive_dir(@_); }
229 sub create_archive_dir {
231 my( $year, $mon, $mday) = &_offline_date;
232 my $dir = "$base_dir/archive/$org/${year}_${mon}_${mday}/$seskey/";
234 if( $create and ! -e $dir ) {
235 $logger->debug("offline: creating archive directory $dir");
236 qx/mkdir -p $dir/ and handle_error("Unable to create archive directory $dir");
243 # --------------------------------------------------------------------
244 # Fetches the workstation object by name
245 # --------------------------------------------------------------------
246 sub fetch_workstation {
248 $logger->debug("offline: Fetching workstation $name");
249 my $ws = $U->storagereq(
250 'open-ils.storage.direct.actor.workstation.search.name', $name);
251 handle_event(OpenILS::Event->new('WORKSTATION_NOT_FOUND')) unless $ws;
256 # --------------------------------------------------------------------
257 # Read/Write to/from the essential files
258 # --------------------------------------------------------------------
259 sub append_meta { &_offline_file_append_perl( shift(), &offline_meta_file ); }
260 sub append_result { &_offline_file_append_perl( shift(), &offline_result_file ); }
261 sub _offline_file_append_perl {
262 my( $obj, $file ) = @_;
264 $obj = JSON->perl2JSON($obj);
265 open(F, ">>$file") or die
266 "Unable to append data to file: $file [$! $@]\n";
272 sub offline_read_meta { return &_offline_read_meta(&offline_meta_file); }
273 sub offline_read_archive_meta { return &_offline_read_meta(&offline_archive_meta_file); }
274 sub _offline_read_meta { return &_offline_file_to_perl(shift(), 'workstation'); }
275 sub offline_read_archive_results { return &_offline_read_results(&offline_archive_result_file); }
276 sub offline_read_results { return &_offline_read_results(&offline_result_file); }
277 sub _offline_read_results { return &_offline_file_to_perl(shift(), 'command'); }
279 sub _offline_file_to_perl {
280 my( $file, $exist_key ) = @_;
281 open(F,$file) or return [];
285 push(@resp, JSON->JSON2perl($_)) for @data;
286 @resp = grep { $_ and $_->{$exist_key} } @resp;
294 $log =~ s#/.*/(\w+)#$1#og;
298 sub offline_pending_orgs {
299 my $dir = &offline_base_pending_dir;
301 for my $org (<$dir/*>) {
302 $org =~ s#/.*/(\w+)#$1#og;
309 # --------------------------------------------------------------------
310 # Returns a list of all pending org sessions as well as all complete
311 # org sessions for today only as [ $name, $directory ] pairs
312 # --------------------------------------------------------------------
313 sub offline_org_sessions {
316 my( $year, $mon, $mday) = &_offline_date;
318 my $pdir = &offline_base_pending_dir . '/' . &offline_org;
319 my $adir = &offline_base_archive_dir .
320 '/' . &offline_org . "/${year}_${mon}_${mday}/";
323 for my $ses (<$pdir/*>, <$adir/*>) {
325 $name =~ s#/.*/(\w+)#$1#og;
326 push @ses, [ $name, $ses ];