]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/offline/offline-lib.pl
added a status summary query that just returns count info
[working/Evergreen.git] / Open-ILS / src / offline / offline-lib.pl
1 #!/usr/bin/perl
2 use strict; use warnings;
3 use CGI;
4 use OpenSRF::System;
5 use OpenSRF::Utils::Logger qw/$logger/;
6 use OpenILS::Application::AppUtils;
7 use OpenILS::Event;
8 use OpenSRF::EX qw/:try/;
9 use JSON;
10 use Data::Dumper;
11 use OpenILS::Utils::Fieldmapper;
12 use Digest::MD5 qw/md5_hex/;
13 use OpenSRF::Utils qw/:daemon/;
14 our $U = "OpenILS::Application::AppUtils";
15 our %config;
16
17
18 # --------------------------------------------------------------------
19 # Load the config options
20 # --------------------------------------------------------------------
21 my $time_delta;
22 my $cgi; 
23 my $base_dir; 
24 my $requestor; 
25 my $workstation;
26 my $org;
27 my $org_unit;
28 my $authtoken;
29 my $seskey;
30
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
50
51
52 # --------------------------------------------------------------------
53 # Load the config
54 # --------------------------------------------------------------------
55 #do '##CONFIG##/upload-server.pl';
56 do 'offline-config.pl';
57
58
59 # --------------------------------------------------------------------
60 # Set everything up
61 # --------------------------------------------------------------------
62 &initialize();
63
64
65
66
67
68
69 # --------------------------------------------------------------------
70 # Loads the necessary CGI params, connects to OpenSRF, and verifies
71 # the login session
72 # --------------------------------------------------------------------
73 sub initialize {
74
75         $base_dir       = $config{base_dir};
76         my $bsconfig    = $config{bootstrap};
77         my $evt;
78
79         # --------------------------------------------------------------------
80         # Connect to OpenSRF
81         # --------------------------------------------------------------------
82         OpenSRF::System->bootstrap_client(config_file => $bsconfig); 
83
84
85         # --------------------------------------------------------------------
86         # Load the required CGI params
87         # --------------------------------------------------------------------
88         $cgi = new CGI;
89
90         $authtoken      = $cgi->param('ses') 
91                 or handle_event(OpenILS::Event->new('NO_SESSION'));
92
93         $org = $cgi->param('org') || "";
94         if(!$org) {
95                 if(my $ws = $cgi->param('ws')) {
96                         $workstation = fetch_workstation($ws);
97                         $org = $workstation->owning_lib if $workstation;
98                 }
99         }
100
101         if($org) {
102                 ($org_unit, $evt) = $U->fetch_org_unit($org);   
103                 handle_event($evt) if $evt;
104         } 
105
106         ($requestor, $evt) = $U->checkses($authtoken);
107         handle_event($evt) if $evt;
108
109         $time_delta      = $cgi->param('delta') || "0";
110
111         $seskey = $cgi->param('seskey') || time . "_$$";
112 }
113
114
115 # --------------------------------------------------------------------
116 # Print out a full HTML page and exits
117 # --------------------------------------------------------------------
118 sub print_html {
119
120         my %args        = @_;
121         my $body        = $args{body} || "";
122         my $res  = $args{result} || "";
123         my $on  = ($org_unit) ? $org_unit->name : "";
124
125         $authtoken      ||= "";
126         $org                    ||= "";
127         $seskey         ||= "";
128
129         my $html = <<"  HTML";
130                 <html>
131                         <head>
132                                 <script src='/opac/common/js/JSON.js'> </script>
133                                 <script>
134                                         function offline_complete(obj) { if(obj) alert(js2JSON(obj)); }
135                                 </script>
136                                 <style> 
137                                         a { margin: 6px; } 
138                                         div { margin: 10px; text-align: center; }
139                                 </style>
140                         </head>
141                         <body onload='offline_complete($res);'>
142                                 <div>
143                                         <div style='margin: 5px;'><b>$on</b></div>
144                                         <a href='offline-upload.pl?ses=$authtoken&org=$org'>Upload More Files</a>
145                                         <a href='offline-status.pl?ses=$authtoken&org=$org&seskey=$seskey'>Status Page</a>
146                                         <a href='offline-execute.pl?ses=$authtoken&org=$org&seskey=$seskey'>Execute Batch</a>
147                                 </div>
148                                 <hr/>
149                                 <div>$body</div>
150                         </body>
151                 </html>
152         HTML
153
154         if( &offline_cgi->param('raw') ) {
155                 print "content-type: text/plain\n\n";
156                 print $res;     
157
158         } else {
159                 print "content-type: text/html\n\n";
160                 print $html;
161         }
162
163         exit(0);
164 }
165
166
167 # --------------------------------------------------------------------
168 # Prints the JSON form of the event out to the client
169 # --------------------------------------------------------------------
170 sub handle_event { &offline_handle_json(@_); }
171
172 sub offline_handle_json {
173         my $obj = shift;
174         my $ischild = shift;
175         return unless $obj;
176         print_html(result => JSON->perl2JSON($obj)) unless $ischild;
177         append_result($obj) and exit;
178 }
179
180
181
182 sub handle_error { warn shift() . "\n"; }
183
184
185 # --------------------------------------------------------------------
186 # Fetches (and creates if necessary) the pending directory
187 # --------------------------------------------------------------------
188 sub offline_pending_dir {
189         my $create = shift;
190         my $dir = "$base_dir/pending/$org/$seskey/";
191
192         if( $create and ! -e $dir ) {
193                 $logger->debug("offline: creating pending directory $dir");
194                 qx/mkdir -p $dir/ and handle_error("Unable to create directory $dir");
195         }
196
197         return $dir;
198 }
199
200 # --------------------------------------------------------------------
201 # Fetches and creates if necessary the archive directory
202 # --------------------------------------------------------------------
203 sub offline_archive_dir { return create_archive_dir(@_); }
204 sub create_archive_dir {
205
206         my $create = shift;
207         my (undef,undef, undef, $mday,$mon,$year) = localtime(time);
208
209         $mon++; $year   += 1900;
210         $mday   = "0$mday" unless $mday =~ /\d{2}/o;
211         $mon    = "0$mon" unless $mon   =~ /\d{2}/o;
212
213         my $dir = "$base_dir/archive/$org/${year}_${mon}_${mday}/$seskey/";
214
215         if( $create and ! -e $dir ) {
216                 $logger->debug("offline: creating archive directory $dir");
217                 qx/mkdir -p $dir/ and handle_error("Unable to create archive directory $dir");
218         }
219         return $dir;
220 }
221
222
223
224 # --------------------------------------------------------------------
225 # Fetches the workstation object by name
226 # --------------------------------------------------------------------
227 sub fetch_workstation {
228         my $name = shift;
229         $logger->debug("offline: Fetching workstation $name");
230         my $ws = $U->storagereq(
231                 'open-ils.storage.direct.actor.workstation.search.name', $name);
232         handle_event(OpenILS::Event->new('WORKSTATION_NOT_FOUND')) unless $ws;
233         return $ws;
234 }
235
236
237 # --------------------------------------------------------------------
238 # Read/Write to/from the essential files
239 # --------------------------------------------------------------------
240 sub append_meta { &_offline_file_append_perl( shift(), &offline_meta_file ); }
241 sub append_result { &_offline_file_append_perl( shift(), &offline_result_file ); }
242 sub _offline_file_append_perl {
243         my( $obj, $file ) = @_;
244         return unless $obj;
245         $obj = JSON->perl2JSON($obj);
246         open(F, ">>$file") or die
247                 "Unable to append data to file: $file [$! $@]\n";
248         print F "$obj\n";
249         close(F);
250 }
251
252
253 sub offline_read_meta { return &_offline_read_meta(&offline_meta_file); }
254 sub offline_read_archive_meta { return &_offline_read_meta(&offline_archive_meta_file); }
255 sub _offline_read_meta { return &_offline_file_to_perl(shift(), 'workstation'); }
256 sub offline_read_archive_results { return &_offline_read_results(&offline_archive_result_file); }
257 sub offline_read_results { return &_offline_read_results(&offline_result_file); }
258 sub _offline_read_results { return &_offline_file_to_perl(shift(), 'command'); }
259
260 sub _offline_file_to_perl {
261         my( $file, $exist_key ) = @_;
262         open(F,$file) or return [];
263         my @data = <F>;
264         close(F);
265         my @resp;
266         push(@resp, JSON->JSON2perl($_)) for @data;
267         @resp = grep { $_ and $_->{$exist_key} } @resp;
268         return \@resp;
269 }
270
271
272 sub log_to_wsname {
273         my $log = shift;
274         $log =~ s/\.log//og;
275         $log =~ s#/.*/(\w+)#$1#og;
276         return $log
277 }
278
279 1;