source: trunk/gsdl/perllib/plugins/ConvertToPlug.pm@ 2226

Last change on this file since 2226 was 2086, checked in by jrm21, 23 years ago

We create a copy of any args to new() because parsargs might modify the
list, deleting items needed later by call to TEXTPlug::new or HTMLPlug::new

  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1###########################################################################
2#
3# ConvertToPlug.pm -- plugin that inherits from HTML or TEXT Plug, depending
4# on plugin argument convert_to
5#
6# A component of the Greenstone digital library software
7# from the New Zealand Digital Library Project at the
8# University of Waikato, New Zealand.
9#
10# Copyright (C) 1999 New Zealand Digital Library Project
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25#
26###########################################################################
27
28# The plugin is inherited by such plugins as WordPlug and PDFPlug.
29# It facilitates the conversion of these document types to either HTML
30# or TEXT by setting up variable that instruct ConvertToBasPlug
31# how to work.
32
33# It works by dynamically inheriting HTMLPlug or TEXTPlug based on
34# the plugin argument 'convert_to'. If the argument is not present,
35# the default is to inherit HTMLPlug.
36
37
38package ConvertToPlug;
39
40use BasPlug;
41use HTMLPlug;
42use TEXTPlug;
43
44sub BEGIN {
45 @ISA = ('HTMLPlug');
46# @ISA = ('HTMLPlug', 'TEXTPlug');
47# @ISA = ('BasPlug'); #, 'HTMLPlug', 'TEXTPlug');
48}
49
50# use strict; # this breaks 'print $outhandle ' error msgs.
51
52sub print_usage {
53 my ($plugin_name) = @_;
54
55 # for when this function is called directly by pluginfo.pl
56 if (ref ($plugin_name)) {
57 $plugin_name = ref ($plugin_name);
58 }
59
60 print STDERR "\n usage: plugin $plugin_name [options]\n\n";
61 print STDERR " options:\n";
62 print STDERR " -convert_to (html|text) plugin converts to TEXT or HTML\n";
63 print STDERR " (default html)\n";
64}
65
66sub parse_args
67{
68 my $class = shift (@_);
69 my ($args) = @_;
70
71 my $plugin_name = $class;
72 $plugin_name =~ s/\.pm$//;
73
74 my $generate_format;
75 my $kea_arg;
76
77 if (!parsargv::parse($args,
78 q^extract_keyphrases^, \$kea_arg->{'kea'}, #with extra options
79 q^extract_keyphrase_options/.*/^, \$kea_arg->{'kea_options'}, #no extra options
80 q^convert_to/(html|text)/html^, \$generate_format,
81 "allow_extra_options")) {
82
83 print STDERR "\nIncorrect options passed to $plugin_name, ";
84 print STDERR "check your collect.cfg configuration file\n";
85 &print_usage($plugin_name);
86 die "\n";
87 }
88
89 return ($plugin_name,$generate_format, $kea_arg);
90}
91
92sub new {
93 my $class = shift (@_);
94 if ($class eq "ConvertToPlug") {$class = shift (@_);}
95 my $self;
96# parsargv::parse might modify the list, so we do this by creating a copy
97# of the argument list.
98 my @arglist = @_;
99 my ($plugin_name,$generate_format, $kea_arg) = $class->parse_args(\@_);
100
101 if ($generate_format eq "text")
102 {
103 $self = new TEXTPlug ($class, @arglist);
104 $self->{'convert_to'} = "TEXT";
105 $self->{'convert_to_ext'} = "txt";
106 }
107 else
108 {
109 $self = new HTMLPlug ($class, @arglist);
110 $self->{'convert_to'} = "HTML";
111 $self->{'convert_to_ext'} = "html";
112
113 $self->{'rename_assoc_files'} = 1;
114 $self->{'metadata_fields'} .= ",GENERATOR";
115 }
116
117 #if kea data to be extracted...
118 $self->{'kea'} = 1 if($kea_arg->{'kea'});
119 $self->{'kea_options'} = 1 if($kea_arg->{'kea_options'});
120
121 return bless $self, $class;
122}
123
124
125
126# Run conversion utility on the input file.
127#
128# The conversion takes place in a collection specific 'tmp' directory so
129# that we don't accidentally damage the input.
130#
131# The desired output type is indicated by $output_ext. This is usually
132# something like "html" or "word", but can be "best" (or the empty string)
133# to indicate that the conversion utility should do the best it can.
134
135sub tmp_area_convert_file {
136 my $self = shift (@_);
137 my ($output_ext,$input_filename, $textref) = @_;
138
139 my $convert_to = $self->{'convert_to'};
140
141 # softlink to collection tmp dir
142 my $colname = &util::use_collection();
143 my $tmp_dirname
144 = &util::filename_cat($ENV{'GSDLHOME'},"collect",$colname,"tmp");
145 &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
146
147 # derive tmp filename from input filename
148 my ($tailname,$dirname,$suffix)
149 = File::Basename::fileparse($input_filename,'\.[^\.]+$');
150
151 # Remove any white space from filename -- no risk of name collision, and
152 # makes later conversion by utils simpler. Leave spaces in path...
153 $tailname =~ s/\s+//g;
154
155 my $tmp_filename = &util::filename_cat($tmp_dirname,"$tailname$suffix");
156
157 &util::soft_link($input_filename,$tmp_filename);
158
159 my $verbosity = $self->{'verbosity'};
160 if ($verbosity>0)
161 {
162 print STDERR "Converting $tailname$suffix to $convert_to format\n";
163 }
164
165 # Execute the conversion command and get the type of the result,
166 # making sure the converter gives us the appropriate output type
167 my $output_type = lc($convert_to);
168 my $cmd = "gsConvert.pl -verbose $verbosity -output $output_type \"$tmp_filename\"";
169 $output_type = `$cmd`;
170
171 # Check STDERR here
172
173 chomp $output_type;
174 if ($output_type eq "fail") {
175 print STDERR "Could not convert $tailname$suffix to $convert_to format\n";
176 return "";
177### exit 1;
178 }
179
180 # remove symbolic link to original file
181 &util::rm($tmp_filename);
182
183 # store the *actual* output type and return the output filename
184 $self->{'convert_to_ext'} = $output_type;
185 my $output_filename = $tmp_filename;
186 $output_filename =~ s/$suffix$/.$output_type/;
187
188 return $output_filename;
189}
190
191
192# Remove collection specific tmp directory and all its contents.
193
194sub cleanup_tmp_area {
195 my $self = shift (@_);
196
197 my $colname = &util::use_collection();
198 my $tmp_dirname
199 = &util::filename_cat($ENV{'GSDLHOME'},"collect",$colname,"tmp");
200 &util::rm_r($tmp_dirname);
201 &util::mk_dir($tmp_dirname);
202}
203
204
205
206
207# Override BasPlug read
208# We don't want to get language encoding stuff until after we've converted
209# our file to either TEXT or HTML.
210sub read {
211 my $self = shift (@_);
212 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs) = @_;
213# if ($self->is_recursive()) {
214# die "BasPlug::read function must be implemented in sub-class for recursive plugins\n";
215# }
216
217 my $outhandle = $self->{'outhandle'};
218
219 my $filename = &util::filename_cat($base_dir, $file);
220 return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
221 if ($filename !~ /$self->{'process_exp'}/ || !-f $filename) {
222 return undef;
223 }
224 my $plugin_name = ref ($self);
225 $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
226
227 # read in file ($text will be in utf8)
228 my $text = "";
229
230 my $output_ext = $self->{'convert_to_ext'};
231 my $conv_filename = $self->tmp_area_convert_file($output_ext,$filename);
232 if ("$conv_filename" eq "") {return 0;} # allows continue on errors
233 if (! -e "$conv_filename") {return 0;} # allows continue on errors
234 $self->{'conv_filename'} = $conv_filename;
235
236# Do encoding stuff
237 my ($language, $encoding);
238 if ($self->{'input_encoding'} eq "auto") {
239 # use textcat to automatically work out the input encoding and language
240 ($language, $encoding) = $self->get_language_encoding ($conv_filename);
241 } elsif ($self->{'extract_language'}) {
242 # use textcat to get language metadata
243
244 my ($language, $extracted_encoding) = $self->get_language_encoding ($conv_filename);
245 $encoding = $self->{'input_encoding'};
246 if ($extracted_encoding ne $encoding && $self->{'verbosity'}) {
247 print $outhandle "$plugin_name: WARNING: $file was read using $encoding encoding but ";
248 print $outhandle "appears to be encoded as $extracted_encoding.\n";
249 }
250 } else {
251 $language = $self->{'default_language'};
252 $encoding = $self->{'input_encoding'};
253 }
254
255 BasPlug::read_file($self,$conv_filename, $encoding, \$text);
256 if (!length ($text)) {
257 print $outhandle "$plugin_name: ERROR: $file contains no text\n" if $self->{'verbosity'};
258 return 0;
259 }
260
261 # create a new document
262 my $doc_obj = new doc ($conv_filename, "indexed_doc");
263
264 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Language",
265 $language);
266 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Encoding",
267 $encoding);
268
269
270 # include any metadata passed in from previous plugins
271 # note that this metadata is associated with the top level section
272 $self->extra_metadata ($doc_obj, $doc_obj->get_top_section(), $metadata);
273 # do plugin specific processing of doc_obj
274 return undef unless defined ($self->process (\$text, $pluginfo, $base_dir, $file, $metadata, $doc_obj));
275 # do any automatic metadata extraction
276 $self->auto_extract_metadata ($doc_obj);
277 # add an OID
278 $doc_obj->set_OID();
279 # process the document
280 $processor->process($doc_obj);
281 $self->cleanup_tmp_area();
282
283
284 return 1;
285}
286
287
288# do plugin specific processing of doc_obj for HTML type
289sub process_type {
290 my $self = shift (@_);
291 my ($doc_ext, $textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_;
292
293 my $conv_filename = $self->{'conv_filename'};
294 my $tmp_dirname = File::Basename::dirname($conv_filename);
295 my $tmp_tailname = File::Basename::basename($conv_filename);
296
297 my $convert_to = $self->{'convert_to'};
298 my $ret_val;
299
300 if ($convert_to eq "TEXT")
301 {
302
303 $ret_val = TEXTPlug::process($self,$textref,$pluginfo,
304 $tmp_dirname,$tmp_tailname,
305 $metadata,$doc_obj);
306 }
307 else
308 {
309 $ret_val = HTMLPlug::process($self,$textref,$pluginfo,
310 $tmp_dirname,$tmp_tailname,
311 $metadata,$doc_obj);
312 }
313
314 # associate original file with doc object
315 my $cursection = $doc_obj->get_top_section();
316 my $filename = &util::filename_cat($base_dir,$file);
317 $doc_obj->associate_file($filename, "doc.$doc_ext", undef, $cursection);
318
319 my $doclink = "<a href=_httpcollection_/index/assoc/[archivedir]/doc.$doc_ext>";
320 $doc_obj->add_utf8_metadata ($cursection, "srclink", $doclink);
321 $doc_obj->add_utf8_metadata ($cursection, "srcicon", "_icon".$doc_ext."_");
322 $doc_obj->add_utf8_metadata ($cursection, "/srclink", "</a>");
323 return $ret_val;
324}
325
3261;
Note: See TracBrowser for help on using the repository browser.