source: main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm

Last change on this file was 37591, checked in by davidb, 13 months ago

fixed mistake in fldv file concat; changed type of logged error message

File size: 41.6 KB
Line 
1##########################################################################
2#
3# metadataaction.pm --
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) 2009 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 metadataaction;
27
28use strict;
29
30use cgiactions::baseaction;
31use cgiactions::metadataactioncommon;
32
33use dbutil;
34use ghtml;
35
36use JSON;
37
38# convenient to have shorter version around
39my $FLDV_HISTORY_DIR = $metadataactioncommon::FLDV_HISTORY_DIR;
40
41# This class is conditionally expanded with set-metadata, remove-metadata and insert-metadata subroutines
42# defined in modmetadataaction.pm. The BEGIN code block determines whether the condition holds.
43# See
44# http://stackoverflow.com/questions/3998619/what-is-the-role-of-the-begin-block-in-perl
45# http://www.perlmonks.org/?node_id=881761 - splitting module into multiple files
46# http://www.perlmonks.org/?node_id=524456 - merging hashes
47
48our $modmeta_action_table; # don't init to empty hash here, else it will overwrite whatever BEGIN sets this to
49 # see http://stackoverflow.com/questions/3998619/what-is-the-role-of-the-begin-block-in-perl
50
51BEGIN {
52# unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/perl-5.8");
53 require XML::Rules;
54
55 # if we're GS3, then GS3_AUTHENTICATED must be defined and set to true
56 # in order to have access to subroutines that modify metadata (the set-
57 # and remove- metadata subroutines).
58 # TODO: if we're GS2, then we continue to behave as before?
59
60 if(!defined $ENV{'GSDL3HOME'} || (defined $ENV{'GS3_AUTHENTICATED'} && $ENV{'GS3_AUTHENTICATED'} eq "true")) {
61 require modmetadataaction;
62 }
63 else {
64 $modmeta_action_table = {};
65 }
66}
67
68@metadataaction::ISA = ('baseaction');
69
70
71my $getmeta_action_table =
72{
73 # unused and untested
74 # when DocEdit=1, need to retrieve a doc's full text (or doc section's full text) from archives
75 "get-archives-text" => {
76 'compulsory-args' => [ "d" ],
77 'optional-args' => [ "dv" ]
78 #'compulsory-args' => [ "d" ],
79 #'optional-args' => [ "section" ] },
80 },
81
82 #GET METHODS
83 "get-import-metadata" => {
84 'compulsory-args' => [ "d", "metaname" ],
85 'optional-args' => [ "metapos" ]
86 },
87
88 "get-archives-metadata" => {
89 'compulsory-args' => [ "d", "metaname" ],
90 'optional-args' => [ "dv", "metapos" ]
91 },
92
93 "get-archives-assocfile" => {
94 'compulsory-args' => [ "d", "assocname" ],
95 'optional-args' => [ "dv" ]
96 },
97
98 "get-index-metadata" => {
99 'compulsory-args' => [ "d", "metaname" ],
100 'optional-args' => [ "metapos" ]
101 },
102
103 "get-metadata" => { # alias for get-index-metadata
104 'compulsory-args' => [ "d", "metaname" ],
105 'optional-args' => [ "metapos" ]
106 },
107
108 "get-live-metadata" => {
109 'compulsory-args' => [ "d", "metaname" ],
110 'optional-args' => [ ]
111 },
112
113 "get-metadata-array" => { # where param can be ONE of: index (default), import, archives, live
114 'compulsory-args' => [ "json" ],
115 'optional-args' => [ "where" ],
116 'help-string' => [
117 'metadata-server.pl?a=get-metadata-array&c=demo&where=index&json=[{"docid":"HASHc5bce2d6d3e5b04e470ec9","metatable":[{"metaname":"username","metapos":"all"},{"metaname":"usertimestamp","metapos":"all"}, {"metaname":"usercomment","metapos":"all"}]}]' ]
118 },
119
120 "get-fldv-info" => {
121 'compulsory-args' => [ "d", ],
122 'optional-args' => [ ],
123 'help-string' => [
124 "fldv is short for file-level document-version history. It refers to the filesystem level approach Greenstone takes to keeping a document version history of the documents formed in the 'archives' directory. When collection is imported with -keepold, for example, any existing documents in the archives area get 'bundled up' as a subfolder called 'nminus-1' within the newly formed document. If there is an existing 'nminus-1' subdirectory then this is moved to nminus-2 prior to forming a new 'nminus-1'. And so on.",
125 "Calling this action returns in JSON formated the array of 'nminus-<n>' subdirectories that a particular document has." ]
126 }
127};
128
129
130# To get the final action_table of all available subroutines in this class,
131# merge the get- and mod-metadata hashes. See http://www.perlmonks.org/?node_id=524456
132# Note that modmeta_action_table will be empty of subroutines if the user does not have permissions
133# to modify metadata.
134my $action_table = { %$getmeta_action_table, %$modmeta_action_table };
135
136
137sub new
138{
139 my $class = shift (@_);
140 my ($gsdl_cgi,$iis6_mode) = @_;
141
142 # Treat metavalue specially. To transmit this through a GET request
143 # the Javascript side has url-encoded it, so here we need to decode
144 # it before proceeding
145
146 my $url_encoded_metavalue = $gsdl_cgi->param("metavalue");
147 my $url_decoded_metavalue = &unicode::url_decode($url_encoded_metavalue,1);
148#$gsdl_cgi->generate_message("@@@ metaaction new - DEBUG before utf82unicode: " . &unicode::debug_unicode_string($url_decoded_metavalue));
149
150 my $unicode_array = &unicode::utf82unicode($url_decoded_metavalue);
151
152 $url_decoded_metavalue = join("",map(chr($_),@$unicode_array));
153
154#$gsdl_cgi->generate_message("@@@ metaaction new - DEBUG after utf82unicode: " . &unicode::debug_unicode_string($url_decoded_metavalue));
155
156 $gsdl_cgi->param("metavalue",$url_decoded_metavalue);
157
158 # need to do the same with prevmetavalue
159 my $url_encoded_prevmetavalue = $gsdl_cgi->param("prevmetavalue");
160 my $url_decoded_prevmetavalue = &unicode::url_decode($url_encoded_prevmetavalue,1);
161 my $prevunicode_array = &unicode::utf82unicode($url_decoded_prevmetavalue);
162
163 $url_decoded_prevmetavalue = join("",map(chr($_),@$prevunicode_array));
164 $gsdl_cgi->param("prevmetavalue",$url_decoded_prevmetavalue);
165
166 my $self = new baseaction($action_table,$gsdl_cgi,$iis6_mode);
167
168 return bless $self, $class;
169}
170
171
172sub get_live_metadata
173{
174 my $self = shift @_;
175
176 my $username = $self->{'username'};
177 my $collect = $self->{'collect'};
178 my $gsdl_cgi = $self->{'gsdl_cgi'};
179 #my $gsdlhome = $self->{'gsdlhome'};
180 my $infodbtype = $self->{'infodbtype'};
181
182 # live metadata gets/saves value scoped (prefixed) by the current usename
183 # so (for now) let's not bother to enforce authentication
184
185 # Obtain the collect dir
186 my $site = $self->{'site'};
187 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
188 ## my $collect_dir = &util::filename_cat($gsdlhome, "collect");
189
190 # No locking collection when getting metadata, only when setting it
191# $self->lock_collection($username, $collect); # Make sure the collection isn't locked by someone else
192
193 # look up additional args
194 my $docid = $self->{'d'};
195 if ((!defined $docid) || ($docid =~ m/^\s*$/)) {
196 $gsdl_cgi->generate_error("No docid (d=...) specified.");
197 }
198
199 # Generate the dbkey
200 my $metaname = $self->{'metaname'};
201 my $dbkey = "$docid.$metaname";
202
203 # To people who know $collect_tail please add some comments
204 # Obtain path to the database
205 my $collect_tail = $collect;
206 $collect_tail =~ s/^.*[\/|\\]//;
207 my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
208 my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, "live-$collect_tail", $index_text_directory);
209
210 # Obtain the content of the key
211 my $cmd = "gdbmget $infodb_file_path $dbkey";
212 if (open(GIN,"$cmd |") == 0) {
213 # Catch error if gdbmget failed
214 my $mess = "Failed to get metadata key: $metaname\n";
215 $mess .= "$!\n";
216
217 $gsdl_cgi->generate_error($mess);
218 }
219 else {
220 binmode(GIN,":utf8");
221 # Read everything in and concatenate them into $metavalue
222 my $metavalue = "";
223 my $line;
224 while (defined ($line=<GIN>)) {
225 $metavalue .= $line;
226 }
227 close(GIN);
228 chomp($metavalue); # Get rid off the tailing newlines
229 $gsdl_cgi->generate_ok_message("$metavalue");
230 }
231
232 # Release the lock once it is done
233# $self->unlock_collection($username, $collect);
234}
235
236# just calls the index version
237sub get_metadata
238{
239 my $self = shift @_;
240 $self->get_index_metadata(@_);
241}
242
243# JSON version that will get the requested metadata values
244# from the requested source (index, import, archives or live)
245# One of the params is a JSON string and the return value is JSON too
246# http://forums.asp.net/t/1844684.aspx/1 - Web api method return json in string
247sub get_metadata_array
248{
249 my $self = shift @_;
250
251 my $where = $self->{'where'};
252 if (!$where || ($where =~ m/^\s*$/)) { # 0, "0", "" and undef are all false. All else is true.
253 # What is truth in perl: http://www.berkeleyinternet.com/perl/node11.html
254 # and http://www.perlmonks.org/?node_id=33638
255
256 $where = "index"; # default behaviour is to get the values from index
257 }
258
259 # Only when setting metadata do we perform authentication and do we lock the collection,
260 # not when getting metadata
261
262 # for get_meta_array, the where param can only be ONE of import, archives, index, live
263 if($where =~ m/index/) {
264 $self->_get_index_metadata_array(@_);
265 }
266 elsif($where =~ m/archives/) {
267 $self->_get_archives_metadata_array(@_);
268 }
269 elsif($where =~ m/import/) {
270 $self->_get_import_metadata_array(@_);
271 }
272 elsif($where =~ m/live/) {
273 $self->_get_live_metadata_array(@_);
274 }
275}
276
277# Unused at present. Added for completion. Tested.
278sub _get_import_metadata_array {
279
280 my $self = shift @_;
281
282 my $collect = $self->{'collect'};
283 my $gsdl_cgi = $self->{'gsdl_cgi'};
284 my $site = $self->{'site'};
285 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
286
287 # look up additional args
288 my $infodbtype = $self->{'infodbtype'};
289
290 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
291 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
292 my $json_str = $self->{'json'};
293 my $doc_array = decode_json $json_str;
294
295 my $json_result_str = "[";
296 my $first_doc_rec = 1;
297 foreach my $doc_array_rec ( @$doc_array ) {
298
299 my $docid = $doc_array_rec->{'docid'}; # no subsection metadata support in metadata.xml, only toplevel meta
300
301 if($first_doc_rec) {
302 $first_doc_rec = 0;
303 } else {
304 $json_result_str .= ",";
305 }
306 $json_result_str = $json_result_str . "{\"docid\":\"" . $docid . "\"";
307
308 my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong
309 $json_result_str = $json_result_str . ",\"metatable\":[";
310
311 my $first_rec = 1;
312 foreach my $metatable_rec ( @$metatable ) { # the subarray metatable is an array of hashmaps
313
314 # Read the docid entry
315 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
316 # This now stores the full pathname
317 my $import_filename = $doc_rec->{'src-file'}->[0];
318 $import_filename = &util::placeholders_to_abspath($import_filename);
319
320 # figure out correct metadata.xml file [?]
321 # Assuming the metadata.xml file is next to the source file
322 # Note: This will not work if it is using the inherited metadata from the parent folder
323 my ($import_tailname, $import_dirname) = File::Basename::fileparse($import_filename);
324 my $metadata_xml_filename = &util::filename_cat($import_dirname, "metadata.xml");
325
326
327 if($first_rec) {
328 $first_rec = 0;
329 } else {
330 $json_result_str .= ",";
331 }
332
333 my $metaname = $metatable_rec->{'metaname'};
334 $json_result_str .= "{\"metaname\":\"$metaname\",\"metavals\":[";
335
336 my $metapos = $metatable_rec->{'metapos'}; # 0... 1|all|undefined
337 if(!defined $metapos) {
338 $metapos = 0;
339 }
340
341 # Obtain the specified metadata value(s)
342 my $metavalue;
343
344 if($metapos ne "all") { # get the value at a single metapos
345 $metavalue = $self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $import_tailname);
346
347 #print STDERR "**** Metafilename, metaname, metapos, sec_num: $metadata_xml_filename, $metaname, $metapos, $import_tailname\n";
348
349 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
350
351 } else {
352 my $first_metaval = 1;
353 $metapos = 0;
354 $metavalue = $self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $import_tailname);
355
356 while (defined $metavalue && $metavalue ne "") {
357 if($first_metaval) {
358 $first_metaval = 0;
359 } else {
360 $json_result_str .= ",";
361 }
362
363 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
364
365 $metapos++;
366 $metavalue = $self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $import_tailname);
367 }
368 }
369
370 $json_result_str .= "]}"; # close metavals array and metatable record
371 }
372
373 $json_result_str .= "]}"; # close metatable array and docid record
374 }
375
376 $json_result_str .= "]"; # close array of docids
377 $gsdl_cgi->generate_ok_message($json_result_str."\n");
378}
379
380# Unused method, but included for completion. Tested, works. Takes a JSON string and returns a JSON string.
381# For more information on the format of the output, see _get_index_metadata_array, which is in use.
382sub _get_archives_metadata_array {
383
384 my $self = shift @_;
385
386 my $collect = $self->{'collect'};
387 my $gsdl_cgi = $self->{'gsdl_cgi'};
388 my $site = $self->{'site'};
389 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
390
391 # look up additional args
392 my $infodbtype = $self->{'infodbtype'};
393
394 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
395 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
396
397 my $json_str = $self->{'json'};
398 my $doc_array = decode_json $json_str;
399
400 my $json_result_str = "[";
401 my $first_doc_rec = 1;
402 foreach my $doc_array_rec ( @$doc_array ) {
403
404 my $docid = $doc_array_rec->{'docid'};
405
406 if($first_doc_rec) {
407 $first_doc_rec = 0;
408 } else {
409 $json_result_str .= ",";
410 }
411 $json_result_str = $json_result_str . "{\"docid\":\"" . $docid . "\"";
412
413 my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong
414 $json_result_str = $json_result_str . ",\"metatable\":[";
415
416 my $first_rec = 1;
417 foreach my $metatable_rec ( @$metatable ) { # the subarray metatable is an array of hashmaps
418
419 my ($docid, $docid_secnum) = ($doc_array_rec->{'docid'} =~ m/^(.*?)(\..*)?$/);
420 $docid_secnum = "" if (!defined $docid_secnum);
421
422 # Read the docid entry
423 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
424 # This now stores the full pathname
425 my $doc_file = $doc_rec->{'doc-file'}->[0];
426
427 # check if request if for file-level doc-version history 'nminus-<n>' version
428 my $dv = $self->{'dv'};
429 if (defined $dv && ($dv ne "")) {
430 # Need to insert '_fldv_history/nminus-<n>' into doc_filename
431
432 my ($doc_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
433 $doc_file = &util::filename_cat($doc_dirname,$FLDV_HISTORY_DIR,$dv,$doc_tailname);
434 }
435
436 my $doc_filename = &util::filename_cat($archive_dir, $doc_file);
437
438 if($first_rec) {
439 $first_rec = 0;
440 } else {
441 $json_result_str .= ",";
442 }
443
444 my $metaname = $metatable_rec->{'metaname'};
445 $json_result_str .= "{\"metaname\":\"$metaname\",\"metavals\":[";
446
447 my $metapos = $metatable_rec->{'metapos'}; # 0... 1|all|undefined
448 if(!defined $metapos) {
449 $metapos = 0;
450 }
451
452
453 # Obtain the specified metadata value(s)
454 my $metavalue;
455
456 if($metapos ne "all") { # get the value at a single metapos
457
458 $metavalue = $self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, $metaname, $metapos, $docid_secnum);
459 #print STDERR "**** Docname, metaname, metapos, sec_num: $doc_filename, $metaname, $metapos, $docid_secnum\n";
460
461 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
462
463 } else {
464 my $first_metaval = 1;
465 $metapos = 0;
466 $metavalue = $self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, $metaname, $metapos, $docid_secnum);
467
468 while (defined $metavalue && $metavalue ne "") {
469 if($first_metaval) {
470 $first_metaval = 0;
471 } else {
472 $json_result_str .= ",";
473 }
474
475 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
476
477 $metapos++;
478 $metavalue = $self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, $metaname, $metapos, $docid_secnum);
479 }
480 }
481
482 $json_result_str .= "]}"; # close metavals array and metatable record
483 }
484
485 $json_result_str .= "]}"; # close metatable array and docid record
486 }
487
488 $json_result_str .= "]"; # close array of docids
489 $gsdl_cgi->generate_ok_message($json_result_str."\n");
490}
491
492
493# Unused at present. Added for completion. Tested, but not sure if it retrieves metadata in the manner it's expected to.
494sub _get_live_metadata_array
495{
496 my $self = shift @_;
497
498 my $collect = $self->{'collect'};
499 my $gsdl_cgi = $self->{'gsdl_cgi'};
500 my $site = $self->{'site'};
501 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
502
503 # look up additional args
504 my $infodbtype = $self->{'infodbtype'};
505
506 # To people who know $collect_tail please add some comments
507 # Obtain the path to the database
508 my $collect_tail = $collect;
509 $collect_tail =~ s/^.*[\/|\\]//;
510 my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
511 my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, "live-$collect_tail", $index_text_directory);
512
513 my $json_str = $self->{'json'};
514 my $doc_array = decode_json $json_str;
515
516 my $json_result_str = "[";
517 my $first_doc_rec = 1;
518
519 foreach my $doc_array_rec ( @$doc_array ) {
520
521 my $docid = $doc_array_rec->{'docid'};
522
523 if($first_doc_rec) {
524 $first_doc_rec = 0;
525 } else {
526 $json_result_str .= ",";
527 }
528 $json_result_str = $json_result_str . "{\"docid\":\"" . $docid . "\"";
529
530 my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong
531 $json_result_str = $json_result_str . ",\"metatable\":[";
532
533 my $first_rec = 1;
534 foreach my $metatable_rec ( @$metatable ) { # the subarray metatable is an array of hashmaps
535 if($first_rec) {
536 $first_rec = 0;
537 } else {
538 $json_result_str .= ",";
539 }
540
541 my $metaname = $metatable_rec->{'metaname'};
542 $json_result_str .= "{\"metaname\":\"$metaname\",\"metavals\":[";
543
544 # Generate the dbkey
545 my $dbkey = "$docid.$metaname";
546
547 # metapos for get_live_metadata is always assumed to be "all".
548 # It's always going to get all the lines of metavalues associated with a metaname
549 # (It's the metaname itself that should contain an increment number, if there are to be multiple values).
550 #my $metapos = "all";
551 my $metapos = $metatable_rec->{'metapos'} || 0; # Can be 0... 1|all|undefined. Defaults to 0 if undefined/false
552 my $metavalue = "";
553
554 # Obtain the content of the key
555 my $cmd = "gdbmget $infodb_file_path $dbkey";
556 if (open(GIN,"$cmd |") != 0) { # Success.
557
558 binmode(GIN,":utf8");
559 # Read everything in and concatenate them into $metavalue
560 my $line;
561 my $first_metaval = 1;
562 my $pos = 0;
563 while (defined ($line=<GIN>)) {
564 chomp($line); # Get rid off the tailing newlines
565
566 if($metapos eq "all") {
567 if($first_metaval) {
568 $first_metaval = 0;
569 } else {
570 $json_result_str .= ",";
571 }
572 $metavalue = $line;
573 $json_result_str .= "{\"metapos\":\"$pos\",\"metavalue\":\"$metavalue\"}";
574 } elsif($metapos == $pos) {
575 $metavalue = $line;
576 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
577 last;
578 } # else, the current $pos is not the required $metapos
579 $pos += 1;
580 }
581 close(GIN);
582 } # else open cmd == 0 (failed) and metavals array will be empty [] for this metaname
583
584 $json_result_str .= "]}"; # close metavals array and metatable record
585 }
586
587 $json_result_str .= "]}"; # close metatable array and docid record
588 }
589
590 $json_result_str .= "]"; # close array of docids
591
592 $gsdl_cgi->generate_ok_message($json_result_str."\n");
593}
594
595
596# Takes a JSON string and returns a JSON string
597# Request string is of the form:
598# http://localhost:8283/greenstone/cgi-bin/metadata-server.pl?a=get-metadata-array&c=demo&where=index&json=[{"docid":"HASHc5bce2d6d3e5b04e470ec9","metatable":[{"metaname":"username","metapos":"all"},{"metaname":"usertimestamp","metapos":"all"}, {"metaname":"usercomment","metapos":"all"}]}]
599# Resulting string is of the form:
600# [{"docid":"HASHc5bce2d6d3e5b04e470ec9","metatable":[{"metaname":"username","metavals":[{"metapos":"0","metavalue":"me"},{"metapos":"1","metavalue":"admin"}]},{"metaname":"usertimestamp","metavals":[{"metapos":"0","metavalue":"1367900586888"},{"metapos":"1","metavalue":"1367900616574"}]},{"metaname":"usercomment","metavals":[{"metapos":"0","metavalue":"Hi"},{"metapos":"1","metavalue":"Hello"}]}]}]
601sub _get_index_metadata_array
602{
603 my $self = shift @_;
604
605 my $collect = $self->{'collect'};
606 my $gsdl_cgi = $self->{'gsdl_cgi'};
607 my $site = $self->{'site'};
608 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
609
610 # look up additional args
611 my $infodbtype = $self->{'infodbtype'};
612
613 # To people who know $collect_tail please add some comments
614 # Obtain the path to the database
615 my $collect_tail = $collect;
616 $collect_tail =~ s/^.*[\/|\\]//;
617 my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
618 my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, $collect_tail, $index_text_directory);
619
620 my $json_str = $self->{'json'};
621 my $doc_array = decode_json $json_str;
622
623 my $json_result_str = "[";
624 my $first_doc_rec = 1;
625
626 foreach my $doc_array_rec ( @$doc_array ) {
627
628 my $docid = $doc_array_rec->{'docid'};
629
630 if($first_doc_rec) {
631 $first_doc_rec = 0;
632 } else {
633 $json_result_str .= ",";
634 }
635 $json_result_str = $json_result_str . "{\"docid\":\"" . $docid . "\"";
636
637 my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong
638 $json_result_str = $json_result_str . ",\"metatable\":[";
639
640 my $first_rec = 1;
641 foreach my $metatable_rec ( @$metatable ) { # the subarray metatable is an array of hashmaps
642 if($first_rec) {
643 $first_rec = 0;
644 } else {
645 $json_result_str .= ",";
646 }
647
648 my $metaname = $metatable_rec->{'metaname'};
649 $json_result_str .= "{\"metaname\":\"$metaname\",\"metavals\":[";
650
651 my $metapos = $metatable_rec->{'metapos'}; # 0... 1|all|undefined
652 if(!defined $metapos) {
653 $metapos = 0;
654 }
655
656 # Read the docid entry
657 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $infodb_file_path, $docid);
658
659 # Basically loop through and unescape_html the values
660 foreach my $k (keys %$doc_rec) {
661 my @escaped_v = ();
662 foreach my $v (@{$doc_rec->{$k}}) {
663 my $ev = &ghtml::unescape_html($v);
664 push(@escaped_v, $ev);
665 }
666 $doc_rec->{$k} = \@escaped_v;
667 }
668
669 # Obtain the specified metadata value(s)
670 my $metavalue;
671
672 if($metapos ne "all") { # get the value at a single metapos
673
674 $metavalue = $doc_rec->{$metaname}->[$metapos];
675
676 # protect any double quotes and colons in the metavalue before putting it into JSON
677 $metavalue =~ s/\"/&quot;/g if defined $metavalue;
678 $metavalue =~ s/\:/&58;/g if defined $metavalue;
679
680 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
681
682 } else {
683 my $first_metaval = 1;
684 $metapos = 0;
685 $metavalue = $doc_rec->{$metaname}->[$metapos];
686
687 while (defined $metavalue) {
688
689 # protect any double quotes and colons in the metavalue before putting it into JSON
690 $metavalue =~ s/\"/&quot;/g;
691 $metavalue =~ s/\:/&58;/g;
692
693 if($first_metaval) {
694 $first_metaval = 0;
695 } else {
696 $json_result_str .= ",";
697 }
698
699 $json_result_str .= "{\"metapos\":\"$metapos\",\"metavalue\":\"$metavalue\"}";
700
701 $metapos++;
702 $metavalue = $doc_rec->{$metaname}->[$metapos];
703 }
704 }
705
706 $json_result_str .= "]}"; # close metavals array and metatable record
707 }
708
709 $json_result_str .= "]}"; # close metatable array and docid record
710 }
711
712 $json_result_str .= "]"; # close array of docids
713
714 $gsdl_cgi->generate_ok_message($json_result_str."\n");
715}
716
717
718sub get_index_metadata
719{
720 my $self = shift @_;
721
722 my $username = $self->{'username'};
723 my $collect = $self->{'collect'};
724 my $gsdl_cgi = $self->{'gsdl_cgi'};
725 #my $gsdlhome = $self->{'gsdlhome'};
726
727 # Obtain the collect dir
728 my $site = $self->{'site'};
729 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
730 ##my $collect_dir = &util::filename_cat($gsdlhome, "collect");
731
732 # look up additional args
733 my $docid = $self->{'d'};
734 my $metaname = $self->{'metaname'};
735 my $metapos = $self->{'metapos'};
736 my $infodbtype = $self->{'infodbtype'};
737
738 # To people who know $collect_tail please add some comments
739 # Obtain path to the database
740 my $collect_tail = $collect;
741 $collect_tail =~ s/^.*[\/|\\]//;
742 my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
743 my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, $collect_tail, $index_text_directory);
744
745 # Read the docid entry
746 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $infodb_file_path, $docid);
747
748 # Basically loop through and unescape_html the values
749 foreach my $k (keys %$doc_rec) {
750 my @escaped_v = ();
751 foreach my $v (@{$doc_rec->{$k}}) {
752 my $ev = &ghtml::unescape_html($v);
753 push(@escaped_v, $ev);
754 }
755 $doc_rec->{$k} = \@escaped_v;
756 }
757
758 # Obtain the specified metadata value
759 $metapos = 0 if (!defined $metapos || ($metapos =~ m/^\s*$/));
760 my $metavalue = $doc_rec->{$metaname}->[$metapos];
761 $gsdl_cgi->generate_ok_message("$metavalue");
762
763}
764
765
766sub get_import_metadata
767{
768 my $self = shift @_;
769
770 my $username = $self->{'username'};
771 my $collect = $self->{'collect'};
772 my $gsdl_cgi = $self->{'gsdl_cgi'};
773 #my $gsdlhome = $self->{'gsdlhome'};
774
775 # Obtain the collect dir
776 my $site = $self->{'site'};
777 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
778 ##my $collect_dir = &util::filename_cat($gsdlhome, "collect");
779
780 # look up additional args
781 my $docid = $self->{'d'};
782 my $metaname = $self->{'metaname'};
783 my $metapos = $self->{'metapos'};
784 $metapos = 0 if (!defined $metapos || ($metapos =~ m/^\s*$/)); # gets the first value by default since metapos defaults to 0
785
786 my $infodbtype = $self->{'infodbtype'};
787 if (!defined $docid)
788 {
789 $gsdl_cgi->generate_error("No docid (d=...) specified.\n");
790 }
791
792 # Obtain where the metadata.xml is from the archiveinfo-doc.gdb file
793 # If the doc oid is not specified, we assume the metadata.xml is next to the specified "f"
794 my $metadata_xml_file;
795 my $import_filename = undef;
796
797
798 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
799 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
800 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
801
802 # This now stores the full pathname
803 $import_filename = $doc_rec->{'src-file'}->[0];
804 $import_filename = &util::placeholders_to_abspath($import_filename);
805
806 # figure out correct metadata.xml file [?]
807 # Assuming the metadata.xml file is next to the source file
808 # Note: This will not work if it is using the inherited metadata from the parent folder
809 my ($import_tailname, $import_dirname) = File::Basename::fileparse($import_filename);
810 my $metadata_xml_filename = &util::filename_cat($import_dirname, "metadata.xml");
811
812 $gsdl_cgi->generate_ok_message($self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $import_tailname));
813
814}
815
816sub get_metadata_from_metadata_xml
817{
818 my $self = shift @_;
819 my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $src_file) = @_;
820
821 my @rules =
822 (
823 _default => 'raw',
824 'Metadata' => \&gfmxml_metadata,
825 'FileName' => \&mxml_filename
826 );
827
828 my $parser = XML::Rules->new
829 (
830 rules => \@rules,
831 output_encoding => 'utf8'
832 );
833
834 my $xml_in = "";
835 if (!open(MIN,"<$metadata_xml_filename"))
836 {
837 $gsdl_cgi->generate_error("Unable to read in $metadata_xml_filename: $!");
838 }
839 else
840 {
841 # Read them in
842 my $line;
843 while (defined ($line=<MIN>)) {
844 $xml_in .= $line;
845 }
846 close(MIN);
847
848 $parser->parse($xml_in, {metaname => $metaname, metapos => $metapos, src_file => $src_file});
849
850 if(defined $parser->{'pad'}->{'metavalue'})
851 {
852 return $parser->{'pad'}->{'metavalue'};
853 }
854 else
855 {
856 return "";
857 }
858 }
859}
860
861sub gfmxml_metadata
862{
863 my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
864
865 # no subsection support yet in metadata.xml
866
867 if (($parser->{'parameters'}->{'src_file'} eq $parser->{'parameters'}->{'current_file'}) && $parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'})
868 {
869 if (!defined $parser->{'parameters'}->{'poscount'})
870 {
871 $parser->{'parameters'}->{'poscount'} = 0;
872 }
873 else
874 {
875 $parser->{'parameters'}->{'poscount'}++;
876 }
877
878 # gets the first value by default, since metapos defaults to 0
879 if (($parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'}))
880 {
881 if($parser->{'parameters'}->{'metapos'} > 0) {
882 print STDERR "@@@@ WARNING: non-zero metapos.\n";
883 print STDERR "@@@@ Assuming SIMPLE collection and proceeding to retrieve the import meta at position: ".$parser->{'parameters'}->{'metapos'}.".\n";
884 }
885 $parser->{'pad'}->{'metavalue'} = $attrHash->{'_content'};
886 }
887 }
888}
889
890sub mxml_filename
891{
892 my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
893
894 # Store the filename of the Current Fileset
895 # Note: According to http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd
896 # FileName tag must come before Description tag
897 $parser->{'parameters'}->{'current_file'} = $attrHash->{'_content'};
898
899 # RAW is [$tagname => $attrHash] not $tagname => $attrHash!!
900 return [$tagname => $attrHash];
901}
902
903sub get_archives_metadata
904{
905 my $self = shift @_;
906
907 my $username = $self->{'username'};
908 my $collect = $self->{'collect'};
909 my $gsdl_cgi = $self->{'gsdl_cgi'};
910 my $infodbtype = $self->{'infodbtype'};
911
912 # Obtain the collect dir
913 my $site = $self->{'site'};
914 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
915
916 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
917
918 # look up additional args
919 my ($docid, $docid_secnum) = ($self->{'d'} =~ m/^(.*?)(\..*)?$/);
920 $docid_secnum = "" if (!defined $docid_secnum);
921
922 my $metaname = $self->{'metaname'};
923 my $metapos = $self->{'metapos'};
924 $metapos = 0 if (!defined $metapos || ($metapos =~ m/^\s*$/));
925
926 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
927 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
928
929 # This now stores the full pathname
930 my $doc_file = $doc_rec->{'doc-file'}->[0];
931
932 # check if request if for file-level doc-version history 'nminus-<n>' version
933 my $dv = $self->{'dv'};
934 if (defined $dv && ($dv ne "")) {
935 # Need to insert '_fldv_history/nminus-<n>' into doc_filename
936
937 my ($doc_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
938 $doc_file = &util::filename_cat($doc_dirname,$FLDV_HISTORY_DIR,$dv,$doc_tailname);
939 }
940
941 my $doc_filename = &util::filename_cat($archive_dir, $doc_file);
942
943
944 $gsdl_cgi->generate_ok_message($self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, $metaname, $metapos, $docid_secnum));
945}
946
947# unused and untested
948sub get_archives_text
949{
950 my $self = shift @_;
951
952 my $username = $self->{'username'};
953 my $collect = $self->{'collect'};
954 my $gsdl_cgi = $self->{'gsdl_cgi'};
955 my $infodbtype = $self->{'infodbtype'};
956
957 # Obtain the collect dir
958 my $site = $self->{'site'};
959 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
960
961 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
962
963 # look up additional args
964 my ($docid, $docid_secnum) = ($self->{'d'} =~ m/^(.*?)(\..*)?$/);
965 $docid_secnum = "" if (!defined $docid_secnum);
966
967 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
968 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
969
970 # This now stores the full pathname
971 my $doc_file = $doc_rec->{'doc-file'}->[0];
972
973 # check if request if for file-level doc-version history 'nminus-<n>' version
974 my $dv = $self->{'dv'};
975 if (defined $dv && ($dv ne "")) {
976 # Need to insert '_fldv_history/nminus-<n>' into doc_filename
977
978 my ($doc_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
979 $doc_file = &util::filename_cat($doc_dirname,$FLDV_HISTORY_DIR,$dv,$doc_tailname);
980 }
981
982 my $doc_filename = &util::filename_cat($archive_dir, $doc_file);
983
984 my $metaname = undef;
985 my $metapos = -1;
986
987 $gsdl_cgi->generate_ok_message($self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, $metaname, $metapos, $docid_secnum));
988
989}
990
991sub get_archives_assocfile
992{
993 my $self = shift @_;
994
995 my $username = $self->{'username'};
996 my $collect = $self->{'collect'};
997 my $gsdl_cgi = $self->{'gsdl_cgi'};
998 my $infodbtype = $self->{'infodbtype'};
999
1000 # Obtain the collect and archive dir
1001 my $site = $self->{'site'};
1002 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
1003
1004 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
1005
1006 # look up additional args
1007 my $docid = $self->{'d'};
1008
1009 my $assocname = $self->{'assocname'};
1010
1011 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
1012 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
1013
1014 my $doc_file = $doc_rec->{'doc-file'}->[0];
1015
1016 # check if request if for file-level doc-version history 'nminus-<n>' version
1017 my $dv = $self->{'dv'};
1018 if (defined $dv && ($dv ne "")) {
1019 # Need to insert '_fldv_history/nminus-<n>' into doc_file
1020
1021 my ($doc_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
1022 $doc_file = &util::filename_cat($doc_dirname,$FLDV_HISTORY_DIR,$dv,$doc_tailname);
1023 }
1024
1025 my $doc_filename = &util::filename_cat($archive_dir, $doc_file);
1026
1027
1028 # In the following the repeated calls to $self->get_metadata_from_archive_xml() with increasing $metapos
1029 # get the job done, but is not very efficient
1030 # => candidate for refactoring
1031
1032
1033 my $metapos = 0;
1034 my $metavalue = $self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, "gsdlassocfile", $metapos, "");
1035
1036 my $found_file = undef;
1037 my $found_mimetype = undef;
1038
1039 while (defined $metavalue && $metavalue ne "") {
1040
1041 my ($assoc_file,$assoc_mimetype) = ($metavalue =~ m/^(.+?):(.+?):(?:.*)$/); # only need first two fields, third one might be section???
1042
1043 if ($assoc_file eq $assocname) {
1044 $found_file = $assoc_file;
1045 $found_mimetype = $assoc_mimetype;
1046 last;
1047 }
1048
1049 $metapos++;
1050 $metavalue = $self->get_metadata_from_archive_xml($gsdl_cgi, $doc_filename, "gsdlassocfile", $metapos, "");
1051 }
1052
1053 if (defined $found_file) {
1054
1055 my ($unused_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
1056
1057 if (defined $dv && ($dv ne "")) {
1058 # Need to insert '_fldv_history/nminus-<n>' into found_file
1059
1060 $found_file = &util::filename_cat($doc_dirname,$found_file);
1061
1062 }
1063 else {
1064 $found_file = &util::filename_cat($doc_dirname,$found_file);
1065 }
1066
1067 my $found_filename = &util::filename_cat($archive_dir, $found_file);
1068
1069 $gsdl_cgi->generate_file($found_mimetype,$found_filename);
1070 }
1071 else {
1072
1073 $gsdl_cgi->generate_error("Failed to find associated file $assocname in 'archives' for $docid");
1074 }
1075}
1076
1077
1078
1079sub get_fldv_info
1080{
1081 my $self = shift @_;
1082
1083 my $username = $self->{'username'};
1084 my $collect = $self->{'collect'};
1085 my $gsdl_cgi = $self->{'gsdl_cgi'};
1086 my $infodbtype = $self->{'infodbtype'};
1087
1088 # Obtain the collect dir
1089 my $site = $self->{'site'};
1090 my $collect_dir = $gsdl_cgi->get_collection_dir($site);
1091
1092 my $archive_dir = &util::filename_cat($collect_dir, $collect, "archives");
1093
1094 # look up additional args
1095 my $docid = $self->{'d'};
1096
1097
1098 my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
1099 my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
1100
1101 # This now stores the full pathname [is this still true??]
1102 my $doc_file = $doc_rec->{'doc-file'}->[0];
1103
1104 my ($unused_doc_tailname, $doc_dirname) = File::Basename::fileparse($doc_file);
1105 my $doc_full_dirname = &util::filename_cat($archive_dir,$doc_dirname);
1106
1107 my $fldv_full_dirname = &util::filename_cat($doc_full_dirname,$FLDV_HISTORY_DIR);
1108
1109 my $sorted_fldv_filtered_dirs_json = "[]";
1110 if (-d $fldv_full_dirname) {
1111 my $fldv_filtered_dirs = &FileUtils::readDirectoryFiltered($fldv_full_dirname,undef,"^nminus-\\d+\$");
1112
1113 my @sorted_fldv_filtered_dirs = sort {
1114 my ($a_num) = ($a =~ m/(\d+)$/);
1115 my ($b_num) = ($b =~ m/(\d+)$/);
1116
1117 # sort into ascending order
1118 return $a_num <=> $b_num;
1119 } @$fldv_filtered_dirs;
1120
1121 $sorted_fldv_filtered_dirs_json = encode_json \@sorted_fldv_filtered_dirs;
1122 }
1123
1124 $gsdl_cgi->generate_ok_message($sorted_fldv_filtered_dirs_json);
1125}
1126
1127
1128sub get_metadata_from_archive_xml
1129{
1130 my $self = shift @_;
1131 my ($gsdl_cgi, $doc_xml_filename, $metaname, $metapos, $secid) = @_;
1132
1133 my @start_rules = ('Section' => \&dxml_start_section);
1134
1135 my @rules =
1136 (
1137 _default => 'raw',
1138 'Metadata' => \&gfdxml_metadata
1139 );
1140
1141 my $parser = XML::Rules->new
1142 (
1143 start_rules => \@start_rules,
1144 rules => \@rules,
1145 output_encoding => 'utf8'
1146 );
1147
1148 my $xml_in = "";
1149 if (!open(MIN,"<$doc_xml_filename"))
1150 {
1151 $gsdl_cgi->generate_error("Unable to read in $doc_xml_filename: $!");
1152 }
1153 else
1154 {
1155 # Read them in
1156 my $line;
1157 while (defined ($line=<MIN>)) {
1158 $xml_in .= $line;
1159 }
1160 close(MIN);
1161
1162 $parser->parse($xml_in, {metaname => $metaname, metapos => $metapos, secid => $secid});
1163
1164 if(defined $parser->{'pad'}->{'metavalue'})
1165 {
1166 return $parser->{'pad'}->{'metavalue'};
1167 }
1168 else
1169 {
1170 return "";
1171 }
1172 }
1173}
1174
1175# unused and untested
1176sub get_text_from_archive_xml
1177{
1178 my $self = shift @_;
1179 my ($gsdl_cgi, $doc_xml_filename, $secid) = @_;
1180
1181 # To monitor which section/subsection number we are in
1182 my @start_rules = ('Section' => \&dxml_start_section);
1183
1184 # set the callback functions for the elements in doc.xml we're interested in, <Content>
1185 my @rules =
1186 (
1187 _default => 'raw',
1188 'Content' => \&gfdxml_text # gfdxml = get from doc xml?
1189 );
1190
1191 my $parser = XML::Rules->new
1192 (
1193 start_rules => \@start_rules,
1194 rules => \@rules,
1195 output_encoding => 'utf8'
1196 );
1197
1198 my $xml_in = "";
1199 if (!open(MIN,"<$doc_xml_filename"))
1200 {
1201 $gsdl_cgi->generate_error("Unable to read in $doc_xml_filename: $!");
1202 }
1203 else
1204 {
1205 # Read them in
1206 my $line;
1207 while (defined ($line=<MIN>)) {
1208 $xml_in .= $line;
1209 }
1210 close(MIN);
1211
1212 $parser->parse($xml_in, {secid => $secid});
1213
1214 if(defined $parser->{'pad'}->{'textcontent'})
1215 {
1216 return $parser->{'pad'}->{'textcontent'};
1217 }
1218 else
1219 {
1220 return "";
1221 }
1222 }
1223}
1224
1225sub gfdxml_metadata
1226{
1227 my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
1228
1229 if(!($parser->{'parameters'}->{'secid'} eq $parser->{'parameters'}->{'curr_section_num'}))
1230 {
1231 return;
1232 }
1233
1234 if ($parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'})
1235 {
1236 if (!defined $parser->{'parameters'}->{'poscount'})
1237 {
1238 $parser->{'parameters'}->{'poscount'} = 0;
1239 }
1240 else
1241 {
1242 $parser->{'parameters'}->{'poscount'}++;
1243 }
1244 }
1245
1246 if (($parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'}) && ($parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'}))
1247 {
1248 $parser->{'pad'}->{'metavalue'} = $attrHash->{'_content'};
1249 }
1250}
1251
1252# unused and untested - for get_archives_text
1253sub gfdxml_text
1254{
1255 my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
1256
1257 if($parser->{'parameters'}->{'secid'} eq $parser->{'parameters'}->{'curr_section_num'})
1258 {
1259 $parser->{'pad'}->{'textcontent'} = $attrHash->{'_content'}; # the textnode content
1260
1261 }
1262 else {
1263 return;
1264 }
1265}
1266
1267sub dxml_start_section
1268{
1269 my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
1270
1271 my $new_depth = scalar(@$contextArray);
1272
1273# print STDERR "**** START SECTION \n";
1274
1275 if ($new_depth == 1) {
1276 $parser->{'parameters'}->{'curr_section_depth'} = 1;
1277 $parser->{'parameters'}->{'curr_section_num'} = "";
1278 }
1279
1280 my $old_depth = $parser->{'parameters'}->{'curr_section_depth'};
1281 my $old_secnum = $parser->{'parameters'}->{'curr_section_num'};
1282
1283 my $new_secnum;
1284
1285 if ($new_depth > $old_depth) {
1286 # child subsection
1287 $new_secnum = "$old_secnum.1";
1288 }
1289 elsif ($new_depth == $old_depth) {
1290 # sibling section => increase its value by 1
1291 my ($tail_num) = ($old_secnum =~ m/\.(\d+)$/);
1292 $tail_num++;
1293 $new_secnum = $old_secnum;
1294 $new_secnum =~ s/\.(\d+)$/\.$tail_num/;
1295 }
1296 else {
1297 # back up to parent section => lop off tail
1298 $new_secnum = $old_secnum;
1299 $new_secnum =~ s/\.\d+$//;
1300 # remember to increment from parent section
1301 my ($tail_num) = ($new_secnum =~ m/\.(\d+)$/);
1302 $tail_num++;
1303 $new_secnum =~ s/\.(\d+)$/\.$tail_num/;
1304 }
1305
1306 $parser->{'parameters'}->{'curr_section_depth'} = $new_depth;
1307 $parser->{'parameters'}->{'curr_section_num'} = $new_secnum;
1308
1309 #print STDERR "**** START SECTION - $new_secnum\n************************\n\n";
1310 1;
1311}
1312
13131;
Note: See TracBrowser for help on using the repository browser.