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

Last change on this file since 15073 was 14933, checked in by davidb, 16 years ago

plugin.pm modified to look for plugins in extension folder

  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 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
30no strict 'subs';
31
32require util;
33use gsprintf 'gsprintf';
34
35# global variables
36my $stats = {'num_processed' => 0,
37 'num_blocked' => 0,
38 'num_not_processed' => 0,
39 'num_not_recognised' => 0,
40 'num_archives' => 0
41 };
42
43#globaloptions contains any options that should be passed to all plugins
44my ($verbosity, $outhandle, $failhandle, $globaloptions);
45
46
47sub load_plugin_require
48{
49 my ($pluginname) = @_;
50
51 my @check_list = ();
52
53 # pp_plugname shorthand for 'perllib' 'plugin' '$pluginname.pm'
54 my $pp_plugname
55 = &util::filename_cat('perllib', 'plugins', "${pluginname}.pm");
56 my $collectdir = $ENV{'GSDLCOLLECTDIR'};
57
58 # find the plugin
59 if (defined($ENV{'GSDLCOLLECTION'}))
60 {
61 my $customplugname
62 = &util::filename_cat($collectdir, "custom",$ENV{'GSDLCOLLECTION'},
63 $pp_plugname);
64 push(@check_list,$customplugname);
65 }
66
67 my $colplugname = &util::filename_cat($collectdir, $pp_plugname);
68 push(@check_list,$colplugname);
69
70 if (defined $ENV{'GSDLEXTS'}) {
71
72 my $ext_prefix = &util::filename_cat($ENV{'GSDLHOME'}, "ext");
73
74 my @extensions = split(/:/,$ENV{'GSDLEXTS'});
75 foreach my $e (@extensions) {
76 my $extplugname = &util::filename_cat($ext_prefix, $e, $pp_plugname);
77 push(@check_list,$extplugname);
78
79 }
80 }
81
82
83 my $mainplugname = &util::filename_cat($ENV{'GSDLHOME'}, $pp_plugname);
84 push(@check_list,$mainplugname);
85
86 my $success=0;
87 foreach my $plugname (@check_list) {
88 if (-e $plugname) {
89 require $plugname;
90 $success=1;
91 last;
92 }
93 }
94
95 if (!$success) {
96 &gsprintf(STDERR, "{plugin.could_not_find_plugin}\n",
97 $pluginname);
98 die "\n";
99 }
100}
101
102sub load_plugin_for_info {
103 my ($pluginname) = shift @_;
104
105 load_plugin_require($pluginname);
106
107 # create a plugin object
108 my ($plugobj);
109 my $options = "-gsdlinfo";
110
111 eval ("\$plugobj = new \$pluginname([],[$options])");
112 die "$@" if $@;
113
114 return $plugobj;
115}
116
117sub load_plugins {
118 my ($plugin_list) = shift @_;
119 my $incremental;
120 ($verbosity, $outhandle, $failhandle, $globaloptions, $incremental) = @_; # globals
121 my @plugin_objects = ();
122 $incremental = 0 unless (defined $incremental && $incremental == 1);
123 $verbosity = 2 unless defined $verbosity;
124 $outhandle = 'STDERR' unless defined $outhandle;
125 $failhandle = 'STDERR' unless defined $failhandle;
126
127 my $colplugindir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/plugins");
128 unshift (@INC, $colplugindir);
129
130 map { $_ = "\"$_\""; } @$globaloptions;
131 my $globals = join (",", @$globaloptions);
132
133 foreach my $pluginoptions (@$plugin_list) {
134 my $pluginname = shift @$pluginoptions;
135 next unless defined $pluginname;
136
137 load_plugin_require($pluginname);
138
139 # create a plugin object
140 my ($plugobj);
141 map { $_ = "\"$_\""; } @$pluginoptions;
142 my $options = join (",", @$pluginoptions);
143 if ($globals) {
144 if (@$pluginoptions) {
145 $options .= ",";
146 }
147 $options .= "$globals";
148 }
149 $options =~ s/\$/\\\$/g;
150
151 eval ("\$plugobj = new \$pluginname([],[$options])");
152 die "$@" if $@;
153
154 # initialize plugin
155 $plugobj->init($verbosity, $outhandle, $failhandle);
156
157 $plugobj->set_incremental($incremental);
158
159 # add this object to the list
160 push (@plugin_objects, $plugobj);
161 }
162
163 return \@plugin_objects;
164}
165
166
167sub begin {
168 my ($pluginfo, $base_dir, $processor, $maxdocs, $gli) = @_;
169
170 map { $_->{'gli'} = $gli; } @$pluginfo;
171 map { $_->begin($pluginfo, $base_dir, $processor, $maxdocs); } @$pluginfo;
172}
173
174
175sub metadata_read {
176 my ($pluginfo, $base_dir, $file, $metadata, $extrametakeys, $extrametadata, $processor, $maxdocs, $gli, $aux) = @_;
177
178 $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
179 $gli = 0 unless defined $gli;
180
181 my $rv = 0;
182 my $glifile = $file;
183
184 $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
185
186 # Announce to GLI that we are handling a file
187 print STDERR "<File n='$glifile'>\n" if $gli;
188
189 # the .kill file is a handy (if not very elegant) way of aborting
190 # an import.pl or buildcol.pl process
191 if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
192 gsprintf($outhandle, "{plugin.kill_file}\n");
193 die "\n";
194 }
195
196 my $had_error = 0;
197 # pass this file by each of the plugins in turn until one
198 # is found which will process it
199 # read must return:
200 # undef - could not recognise
201 # -1 - tried but error
202 # 0 - blocked
203 # anything else for successful processing
204
205 foreach my $plugobj (@$pluginfo) {
206
207 $rv = $plugobj->metadata_read($pluginfo, $base_dir, $file,
208 $metadata, $extrametakeys, $extrametadata, $processor, $maxdocs, $gli, $aux);
209
210 if (defined $rv) {
211 if ($rv == -1) {
212 # an error has occurred
213 $had_error = 1;
214 print STDERR "<ProcessingError n='$glifile'>\n" if $gli;
215 } else {
216 return $rv;
217 }
218 } # else undefined - was not recognised by the plugin
219 }
220
221 return 0;
222}
223
224sub read {
225 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli, $aux) = @_;
226
227 $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
228 $total_count = 0 unless defined $total_count && $total_count =~ /\d/;
229 $gli = 0 unless defined $gli;
230
231 my $rv = 0;
232 my $glifile = $file;
233
234 $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
235
236 # Announce to GLI that we are handling a file
237 print STDERR "<File n='$glifile'>\n" if $gli;
238
239 # the .kill file is a handy (if not very elegant) way of aborting
240 # an import.pl or buildcol.pl process
241 if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
242 gsprintf($outhandle, "{plugin.kill_file}\n");
243 die "\n";
244 }
245
246 my $had_error = 0;
247 # pass this file by each of the plugins in turn until one
248 # is found which will process it
249 # read must return:
250 # undef - could not recognise
251 # -1 - tried but error
252 # 0 - blocked
253 # anything else for successful processing
254
255 foreach my $plugobj (@$pluginfo) {
256
257 $rv = $plugobj->read($pluginfo, $base_dir, $file,
258 $metadata, $processor, $maxdocs, $total_count, $gli, $aux);
259
260 if (defined $rv) {
261 if ($rv == -1) {
262 # an error has occurred
263 $had_error = 1;
264 } else {
265 return $rv;
266 }
267 } # else undefined - was not recognised by the plugin
268 }
269
270 if ($had_error) {
271 # was recognised but couldn't be processed
272 if ($verbosity >= 2) {
273 gsprintf($outhandle, "{plugin.no_plugin_could_process}\n", $file);
274 }
275 # tell the GLI that it was not processed
276 print STDERR "<NonProcessedFile n='$glifile'>\n" if $gli;
277
278 gsprintf($failhandle, "$file: {plugin.no_plugin_could_process_this_file}\n");
279 $stats->{'num_not_processed'} ++;
280 } else {
281 # was not recognised
282 if ($verbosity >= 2) {
283 gsprintf($outhandle, "{plugin.no_plugin_could_recognise}\n",$file);
284 }
285 # tell the GLI that it was not processed
286 print STDERR "<NonRecognisedFile n='$glifile'>\n" if $gli;
287
288 gsprintf($failhandle, "$file: {plugin.no_plugin_could_recognise_this_file}\n");
289 $stats->{'num_not_recognised'} ++;
290 }
291 return 0;
292}
293
294# write out some general stats that the plugins have compiled - note that
295# the buildcol.pl process doesn't currently call this process so the stats
296# are only output after import.pl -
297sub write_stats {
298 my ($pluginfo, $statshandle, $faillog, $gli) = @_;
299
300 $gli = 0 unless defined $gli;
301
302 foreach my $plugobj (@$pluginfo) {
303 $plugobj->compile_stats($stats);
304 }
305
306 my $total = $stats->{'num_processed'} + $stats->{'num_blocked'} +
307 $stats->{'num_not_processed'} + $stats->{'num_not_recognised'};
308
309 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;
310
311 if ($total == 1) {
312 gsprintf($statshandle, "* {plugin.one_considered}\n");
313 } else {
314 gsprintf($statshandle, "* {plugin.n_considered}\n", $total);
315 }
316 if ($stats->{'num_archives'}) {
317 if ($stats->{'num_archives'} == 1) {
318 gsprintf($statshandle, " ({plugin.including_archive})\n");
319 }
320 else {
321 gsprintf($statshandle, " ({plugin.including_archives})\n",
322 $stats->{'num_archives'});
323 }
324 }
325 if ($stats->{'num_processed'} == 1) {
326 gsprintf($statshandle, "* {plugin.one_included}\n");
327 } else {
328 gsprintf($statshandle, "* {plugin.n_included}\n", $stats->{'num_processed'});
329 }
330 if ($stats->{'num_not_recognised'}) {
331 if ($stats->{'num_not_recognised'} == 1) {
332 gsprintf($statshandle, "* {plugin.one_unrecognised}\n");
333 } else {
334 gsprintf($statshandle, "* {plugin.n_unrecognised}\n",
335 $stats->{'num_not_recognised'});
336 }
337
338 }
339 if ($stats->{'num_not_processed'}) {
340 if ($stats->{'num_not_processed'} == 1) {
341 gsprintf($statshandle, "* {plugin.one_rejected}\n");
342 } else {
343 gsprintf($statshandle, "* {plugin.n_rejected}\n",
344 $stats->{'num_not_processed'});
345 }
346 }
347 if ($stats->{'num_not_processed'} || $stats->{'num_not_recognised'}) {
348 gsprintf($statshandle, " {plugin.see_faillog}\n", $faillog);
349 }
350}
351
352sub end {
353 my ($pluginfo, $processor) = @_;
354 map { $_->end($processor); } @$pluginfo;
355}
356
357sub deinit {
358 my ($pluginfo, $processor) = @_;
359
360
361 map { $_->deinit($processor); } @$pluginfo;
362}
363
3641;
Note: See TracBrowser for help on using the repository browser.