source: main/tags/2.60/gsdl/perllib/lucenebuildproc.pm@ 32313

Last change on this file since 32313 was 9669, checked in by kjdon, 19 years ago

fixed up the case where you have subcollection partitions and language partitions - was doing an OR on both, but really needed an OR for partitions ANDed with an OR for langs

  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1###########################################################################
2#
3# lucenebuildproc.pm -- perl wrapper for building index with Lucene
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 lucenebuildproc;
27
28# This document processor outputs a document
29# for lucene to process
30
31# Use same basic XML structure setup by mgppbuilder/mgppbuildproc
32
33use mgppbuildproc;
34use ghtml;
35
36sub BEGIN {
37 @lucenebuildproc::ISA = ('mgppbuildproc');
38}
39
40
41sub new {
42 my $class = shift @_;
43 my $self = new mgppbuildproc (@_);
44
45 return bless $self, $class;
46}
47
48sub set_gdbm_level {
49 my $self = shift(@_);
50 my ($level) = @_;
51
52 $self->{'gdbm_level'} = $level;
53}
54sub preprocess_text {
55 my $self = shift (@_);
56 my ($text, $strip_html, $para) = @_;
57
58 my ($outtext) = "";
59 if ($strip_html) {
60 while ($text =~ /<([^>]*)>/ && $text ne "") {
61
62 my $tag = $1;
63 $outtext .= $`." "; #add everything before the matched tag
64 $text = $'; #'everything after the matched tag
65 if ($para && $tag =~ /^\s*p\s/i) {
66 $outtext .= $para;
67 }
68 elsif ($tag =~ /^pre$/) { # a pre tag
69 $text =~ /<\/pre>/; # find the closing pre tag
70 my $tmp_text = $`; #everything before the closing pre tag
71 $text = $'; #'everything after the </pre>
72 $tmp_text =~ s/[<>]//g; # remove all < and >
73 $outtext.= $tmp_text . " ";
74 }
75 }
76
77 $outtext .= $text; # add any remaining text
78 } #if strip_html
79 else {
80 $outtext = $text;
81 }
82 #if ($para) {
83 #$text =~ s/(<p\b)/$para$1/gi;
84 #return $text;
85 #}
86
87 # remove entities
88 $outtext =~ s/&\w{1,10};//g;
89
90 return $outtext;
91}
92
93sub text {
94 my $self = shift (@_);
95 my ($doc_obj,$file) = @_;
96 my $handle = $self->{'output_handle'};
97 my $outhandle = $self->{'outhandle'};
98 my $indexed_doc = 1;
99
100 # only output this document if it is one to be indexed
101 return if ($doc_obj->get_doc_type() ne "indexed_doc");
102
103 # see if this document belongs to this subcollection
104 foreach my $indexexp (@{$self->{'indexexparr'}}) {
105 $indexed_doc = 0;
106 my ($field, $exp, $options) = split /\//, $indexexp;
107 if (defined ($field) && defined ($exp)) {
108 my ($bool) = $field =~ /^(.)/;
109 $field =~ s/^.// if $bool eq '!';
110 if ($field =~ /^filename$/i) {
111 $field = $doc_obj->get_source_filename();
112 } else {
113 $field = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $field);
114 }
115 next unless defined $field;
116 if ($bool eq '!') {
117 if ($options =~ /^i$/i) {
118 if ($field !~ /$exp/i) {$indexed_doc = 1; last;}
119 } else {
120 if ($field !~ /$exp/) {$indexed_doc = 1; last;}
121 }
122 } else {
123 if ($options =~ /^i$/i) {
124 if ($field =~ /$exp/i) {$indexed_doc = 1; last;}
125 } else {
126 if ($field =~ /$exp/) {$indexed_doc = 1; last;}
127 }
128 }
129 }
130 }
131
132 # if this doc is so far in the sub collection, and we have lang info,
133 # now we check the languages to see if it matches
134 if($indexed_doc && defined $self->{'lang_meta'}) {
135 $indexed_doc = 0;
136 my $field = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'lang_meta'});
137 if (defined $field) {
138 foreach my $lang (@{$self->{'langarr'}}) {
139 my ($bool) = $lang =~ /^(.)/;
140 if ($bool eq '!') {
141 $lang =~ s/^.//;
142 if ($field !~ /$lang/) {
143 $indexed_doc = 1; last;
144 }
145 } else {
146 if ($field =~ /$lang/) {
147 $indexed_doc = 1; last;
148 }
149 }
150 }
151 }
152 }
153
154 # this is another document
155 $self->{'num_docs'} += 1;
156
157 # get the parameters for the output
158 # split on : just in case there is subcoll and lang stuff
159 my ($fields) = split (/:/, $self->{'index'});
160
161 my $doc_level = $mgppbuildproc::level_map{'document'};
162 my $gs2ns = 'xmlns:gs2="http://www.greenstone.org/gs2"';
163
164 my $levels = $self->{'levels'};
165 my $ldoc_level = $levels->{'document'};
166 my $lsec_level = $levels->{'section'};
167 my $lpar_level = $levels->{'paragraph'};
168
169 my $docid="";
170 if ($ldoc_level) {
171 if ($self->{'gdbm_level'} eq 'document') {
172 my $doc_sec_num = $self->{'num_docs'};
173 $docid = "gs2:id=\"$doc_sec_num\"";
174 } else {
175 # default is section level
176 my $doc_sec_num = $self->{'num_sections'}+1;
177 $docid = "gs2:id=\"$doc_sec_num\"";
178 }
179 }
180 my $documenttag = "<$doc_level $gs2ns file=\"$file\" $docid >\n";
181 my $documentendtag = "\n</$doc_level>\n";
182
183 my ($sectiontag) = "";
184 if ($lsec_level) {
185 $sectiontag = $mgppbuildproc::level_map{'section'};
186 }
187 my ($parastarttag) = "";
188 my ($paraendtag) = "";
189 if ($self->{'levels'}->{'paragraph'}) {
190 if ($self->{'strip_html'}) {
191 $parastarttag = "<".$mgppbuildproc::level_map{'paragraph'}.">";
192 $paraendtag = "</".$mgppbuildproc::level_map{'paragraph'}.">";
193 } else {
194 print $outhandle "Paragraph level can not be used with no_strip_html!. Not indexing Paragraphs.\n";
195 }
196 }
197
198 my $doc_section = 0; # just for this document
199
200 my $text = "";
201 $text .= $documenttag;
202 # get the text for this document
203 my $section = $doc_obj->get_top_section();
204 while (defined $section) {
205 # update a few statistics
206 $doc_section++;
207 $self->{'num_sections'} += 1;
208
209 if ($sectiontag ne "") {
210 my $secid = "gs2:id=\"".$self->{'num_sections'}."\"";
211 $text .= "\n<$sectiontag $secid >\n";
212 }
213
214 # if we are doing subcollections, then some docs shouldn't be indexed.
215 # but we need to put the section tag placeholders in there so the
216 # sections match up with gdbm db
217 if ($indexed_doc) {
218 #if ($self->{'indexing_text'}) {
219 # $text .= "$parastarttag"; # only add para tags for indexing
220 # note that we assume that metadata will not be asked for for the compressed text, so we add para tags without checking for indexing_text
221 # }
222 $self->{'num_bytes'} += $doc_obj->get_text_length ($section);
223 foreach my $field (split (/,/, $fields)) {
224 # only deal with this field if it doesn't start with top or
225 # this is the first section
226 my $real_field = $field;
227 if (!($real_field =~ s/^top//) || ($doc_section == 1)) {
228 my $new_text = "";
229 my $tmp_text = "";
230 if ($real_field eq "text") {
231 if ($self->{'indexing_text'}) { #tag the text with <Text>...</Text>, add the <Paragraph> tags and strip out html if needed
232 $new_text .= "$parastarttag<TX index=\"1\">\n";
233 $tmp_text .= $doc_obj->get_text ($section);
234 if ($parastarttag =~ "") {
235 # we don't want to individually tag each paragraph if not doing para indexing
236 $tmp_text = $self->preprocess_text($tmp_text, $self->{'strip_html'}, "");
237 } else {
238 $tmp_text = $self->preprocess_text($tmp_text, $self->{'strip_html'}, "</TX>$paraendtag$parastarttag<TX index=\"1\">");
239 }
240
241 $new_text .= "$tmp_text</TX>$paraendtag\n";
242 #if (!defined $self->{'indexfields'}->{'TextOnly'}) {
243 #$self->{'indexfields'}->{'TextOnly'} = 1;
244 #}
245 }
246 else { # leave html stuff in, but escape the tags, and dont add Paragraph tags - never retrieve paras at the moment
247 if ($self->{'store_text'}) {
248 $tmp_text .= $doc_obj->get_text ($section);
249 &ghtml::htmlsafe($tmp_text);
250 $new_text .= $tmp_text;
251 }
252 }
253 } else { # metadata field
254 if ($real_field eq "allfields") { #ignore
255 }
256 elsif ($real_field eq "metadata") { # insert all metadata
257 #except gsdl stuff
258 my $shortname = "";
259 my $metadata = $doc_obj->get_all_metadata ($section);
260 foreach $pair (@$metadata) {
261 my ($mfield, $mvalue) = (@$pair);
262 # check fields here, maybe others dont want - change to use dontindex!!
263 if ($mfield ne "Identifier"
264 && $mfield !~ /^gsdl/
265 && $mfield ne "classifytype"
266 && $mfield ne "assocfilepath"
267 && defined $mvalue && $mvalue ne "") {
268
269 if (defined $self->{'indexfieldmap'}->{$mfield}) {
270 $shortname = $self->{'indexfieldmap'}->{$mfield};
271 }
272 else {
273 $shortname = $self->create_shortname($mfield);
274 $self->{'indexfieldmap'}->{$mfield} = $shortname;
275 $self->{'indexfieldmap'}->{$shortname} = 1;
276 }
277 $new_text .= "$parastarttag<$shortname index=\"1\">$mvalue</$shortname>$paraendtag\n";
278 if (!defined $self->{'indexfields'}->{$mfield}) {
279 $self->{'indexfields'}->{$mfield} = 1;
280 }
281 }
282 }
283
284 }
285 else { #individual metadata specified
286 my $shortname="";
287 #if (!defined $self->{'indexfields'}->{$real_field}) {
288 #$self->{'indexfields'}->{$real_field} = 1;
289 #}
290 if (defined $self->{'indexfieldmap'}->{$real_field}) {
291 $shortname = $self->{'indexfieldmap'}->{$real_field};
292 }
293 else {
294 $shortname = $self->create_shortname($real_field);
295 $self->{'indexfieldmap'}->{$real_field} = $shortname;
296 $self->{'indexfieldmap'}->{$shortname} = 1;
297 }
298 foreach $item (@{$doc_obj->get_metadata ($section, $real_field)}) {
299 $new_text .= "$parastarttag<$shortname index=\"1\">$item</$shortname>$paraendtag\n";
300 # remove entities
301 $new_text =~ s/&\w{1,10};//g;
302 }
303 }
304
305 }
306
307 # filter the text
308 $self->filter_text ($field, $new_text);
309 $self->{'num_processed_bytes'} += length ($new_text);
310 $text .= "$new_text";
311 }
312 }
313 } # if (indexed_doc)
314
315 $text .= "\n</$sectiontag>\n" if ($sectiontag ne "");
316
317 $section = $doc_obj->get_next_section($section);
318 } #while defined section
319 print $handle "$text\n$documentendtag";
320}
321
3221;
323
Note: See TracBrowser for help on using the repository browser.