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

Last change on this file since 15114 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
RevLine 
[537]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###########################################################################
[4]25
26package plugin;
27
[7829]28use strict; # to pick up typos and undeclared variables...
29no strict 'refs'; # ...but allow filehandles to be variables and vice versa
[10579]30no strict 'subs';
[7829]31
[134]32require util;
[7829]33use gsprintf 'gsprintf';
[4]34
[7829]35# global variables
[2785]36my $stats = {'num_processed' => 0,
37 'num_blocked' => 0,
38 'num_not_processed' => 0,
[7363]39 'num_not_recognised' => 0,
[2785]40 'num_archives' => 0
41 };
42
[7829]43#globaloptions contains any options that should be passed to all plugins
44my ($verbosity, $outhandle, $failhandle, $globaloptions);
[5682]45
[10579]46
[14933]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
[10579]58 # find the plugin
[14239]59 if (defined($ENV{'GSDLCOLLECTION'}))
60 {
[14933]61 my $customplugname
62 = &util::filename_cat($collectdir, "custom",$ENV{'GSDLCOLLECTION'},
63 $pp_plugname);
64 push(@check_list,$customplugname);
[14239]65 }
[14933]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) {
[10579]96 &gsprintf(STDERR, "{plugin.could_not_find_plugin}\n",
[14933]97 $pluginname);
[10579]98 die "\n";
99 }
[14933]100}
[10579]101
[14933]102sub load_plugin_for_info {
103 my ($pluginname) = shift @_;
104
105 load_plugin_require($pluginname);
106
[10579]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
[4]117sub load_plugins {
[1431]118 my ($plugin_list) = shift @_;
[12968]119 my $incremental;
120 ($verbosity, $outhandle, $failhandle, $globaloptions, $incremental) = @_; # globals
[4]121 my @plugin_objects = ();
[12968]122 $incremental = 0 unless (defined $incremental && $incremental == 1);
[1243]123 $verbosity = 2 unless defined $verbosity;
[7829]124 $outhandle = 'STDERR' unless defined $outhandle;
125 $failhandle = 'STDERR' unless defined $failhandle;
[1243]126
[13933]127 my $colplugindir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/plugins");
128 unshift (@INC, $colplugindir);
129
[6584]130 map { $_ = "\"$_\""; } @$globaloptions;
131 my $globals = join (",", @$globaloptions);
132
[7829]133 foreach my $pluginoptions (@$plugin_list) {
[809]134 my $pluginname = shift @$pluginoptions;
135 next unless defined $pluginname;
136
[14933]137 load_plugin_require($pluginname);
[4]138
139 # create a plugin object
140 my ($plugobj);
[809]141 map { $_ = "\"$_\""; } @$pluginoptions;
142 my $options = join (",", @$pluginoptions);
[6584]143 if ($globals) {
144 if (@$pluginoptions) {
145 $options .= ",";
146 }
147 $options .= "$globals";
148 }
[1244]149 $options =~ s/\$/\\\$/g;
[7904]150
[10218]151 eval ("\$plugobj = new \$pluginname([],[$options])");
[4]152 die "$@" if $@;
[809]153
[1243]154 # initialize plugin
[2785]155 $plugobj->init($verbosity, $outhandle, $failhandle);
[10478]156
[12968]157 $plugobj->set_incremental($incremental);
[1243]158
[4]159 # add this object to the list
160 push (@plugin_objects, $plugobj);
161 }
162
163 return \@plugin_objects;
164}
165
[835]166
167sub begin {
[11333]168 my ($pluginfo, $base_dir, $processor, $maxdocs, $gli) = @_;
[835]169
[11333]170 map { $_->{'gli'} = $gli; } @$pluginfo;
[835]171 map { $_->begin($pluginfo, $base_dir, $processor, $maxdocs); } @$pluginfo;
172}
173
[10155]174
[8515]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
[4]224sub read {
[9853]225 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli, $aux) = @_;
[4]226
[809]227 $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
[9853]228 $total_count = 0 unless defined $total_count && $total_count =~ /\d/;
[6332]229 $gli = 0 unless defined $gli;
230
[315]231 my $rv = 0;
[7363]232 my $glifile = $file;
[7904]233
[7363]234 $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
[8515]235
[6332]236 # Announce to GLI that we are handling a file
[7363]237 print STDERR "<File n='$glifile'>\n" if $gli;
[8515]238
[1454]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")) {
[7829]242 gsprintf($outhandle, "{plugin.kill_file}\n");
[1454]243 die "\n";
244 }
[8515]245
[7363]246 my $had_error = 0;
[4]247 # pass this file by each of the plugins in turn until one
248 # is found which will process it
[7363]249 # read must return:
250 # undef - could not recognise
251 # -1 - tried but error
252 # 0 - blocked
253 # anything else for successful processing
[8515]254
[7829]255 foreach my $plugobj (@$pluginfo) {
[8515]256
257 $rv = $plugobj->read($pluginfo, $base_dir, $file,
[9853]258 $metadata, $processor, $maxdocs, $total_count, $gli, $aux);
[8515]259
260 if (defined $rv) {
[7363]261 if ($rv == -1) {
[7904]262 # an error has occurred
[7363]263 $had_error = 1;
264 } else {
[7904]265 return $rv;
[7363]266 }
267 } # else undefined - was not recognised by the plugin
[4]268 }
[7904]269
[7363]270 if ($had_error) {
271 # was recognised but couldn't be processed
272 if ($verbosity >= 2) {
[7829]273 gsprintf($outhandle, "{plugin.no_plugin_could_process}\n", $file);
[7363]274 }
275 # tell the GLI that it was not processed
276 print STDERR "<NonProcessedFile n='$glifile'>\n" if $gli;
[7904]277
[7829]278 gsprintf($failhandle, "$file: {plugin.no_plugin_could_process_this_file}\n");
[7363]279 $stats->{'num_not_processed'} ++;
280 } else {
281 # was not recognised
282 if ($verbosity >= 2) {
[7829]283 gsprintf($outhandle, "{plugin.no_plugin_could_recognise}\n",$file);
[7363]284 }
285 # tell the GLI that it was not processed
286 print STDERR "<NonRecognisedFile n='$glifile'>\n" if $gli;
287
[7829]288 gsprintf($failhandle, "$file: {plugin.no_plugin_could_recognise_this_file}\n");
[7363]289 $stats->{'num_not_recognised'} ++;
[170]290 }
[315]291 return 0;
[4]292}
293
[2785]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 {
[6332]298 my ($pluginfo, $statshandle, $faillog, $gli) = @_;
[2785]299
[6332]300 $gli = 0 unless defined $gli;
301
[7829]302 foreach my $plugobj (@$pluginfo) {
[2785]303 $plugobj->compile_stats($stats);
304 }
305
306 my $total = $stats->{'num_processed'} + $stats->{'num_blocked'} +
[7363]307 $stats->{'num_not_processed'} + $stats->{'num_not_recognised'};
[2785]308
[7363]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;
[6332]310
[2785]311 if ($total == 1) {
[7829]312 gsprintf($statshandle, "* {plugin.one_considered}\n");
[2785]313 } else {
[7829]314 gsprintf($statshandle, "* {plugin.n_considered}\n", $total);
[2785]315 }
316 if ($stats->{'num_archives'}) {
[5682]317 if ($stats->{'num_archives'} == 1) {
[7829]318 gsprintf($statshandle, " ({plugin.including_archive})\n");
[5682]319 }
320 else {
[7829]321 gsprintf($statshandle, " ({plugin.including_archives})\n",
322 $stats->{'num_archives'});
[5682]323 }
[2785]324 }
325 if ($stats->{'num_processed'} == 1) {
[7829]326 gsprintf($statshandle, "* {plugin.one_included}\n");
[2785]327 } else {
[7829]328 gsprintf($statshandle, "* {plugin.n_included}\n", $stats->{'num_processed'});
[2785]329 }
[7363]330 if ($stats->{'num_not_recognised'}) {
331 if ($stats->{'num_not_recognised'} == 1) {
[7829]332 gsprintf($statshandle, "* {plugin.one_unrecognised}\n");
[7363]333 } else {
[7829]334 gsprintf($statshandle, "* {plugin.n_unrecognised}\n",
335 $stats->{'num_not_recognised'});
[7363]336 }
337
338 }
[2797]339 if ($stats->{'num_not_processed'}) {
340 if ($stats->{'num_not_processed'} == 1) {
[7829]341 gsprintf($statshandle, "* {plugin.one_rejected}\n");
[2797]342 } else {
[7829]343 gsprintf($statshandle, "* {plugin.n_rejected}\n",
344 $stats->{'num_not_processed'});
[5682]345 }
[7363]346 }
347 if ($stats->{'num_not_processed'} || $stats->{'num_not_recognised'}) {
[7829]348 gsprintf($statshandle, " {plugin.see_faillog}\n", $faillog);
[2797]349 }
[2785]350}
351
[835]352sub end {
[1587]353 my ($pluginfo, $processor) = @_;
354 map { $_->end($processor); } @$pluginfo;
[835]355}
[4]356
[10155]357sub deinit {
358 my ($pluginfo, $processor) = @_;
359
360
361 map { $_->deinit($processor); } @$pluginfo;
362}
363
[4]3641;
Note: See TracBrowser for help on using the repository browser.