source: main/trunk/greenstone2/cgi-bin/talkback-progressbar.pl@ 23517

Last change on this file since 23517 was 23517, checked in by davidb, 13 years ago

Additional check added to ensure GLIServer.jar file exists, and issues an error message if not.

  • Property svn:executable set to *
File size: 9.7 KB
Line 
1#!/usr/bin/perl -w
2
3use strict;
4
5use CGI::Carp qw(fatalsToBrowser);
6use CGI;
7
8my $gsdl_cgi;
9my $gsdl_home;
10my $gsdl_tmp_dir;
11
12my $debugging_enabled = 0; # if 1, if enabled deleting files will not happen
13
14BEGIN {
15
16 $|=1; # Force auto-flushing for output
17
18 eval('require "./gsdlCGI.pm"');
19 if ($@)
20 {
21 print STDOUT "Content-type:text/plain\n\n";
22 print STDOUT "ERROR: $@\n";
23 exit 0;
24 }
25
26}
27
28
29sub get_progress_filename
30{
31 my ($uploaded_file) = @_;
32
33 my $progress_file = $uploaded_file;
34
35 $progress_file =~ s{^(.*)\/}{};
36 $progress_file =~ s/\.*?$//;
37 $progress_file .= "-progress.txt";
38
39 my $progress_filename = &util::filename_cat($gsdl_tmp_dir, $progress_file);
40
41 return $progress_filename;
42}
43
44sub get_file_central_filename
45{
46 my $file_central = &util::filename_cat($gsdl_tmp_dir,"file-central.txt");
47
48 return $file_central;
49}
50
51sub read_file_central
52{
53 my $fc_filename = get_file_central_filename();
54
55 my @fc_list;
56
57 if (open(FCIN,"<$fc_filename")) {
58
59 my $fc_list_str = do { local $/; <FCIN> };
60 @fc_list = split(/\n/,$fc_list_str);
61
62 close(FCIN);
63 }
64 else {
65 # OK to have no file-central.txt to start with
66 # return empty list
67 @fc_list = ();
68 }
69
70 return \@fc_list;
71
72}
73
74sub remove_from_file_central
75{
76 my ($filename,$fc_list) = @_;
77
78 my @new_fc_list = ();
79
80 my $removed = 0;
81
82 foreach my $f (@$fc_list) {
83
84 if ($f ne $filename) {
85 push(@new_fc_list,$f);
86 }
87 else {
88 $removed = 1;
89 }
90 }
91
92 if (!$removed) {
93 print STDERR "Warning: Failed to locate '$filename' in file-central.txt\n";
94 }
95
96 return \@new_fc_list;
97}
98
99sub add_to_file_central
100{
101 my ($filename,$fc_list) = @_;
102
103 my @new_fc_list = @$fc_list;
104
105 my $duplicate = 0;
106 foreach my $f (@new_fc_list) {
107
108 if ($f eq $filename) {
109 $duplicate = 1;
110 }
111 }
112
113 if (!$duplicate) {
114 push(@new_fc_list,$filename);
115 }
116 else {
117 print STDERR "Warning: Ingoring request to add duplicate entry:\n";
118 print STDERR " '$filename' into file-central.txt\n"
119 }
120
121 return \@new_fc_list;
122}
123
124
125
126sub write_file_central
127{
128 my ($fc_list) = @_;
129
130 my $fc_filename = get_file_central_filename();
131
132
133 if (open(FCOUT,">$fc_filename")) {
134
135 foreach my $f (@$fc_list) {
136 print FCOUT "$f\n";
137 }
138
139 close(FCOUT);
140
141
142 # Ensure it can be edited by owner of Greenstone install (if needed)
143 chmod(0777,$fc_filename);
144 }
145 else {
146 print STDERR "Error: Failed to write out $fc_filename\n";
147 print STDERR "$!\n";
148 }
149}
150
151sub monitor_upload
152{
153 my ($uploading_file, $buffer, $bytes_read, $data) = @_;
154
155 $bytes_read ||= 0;
156
157 my $progress_filename = get_progress_filename($uploading_file);
158
159 if (! -f $progress_filename) {
160 my $fc_list = read_file_central();
161 $fc_list = add_to_file_central($uploading_file,$fc_list);
162 write_file_central($fc_list);
163 }
164
165 open(COUNTER, ">$progress_filename");
166
167 my $per = 0;
168 if ($ENV{CONTENT_LENGTH} > 0) {
169 $per = int(($bytes_read * 100) / $ENV{CONTENT_LENGTH});
170 }
171 print COUNTER $per;
172 close(COUNTER);
173
174 # Useful debug to slow down a 'fast' upload
175 # Sleep for 10 msecs
176 #select(undef, undef, undef, 0.01);
177 #select(undef, undef, undef, 0.1);
178}
179
180
181
182sub upload_file {
183
184 my ($gsdl_cgi,$full_filename) = @_;
185
186 my $fh = $gsdl_cgi->upload('uploadedfile');
187 my $filename = $gsdl_cgi->param('uploadedfile');
188
189 return '' if ! $filename;
190
191 open (OUTFILE, '>' . $full_filename)
192 || die("Can't write to $full_filename: $!");
193
194 binmode(OUTFILE);
195
196 while (my $bytesread = read($fh, my $buffer, 1024)) {
197 print OUTFILE $buffer;
198 }
199
200 close (OUTFILE);
201 chmod(0666, $full_filename);
202
203}
204
205sub remove_progress_file
206{
207 my ($uploaded_file) = @_;
208
209 my $progress_filename = get_progress_filename($uploaded_file);
210
211 unlink($progress_filename)
212 unless $debugging_enabled;
213
214 my $fc_list = read_file_central();
215 $fc_list = remove_from_file_central($uploaded_file,$fc_list);
216 write_file_central($fc_list);
217}
218
219
220sub unzip_archives_doc
221{
222 my ($gsdl_cgi,$gsdl_home,$collect_home,$collect,$zip_filename) = @_;
223
224 my $lang_env = $gsdl_cgi->clean_param("lr") || "";
225
226 my $import_dir = &util::filename_cat($collect_home,$collect,"import");
227
228 # Unzip $zip_filename in the collection's import folder
229 my $java = $gsdl_cgi->get_java_path();
230 my $jar_dir= &util::filename_cat($gsdl_home, "bin", "java");
231 my $java_classpath = &util::filename_cat($jar_dir,"GLIServer.jar");
232
233 if (!-f $java_classpath) {
234 $gsdl_cgi->generate_error("$0:\nFailed to find $java_classpath\n");
235 }
236
237 my $java_args = "\"$zip_filename\" \"$import_dir\"";
238
239 $ENV{'LANG'} = $lang_env;
240 my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.Unzip $java_args";
241
242 my $java_output = `$java_command`;
243 my $java_status = $?;
244 if ($java_status > 0) {
245 my $report = "Java failed: $java_command\n--\n";
246 $report .= "$java_output\n";
247 $report .= "Exit status: " . ($java_status / 256) . "\n";
248 $report .= $gsdl_cgi->check_java_home();
249
250 $gsdl_cgi->generate_error($report);
251 }
252 else {
253 # Remove the zip file once we have unzipped it, since it is an intermediate file only
254 `chmod -R a+rw $import_dir/HASH*`;
255 unlink($zip_filename) unless $debugging_enabled;
256 }
257}
258
259
260sub rebuild_collection
261{
262 my ($collect) = @_;
263
264 my $bin_script = &util::filename_cat($gsdl_home,"bin","script");
265## my $inc_rebuild_pl = &util::filename_cat($bin_script,"incremental-rebuild.pl");
266
267 my $rebuild_cmd = "perl -S incremental-rebuild.pl \"$collect\"";
268
269 my $rebuild_output = `$rebuild_cmd 2>&1`;
270 my $rebuild_status = $?;
271 if ($rebuild_status > 0) {
272 my $report = "Perl rebuild failed: $rebuild_cmd\n--\n";
273 $report .= "$rebuild_output\n";
274 $report .= "Exit status: " . ($rebuild_status / 256) . "\n";
275## $report .= $gsdl_cgi->check_perl_home();
276
277# $report .= "PATH = ". $ENV{'PATH'}. "\n";
278
279
280 $gsdl_cgi->generate_error($report);
281 }
282}
283
284sub main {
285
286 # gsdlCGI->prenew() constructs a 'lite' version of the object where the
287 # GSDL environment has been setup
288 #
289 # This is needed because the main call the gsdlCGI->new takes an
290 # initializer rountine -- monitor_upload() -- as a parameter, AND THAT
291 # routine (which is called before the constructor is finished) needs to
292 # know the tmp directory to use to write out the progress file.
293
294 my $gsdl_config = gsdlCGI->prenew();
295
296 $gsdl_home = $gsdl_config->get_gsdl_home();
297 $gsdl_tmp_dir = &util::get_toplevel_tmp_dir();
298
299 require talkback;
300
301 # Use the initializer mechanism so a 'callback' routine can monitor
302 # the progress of how much data has been uploaded
303
304 $gsdl_cgi = gsdlCGI->new(\&monitor_upload);
305
306
307 require CGI::Ajax;
308
309 my $perlAjax = new CGI::Ajax('check_status' => \&check_status);
310
311
312 if ($gsdl_cgi->param('process')) {
313
314 my $uploaded_file = $gsdl_cgi->param('uploadedfile');
315 my $full_filename = &util::filename_cat($gsdl_tmp_dir,$uploaded_file);
316
317 my $done_html = &talkback::generate_done_html($full_filename);
318
319 if ($gsdl_cgi->param('yes_upload')) {
320 upload_file($gsdl_cgi,$full_filename);
321
322 my $collect = $gsdl_cgi->param('toCollect');
323 my $collect_home = &util::filename_cat($gsdl_home,"collect");
324
325 unzip_archives_doc($gsdl_cgi,$gsdl_home,$collect_home,$collect,$full_filename);
326 rebuild_collection($collect);
327 }
328
329 print $gsdl_cgi->header();
330 print $done_html;
331
332 remove_progress_file($uploaded_file);
333 }
334 else {
335
336 my $upload_html_form;
337
338 #my $oid = $gsdl_cgi->param('oid');
339 #my $collect = $gsdl_cgi->param('collect');
340 my $uniq_file = $gsdl_cgi->param('uploadedfile');
341
342 #my $uniq_file = "$collect-$oid-doc.zip";
343 # Light-weight (hidden) form with progress bar
344
345 $upload_html_form
346 = &talkback::generate_upload_form_progressbar($uniq_file);
347
348 print $perlAjax->build_html($gsdl_cgi, $upload_html_form);
349 }
350}
351
352
353main();
354
355
356#=====
357
358sub inc_wait_dots
359{
360 my $wait_filename = &util::filename_cat($gsdl_tmp_dir,"wait.txt");
361 open(WIN,"<$wait_filename");
362 my $wait = <WIN>;
363 close(WIN);
364
365 $wait = ($wait+1) %6;
366 my $wait_dots = "." x ($wait+1);
367
368 open(WOUT,">$wait_filename");
369 print WOUT "$wait\n";
370 close(WOUT);
371
372 return $wait_dots;
373}
374
375
376sub check_status_single_file
377{
378 my ($filename) = @_;
379
380 my $monitor_filename = get_progress_filename($filename);
381
382 if (! -f $monitor_filename ) {
383 return "";
384 }
385
386 open my $PROGRESS, '<', $monitor_filename or die $!;
387 my $s = do { local $/; <$PROGRESS> };
388 close ($PROGRESS);
389
390 my $fgwidth = int($s * 1.5);
391 my $bgwidth = 150 - $fgwidth;
392
393 my $fgcol = "background-color:#dddd00;";
394 my $bgcol = "background-color:#008000;";
395
396 my $style_base = "height:10px; float:left;";
397
398 my $r = "";
399 $r .= "<div>$filename:</div>";
400 $r .= "<nobr>";
401 $r .= "<div style=\"width: ${fgwidth}px; $fgcol $style_base\"></div>";
402 $r .= "<div style=\"width: ${bgwidth}px; $bgcol $style_base\"></div>";
403 $r .= "<div style=\"float:left; width: 80px\">&nbsp;$s%</div>";
404 $r .= "</nobr>";
405 $r .= "<br />";
406
407 return $r;
408}
409
410
411sub check_status_all
412{
413 my $file_central = get_file_central_filename();
414
415 my $html = "";
416
417 my $fc_list = read_file_central();
418
419 foreach my $f (@$fc_list) {
420 $html .= check_status_single_file($f);
421 }
422
423 return $html;
424
425}
426
427
428# Accessed from HTML web page through the majic of perlAjax
429
430sub check_status
431{
432
433 my $wait_dots = inc_wait_dots();
434 my $html = "$wait_dots<br>";
435
436 my $filename = $gsdl_cgi->param('uploadedfile');
437
438 if ((defined $filename) && ($filename ne "")) {
439 $html .= check_status_single_file($filename);
440 }
441 else {
442 $html .= check_status_all();
443 }
444
445 return $html;
446}
Note: See TracBrowser for help on using the repository browser.