source: gsdl/trunk/perllib/convertutil.pm@ 18474

Last change on this file since 18474 was 18474, checked in by mdewsnip, 15 years ago

Fix to problem when using cached generated images where the image width and height metadata values were left undefined. Now saves the conversion result to a file (similar to what is done with the conversion arguments), and this is read when a cached image is used. By Jeffrey Ke at DL Consulting Ltd.

File size: 8.1 KB
Line 
1###########################################################################
2#
3# convertutil.pm -- utility to help convert files using external applications
4#
5# Copyright (C) 1999 DigiLib Systems Limited, NZ
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20#
21###########################################################################
22
23
24package convertutil;
25
26use strict;
27no strict 'refs'; # allow filehandles to be variables and viceversa
28
29
30use File::Basename;
31
32
33sub monitor_init
34{
35 # do nothing
36 return {};
37}
38
39sub monitor_deinit
40{
41 my ($saved_rec) = @_;
42
43 # nothing to do
44}
45
46sub monitor_init_unbuffered
47{
48 my $saved_buffer_len = $|;
49 $| = 1;
50
51 my $saved_rec = { 'saved_buffer_len' => $saved_buffer_len };
52
53 return $saved_rec;
54}
55
56sub monitor_deinit_unbuffered
57{
58 my ($saved_rec) = @_;
59
60 my $saved_buffer_len = $saved_rec->{'saved_buffer_len'};
61
62 $| = $saved_buffer_len;
63}
64
65sub monitor_line
66{
67 my ($line) = @_;
68
69 my $had_error = 0;
70 my $generate_dot = 0;
71
72 return ($had_error,$generate_dot);
73}
74
75sub monitor_line_with_dot
76{
77 my ($line) = @_;
78
79 my $had_error = 0;
80 my $generate_dot = 1;
81
82 return ($had_error,$generate_dot);
83}
84
85
86sub run_general_cmd
87{
88 my ($command,$options) = @_;
89
90
91 # $options points to a hashtable that must have fields for:
92 # 'verbosity', 'outhandle', 'message_prefix' and 'message'
93 #
94 # it can also include functions for monitoring
95 # 'monitor_init' => takes no input arguments and returns a hashtable for saved data values
96 # 'monitor_line' => takes $line as input argument, return tuple (had_error,generate_dot)
97 # 'monitor_deinit' => takes the saved data values as input, restores saved values
98 #
99 # Default are provided for these monitor functions if none specified
100
101 my $verbosity = $options->{'verbosity'};
102 my $outhandle = $options->{'outhandle'};
103
104 my $message_prefix = $options->{'message_prefix'};
105 my $message = $options->{'message'};
106
107 my $monitor_init = $options->{'monitor_init'};
108 my $monitor_line = $options->{'monitor_line'};
109 my $monitor_deinit = $options->{'monitor_deinit'};
110
111 if (!defined $monitor_init) {
112 $monitor_init = "monitor_init";
113 }
114 if (!defined $monitor_line) {
115 $monitor_line = "monitor_line";
116 }
117 if (!defined $monitor_deinit) {
118 $monitor_deinit = "monitor_deinit";
119 }
120
121 print $outhandle "$message_prefix: $command\n" if ($verbosity > 3);
122 print $outhandle " $message ..." if ($verbosity >= 1);
123
124 my $command_status = undef;
125 my $result = "";
126 my $had_error = 0;
127
128 my $saved_rec = &$monitor_init();
129
130 if (open(CMD,"$command 2>&1 |"))
131 {
132 my $line;
133
134 my $linecount = 0;
135 my $dot_count = 0;
136
137
138 while (defined ($line = <CMD>))
139 {
140 $linecount++;
141
142 my ($had_local_error,$generate_dot) = &$monitor_line($line);
143
144 if ($had_local_error) {
145 # set general flag, but allow loop to continue to end building up the $result line
146 print $outhandle "$line\n";
147 $had_error = 1;
148 }
149
150 if ($generate_dot)
151 {
152 if ($dot_count == 0) { print $outhandle "\n "; }
153 print $outhandle ".";
154 $dot_count++;
155
156 if (($dot_count%76)==0)
157 {
158 print $outhandle "\n ";
159 }
160 }
161
162 $result .= $line;
163
164 }
165 print $outhandle "\n";
166
167
168 close(CMD);
169
170 $command_status = $?;
171 if ($command_status != 0) {
172 $had_error = 1;
173
174 print $outhandle "Error: processing command failed. Exit status $?\n";
175
176 if ($verbosity >= 3) {
177 print $outhandle " Command was: $command\n";
178 }
179 if ($verbosity >= 4) {
180 print $outhandle "$message_prefix result: $result\n";
181 }
182 }
183 }
184 else
185 {
186 $had_error = 1;
187 print STDERR "Error: failed to execute $command\n";
188 }
189
190 &$monitor_deinit($saved_rec);
191
192 if ($verbosity >= 1) {
193 if ($had_error) {
194 print $outhandle " ...error encounterd\n";
195 }
196 else {
197 print $outhandle " ...done\n";
198 }
199 }
200
201 if (defined $command_status && ($command_status == 0))
202 {
203 # only want to print the following out if verbosity is high enough
204 # and we haven't already printed it out as a detected error above
205 print $outhandle "$message_prefix result: $result\n" if ($verbosity > 5);
206 }
207
208 return ($result,$had_error);
209}
210
211
212sub regenerate_general_cmd
213{
214 my ($command,$ofilename,$options) = @_;
215
216 my $regenerated = 1;
217 my $result = "";
218 my $had_error = 0;
219
220 ($result,$had_error) = run_general_cmd($command,$options);
221
222 # store command args so can be compared with subsequent runs of the command
223 my $args_filename = "$ofilename.args";
224
225 if (open(ARGSOUT,">$args_filename")) {
226 print ARGSOUT $command;
227 print ARGSOUT "\n";
228 close(ARGSOUT);
229 }
230 else {
231 my $outhandle = $options->{'outhandle'};
232 print $outhandle "Warning: Unable to write out caching information to file $args_filename\n";
233 print $outhandle " This means $ofilename will be regenerated on next build whether\n";
234 print $outhandle " processing args have changed or not.\n";
235 }
236
237 # Store the result, since ImageConverter.pm extracts the image height and width from the processed result
238 my $result_filename = "$ofilename.result";
239 if (open(RESOUT, ">$result_filename"))
240 {
241 print RESOUT $result;
242 close(RESOUT);
243 }
244 else
245 {
246 my $outhandle = $options->{'outhandle'};
247 print $outhandle "Warning: Unable to write out cached process result to file $result_filename.\n";
248 }
249
250 return ($regenerated,$result,$had_error);
251}
252
253
254
255sub run_cached_general_cmd
256{
257 my ($command,$ofilename,$options) = @_;
258
259 my $regenerated = 0;
260 my $result = "";
261 my $had_error = 0;
262
263 if (!-e $ofilename) {
264 ($regenerated,$result,$had_error)
265 = regenerate_general_cmd($command,$ofilename,$options);
266 }
267 else {
268 # file exists => check to see if command to generate it has changed
269 my $args_filename = "$ofilename.args";
270 if (open (ARGSIN,"<$args_filename")) {
271 my $prev_command = <ARGSIN>;
272 chomp($prev_command);
273
274 close(ARGSIN);
275
276 if (defined $prev_command) {
277 # if commands are different
278 if ($prev_command ne $command) {
279 # need to rerun command
280 ($regenerated,$result,$had_error)
281 = regenerate_general_cmd($command,$ofilename,$options);
282 }
283 else {
284 my $outhandle = $options->{'outhandle'};
285 my $verbosity = $options->{'verbosity'};
286
287 my $message_prefix = $options->{'message_prefix'};
288
289 my ($ofile) = ($ofilename =~ m/^.*(cached.*)$/);
290
291 my $ofile_no_dir = basename($ofile);
292 print $outhandle " $message_prefix: Cached file $ofile_no_dir already exists.\n";
293 print $outhandle " $message_prefix: No need to regenerate $ofile\n" if ($verbosity > 2);
294
295 # Read in the cached result lines and join them into a single string
296 my $result_filename = "$ofilename.result";
297 if (open(RESIN, "<$result_filename"))
298 {
299 my @result_lines = <RESIN>;
300 $result = join("\n", @result_lines);
301 close(RESIN);
302 }
303 else
304 {
305 print $outhandle " $message_prefix: Error, failed to obtain cached result from $result_filename.\n";
306 }
307 }
308
309 }
310 }
311 else {
312 my $outhandle = $options->{'outhandle'};
313 my $message_prefix = $options->{'message_prefix'};
314
315 print $outhandle " $message_prefix: No cached previous args found. Regenerating $ofilename\n";
316
317 ($regenerated,$result,$had_error) = regenerate_general_cmd($command,$ofilename,$options);
318 }
319 }
320
321 return ($regenerated,$result,$had_error);
322}
323
324
3251;
Note: See TracBrowser for help on using the repository browser.