]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/offline/offline-lib.pl
more work done
[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 our $U = "OpenILS::Application::AppUtils";
12
13
14 # --------------------------------------------------------------------
15 # Load the config options
16 # --------------------------------------------------------------------
17 our $META_FILE = "meta"; # name of the metadata file
18 our $LOCK_FILE = "lock"; # name of the lock file
19 our $ORG; # org id
20 our $ORG_UNIT; # org unit object
21 our $TIME_DELTA; # time offset for the log files
22 our %config; # config data
23 our $cgi; # our CGI object
24 our $PRINT_HTML; # true if access the CGIs via a web browser
25 our $AUTHTOKEN; # The login session key
26 our $REQUESTOR; # the requestor user object
27 our $base_dir; # the base directory for logs
28 our $WORKSTATION;
29
30 #do '##CONFIG##/upload-server.pl';
31 do 'offline-config.pl';
32
33 &initialize();
34
35
36
37
38
39 # --------------------------------------------------------------------
40 # Loads the necessary CGI params, connects to OpenSRF, and verifies
41 # the login session
42 # --------------------------------------------------------------------
43 sub initialize {
44
45         $base_dir       = $config{base_dir};
46         my $bsconfig    = $config{bootstrap};
47         my $evt;
48
49         # --------------------------------------------------------------------
50         # Connect to OpenSRF
51         # --------------------------------------------------------------------
52         OpenSRF::System->bootstrap_client(config_file => $bsconfig); 
53
54
55         # --------------------------------------------------------------------
56         # Load the required CGI params
57         # --------------------------------------------------------------------
58         $cgi = new CGI;
59         $PRINT_HTML = $cgi->param('html') || "";
60         $AUTHTOKEN      = $cgi->param('ses') 
61                 or handle_event(OpenILS::Event->new('NO_SESSION'));
62
63         $ORG = $cgi->param('org') || "";
64         if(!$ORG) {
65                 my $ws = fetch_workstation($cgi->param('ws'));
66                 $ORG = $ws->owning_lib if $ws;
67         }
68
69         if($ORG) {
70                 ($ORG_UNIT, $evt) = $U->fetch_org_unit($ORG);   
71                 handle_event($evt) if $evt;
72         } 
73
74         ($REQUESTOR, $evt) = $U->checkses($AUTHTOKEN);
75         handle_event($evt) if $evt;
76
77         $TIME_DELTA      = $cgi->param('delta') || "0";
78 }
79
80 # --------------------------------------------------------------------
81 # Generic HTML template to provide basic functionality
82 # --------------------------------------------------------------------
83 my $on = ($ORG_UNIT) ? $ORG_UNIT->name : "";
84 my $HTML = <<HTML;
85         <html>
86                 <head>
87                         <title>{TITLE}</title>
88                 </head>
89                 <body>
90                         <div style='text-align: center; border-bottom: 2px solid #E0F0E0; padding: 10px; margin-bottom: 50px;'>
91                                 <div style='margin: 5px;'><b>$on</b></div>
92                                 <a style='margin: 6px;' href='offline-upload.pl?ses=$AUTHTOKEN&org=$ORG&html=1'>Upload More Files</a>
93                                 <a style='margin: 6px;' href='offline-status.pl?ses=$AUTHTOKEN&org=$ORG&html=1'>Status Page</a>
94                                 <a style='margin: 6px;' href='offline-execute.pl?ses=$AUTHTOKEN&org=$ORG&html=1'>Execute Batch</a>
95                         </div>
96                         <div style='text-align: center;'>
97                                 {BODY}
98                         </div>
99                 </body>
100         </html>
101 HTML
102
103
104 # --------------------------------------------------------------------
105 # Print out a full HTML page and exits
106 # --------------------------------------------------------------------
107 sub print_html {
108         my %args                = @_;
109         my $title       = $args{title} || "";
110         my $body                = $args{body} || "";
111
112         if($HTML) {
113                 $HTML =~ s/{TITLE}/$title/;
114                 $HTML =~ s/{BODY}/$body/;
115
116         } else { # it can happen..
117                 $HTML = "$body"; 
118         }
119
120         print "content-type: text/html\n\n";
121         print $HTML;
122         exit(0);
123 }
124
125
126 # --------------------------------------------------------------------
127 # Prints JSON to the client
128 # --------------------------------------------------------------------
129 sub print_json {
130         my( $obj, $add_header ) = @_;
131         print "content-type: text/html\n\n" if $add_header;
132         print JSON->perl2JSON($obj);
133 }
134
135 # --------------------------------------------------------------------
136 # Prints the JSON form of the event out to the client
137 # --------------------------------------------------------------------
138 sub handle_event {
139         my $evt = shift;
140         return unless $evt;
141
142         $logger->info("offline: returning event ".$evt->{textcode});
143
144         if( $PRINT_HTML ) {
145
146                 # maybe make this smarter
147                 print_html(
148                         title => 'Offline Event Occurred', 
149                         body => JSON->perl2JSON($evt));
150
151         } else {
152                 print_json($evt,1);
153
154         }
155         exit(0);
156 }
157
158
159 # --------------------------------------------------------------------
160 # Fetches and creates if necessary the pending directory
161 # --------------------------------------------------------------------
162 sub get_pending_dir {
163         my $dir = "$base_dir/pending/$ORG/";
164         system( ('mkdir', '-p', "$dir") ) == 0 
165                 or handle_error("Unable to create directory $dir");
166         return $dir;
167 }
168
169 # --------------------------------------------------------------------
170 # Fetches and creates if necessary the archive directory
171 # --------------------------------------------------------------------
172 sub create_archive_dir {
173         my (undef,$min,$hour,$mday,$mon,$year) = localtime(time);
174
175         $mon++;
176         $year           += 1900;
177         $min            = "0$min"       unless $min             =~ /\d{2}/o;
178         $hour           = "0$hour"      unless $hour    =~ /\d{2}/o;
179         $mday           = "0$mday"      unless $mday    =~ /\d{2}/o;
180         $mon            = "0$mon"       unless $mon             =~ /\d{2}/o;
181
182         my $dir = "$base_dir/archive/$ORG/$year$mon$mday$hour$min/";
183         system( ('mkdir', '-p', "$dir") ) == 0 
184                 or handle_error("Unable to create archive directory $dir");
185         return $dir;
186 }
187
188
189
190 # --------------------------------------------------------------------
191 # Fetches the workstation object by name
192 # --------------------------------------------------------------------
193 sub fetch_workstation {
194         my $name = shift;
195         $logger->debug("offline: Fetching workstation $name");
196         my $ws = $U->storagereq(
197                 'open-ils.storage.direct.actor.workstation.search.name', $name);
198         handle_error("Workstation $name does not exists") unless $ws;
199         return $ws;
200 }
201
202 sub append_meta {
203         my $data = shift;
204         $data = JSON->perl2JSON($data);
205         my $mf = get_pending_dir($ORG) . "/$META_FILE";
206         $logger->debug("offline: Append metadata to file $mf: $data");
207         open(F, ">>$mf") or handle_event(OpenILS::Event->new('OFFLINE_FILE_ERROR', payload => $@));
208         print F "$data\n";
209         close(F);
210 }
211
212 sub read_meta {
213         my $mf = get_pending_dir($ORG) . "/$META_FILE";
214         open(F, "$mf") or return [];
215         my @data = <F>;
216         close(F);
217         my @resp;
218         push(@resp, JSON->JSON2perl($_)) for @data;
219         @resp = grep { $_ and $_->{'workstation'} } @resp;
220         return \@resp;
221 }
222
223 sub log_to_wsname {
224         my $log = shift;
225         $log =~ s/\.log//og;
226         $log =~ s#/.*/(\w+)#$1#og;
227         return $log
228 }