source: trunk/cic-hcap/perllib/plugins/CICPlug.pm@ 11927

Last change on this file since 11927 was 11927, checked in by mdewsnip, 18 years ago

Now throws errors on multiline function values (which were causing some problems), and deals with nested parentheses in function values better.

  • Property svn:keywords set to Author Date Id Revision
File size: 48.6 KB
Line 
1###########################################################################
2#
3# CICPlug.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) 2005 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 CICPlug;
27
28
29use BasPlug;
30use DBI;
31use strict;
32no strict 'refs';
33
34
35sub BEGIN {
36 @CICPlug::ISA = ('BasPlug');
37}
38
39
40my $arguments =
41 [
42 { 'name' => "images_directory",
43 'type' => "string",
44 'deft' => "",
45 'reqd' => "yes" },
46 { 'name' => "cache_directory",
47 'type' => "string",
48 'deft' => &util::filename_cat($ENV{'GSDLHOME'}, "tmp"),
49 'reqd' => "no" },
50 { 'name' => "large_image_options",
51 'type' => "string",
52 'deft' => "",
53 'reqd' => "no" },
54 { 'name' => "large_image_type",
55 'type' => "string",
56 'deft' => "jpg",
57 'reqd' => "no" },
58 { 'name' => "large_image_width",
59 'type' => "string",
60 'deft' => "1250",
61 'reqd' => "no" },
62 { 'name' => "medium_image_options",
63 'type' => "string",
64 'deft' => "",
65 'reqd' => "no" },
66 { 'name' => "medium_image_type",
67 'type' => "string",
68 'deft' => "jpg",
69 'reqd' => "no" },
70 { 'name' => "medium_image_width",
71 'type' => "string",
72 'deft' => "375",
73 'reqd' => "no" },
74 { 'name' => "small_image_options",
75 'type' => "string",
76 'deft' => "",
77 'reqd' => "no" },
78 { 'name' => "small_image_type",
79 'type' => "string",
80 'deft' => "jpg",
81 'reqd' => "no" },
82 { 'name' => "small_image_width",
83 'type' => "string",
84 'deft' => "125",
85 'reqd' => "no" }
86 ];
87
88my $options = { 'name' => "CICPlug",
89 'desc' => "{CICPlug.desc}",
90 'abstract' => "no",
91 'inherits' => "yes" };
92
93
94sub get_default_process_exp
95{
96 return q^(?i)\.mdb$^;
97}
98
99
100sub new
101{
102 my ($class) = shift (@_);
103 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
104 push(@$pluginlist, $class);
105
106 if (defined $arguments) { push(@{$hashArgOptLists->{"ArgList"}}, @{$arguments}); }
107 if (defined $options) { push(@{$hashArgOptLists->{"OptList"}}, $options); }
108
109 my $self = (defined $hashArgOptLists) ? new BasPlug($pluginlist,$inputargs,$hashArgOptLists) : new BasPlug($pluginlist,$inputargs);
110
111 return bless $self, $class;
112}
113
114
115my $state_abbr_to_name_mapping = {
116 "AL" => "Alabama",
117 "AK" => "Alaska",
118 "AZ" => "Arizona",
119 "AR" => "Arkansas",
120 "CA" => "California",
121 "CO" => "Colorado",
122 "CT" => "Connecticut",
123 "DE" => "Delaware",
124 "FL" => "Florida",
125 "GA" => "Georgia",
126 "HI" => "Hawaii",
127 "ID" => "Idaho",
128 "IL" => "Illinois",
129 "IN" => "Indiana",
130 "IA" => "Iowa",
131 "KS" => "Kansas",
132 "KY" => "Kentucky",
133 "LA" => "Louisiana",
134 "ME" => "Maine",
135 "MD" => "Maryland",
136 "MA" => "Massachusetts",
137 "MI" => "Michigan",
138 "MN" => "Minnesota",
139 "MS" => "Mississippi",
140 "MO" => "Missouri",
141 "MT" => "Montana",
142 "NE" => "Nebraska",
143 "NV" => "Nevada",
144 "NH" => "New Hampshire",
145 "NJ" => "New Jersey",
146 "NM" => "New Mexico",
147 "NY" => "New York",
148 "NC" => "North Carolina",
149 "ND" => "North Dakota",
150 "OH" => "Ohio",
151 "OK" => "Oklahoma",
152 "OR" => "Oregon",
153 "PA" => "Pennsylvania",
154 "RI" => "Rhode Island",
155 "SC" => "South Carolina",
156 "SD" => "South Dakota",
157 "TN" => "Tennessee",
158 "TX" => "Texas",
159 "UT" => "Utah",
160 "VT" => "Vermont",
161 "VA" => "Virginia",
162 "WA" => "Washington",
163 "WV" => "West Virginia",
164 "WI" => "Wisconsin",
165 "WY" => "Wyoming"
166 };
167
168
169my $place_type_id_to_name_mapping = {
170 "1" => "Individual building",
171 "2" => "Landscape site",
172 "3" => "Campus arrangement",
173 "4" => "Building group",
174};
175
176
177sub read
178{
179 my $self = shift (@_);
180 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
181
182 $self->{'filename'} = &util::filename_cat($base_dir, $file);
183 if ($self->{'filename'} !~ /$self->{'process_exp'}/ || !-f $self->{'filename'}) {
184 return undef;
185 }
186 $self->{'processor'} = $processor;
187 $self->{'gli'} = $gli;
188
189 # Open connection to Access database
190 my $dbh = DBI->connect('dbi:ODBC:CIC-HCAP');
191
192 $self->process_institutions($dbh);
193 $self->process_places($dbh);
194 $self->process_designers($dbh);
195
196 return 1;
197}
198
199
200sub process_institutions
201{
202 my $self = shift(@_);
203 my $dbh = shift(@_);
204 my $fail_log_handle = $self->{'failhandle'};
205
206 # Prepare SQL statement for getting everything from the Institution table
207 my $institution_sql_statement = "SELECT * FROM tblInstitution"; # WHERE Institution_ID<200";
208 my $institution_sql_handle = $dbh->prepare($institution_sql_statement);
209 $institution_sql_handle->{LongReadLen} = 65536;
210 $institution_sql_handle->execute() or die "Could not execute SQL statement.";
211
212 # Prepare SQL statement for getting the Institution places
213 my $institution_places_sql_statement = "SELECT Entry_ID,Current_name FROM tblPlace WHERE PlaceType>0 AND Institution_ID=?";
214 my $institution_places_sql_handle = $dbh->prepare($institution_places_sql_statement);
215 $institution_places_sql_handle->{LongReadLen} = 65536;
216
217 # Prepare SQL statement for getting the Institution best place image location
218 my $institution_best_place_image_location_sql_statement = "SELECT Location FROM tblImages WHERE FileType=1 AND FileName=?";
219 my $institution_best_place_image_location_sql_handle = $dbh->prepare($institution_best_place_image_location_sql_statement);
220 $institution_best_place_image_location_sql_handle->{LongReadLen} = 65536;
221
222 # Prepare SQL statement for getting the Institution places images
223 my $institution_places_images_sql_statement = "SELECT FileName FROM tblImages,tblPlace WHERE tblImages.FileType=1 AND tblImages.Entry_ID=tblPlace.Entry_ID AND tblPlace.Institution_ID=?";
224 my $institution_places_images_sql_handle = $dbh->prepare($institution_places_images_sql_statement);
225 $institution_places_images_sql_handle->{LongReadLen} = 65536;
226
227 # Prepare SQL statement for getting the Institution campus plans
228 my $institution_campus_plans_sql_statement = "SELECT * FROM tblCampusMaps WHERE Electronic=1 AND Institution_ID=?";
229 my $institution_campus_plans_sql_handle = $dbh->prepare($institution_campus_plans_sql_statement);
230 $institution_campus_plans_sql_handle->{LongReadLen} = 65536;
231
232 # Create a document object for each institution
233 my %institution_id_to_name_mapping;
234 my %institution_state_to_ids_mapping;
235 while (my $row_hashref = $institution_sql_handle->fetchrow_hashref) {
236 # Skip any institutions that didn't respond
237 next if !defined($row_hashref->{"City"});
238
239 my $institution_id = $row_hashref->{"Institution_ID"};
240 # print STDERR " Institution $institution_id\n";
241 my $institution_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
242 $institution_doc_obj->set_OID("i$institution_id");
243 &new_metadata_entry($institution_doc_obj, "DocumentType", "Institution");
244
245 # For some reason the hyphen seems to be lost from the Zip field, so add it back in
246 my $institution_zip = $row_hashref->{"Zip"};
247 if ($institution_zip =~ /^(\d\d\d\d\d)(\d\d\d\d)$/) {
248 $row_hashref->{"Zip"} = $1 . "-" . $2;
249 }
250
251 # Map state to full name
252 $row_hashref->{"State"} = $state_abbr_to_name_mapping->{$row_hashref->{"State"}};
253
254 # Get the places in this institution
255 my $institution_random_place_id;
256 my $institution_places_list_html = "";
257 $institution_places_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
258 while (my $institution_places_match_hashref = $institution_places_sql_handle->fetchrow_hashref) {
259 my $institution_place_id = $institution_places_match_hashref->{"Entry_ID"};
260 my $institution_place_name = $institution_places_match_hashref->{"Current_name"};
261 $institution_places_list_html .= "<span class=\"cictext\"><a href=\"_gwcgi_?a=d&d=p$institution_place_id\">$institution_place_name</a></span><br />\n";
262 }
263 &new_metadata_entry($institution_doc_obj, "InstitutionPlacesListHTML", $institution_places_list_html);
264
265 # Get the best place image for this institution
266 my $institution_best_place_image_name = $row_hashref->{"Best_image"};
267 if (!defined($institution_best_place_image_name) || $institution_best_place_image_name eq "") {
268 # Some institutions have no electronic images, and thus have no best image
269 $institution_places_images_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
270 if (defined($institution_places_images_sql_handle->fetchrow_hashref())) {
271 print STDERR "<ProcessingError n='Institution $institution_id' p='CICPlug' r='No best image'>\n" if ($self->{'gli'});
272 print STDERR "Error: Institution $institution_id -- No best image.\n";
273 print $fail_log_handle "Error: Institution $institution_id -- No best image.\n";
274 $self->{'num_not_processed'}++;
275 next;
276 }
277 &new_metadata_entry($institution_doc_obj, "InstitutionBestPlaceImageHTML", "");
278 }
279 else {
280 # Get the file location of the best place image for this institution
281 $institution_best_place_image_location_sql_handle->execute($institution_best_place_image_name) or die "Could not execute SQL statement.";
282 my $institution_best_place_image_location = $institution_best_place_image_location_sql_handle->fetchrow();
283 if (!defined($institution_best_place_image_location) || $institution_best_place_image_location eq "") {
284 print STDERR "<ProcessingError n='Institution $institution_id' p='CICPlug' r='Could not match best image $institution_best_place_image_name to a file'>\n" if ($self->{'gli'});
285 print STDERR "Error: Institution $institution_id -- Could not match best image $institution_best_place_image_name to a file.\n";
286 print $fail_log_handle "Error: Institution $institution_id -- Could not match best image $institution_best_place_image_name to a file.\n";
287 $self->{'num_not_processed'}++;
288 next;
289 }
290
291 # PDFs are not allowed for institution best place images
292 if ($institution_best_place_image_location =~ /.pdf$/i) {
293 print STDERR "<ProcessingError n='Institution $institution_id' p='CICPlug' r='PDF not allowed for best image'>\n" if ($self->{'gli'});
294 print STDERR "Error: Institution $institution_id -- PDF not allowed for best image.\n";
295 print $fail_log_handle "Error: Institution $institution_id -- PDF not allowed for best image.\n";
296 $self->{'num_not_processed'}++;
297 next;
298 }
299
300 my $institution_best_place_image_medium_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_best_place_image_location, "medium");
301 my $institution_best_place_image_large_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_best_place_image_location, "large");
302 &new_metadata_entry($institution_doc_obj, "InstitutionBestPlaceImageHTML", "<a href=\"$institution_best_place_image_large_file_href\"><img src=\"$institution_best_place_image_medium_file_href\"/><br /><span class=\"cictext\">$institution_best_place_image_name</span></a>");
303 }
304
305 # Get institution campus plans
306 my $institution_campus_plans_list_html = "";
307 $institution_campus_plans_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
308 while (my $institution_campus_plans_match_hashref = $institution_campus_plans_sql_handle->fetchrow_hashref) {
309 my $institution_campus_plan_name = $institution_campus_plans_match_hashref->{"NameAndFormat"};
310 my $institution_campus_plan_image_location = $institution_campus_plans_match_hashref->{"Location_electronic"};
311
312 # Deal with PDF files separately: don't convert, just associate
313 if ($institution_campus_plan_image_location =~ /\.pdf$/i) {
314 # Convert the server location of the file into the local location of the file
315 my $institution_campus_plan_pdf_file_path = $institution_campus_plan_image_location;
316 $institution_campus_plan_pdf_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
317
318 if (-f $institution_campus_plan_pdf_file_path) {
319 my $institution_campus_plan_pdf_file_name = $institution_campus_plan_name . ".pdf";
320 $institution_campus_plan_pdf_file_name =~ s/ /%20/g;
321 my $institution_campus_plan_pdf_file_href = "_httpcollection_/index/assoc/[assocfilepath]/$institution_campus_plan_pdf_file_name";
322 $institution_campus_plans_list_html .= "<a href=\"$institution_campus_plan_pdf_file_href\"><span class=\"cictext\">$institution_campus_plan_name (PDF)</span></a><br />";
323
324 $institution_doc_obj->associate_file($institution_campus_plan_pdf_file_path, $institution_campus_plan_name . ".pdf", undef, $institution_doc_obj->get_top_section());
325 }
326 else {
327 print STDERR "<ProcessingError n='$institution_campus_plan_pdf_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
328 print STDERR "Error: File $institution_campus_plan_pdf_file_path does not exist.\n";
329 print $fail_log_handle "Error: File $institution_campus_plan_pdf_file_path does not exist.\n";
330 }
331 }
332 else {
333 my $institution_campus_plan_image_large_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_campus_plan_image_location, "large");
334 $institution_campus_plans_list_html .= "<a href=\"$institution_campus_plan_image_large_file_href\"><span class=\"cictext\">$institution_campus_plan_name</span></a><br />";
335 }
336 }
337 &new_metadata_entry($institution_doc_obj, "InstitutionCampusPlansListHTML", $institution_campus_plans_list_html);
338
339 # Add each field from the table as metadata
340 foreach my $key (keys(%$row_hashref)) {
341 my $value = $row_hashref->{$key};
342 if (defined($value)) {
343 &new_metadata_entry($institution_doc_obj, $key, $value);
344 }
345 }
346
347 $institution_doc_obj->add_utf8_text($institution_doc_obj->get_top_section(), "Some dummy text.");
348 $self->{'processor'}->process($institution_doc_obj);
349 $self->{'num_processed'}++;
350
351 # Build mappings for creating the static macrofiles
352 my $institution_name = $row_hashref->{"Institution_Name"};
353 $institution_id_to_name_mapping{$institution_doc_obj->get_OID()} = $institution_name;
354 my $institution_state = $row_hashref->{"State"};
355 push(@{$institution_state_to_ids_mapping{$institution_state}}, $institution_doc_obj->get_OID());
356 }
357
358 # Write the institutions.dm macrofile
359 &write_static_browser_macrofile("institutions", \%institution_id_to_name_mapping);
360
361 # Write the states.dm macrofile
362 &write_state_browser_macrofile("states", \%institution_state_to_ids_mapping, \%institution_id_to_name_mapping);
363}
364
365
366sub process_places
367{
368 my $self = shift(@_);
369 my $dbh = shift(@_);
370 my $fail_log_handle = $self->{'failhandle'};
371
372 # Prepare SQL statement for getting everything from the Place table
373 my $place_sql_statement = "SELECT * FROM tblPlace";
374 my $place_sql_handle = $dbh->prepare($place_sql_statement);
375 $place_sql_handle->{LongReadLen} = 65536;
376 $place_sql_handle->execute() or die "Could not execute SQL statement.";
377
378 # Prepare SQL statement for getting the Place institution
379 my $place_institution_sql_statement = "SELECT Institution_Name FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID and tblPlace.Entry_ID=?";
380 my $place_institution_sql_handle = $dbh->prepare($place_institution_sql_statement);
381
382 # Prepare SQL statement for getting the Place "date of construction"
383 my $place_construction_date_sql_statement = "SELECT Date FROM tblConstruction_and_Dates WHERE Entry_ID=?";
384 my $place_construction_date_sql_handle = $dbh->prepare($place_construction_date_sql_statement);
385
386 # Prepare SQL statement for getting the Place images
387 my $place_images_sql_statement = "SELECT FileName,Location FROM tblImages WHERE FileType=1 AND Entry_ID=?";
388 my $place_images_sql_handle = $dbh->prepare($place_images_sql_statement);
389 $place_images_sql_handle->{LongReadLen} = 65536;
390
391 # Prepare SQL statement for getting the Place materials
392 my $place_materials_sql_statement = "SELECT * FROM tblDescription_building WHERE Entry_ID=?";
393 my $place_materials_sql_handle = $dbh->prepare($place_materials_sql_statement);
394 $place_materials_sql_handle->{LongReadLen} = 65536;
395
396 # Prepare SQL statement for getting the Place building styles
397 my $place_styles_sql_statement = "SELECT Architectural_Classification FROM tblArchTypes,jnxtblArchPlace WHERE tblArchTypes.ArchType_ID=jnxtblArchPlace.ArchType_ID AND Entry_ID=?";
398 my $place_styles_sql_handle = $dbh->prepare($place_styles_sql_statement);
399 $place_styles_sql_handle->{LongReadLen} = 65536;
400
401 # Prepare SQL statement for getting the Place functions
402 my $place_functions_sql_statement = "SELECT Function,Year,Prefix FROM tblFunction_and_dates WHERE Entry_ID=?";
403 my $place_functions_sql_handle = $dbh->prepare($place_functions_sql_statement);
404 $place_functions_sql_handle->{LongReadLen} = 65536;
405
406 # Prepare SQL statement for getting the Place significance
407 my $place_significance_sql_statement = "SELECT SigType FROM tblSigTypes,SigPlace WHERE tblSigTypes.SigTypes_ID=SigPlace.SigType_ID+1 AND SigPlace.Entry_ID=?";
408 my $place_significance_sql_handle = $dbh->prepare($place_significance_sql_statement);
409 $place_significance_sql_handle->{LongReadLen} = 65536;
410
411 # Prepare SQL statement for getting the Place references
412 my $place_references_sql_statement = "SELECT Bibliography FROM tblReferences WHERE Entry_ID=?";
413 my $place_references_sql_handle = $dbh->prepare($place_references_sql_statement);
414 $place_references_sql_handle->{LongReadLen} = 65536;
415
416 # Prepare SQL statement for getting the Place narrative
417 my $place_narrative_sql_statement = "SELECT Narrative FROM tblSignificance_Narrative WHERE Entry_ID=?";
418 my $place_narrative_sql_handle = $dbh->prepare($place_narrative_sql_statement);
419 $place_narrative_sql_handle->{LongReadLen} = 65536;
420
421 # Prepare SQL statement for getting the Place state
422 my $place_state_sql_statement = "SELECT State FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID AND Entry_ID=?";
423 my $place_state_sql_handle = $dbh->prepare($place_state_sql_statement);
424 $place_state_sql_handle->{LongReadLen} = 65536;
425
426 # Create a document object for each place
427 my %place_type_to_ids_mapping;
428 my %place_style_to_ids_mapping;
429 my %place_date_to_ids_mapping;
430 my %place_function_to_ids_mapping;
431 my %place_id_to_name_mapping;
432 my %place_id_to_institution_name_mapping;
433 while (my $row_hashref = $place_sql_handle->fetchrow_hashref) {
434 my $place_id = $row_hashref->{"Entry_ID"};
435 # print STDERR " Place $place_id\n";
436 my $place_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
437 $place_doc_obj->set_OID("p$place_id");
438 &new_metadata_entry($place_doc_obj, "DocumentType", "Place");
439
440 # Convert the place type ID into a name
441 $row_hashref->{"PlaceType"} = $place_type_id_to_name_mapping->{$row_hashref->{"PlaceType"}};
442
443 # Add each field from the table as metadata
444 foreach my $key (keys(%$row_hashref)) {
445 my $value = $row_hashref->{$key};
446 if (defined($value)) {
447 &new_metadata_entry($place_doc_obj, $key, $value);
448 }
449 }
450
451 # Get place name
452 my $place_name = $row_hashref->{"Current_name"};
453 if (!defined($place_name)) {
454 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing place name'>\n" if ($self->{'gli'});
455 print STDERR "Error: Place $place_id -- Missing place name.\n";
456 print $fail_log_handle "Error: Place $place_id -- Missing place name.\n";
457 $self->{'num_not_processed'}++;
458 next;
459 }
460
461 # Get place type
462 my $place_type = $row_hashref->{"PlaceType"};
463 if (!defined($place_type)) {
464 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing place type'>\n" if ($self->{'gli'});
465 print STDERR "Error: Place $place_id -- Missing place type.\n";
466 print $fail_log_handle "Error: Place $place_id -- Missing place type.\n";
467 $self->{'num_not_processed'}++;
468 next;
469 }
470
471 # Get place date of construction, except for landscape sites which have no date
472 $place_construction_date_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
473 my $place_construction_date_value = $place_construction_date_sql_handle->fetchrow();
474 if (!defined($place_construction_date_value) && $place_type eq "Landscape site") {
475 # Landscape sites may not have a construction date
476 $place_construction_date_value = "";
477 }
478 if (!defined($place_construction_date_value)) {
479 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing construction date'>\n" if ($self->{'gli'});
480 print STDERR "Error: Place $place_id -- Missing construction date.\n";
481 print $fail_log_handle "Error: Place $place_id -- Missing construction date.\n";
482 $self->{'num_not_processed'}++;
483 next;
484 }
485 &new_metadata_entry($place_doc_obj, "Construction_date", $place_construction_date_value);
486
487 # Create place styles mapping
488 $place_styles_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
489 while (my $place_styles_match_hashref = $place_styles_sql_handle->fetchrow_hashref()) {
490 my $place_style = $place_styles_match_hashref->{"Architectural_Classification"};
491 push(@{$place_style_to_ids_mapping{$place_style}}, $place_doc_obj->get_OID());
492 &new_metadata_entry($place_doc_obj, "Style", $place_style);
493 }
494
495 # Get place institution
496 $place_institution_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
497 my $place_institution = $place_institution_sql_handle->fetchrow();
498 &new_metadata_entry($place_doc_obj, "Institution_name", $place_institution);
499 $place_id_to_institution_name_mapping{$place_doc_obj->get_OID()} = ", " . $place_institution;
500
501 # Get place state (for searching)
502 $place_state_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
503 my $place_state_abbr = $place_state_sql_handle->fetchrow();
504 &new_metadata_entry($place_doc_obj, "State", $place_state_abbr . " " . $state_abbr_to_name_mapping->{$place_state_abbr});
505
506 # Create place dates mapping
507 my $place_time_period = $place_construction_date_value;
508 if ($place_construction_date_value =~ /^(\d\d\d\d).*$/) {
509 $place_construction_date_value =~ s/^(\d\d\d\d).*$/$1/;
510 if ($place_construction_date_value < 1800) { $place_time_period = "pre-1800"; }
511 elsif ($place_construction_date_value < 1850) { $place_time_period = "1800-1850"; }
512 elsif ($place_construction_date_value < 1900) { $place_time_period = "1850-1900"; }
513 elsif ($place_construction_date_value < 1945) { $place_time_period = "1900-1945"; }
514 elsif ($place_construction_date_value < 1995) { $place_time_period = "1945-1995"; }
515 else { $place_time_period = "post-1995"; }
516 push(@{$place_date_to_ids_mapping{$place_time_period}}, $place_doc_obj->get_OID());
517 }
518 &new_metadata_entry($place_doc_obj, "Time_period", $place_time_period);
519
520 # Get place materials (individual buildings only)
521 if ($row_hashref->{"PlaceType"} eq "Individual building") {
522 $place_materials_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
523 my $place_materials_match_hashref = $place_materials_sql_handle->fetchrow_hashref();
524 &new_metadata_entry($place_doc_obj, "MaterialFoundation", $place_materials_match_hashref->{"foundation"} || "");
525 &new_metadata_entry($place_doc_obj, "MaterialRoof", $place_materials_match_hashref->{"roof"} || "");
526 &new_metadata_entry($place_doc_obj, "MaterialWalls", $place_materials_match_hashref->{"walls"} || "");
527 }
528
529 # Get place functions
530 my $place_functions = "";
531 my $place_functions_table_html = "";
532 $place_functions_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
533 while (my $place_functions_match_hashref = $place_functions_sql_handle->fetchrow_hashref()) {
534 my $place_function = $place_functions_match_hashref->{"Function"};
535 if (!defined($place_function)) {
536 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing function'>\n" if ($self->{'gli'});
537 print STDERR "Error: Place $place_id -- Missing function.\n";
538 print $fail_log_handle "Error: Place $place_id -- Missing function.\n";
539 next;
540 }
541 # Check for multiline values (these are errors)
542 if ($place_function =~ /\n/) {
543 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Multiline function'>\n" if ($self->{'gli'});
544 print STDERR "Error: Place $place_id -- Multiline function.\n";
545 print $fail_log_handle "Error: Place $place_id -- Multiline function.\n";
546 next;
547 }
548 my $place_year = $place_functions_match_hashref->{"Year"};
549 if (!defined($place_year)) {
550 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing function year'>\n" if ($self->{'gli'});
551 print STDERR "Error: Place $place_id -- Missing function year.\n";
552 print $fail_log_handle "Error: Place $place_id -- Missing function year.\n";
553 next;
554 }
555 my $place_year_prefix = $place_functions_match_hashref->{"Prefix"} || "";
556 $place_functions .= "$place_function ";
557 $place_functions_table_html .= "<tr><td valign=\"top\"><nobr>$place_year_prefix $place_year</nobr>&nbsp;</td><td valign=\"top\">$place_function</td></tr>";
558
559 # Create place functions mapping
560 $place_function =~ s/\(.*\)//g;
561 $place_function =~ s/^\s*//;
562 $place_function =~ s/\s*$//;
563 next if ($place_function eq "");
564 push(@{$place_function_to_ids_mapping{$place_function}}, $place_doc_obj->get_OID());
565 }
566 &new_metadata_entry($place_doc_obj, "Functions", $place_functions);
567 &new_metadata_entry($place_doc_obj, "PlaceFunctionsTableHTML", "<table cellpadding=\"0\" cellspacing=\"0\">" . $place_functions_table_html . "</table>");
568
569 # Get place significance
570 $place_significance_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
571 while (my $place_significance_match_hashref = $place_significance_sql_handle->fetchrow_hashref()) {
572 my $place_significance = $place_significance_match_hashref->{"SigType"};
573 &new_metadata_entry($place_doc_obj, "Significance", lc($place_significance));
574 }
575
576 # Get place references
577 $place_references_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
578 my $place_references = $place_references_sql_handle->fetchrow();
579 if (defined($place_references)) {
580 &new_metadata_entry($place_doc_obj, "References", &rtf_to_html($place_references));
581 }
582
583 # Get place narrative
584 $place_narrative_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
585 my $place_narrative = $place_narrative_sql_handle->fetchrow();
586 if (defined($place_narrative)) {
587 $place_narrative = &rtf_to_html($place_narrative);
588 $place_narrative =~ s/<br \/>(\s|\n)*$//; # Remove any trailing <br /> tags
589 &new_metadata_entry($place_doc_obj, "Narrative", $place_narrative);
590 }
591
592 # Get place images
593 my $place_images_html = "";
594 $place_images_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
595 while (my $place_images_match_hashref = $place_images_sql_handle->fetchrow_hashref) {
596 my $place_image_location = $place_images_match_hashref->{"Location"};
597 my $place_image_name = $place_images_match_hashref->{"FileName"};
598
599 # Deal with PDF files separately: don't convert, just associate
600 if ($place_image_location =~ /\.pdf$/i) {
601 # Convert the server location of the PDF file into the local location of the file
602 my $place_pdf_file_path = $place_image_location;
603 $place_pdf_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
604
605 if (-f $place_pdf_file_path) {
606 my ($place_pdf_file_name) = ($place_pdf_file_path =~ /^.+\\(.+)$/);
607 $place_doc_obj->associate_file($place_pdf_file_path, $place_pdf_file_name, undef, $place_doc_obj->get_top_section());
608
609 $place_pdf_file_name =~ s/ /%20/g;
610 my $place_pdf_file_href = "_httpcollection_/index/assoc/[assocfilepath]/$place_pdf_file_name";
611 $place_images_html .= "<tr><td align=\"right\" valign=\"top\"><a href=\"$place_pdf_file_href\">_iconpdf_</a></td><td valign=\"top\"><a href=\"$place_pdf_file_href\"><span class=\"cictext\">$place_image_name (PDF)</span></a></td></tr>\n";
612 }
613 else {
614 print STDERR "<ProcessingError n='$place_pdf_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
615 print STDERR "Error: File $place_pdf_file_path does not exist.\n";
616 print $fail_log_handle "Error: File $place_pdf_file_path does not exist.\n";
617 }
618 }
619 else {
620 my $place_image_small_file_href = $self->generate_place_image_variant($place_doc_obj, $place_image_location, "small");
621 my $place_image_large_file_href = $self->generate_place_image_variant($place_doc_obj, $place_image_location, "large");
622
623 if (defined($place_image_name)) {
624 $place_images_html .= "<tr><td valign=\"top\"><a href=\"$place_image_large_file_href\"><img src=\"$place_image_small_file_href\"/></a></td><td valign=\"top\"><a href=\"$place_image_large_file_href\"><span class=\"cictext\">$place_image_name</span></a></td></tr>\n";
625 }
626 else {
627 $place_images_html .= "<tr><td valign=\"top\"><img src=\"_httpcollection_/images/no_image-small.jpg\"/></td><td valign=\"top\"><span class=\"cictext\">&nbsp;</span></td></tr>\n";
628 }
629 }
630 }
631
632 &new_metadata_entry($place_doc_obj, "PlaceImagesHTML", "<table>" . $place_images_html . "</table>");
633
634 $place_doc_obj->add_utf8_text($place_doc_obj->get_top_section(), "Some dummy text.");
635 $self->{'processor'}->process($place_doc_obj);
636 $self->{'num_processed'}++;
637
638 # Build mappings for creating the static macrofiles
639 $place_id_to_name_mapping{$place_doc_obj->get_OID()} = $place_name;
640 push(@{$place_type_to_ids_mapping{$place_type}}, $place_doc_obj->get_OID());
641 }
642
643 &write_bilevel_static_browser_macrofile("types", \%place_type_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
644 &write_bilevel_static_browser_macrofile("styles", \%place_style_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
645 &write_bilevel_static_browser_macrofile("dates", \%place_date_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
646 &write_bilevel_static_browser_macrofile("functions", \%place_function_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
647}
648
649
650sub process_designers
651{
652 my $self = shift(@_);
653 my $dbh = shift(@_);
654 my $fail_log_handle = $self->{'failhandle'};
655
656 # Prepare SQL statement for getting all the Architects from the Place table
657 my $designer_sql_statement = "SELECT Architect_Name,Entry_ID FROM tblConstruction_and_dates";
658 my $designer_sql_handle = $dbh->prepare($designer_sql_statement);
659 $designer_sql_handle->{LongReadLen} = 65536;
660 $designer_sql_handle->execute() or die "Could not execute SQL statement.";
661
662 # Prepare SQL statement for getting the Place name
663 my $place_name_sql_statement = "SELECT Current_name FROM tblPlace WHERE Entry_ID=?";
664 my $place_name_sql_handle = $dbh->prepare($place_name_sql_statement);
665
666 # Prepare SQL statement for getting the Place institution
667 my $place_institution_sql_statement = "SELECT Institution_Name FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID and tblPlace.Entry_ID=?";
668 my $place_institution_sql_handle = $dbh->prepare($place_institution_sql_statement);
669
670 # Prepare SQL statement for getting the Place "date of construction"
671 my $place_construction_date_sql_statement = "SELECT Date FROM tblConstruction_and_Dates WHERE Entry_ID=?";
672 my $place_construction_date_sql_handle = $dbh->prepare($place_construction_date_sql_statement);
673
674 # Prepare SQL statement for getting the Place non-PDF images
675 my $place_images_sql_statement = "SELECT Location FROM tblImages WHERE FileType=1 AND Location NOT LIKE '%.pdf' AND Entry_ID=?";
676 my $place_images_sql_handle = $dbh->prepare($place_images_sql_statement);
677 $place_images_sql_handle->{LongReadLen} = 65536;
678
679 # Get a list of all the designers, and the places they worked on
680 my %designer_name_to_place_ids_mapping;
681 my %designer_name_to_id_mapping;
682 my %designer_id_to_name_mapping;
683 my $designer_count = 0;
684 while (my $designer_hashref = $designer_sql_handle->fetchrow_hashref) {
685 my $designer_names_string = $designer_hashref->{"Architect_Name"};
686 next if !defined($designer_names_string);
687 foreach my $designer_name (split(/;/, $designer_names_string)) {
688 $designer_name =~ s/\(.*?\)//g;
689 $designer_name =~ s/^\s*//;
690 $designer_name =~ s/\s*$//;
691
692 if (!defined($designer_name_to_id_mapping{$designer_name})) {
693 $designer_count++;
694 $designer_name_to_id_mapping{$designer_name} = "d" . $designer_count;
695 }
696
697 $designer_id_to_name_mapping{$designer_name_to_id_mapping{$designer_name}} = $designer_name;
698 push(@{$designer_name_to_place_ids_mapping{$designer_name}}, $designer_hashref->{"Entry_ID"});
699 }
700 }
701
702 # Create a document object for each designer
703 foreach my $designer_name (keys %designer_name_to_place_ids_mapping) {
704 my $designer_id = $designer_name_to_id_mapping{$designer_name};
705 # print STDERR " Designer $designer_id\n";
706 my $designer_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
707 $designer_doc_obj->set_OID($designer_id);
708 &new_metadata_entry($designer_doc_obj, "DocumentType", "Designer");
709
710 &new_metadata_entry($designer_doc_obj, "Designer_name", $designer_name);
711
712 my $designer_places_list_html = "";
713 foreach my $designer_place_id (@{$designer_name_to_place_ids_mapping{$designer_name}}) {
714 # Get place name
715 $place_name_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
716 my $designer_place_name = $place_name_sql_handle->fetchrow();
717
718 # Get place institution name
719 $place_institution_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
720 my $designer_place_institution_name = $place_institution_sql_handle->fetchrow();
721
722 # Get place date of construction
723 $place_construction_date_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
724 my $designer_place_construction_date_value = $place_construction_date_sql_handle->fetchrow() || "";
725
726 # Get the first non-PDF image for this place
727 my $designer_place_image_small_file_href;
728 $place_images_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
729 my $designer_place_image_location = $place_images_sql_handle->fetchrow();
730 if (defined($designer_place_image_location)) {
731 $designer_place_image_small_file_href = $self->generate_place_image_variant($designer_doc_obj, $designer_place_image_location, "small");
732 }
733 else {
734 # There is no non-PDF image for this place
735 $designer_place_image_small_file_href = "_httpcollection_/images/no_image-small.jpg";
736 }
737
738 $designer_places_list_html .= "<tr><td valign=\"top\"><a href=\"_gwcgi_?a=d&d=p$designer_place_id\"><img src=\"$designer_place_image_small_file_href\"/></a></td><td valign=\"top\"><a href=\"_gwcgi_?a=d&d=p$designer_place_id\">$designer_place_name</a>, $designer_place_institution_name<br /><b>Date of construction:</b> $designer_place_construction_date_value</td></tr>\n";
739 }
740
741 &new_metadata_entry($designer_doc_obj, "DesignerPlacesListHTML", "<table>" . $designer_places_list_html . "</table>");
742
743 $designer_doc_obj->add_utf8_text($designer_doc_obj->get_top_section(), "Some dummy text.");
744 $self->{'processor'}->process($designer_doc_obj);
745 $self->{'num_processed'}++;
746 }
747
748 # Write the designers.dm macrofile
749 &write_static_browser_macrofile("designers", \%designer_id_to_name_mapping);
750}
751
752
753sub new_metadata_entry
754{
755 my ($doc_obj, $metadata_name, $metadata_value) = (@_);
756
757 # Don't bother with empty metadata
758 return if ($metadata_value eq "");
759
760 # Spaces aren't allowed in metadata names
761 $metadata_name =~ s/ /_/g;
762
763 # Anything from the database is ISO 8859-1 encoded, so convert to UTF-8
764 $metadata_value = &unicode::ascii2utf8(\$metadata_value);
765
766 # Remove '#' characters around links
767 if ($metadata_value =~ /\#(.*?)\#/) {
768 $metadata_value = $1;
769 }
770
771 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), $metadata_name, $metadata_value);
772}
773
774
775sub rtf_to_html
776{
777 my $rtf_string = shift(@_);
778 $rtf_string =~ s/\{(.*?)\}//g;
779 $rtf_string =~ s/\\rquote /'/g; # ' # (for Emacs)
780 $rtf_string =~ s/\\pard//g;
781 $rtf_string =~ s/\\par/<br \/>/g;
782 $rtf_string =~ s/\\i0 /<\/i>/g;
783 $rtf_string =~ s/\\i /<i>/g;
784 $rtf_string =~ s/\\~/ /g;
785 $rtf_string =~ s/\\([A-Za-z0-9]+)//g;
786 $rtf_string =~ s/\}//g;
787
788 # Assume non-ASCII is ISO 8859-1, and convert into HTML entities
789 while ($rtf_string =~ /\\'([a-z0-9][a-z0-9])/) {
790 my $dec = hex($1);
791 $rtf_string =~ s/\\'$1/&#$dec\;/;
792 }
793
794 return $rtf_string;
795}
796
797
798sub get_place_image_dimensions
799{
800 my $self = shift(@_);
801 my $place_image_file_path = shift(@_);
802 my $fail_log_handle = $self->{'failhandle'};
803
804 # Make sure the place image file actually exists
805 if (!-f $place_image_file_path) {
806 print STDERR "<ProcessingError n='$place_image_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
807 print STDERR "Error: Image $place_image_file_path does not exist.\n";
808 print $fail_log_handle "Error: Image $place_image_file_path does not exist.\n";
809 return;
810 }
811 my $place_image_file_date = (stat($place_image_file_path))[9];
812
813 # Check if this place image has already been identified by looking for a ".info" file in the same directory
814 my $place_image_info_file_path = $place_image_file_path . ".info";
815 if (-f $place_image_info_file_path) {
816 # A ".info" file exists, so read the cached place image information from it
817 open(PLACE_IMAGE_INFO_FILE, "<$place_image_info_file_path");
818 my @place_image_info = <PLACE_IMAGE_INFO_FILE>;
819 close(PLACE_IMAGE_INFO_FILE);
820
821 # Read the cached place image file date and check that it matches
822 my $cached_place_image_file_date = $place_image_info[0];
823 $cached_place_image_file_date =~ s/\n$//;
824 if ($cached_place_image_file_date == $place_image_file_date) {
825 # It does match, so use the cached information from the ".info" file instead of re-identifying the file
826 my $place_image_width = $place_image_info[1];
827 $place_image_width =~ s/\n$//;
828 my $place_image_height = $place_image_info[2];
829 $place_image_height =~ s/\n$//;
830 return ($place_image_width, $place_image_height);
831 }
832 }
833
834 # We haven't already identified the place image, so do it now
835 print STDERR "Identifying place image $place_image_file_path...\n";
836 my $identify_command = "identify -format \"%w %h\" \"$place_image_file_path\"";
837 my $identify_result = `$identify_command`;
838 print "Identify result: $identify_result\n" if ($self->{'verbosity'} > 2);
839
840 # Check that the output is what we're expecting
841 if ($identify_result !~ /(\d+) (\d+)/) {
842 print STDERR "<ProcessingError n='$place_image_file_path' p='CICPlug' r='Could not identify'>\n" if ($self->{'gli'});
843 print STDERR "Error: Place image $place_image_file_path could not be identified.\n";
844 print $fail_log_handle "Error: Place image $place_image_file_path could not be identified.\n";
845 return;
846 }
847
848 # Parse the place image width and height from the output
849 my $place_image_width = $1;
850 my $place_image_height = $2;
851
852 # Write the place image info file so we don't have to identify this exact image again in the future
853 open(PLACE_IMAGE_INFO_FILE, ">$place_image_info_file_path");
854 print PLACE_IMAGE_INFO_FILE "$place_image_file_date\n";
855 print PLACE_IMAGE_INFO_FILE "$place_image_width\n";
856 print PLACE_IMAGE_INFO_FILE "$place_image_height\n";
857 close(PLACE_IMAGE_INFO_FILE);
858 return ($place_image_width, $place_image_height);
859}
860
861
862sub generate_place_image_variant
863{
864 my $self = shift(@_);
865 my ($doc_obj, $place_image_location, $place_image_variant_size) = (@_);
866 my $fail_log_handle = $self->{'failhandle'};
867
868 # Convert the server location of the file into the local location of the file
869 my $place_image_file_path = $place_image_location;
870 $place_image_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
871
872 # Get the width and height of the place image
873 my ($place_image_width, $place_image_height) = $self->get_place_image_dimensions($place_image_file_path);
874 if (!defined($place_image_width) || !defined($place_image_height)) {
875 # An error has occurred (error message generated by get_place_image_dimensions())
876 return;
877 }
878 my $place_image_file_date = (stat($place_image_file_path))[9];
879
880 # Generate the path of the place image variant (in the cache directory)
881 my $place_image_variant_file_suffix = "-$place_image_variant_size." . $self->{$place_image_variant_size . '_image_type'};
882 my $place_image_variant_file_path = $place_image_location;
883 $place_image_variant_file_path =~ s/^[A-Z]:/$self->{'cache_directory'}/;
884 $place_image_variant_file_path =~ s/^(.+)(\..*)/$1$place_image_variant_file_suffix/;
885 my ($place_image_variant_file_name) = ($place_image_variant_file_path =~ /^.+\\(.+)$/);
886
887 # Only scale down the place image if it is bigger than the desired width
888 my $place_image_variant_desired_width = $self->{$place_image_variant_size . '_image_width'};
889 if ($place_image_width > $place_image_variant_desired_width) {
890 # Only generate the place image variant if it doesn't already exist, or if the place image is newer
891 if (!-f $place_image_variant_file_path || $place_image_file_date > (stat($place_image_variant_file_path))[9]) {
892 print STDERR "Generating place image variant $place_image_variant_file_path...\n";
893 my ($place_image_variant_directory) = ($place_image_variant_file_path =~ /^(.+)\\.+$/);
894 &util::mk_all_dir($place_image_variant_directory);
895 my $place_image_variant_options = "-scale $place_image_variant_desired_width " . $self->{$place_image_variant_size . '_image_options'};
896 my $convert_command = "convert $place_image_variant_options \"$place_image_file_path\" \"$place_image_variant_file_path\"";
897 my $convert_result = `$convert_command`;
898 }
899 }
900 else {
901 # The desired width is bigger than the place image, so we just use the original
902 $place_image_variant_file_path = $place_image_file_path;
903 }
904
905 my ($place_image_variant_width, $place_image_variant_height) = $self->get_place_image_dimensions($place_image_variant_file_path);
906 if (!defined($place_image_variant_width) || !defined($place_image_variant_height)) {
907 # An error has occurred (error message generated by get_place_image_dimensions())
908 return;
909 }
910
911 # Create a new section for each place image variant (!! TO DO: Check if this is really necessary)
912 my $place_image_variant_section = $doc_obj->insert_section($doc_obj->get_end_child($doc_obj->get_top_section()));
913 $doc_obj->add_utf8_text($place_image_variant_section, "Some dummy text.");
914 $doc_obj->add_utf8_metadata($place_image_variant_section, "Title", "1");
915
916 # Associate the place image variant file
917 $doc_obj->associate_file($place_image_variant_file_path, $place_image_variant_file_name, undef, $place_image_variant_section);
918
919 # Add various bits of metadata for the place image variant
920 my $place_image_variant_href = "_httpcollection_/index/assoc/[assocfilepath]/" . $place_image_variant_file_name;
921 $place_image_variant_href =~ s/ /%20/g;
922 return $place_image_variant_href;
923}
924
925
926sub write_static_browser_macrofile
927{
928 my $static_browser_package_name = shift(@_);
929 my $id_to_name_mapping = shift(@_);
930
931 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_name.dm";
932 print STDERR "Writing $static_browser_macrofile_path...\n";
933 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
934 &write_static_browser_macros($static_browser_package_name, $id_to_name_mapping);
935 close(BROWSER_MACROFILE);
936}
937
938
939sub write_static_browser_macros
940{
941 my $static_browser_package_name = shift(@_);
942 my $id_to_name_mapping = shift(@_);
943 my $id_to_extra_mapping = shift(@_);
944
945 print BROWSER_MACROFILE "package $static_browser_package_name\n\n";
946 print BROWSER_MACROFILE "_cicstaticbrowser_ {\n";
947
948 my %letter_to_ids_mapping;
949 foreach my $id (keys %$id_to_name_mapping) {
950 my $name = $id_to_name_mapping->{$id};
951 my ($letter) = ($name =~ /([A-Za-z0-9])/);
952 push(@{$letter_to_ids_mapping{$letter}}, $id);
953 }
954
955 print BROWSER_MACROFILE "<center><b>";
956 foreach my $letter (split(//, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) {
957 if (defined($letter_to_ids_mapping{$letter})) {
958 print BROWSER_MACROFILE "<a href=\"#$letter\">$letter</a>&nbsp;";
959 }
960 else {
961 print BROWSER_MACROFILE "$letter&nbsp;";
962 }
963 }
964 print BROWSER_MACROFILE "</b></center>\n";
965
966 print BROWSER_MACROFILE "<table cellpadding=\"0\" cellspacing=\"0\" width=\"_pagewidth_\">\n";
967 foreach my $letter (sort(keys %letter_to_ids_mapping)) {
968 my @letter_ids = @{$letter_to_ids_mapping{$letter}};
969 &write_static_browser_macros_chunk($letter, \@letter_ids, $id_to_name_mapping, $id_to_extra_mapping);
970 }
971 print BROWSER_MACROFILE "</table>\n";
972
973 print BROWSER_MACROFILE "}\n";
974}
975
976
977sub write_static_browser_macros_chunk
978{
979 my $chunk_title = shift(@_);
980 my $chunk_ids_ref = shift(@_);
981 my $id_to_name_mapping = shift(@_);
982 my $id_to_extra_mapping = shift(@_);
983
984 print BROWSER_MACROFILE "<tr><td width=\"50%\"><br /><a name=\"$chunk_title\"/><span style=\"color: black;\"><b>$chunk_title</b></span></td><td width=\"50%\"></td></tr>\n";
985
986 my %full_name_to_id_mapping;
987 foreach my $id (@{$chunk_ids_ref}) {
988 my $full_name = $id_to_name_mapping->{$id};
989 if (defined($id_to_extra_mapping)) {
990 $full_name .= " " . $id_to_extra_mapping->{$id};
991 }
992 $full_name_to_id_mapping{$full_name} = $id;
993 }
994
995 my @full_names = sort(keys(%full_name_to_id_mapping));
996 my $half_point = ((scalar(@full_names) % 2 == 0) ? scalar(@full_names) / 2 : (scalar(@full_names) + 1) / 2);
997 for (my $i = 0; $i < $half_point; $i++) {
998 print BROWSER_MACROFILE "<tr>";
999
1000 my $id = $full_name_to_id_mapping{$full_names[$i]};
1001 my $name = $id_to_name_mapping->{$id};
1002 my $extra = $id_to_extra_mapping->{$id} || "";
1003 print BROWSER_MACROFILE "<td valign=\"top\"><a href=\"_gwcgi_?a=d&d=$id\">$name</a>$extra</td>";
1004
1005 print BROWSER_MACROFILE "<td valign=\"top\">";
1006 if (defined($full_names[$i+$half_point])) {
1007 $id = $full_name_to_id_mapping{$full_names[$i+$half_point]};
1008 $name = $id_to_name_mapping->{$id};
1009 $extra = $id_to_extra_mapping->{$id} || "";
1010 print BROWSER_MACROFILE "<a href=\"_gwcgi_?a=d&d=$id\">$name</a>$extra";
1011 }
1012 print BROWSER_MACROFILE "</td>";
1013
1014 print BROWSER_MACROFILE "</tr>\n";
1015 }
1016}
1017
1018
1019sub write_bilevel_static_browser_macrofile
1020{
1021 my $static_browser_package_root = shift(@_);
1022 my $category_to_ids_mapping = shift(@_);
1023 my $id_to_name_mapping = shift(@_);
1024 my $id_to_extra_mapping = shift(@_);
1025
1026 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_root.dm";
1027 print STDERR "Writing $static_browser_macrofile_path...\n";
1028 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
1029
1030 foreach my $category (keys(%{$category_to_ids_mapping})) {
1031 my $static_browser_package_name = $static_browser_package_root . $category;
1032 $static_browser_package_name =~ s/\W//g;
1033
1034 my %id_to_name_mapping_for_category = ();
1035 foreach my $id (@{$category_to_ids_mapping->{$category}}) {
1036 $id_to_name_mapping_for_category{$id} = $id_to_name_mapping->{$id};
1037 }
1038 &write_static_browser_macros($static_browser_package_name, \%id_to_name_mapping_for_category, $id_to_extra_mapping);
1039 }
1040
1041 close(BROWSER_MACROFILE);
1042}
1043
1044
1045sub write_state_browser_macrofile
1046{
1047 my $static_browser_package_name = shift(@_);
1048 my $state_to_ids_mapping = shift(@_);
1049 my $id_to_name_mapping = shift(@_);
1050
1051 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_name.dm";
1052 print STDERR "Writing $static_browser_macrofile_path...\n";
1053 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
1054 print BROWSER_MACROFILE "package $static_browser_package_name\n\n";
1055 print BROWSER_MACROFILE "_cicstaticbrowser_ {\n";
1056
1057 print BROWSER_MACROFILE "<table cellpadding=\"0\" cellspacing=\"0\" width=\"_pagewidth_\">\n";
1058 foreach my $state (sort(keys(%{$state_to_ids_mapping}))) {
1059 my @state_ids = @{$state_to_ids_mapping->{$state}};
1060 &write_static_browser_macros_chunk($state, \@state_ids, $id_to_name_mapping, undef);
1061 }
1062 print BROWSER_MACROFILE "</table>\n";
1063
1064 print BROWSER_MACROFILE "}\n";
1065 close(BROWSER_MACROFILE);
1066}
1067
1068
10691;
Note: See TracBrowser for help on using the repository browser.