source: trunk/gsdl/perllib/plugin.pm@ 10155

Last change on this file since 10155 was 10155, checked in by davidb, 19 years ago

deinit subroutine added that balances out init routine. 'init' called only
once when pipeline is set up. deinit now called when *every* pass using
the pipeline has finished. Note this is different to the 'begin' and 'end'
subroutines that can potentially be called just before a new round of
file processing with the pipeline (note: presently only buildcol.pl makes
multiple passes using the pipeline, importing only uses one pass).

  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1###########################################################################
2#
3# plugin.pm -- functions to handle using plugins
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package plugin;
27
28use strict; # to pick up typos and undeclared variables...
29no strict 'refs'; # ...but allow filehandles to be variables and vice versa
30
31require util;
32use gsprintf 'gsprintf';
33
34# global variables
35my $stats = {'num_processed' => 0,
36 'num_blocked' => 0,
37 'num_not_processed' => 0,
38 'num_not_recognised' => 0,
39 'num_archives' => 0
40 };
41
42#globaloptions contains any options that should be passed to all plugins
43my ($verbosity, $outhandle, $failhandle, $globaloptions);
44
45sub load_plugins {
46 my ($plugin_list) = shift @_;
47 ($verbosity, $outhandle, $failhandle, $globaloptions) = @_; # globals
48 my @plugin_objects = ();
49
50 $verbosity = 2 unless defined $verbosity;
51 $outhandle = 'STDERR' unless defined $outhandle;
52 $failhandle = 'STDERR' unless defined $failhandle;
53
54 map { $_ = "\"$_\""; } @$globaloptions;
55 my $globals = join (",", @$globaloptions);
56
57 foreach my $pluginoptions (@$plugin_list) {
58 my $pluginname = shift @$pluginoptions;
59 next unless defined $pluginname;
60
61 # find the plugin
62 my $colplugname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/plugins",
63 "${pluginname}.pm");
64 my $mainplugname = &util::filename_cat($ENV{'GSDLHOME'},"perllib/plugins",
65 "${pluginname}.pm");
66 if (-e $colplugname) { require $colplugname; }
67 elsif (-e $mainplugname) { require $mainplugname; }
68 else {
69 gsprintf($outhandle, "{plugin.could_not_find_plugin}\n",
70 $pluginname);
71 die "\n";
72 }
73
74 # create a plugin object
75 my ($plugobj);
76 map { $_ = "\"$_\""; } @$pluginoptions;
77 my $options = join (",", @$pluginoptions);
78 if ($globals) {
79 if (@$pluginoptions) {
80 $options .= ",";
81 }
82 $options .= "$globals";
83 }
84 $options =~ s/\$/\\\$/g;
85
86 eval ("\$plugobj = new \$pluginname($options)");
87 die "$@" if $@;
88
89 # initialize plugin
90 $plugobj->init($verbosity, $outhandle, $failhandle);
91
92 # add this object to the list
93 push (@plugin_objects, $plugobj);
94 }
95
96 return \@plugin_objects;
97}
98
99
100sub begin {
101 my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
102
103
104 map { $_->begin($pluginfo, $base_dir, $processor, $maxdocs); } @$pluginfo;
105}
106
107
108sub metadata_read {
109 my ($pluginfo, $base_dir, $file, $metadata, $extrametakeys, $extrametadata, $processor, $maxdocs, $gli, $aux) = @_;
110
111 $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
112 $gli = 0 unless defined $gli;
113
114 my $rv = 0;
115 my $glifile = $file;
116
117 $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
118
119 # Announce to GLI that we are handling a file
120 print STDERR "<File n='$glifile'>\n" if $gli;
121
122 # the .kill file is a handy (if not very elegant) way of aborting
123 # an import.pl or buildcol.pl process
124 if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
125 gsprintf($outhandle, "{plugin.kill_file}\n");
126 die "\n";
127 }
128
129 my $had_error = 0;
130 # pass this file by each of the plugins in turn until one
131 # is found which will process it
132 # read must return:
133 # undef - could not recognise
134 # -1 - tried but error
135 # 0 - blocked
136 # anything else for successful processing
137
138 foreach my $plugobj (@$pluginfo) {
139
140 $rv = $plugobj->metadata_read($pluginfo, $base_dir, $file,
141 $metadata, $extrametakeys, $extrametadata, $processor, $maxdocs, $gli, $aux);
142
143 if (defined $rv) {
144 if ($rv == -1) {
145 # an error has occurred
146 $had_error = 1;
147 print STDERR "<ProcessingError n='$glifile'>\n" if $gli;
148 } else {
149 return $rv;
150 }
151 } # else undefined - was not recognised by the plugin
152 }
153
154 return 0;
155}
156
157sub read {
158 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli, $aux) = @_;
159
160 $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
161 $total_count = 0 unless defined $total_count && $total_count =~ /\d/;
162 $gli = 0 unless defined $gli;
163
164 my $rv = 0;
165 my $glifile = $file;
166
167 $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
168
169 # Announce to GLI that we are handling a file
170 print STDERR "<File n='$glifile'>\n" if $gli;
171
172 # the .kill file is a handy (if not very elegant) way of aborting
173 # an import.pl or buildcol.pl process
174 if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
175 gsprintf($outhandle, "{plugin.kill_file}\n");
176 die "\n";
177 }
178
179 my $had_error = 0;
180 # pass this file by each of the plugins in turn until one
181 # is found which will process it
182 # read must return:
183 # undef - could not recognise
184 # -1 - tried but error
185 # 0 - blocked
186 # anything else for successful processing
187
188 foreach my $plugobj (@$pluginfo) {
189
190 $rv = $plugobj->read($pluginfo, $base_dir, $file,
191 $metadata, $processor, $maxdocs, $total_count, $gli, $aux);
192
193 if (defined $rv) {
194 if ($rv == -1) {
195 # an error has occurred
196 $had_error = 1;
197 } else {
198 return $rv;
199 }
200 } # else undefined - was not recognised by the plugin
201 }
202
203 if ($had_error) {
204 # was recognised but couldn't be processed
205 if ($verbosity >= 2) {
206 gsprintf($outhandle, "{plugin.no_plugin_could_process}\n", $file);
207 }
208 # tell the GLI that it was not processed
209 print STDERR "<NonProcessedFile n='$glifile'>\n" if $gli;
210
211 $file =~ s/.*?([^\\\/]+)$/$1/;
212 gsprintf($failhandle, "$file: {plugin.no_plugin_could_process_this_file}\n");
213 $stats->{'num_not_processed'} ++;
214 } else {
215 # was not recognised
216 if ($verbosity >= 2) {
217 gsprintf($outhandle, "{plugin.no_plugin_could_recognise}\n",$file);
218 }
219 # tell the GLI that it was not processed
220 print STDERR "<NonRecognisedFile n='$glifile'>\n" if $gli;
221
222 $file =~ s/.*?([^\\\/]+)$/$1/;
223 gsprintf($failhandle, "$file: {plugin.no_plugin_could_recognise_this_file}\n");
224 $stats->{'num_not_recognised'} ++;
225 }
226 return 0;
227}
228
229# write out some general stats that the plugins have compiled - note that
230# the buildcol.pl process doesn't currently call this process so the stats
231# are only output after import.pl -
232sub write_stats {
233 my ($pluginfo, $statshandle, $faillog, $gli) = @_;
234
235 $gli = 0 unless defined $gli;
236
237 foreach my $plugobj (@$pluginfo) {
238 $plugobj->compile_stats($stats);
239 }
240
241 my $total = $stats->{'num_processed'} + $stats->{'num_blocked'} +
242 $stats->{'num_not_processed'} + $stats->{'num_not_recognised'};
243
244 print STDERR "<ImportComplete considered='$total' processed='$stats->{'num_processed'}' blocked='$stats->{'num_blocked'}' ignored='$stats->{'num_not_recognised'}' failed='$stats->{'num_not_processed'}'>\n" if $gli;
245
246 if ($total == 1) {
247 gsprintf($statshandle, "* {plugin.one_considered}\n");
248 } else {
249 gsprintf($statshandle, "* {plugin.n_considered}\n", $total);
250 }
251 if ($stats->{'num_archives'}) {
252 if ($stats->{'num_archives'} == 1) {
253 gsprintf($statshandle, " ({plugin.including_archive})\n");
254 }
255 else {
256 gsprintf($statshandle, " ({plugin.including_archives})\n",
257 $stats->{'num_archives'});
258 }
259 }
260 if ($stats->{'num_processed'} == 1) {
261 gsprintf($statshandle, "* {plugin.one_included}\n");
262 } else {
263 gsprintf($statshandle, "* {plugin.n_included}\n", $stats->{'num_processed'});
264 }
265 if ($stats->{'num_not_recognised'}) {
266 if ($stats->{'num_not_recognised'} == 1) {
267 gsprintf($statshandle, "* {plugin.one_unrecognised}\n");
268 } else {
269 gsprintf($statshandle, "* {plugin.n_unrecognised}\n",
270 $stats->{'num_not_recognised'});
271 }
272
273 }
274 if ($stats->{'num_not_processed'}) {
275 if ($stats->{'num_not_processed'} == 1) {
276 gsprintf($statshandle, "* {plugin.one_rejected}\n");
277 } else {
278 gsprintf($statshandle, "* {plugin.n_rejected}\n",
279 $stats->{'num_not_processed'});
280 }
281 }
282 if ($stats->{'num_not_processed'} || $stats->{'num_not_recognised'}) {
283 gsprintf($statshandle, " {plugin.see_faillog}\n", $faillog);
284 }
285}
286
287sub end {
288 my ($pluginfo, $processor) = @_;
289 map { $_->end($processor); } @$pluginfo;
290}
291
292sub deinit {
293 my ($pluginfo, $processor) = @_;
294
295
296 map { $_->deinit($processor); } @$pluginfo;
297}
298
2991;
Note: See TracBrowser for help on using the repository browser.