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

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

Now all states are included in the static states page, even if they contain no institutions (needed for the "search institutions by state" page).

  • Property svn:keywords set to Author Date Id Revision
File size: 55.2 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
168my %state_name_to_abbr_mapping = reverse(%{$state_abbr_to_name_mapping});
169
170my $state_abbr_to_area_mapping = {
171 "AL" => "Southeast",
172 "AK" => "West",
173 "AZ" => "Southwest",
174 "AR" => "Southeast",
175 "CA" => "West",
176 "CO" => "Mountain",
177 "CT" => "Northeast",
178 "DE" => "Northeast",
179 "FL" => "Southeast",
180 "GA" => "Southeast",
181 "HI" => "West",
182 "ID" => "Mountain",
183 "IL" => "Midwest",
184 "IN" => "Midwest",
185 "IA" => "Midwest",
186 "KS" => "Midwest",
187 "KY" => "Southeast",
188 "LA" => "Southeast",
189 "ME" => "Northeast",
190 "MD" => "Northeast",
191 "MA" => "Northeast",
192 "MI" => "Midwest",
193 "MN" => "Midwest",
194 "MS" => "Southeast",
195 "MO" => "Midwest",
196 "MT" => "Mountain",
197 "NE" => "Midwest",
198 "NV" => "West",
199 "NH" => "Northeast",
200 "NJ" => "Northeast",
201 "NM" => "Southwest",
202 "NY" => "Northeast",
203 "NC" => "Southeast",
204 "ND" => "Midwest",
205 "OH" => "Midwest",
206 "OK" => "Southwest",
207 "OR" => "West",
208 "PA" => "Northeast",
209 "RI" => "Northeast",
210 "SC" => "Southeast",
211 "SD" => "Midwest",
212 "TN" => "Southeast",
213 "TX" => "Southwest",
214 "UT" => "Mountain",
215 "VT" => "Northeast",
216 "VA" => "Southeast",
217 "WA" => "West",
218 "WV" => "Southeast",
219 "WI" => "Midwest",
220 "WY" => "Mountain"
221 };
222
223
224my $place_type_id_to_name_mapping = {
225 "1" => "Individual building",
226 "2" => "Landscape site",
227 "3" => "Campus arrangement",
228 "4" => "Building group",
229};
230
231
232my $place_functions_mapping = {
233 "academic department building" => "",
234 "administration" => "",
235 "admissions office" => "",
236 "alumni center" => "",
237 "arboretum" => "",
238 "archaeological site" => "",
239 "auditorium" => "",
240 "bell tower" => "",
241 "chapel" => "",
242 "classrooms" => "",
243 "debating society" => "",
244 "dining hall" => "",
245 "facility management building" => "",
246 "faculty offices" => "",
247 "gardens" => "",
248 "greek letter society" => "",
249 "gymnasium" => "",
250 "infirmary" => "",
251 "library" => "",
252 "master plan (campus)" => "",
253 "master plan (landscape)" => "",
254 "memorial site" => "",
255 "museum" => "",
256 "observatory" => "",
257 "old main" => "",
258 "outdoor space" => "",
259 "president's house" => "",
260 "private residence" => "",
261 "residence hall" => "",
262 "stadium" => "",
263 "student union" => "",
264 "theater" => "",
265 "other" => "",
266};
267
268
269sub read
270{
271 my $self = shift (@_);
272 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
273
274 $self->{'filename'} = &util::filename_cat($base_dir, $file);
275 if ($self->{'filename'} !~ /$self->{'process_exp'}/ || !-f $self->{'filename'}) {
276 return undef;
277 }
278 $self->{'processor'} = $processor;
279 $self->{'gli'} = $gli;
280
281 # Open connection to Access database
282 my $dbh = DBI->connect('dbi:ODBC:CIC-HCAP');
283
284 $self->process_institutions($dbh);
285 $self->process_places($dbh);
286 $self->process_designers($dbh);
287
288 return 1;
289}
290
291
292sub process_institutions
293{
294 my $self = shift(@_);
295 my $dbh = shift(@_);
296 my $fail_log_handle = $self->{'failhandle'};
297
298 # Prepare SQL statement for getting everything from the Institution table
299 my $institution_sql_statement = "SELECT * FROM tblInstitution"; # WHERE Institution_ID<200";
300 my $institution_sql_handle = $dbh->prepare($institution_sql_statement);
301 $institution_sql_handle->{LongReadLen} = 65536;
302 $institution_sql_handle->execute() or die "Could not execute SQL statement.";
303
304 # Prepare SQL statement for getting the Institution places
305 my $institution_places_sql_statement = "SELECT Entry_ID,Current_name FROM tblPlace WHERE PlaceType>0 AND Institution_ID=?";
306 my $institution_places_sql_handle = $dbh->prepare($institution_places_sql_statement);
307 $institution_places_sql_handle->{LongReadLen} = 65536;
308
309 # Prepare SQL statement for getting the Institution best place image location
310 my $institution_best_place_image_location_sql_statement = "SELECT Location FROM tblImages WHERE FileType=1 AND FileName=?";
311 my $institution_best_place_image_location_sql_handle = $dbh->prepare($institution_best_place_image_location_sql_statement);
312 $institution_best_place_image_location_sql_handle->{LongReadLen} = 65536;
313
314 # Prepare SQL statement for getting the Institution places images
315 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=?";
316 my $institution_places_images_sql_handle = $dbh->prepare($institution_places_images_sql_statement);
317 $institution_places_images_sql_handle->{LongReadLen} = 65536;
318
319 # Prepare SQL statement for getting the Institution campus plans
320 my $institution_campus_plans_sql_statement = "SELECT * FROM tblCampusMaps WHERE Electronic=1 AND Institution_ID=?";
321 my $institution_campus_plans_sql_handle = $dbh->prepare($institution_campus_plans_sql_statement);
322 $institution_campus_plans_sql_handle->{LongReadLen} = 65536;
323
324 # Create a document object for each institution
325 my %institution_id_to_name_mapping;
326 my %institution_state_to_ids_mapping;
327 while (my $row_hashref = $institution_sql_handle->fetchrow_hashref) {
328 # Skip any institutions that didn't respond
329 next if !defined($row_hashref->{"City"});
330
331 my $institution_id = $row_hashref->{"Institution_ID"};
332 # print STDERR " Institution $institution_id\n";
333 my $institution_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
334 $institution_doc_obj->set_OID("i$institution_id");
335 &new_metadata_entry($institution_doc_obj, "DocumentType", "Institution");
336
337 # For some reason the hyphen seems to be lost from the Zip field, so add it back in
338 my $institution_zip = $row_hashref->{"Zip"};
339 if ($institution_zip =~ /^(\d\d\d\d\d)(\d\d\d\d)$/) {
340 $row_hashref->{"Zip"} = $1 . "-" . $2;
341 }
342
343 # Map state to full name
344 $row_hashref->{"State"} = $state_abbr_to_name_mapping->{$row_hashref->{"State"}};
345
346 # Get the places in this institution
347 my $institution_random_place_id;
348 my $institution_places_list_html = "";
349 $institution_places_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
350 while (my $institution_places_match_hashref = $institution_places_sql_handle->fetchrow_hashref) {
351 my $institution_place_id = $institution_places_match_hashref->{"Entry_ID"};
352 my $institution_place_name = $institution_places_match_hashref->{"Current_name"};
353 $institution_places_list_html .= "<span class=\"cictext\"><a href=\"_gwcgi_?a=d&d=p$institution_place_id\">$institution_place_name</a></span><br />\n";
354 }
355 &new_metadata_entry($institution_doc_obj, "InstitutionPlacesListHTML", $institution_places_list_html);
356
357 # Get the best place image for this institution
358 my $institution_best_place_image_name = $row_hashref->{"Best_image"};
359 if (!defined($institution_best_place_image_name) || $institution_best_place_image_name eq "") {
360 # Some institutions have no electronic images, and thus have no best image
361 $institution_places_images_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
362 if (defined($institution_places_images_sql_handle->fetchrow_hashref())) {
363 print STDERR "<ProcessingError n='Institution $institution_id' p='CICPlug' r='No best image'>\n" if ($self->{'gli'});
364 print STDERR "Error: Institution $institution_id -- No best image.\n";
365 print $fail_log_handle "Error: Institution $institution_id -- No best image.\n";
366 $self->{'num_not_processed'}++;
367 next;
368 }
369 &new_metadata_entry($institution_doc_obj, "InstitutionBestPlaceImageHTML", "");
370 }
371 else {
372 # Get the file location of the best place image for this institution
373 $institution_best_place_image_location_sql_handle->execute($institution_best_place_image_name) or die "Could not execute SQL statement.";
374 my $institution_best_place_image_location = $institution_best_place_image_location_sql_handle->fetchrow();
375 if (!defined($institution_best_place_image_location) || $institution_best_place_image_location eq "") {
376 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'});
377 print STDERR "Error: Institution $institution_id -- Could not match best image $institution_best_place_image_name to a file.\n";
378 print $fail_log_handle "Error: Institution $institution_id -- Could not match best image $institution_best_place_image_name to a file.\n";
379 $self->{'num_not_processed'}++;
380 next;
381 }
382
383 # PDFs are not allowed for institution best place images
384 if ($institution_best_place_image_location =~ /.pdf$/i) {
385 print STDERR "<ProcessingError n='Institution $institution_id' p='CICPlug' r='PDF not allowed for best image'>\n" if ($self->{'gli'});
386 print STDERR "Error: Institution $institution_id -- PDF not allowed for best image.\n";
387 print $fail_log_handle "Error: Institution $institution_id -- PDF not allowed for best image.\n";
388 $self->{'num_not_processed'}++;
389 next;
390 }
391
392 my $institution_best_place_image_medium_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_best_place_image_location, "medium");
393 my $institution_best_place_image_large_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_best_place_image_location, "large");
394 &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>");
395 }
396
397 # Get institution campus plans
398 my $institution_campus_plans_list_html = "";
399 $institution_campus_plans_sql_handle->execute($institution_id) or die "Could not execute SQL statement.";
400 while (my $institution_campus_plans_match_hashref = $institution_campus_plans_sql_handle->fetchrow_hashref) {
401 my $institution_campus_plan_name = $institution_campus_plans_match_hashref->{"NameAndFormat"};
402 my $institution_campus_plan_image_location = $institution_campus_plans_match_hashref->{"Location_electronic"};
403
404 # Deal with PDF files separately: don't convert, just associate
405 if ($institution_campus_plan_image_location =~ /\.pdf$/i) {
406 # Convert the server location of the file into the local location of the file
407 my $institution_campus_plan_pdf_file_path = $institution_campus_plan_image_location;
408 $institution_campus_plan_pdf_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
409
410 if (-f $institution_campus_plan_pdf_file_path) {
411 my $institution_campus_plan_pdf_file_name = $institution_campus_plan_name . ".pdf";
412 $institution_campus_plan_pdf_file_name =~ s/ /%20/g;
413 my $institution_campus_plan_pdf_file_href = "_httpcollection_/index/assoc/[assocfilepath]/$institution_campus_plan_pdf_file_name";
414 $institution_campus_plans_list_html .= "<a href=\"$institution_campus_plan_pdf_file_href\"><span class=\"cictext\">$institution_campus_plan_name (PDF)</span></a><br />";
415
416 $institution_doc_obj->associate_file($institution_campus_plan_pdf_file_path, $institution_campus_plan_name . ".pdf", undef, $institution_doc_obj->get_top_section());
417 }
418 else {
419 print STDERR "<ProcessingError n='$institution_campus_plan_pdf_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
420 print STDERR "Error: File $institution_campus_plan_pdf_file_path does not exist.\n";
421 print $fail_log_handle "Error: File $institution_campus_plan_pdf_file_path does not exist.\n";
422 }
423 }
424 else {
425 my $institution_campus_plan_image_large_file_href = $self->generate_place_image_variant($institution_doc_obj, $institution_campus_plan_image_location, "large");
426
427 # Create a new section for each institution campus plan image
428 my $institution_campus_plan_image_section = $institution_doc_obj->insert_section($institution_doc_obj->get_end_child($institution_doc_obj->get_top_section()));
429 $institution_doc_obj->add_utf8_text($institution_campus_plan_image_section, "_"); # This is necessary
430 $institution_doc_obj->add_utf8_metadata($institution_campus_plan_image_section, "DocumentType", "Image");
431 $institution_doc_obj->add_utf8_metadata($institution_campus_plan_image_section, "Title", $institution_campus_plan_name);
432 $institution_doc_obj->add_utf8_metadata($institution_campus_plan_image_section, "ImagePath", $institution_campus_plan_image_large_file_href);
433
434 $institution_campus_plans_list_html .= "<a href=\"_gwcgi_?a=d&d=i$institution_id.$institution_campus_plan_image_section\"><span class=\"cictext\">$institution_campus_plan_name</span></a><br />";
435 }
436 }
437 &new_metadata_entry($institution_doc_obj, "InstitutionCampusPlansListHTML", $institution_campus_plans_list_html);
438
439 # Add each field from the table as metadata
440 foreach my $key (keys(%$row_hashref)) {
441 my $value = $row_hashref->{$key};
442 if (defined($value)) {
443 &new_metadata_entry($institution_doc_obj, $key, $value);
444 }
445 }
446
447 $institution_doc_obj->add_utf8_text($institution_doc_obj->get_top_section(), "Some dummy text.");
448 $self->{'processor'}->process($institution_doc_obj);
449 $self->{'num_processed'}++;
450
451 # Build mappings for creating the static macrofiles
452 my $institution_name = $row_hashref->{"Institution_Name"};
453 $institution_id_to_name_mapping{$institution_doc_obj->get_OID()} = $institution_name;
454 my $institution_state = $row_hashref->{"State"};
455 push(@{$institution_state_to_ids_mapping{$institution_state}}, $institution_doc_obj->get_OID());
456 }
457
458 # Write the institutions.dm macrofile
459 &write_static_browser_macrofile("institutions", \%institution_id_to_name_mapping);
460
461 # Write the states.dm macrofile
462 &write_state_browser_macrofile("states", \%institution_state_to_ids_mapping, \%institution_id_to_name_mapping);
463}
464
465
466sub process_places
467{
468 my $self = shift(@_);
469 my $dbh = shift(@_);
470 my $fail_log_handle = $self->{'failhandle'};
471
472 # Prepare SQL statement for getting everything from the Place table
473 my $place_sql_statement = "SELECT * FROM tblPlace";
474 my $place_sql_handle = $dbh->prepare($place_sql_statement);
475 $place_sql_handle->{LongReadLen} = 65536;
476 $place_sql_handle->execute() or die "Could not execute SQL statement.";
477
478 # Prepare SQL statement for getting the Place institution
479 my $place_institution_sql_statement = "SELECT Institution_Name FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID and tblPlace.Entry_ID=?";
480 my $place_institution_sql_handle = $dbh->prepare($place_institution_sql_statement);
481
482 # Prepare SQL statement for getting the Place "date of construction"
483 my $place_construction_date_sql_statement = "SELECT Date FROM tblConstruction_and_Dates WHERE Entry_ID=?";
484 my $place_construction_date_sql_handle = $dbh->prepare($place_construction_date_sql_statement);
485
486 # Prepare SQL statement for getting the Place images
487 my $place_images_sql_statement = "SELECT FileName,Location FROM tblImages WHERE FileType=1 AND Entry_ID=?";
488 my $place_images_sql_handle = $dbh->prepare($place_images_sql_statement);
489 $place_images_sql_handle->{LongReadLen} = 65536;
490
491 # Prepare SQL statement for getting the Place materials
492 my $place_materials_sql_statement = "SELECT * FROM tblDescription_building WHERE Entry_ID=?";
493 my $place_materials_sql_handle = $dbh->prepare($place_materials_sql_statement);
494 $place_materials_sql_handle->{LongReadLen} = 65536;
495
496 # Prepare SQL statement for getting the Place building styles
497 my $place_styles_sql_statement = "SELECT Architectural_Classification FROM tblArchTypes,jnxtblArchPlace WHERE tblArchTypes.ArchType_ID=jnxtblArchPlace.ArchType_ID AND Entry_ID=?";
498 my $place_styles_sql_handle = $dbh->prepare($place_styles_sql_statement);
499 $place_styles_sql_handle->{LongReadLen} = 65536;
500
501 # Prepare SQL statement for getting the Place functions
502 my $place_functions_sql_statement = "SELECT Function,Year,Prefix FROM tblFunction_and_dates WHERE Entry_ID=?";
503 my $place_functions_sql_handle = $dbh->prepare($place_functions_sql_statement);
504 $place_functions_sql_handle->{LongReadLen} = 65536;
505
506 # Prepare SQL statement for getting the Place significance
507 my $place_significance_sql_statement = "SELECT SigType FROM tblSigTypes,SigPlace WHERE tblSigTypes.SigTypes_ID=SigPlace.SigType_ID+1 AND SigPlace.Entry_ID=?";
508 my $place_significance_sql_handle = $dbh->prepare($place_significance_sql_statement);
509 $place_significance_sql_handle->{LongReadLen} = 65536;
510
511 # Prepare SQL statement for getting the Place references
512 my $place_references_sql_statement = "SELECT Bibliography FROM tblReferences WHERE Entry_ID=?";
513 my $place_references_sql_handle = $dbh->prepare($place_references_sql_statement);
514 $place_references_sql_handle->{LongReadLen} = 65536;
515
516 # Prepare SQL statement for getting the Place designations
517 my $place_designations_sql_statement = "SELECT National_Register,Federal_Agency,HABS,HAER,Local_Designation FROM tblReferences WHERE Entry_ID=?";
518 my $place_designations_sql_handle = $dbh->prepare($place_designations_sql_statement);
519 $place_designations_sql_handle->{LongReadLen} = 65536;
520
521 # Prepare SQL statement for getting the Place narrative
522 my $place_narrative_sql_statement = "SELECT Narrative FROM tblSignificance_Narrative WHERE Entry_ID=?";
523 my $place_narrative_sql_handle = $dbh->prepare($place_narrative_sql_statement);
524 $place_narrative_sql_handle->{LongReadLen} = 65536;
525
526 # Prepare SQL statement for getting the Place state
527 my $place_state_sql_statement = "SELECT State FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID AND Entry_ID=?";
528 my $place_state_sql_handle = $dbh->prepare($place_state_sql_statement);
529 $place_state_sql_handle->{LongReadLen} = 65536;
530
531 # Create a document object for each place
532 my %place_type_to_ids_mapping;
533 my %place_style_to_ids_mapping;
534 my %place_date_to_ids_mapping;
535 my %place_function_to_ids_mapping;
536 my %place_id_to_name_mapping;
537 my %place_id_to_institution_name_mapping;
538 while (my $row_hashref = $place_sql_handle->fetchrow_hashref) {
539 my $place_id = $row_hashref->{"Entry_ID"};
540 # print STDERR " Place $place_id\n";
541 my $place_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
542 $place_doc_obj->set_OID("p$place_id");
543 &new_metadata_entry($place_doc_obj, "DocumentType", "Place");
544
545 # Convert the place type ID into a name
546 $row_hashref->{"PlaceType"} = $place_type_id_to_name_mapping->{$row_hashref->{"PlaceType"}};
547
548 # Add each field from the table as metadata
549 foreach my $key (keys(%$row_hashref)) {
550 my $value = $row_hashref->{$key};
551 if (defined($value)) {
552 &new_metadata_entry($place_doc_obj, $key, $value);
553 }
554 }
555
556 # Get place name
557 my $place_name = $row_hashref->{"Current_name"};
558 if (!defined($place_name)) {
559 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing place name'>\n" if ($self->{'gli'});
560 print STDERR "Error: Place $place_id -- Missing place name.\n";
561 print $fail_log_handle "Error: Place $place_id -- Missing place name.\n";
562 $self->{'num_not_processed'}++;
563 next;
564 }
565
566 # Get place type
567 my $place_type = $row_hashref->{"PlaceType"};
568 if (!defined($place_type)) {
569 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing place type'>\n" if ($self->{'gli'});
570 print STDERR "Error: Place $place_id -- Missing place type.\n";
571 print $fail_log_handle "Error: Place $place_id -- Missing place type.\n";
572 $self->{'num_not_processed'}++;
573 next;
574 }
575
576 # Get place date of construction, except for landscape sites which have no date
577 $place_construction_date_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
578 my $place_construction_date_value = $place_construction_date_sql_handle->fetchrow();
579 if (!defined($place_construction_date_value) && $place_type eq "Landscape site") {
580 # Landscape sites may not have a construction date
581 $place_construction_date_value = "";
582 }
583 if (!defined($place_construction_date_value)) {
584 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing construction date'>\n" if ($self->{'gli'});
585 print STDERR "Error: Place $place_id -- Missing construction date.\n";
586 print $fail_log_handle "Error: Place $place_id -- Missing construction date.\n";
587 $self->{'num_not_processed'}++;
588 next;
589 }
590 &new_metadata_entry($place_doc_obj, "Construction_date", $place_construction_date_value);
591
592 # Create place styles mapping
593 $place_styles_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
594 while (my $place_styles_match_hashref = $place_styles_sql_handle->fetchrow_hashref()) {
595 my $place_style = $place_styles_match_hashref->{"Architectural_Classification"};
596 push(@{$place_style_to_ids_mapping{$place_style}}, $place_doc_obj->get_OID());
597 &new_metadata_entry($place_doc_obj, "Style", $place_style);
598 }
599
600 # Get place institution
601 $place_institution_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
602 my $place_institution = $place_institution_sql_handle->fetchrow();
603 &new_metadata_entry($place_doc_obj, "Institution_name", $place_institution);
604 $place_id_to_institution_name_mapping{$place_doc_obj->get_OID()} = ", " . $place_institution;
605
606 # Get place state and area (for searching)
607 $place_state_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
608 my $place_state_abbr = $place_state_sql_handle->fetchrow();
609 &new_metadata_entry($place_doc_obj, "State", $place_state_abbr . " " . $state_abbr_to_name_mapping->{$place_state_abbr} . " " . $state_abbr_to_area_mapping->{$place_state_abbr});
610
611 # Create place dates mapping
612 my $place_time_period = $place_construction_date_value;
613 if ($place_construction_date_value =~ /^(\d\d\d\d).*$/) {
614 $place_construction_date_value =~ s/^(\d\d\d\d).*$/$1/;
615 if ($place_construction_date_value < 1800) { $place_time_period = "pre-1800"; }
616 elsif ($place_construction_date_value < 1850) { $place_time_period = "1800-1850"; }
617 elsif ($place_construction_date_value < 1900) { $place_time_period = "1850-1900"; }
618 elsif ($place_construction_date_value < 1945) { $place_time_period = "1900-1945"; }
619 elsif ($place_construction_date_value < 1995) { $place_time_period = "1945-1995"; }
620 else { $place_time_period = "post-1995"; }
621 push(@{$place_date_to_ids_mapping{$place_time_period}}, $place_doc_obj->get_OID());
622 }
623 &new_metadata_entry($place_doc_obj, "Time_period", $place_time_period);
624
625 # Get place materials (individual buildings only)
626 if ($row_hashref->{"PlaceType"} eq "Individual building") {
627 $place_materials_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
628 my $place_materials_match_hashref = $place_materials_sql_handle->fetchrow_hashref();
629 &new_metadata_entry($place_doc_obj, "MaterialFoundation", $place_materials_match_hashref->{"foundation"} || "");
630 &new_metadata_entry($place_doc_obj, "MaterialRoof", $place_materials_match_hashref->{"roof"} || "");
631 &new_metadata_entry($place_doc_obj, "MaterialWalls", $place_materials_match_hashref->{"walls"} || "");
632
633 &new_metadata_entry($place_doc_obj, "Materials", $place_materials_match_hashref->{"foundation"} || "");
634 &new_metadata_entry($place_doc_obj, "Materials", $place_materials_match_hashref->{"roof"} || "");
635 &new_metadata_entry($place_doc_obj, "Materials", $place_materials_match_hashref->{"walls"} || "");
636 }
637
638 # Get place functions
639 my $place_functions = "";
640 my $place_functions_table_html = "";
641 $place_functions_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
642 while (my $place_functions_match_hashref = $place_functions_sql_handle->fetchrow_hashref()) {
643 my $place_function = $place_functions_match_hashref->{"Function"};
644 if (!defined($place_function)) {
645 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing function'>\n" if ($self->{'gli'});
646 print STDERR "Error: Place $place_id -- Missing function.\n";
647 print $fail_log_handle "Error: Place $place_id -- Missing function.\n";
648 next;
649 }
650 # Check for multiline values (these are errors)
651 if ($place_function =~ /\n/) {
652 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Multiline function'>\n" if ($self->{'gli'});
653 print STDERR "Error: Place $place_id -- Multiline function.\n";
654 print $fail_log_handle "Error: Place $place_id -- Multiline function.\n";
655 next;
656 }
657 my $place_year = $place_functions_match_hashref->{"Year"};
658 if (!defined($place_year)) {
659 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Missing function year'>\n" if ($self->{'gli'});
660 print STDERR "Error: Place $place_id -- Missing function year.\n";
661 print $fail_log_handle "Error: Place $place_id -- Missing function year.\n";
662 next;
663 }
664 my $place_year_prefix = $place_functions_match_hashref->{"Prefix"} || "";
665 $place_functions .= "$place_function ";
666 $place_functions_table_html .= "<tr><td valign=\"top\"><nobr>$place_year_prefix $place_year</nobr>&nbsp;</td><td valign=\"top\">$place_function</td></tr>";
667
668 # Prepare function metadata for browsing and searching
669 my $place_function_to_index = lc($place_function); # Casefold
670 $place_function_to_index =~ s/^\s*//; # Remove whitespace from the start
671 if ($place_function_to_index =~ /^master plan/) {
672 $place_function_to_index =~ s/ \(campus,.*/ \(campus\)/;
673 $place_function_to_index =~ s/ \(campus:.*/ \(campus\)/;
674 }
675 else {
676 $place_function_to_index =~ s/\(.*\)//g; # Remove anything in parentheses
677 }
678 $place_function_to_index =~ s/\s*$//; # Remove whitespace from the end
679
680 # Deal with common plural cases
681 $place_function_to_index =~ s/classroom$/classrooms/;
682 $place_function_to_index =~ s/department buildings$/department building/;
683 $place_function_to_index =~ s/faculty office$/faculty offices/;
684 $place_function_to_index =~ s/garden$/gardens/;
685 $place_function_to_index =~ s/residence halls$/residence hall/;
686 $place_function_to_index =~ s/private residences$/private residence/;
687
688 # Check it is one of the valid function values
689 if (!defined($place_functions_mapping->{$place_function_to_index})) {
690 print STDERR "<ProcessingError n='Place $place_id' p='CICPlug' r='Unknown function: $place_function_to_index'>\n" if ($self->{'gli'});
691 print STDERR "Error: Place $place_id -- Unknown function: $place_function_to_index.\n";
692 print $fail_log_handle "Error: Place $place_id -- Unknown function: $place_function_to_index.\n";
693 next;
694 }
695 push(@{$place_function_to_ids_mapping{$place_function_to_index}}, $place_doc_obj->get_OID());
696 }
697 &new_metadata_entry($place_doc_obj, "Functions", $place_functions);
698 &new_metadata_entry($place_doc_obj, "PlaceFunctionsTableHTML", "<table cellpadding=\"0\" cellspacing=\"0\">" . $place_functions_table_html . "</table>");
699
700 # Get place significance
701 $place_significance_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
702 while (my $place_significance_match_hashref = $place_significance_sql_handle->fetchrow_hashref()) {
703 my $place_significance = $place_significance_match_hashref->{"SigType"};
704 &new_metadata_entry($place_doc_obj, "Significance", lc($place_significance));
705 }
706
707 # Get place references
708 $place_references_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
709 my $place_references = $place_references_sql_handle->fetchrow();
710 if (defined($place_references)) {
711 &new_metadata_entry($place_doc_obj, "References", &rtf_to_html($place_references));
712 }
713
714 # Get place designations
715 $place_designations_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
716 my $place_designations_match_hashref = $place_designations_sql_handle->fetchrow_hashref();
717 if ($place_designations_match_hashref->{"National_Register"} eq "1") {
718 &new_metadata_entry($place_doc_obj, "Designation", "National Register");
719 }
720 if ($place_designations_match_hashref->{"Federal_Agency"} eq "1") {
721 &new_metadata_entry($place_doc_obj, "Designation", "National Historic Landmark");
722 }
723 if ($place_designations_match_hashref->{"HABS"} eq "1" || $place_designations_match_hashref->{"HAER"} eq "1") {
724 &new_metadata_entry($place_doc_obj, "Designation", "HABS/HAER");
725 }
726 if ($place_designations_match_hashref->{"Local_Designation"} eq "1") {
727 &new_metadata_entry($place_doc_obj, "Designation", "Local/State");
728 }
729
730 # Get place narrative
731 $place_narrative_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
732 my $place_narrative = $place_narrative_sql_handle->fetchrow();
733 if (defined($place_narrative)) {
734 $place_narrative = &rtf_to_html($place_narrative);
735 $place_narrative =~ s/<br \/>(\s|\n)*$//; # Remove any trailing <br /> tags
736 &new_metadata_entry($place_doc_obj, "Narrative", $place_narrative);
737 }
738
739 # Get place images
740 my $place_images_html = "";
741 $place_images_sql_handle->execute($place_id) or die "Could not execute SQL statement.";
742 while (my $place_images_match_hashref = $place_images_sql_handle->fetchrow_hashref) {
743 my $place_image_location = $place_images_match_hashref->{"Location"};
744 my $place_image_name = $place_images_match_hashref->{"FileName"};
745
746 # Deal with PDF files separately: don't convert, just associate
747 if ($place_image_location =~ /\.pdf$/i) {
748 # Convert the server location of the PDF file into the local location of the file
749 my $place_pdf_file_path = $place_image_location;
750 $place_pdf_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
751
752 if (-f $place_pdf_file_path) {
753 my ($place_pdf_file_name) = ($place_pdf_file_path =~ /^.+\\(.+)$/);
754 $place_doc_obj->associate_file($place_pdf_file_path, $place_pdf_file_name, undef, $place_doc_obj->get_top_section());
755
756 $place_pdf_file_name =~ s/ /%20/g;
757 my $place_pdf_file_href = "_httpcollection_/index/assoc/[assocfilepath]/$place_pdf_file_name";
758 $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";
759 }
760 else {
761 print STDERR "<ProcessingError n='$place_pdf_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
762 print STDERR "Error: File $place_pdf_file_path does not exist.\n";
763 print $fail_log_handle "Error: File $place_pdf_file_path does not exist.\n";
764 }
765 }
766 else {
767 my $place_image_small_file_href = $self->generate_place_image_variant($place_doc_obj, $place_image_location, "small");
768 my $place_image_large_file_href = $self->generate_place_image_variant($place_doc_obj, $place_image_location, "large");
769
770 if (defined($place_image_name)) {
771 # Create a new section for each place image
772 my $place_image_section = $place_doc_obj->insert_section($place_doc_obj->get_end_child($place_doc_obj->get_top_section()));
773 $place_doc_obj->add_utf8_text($place_image_section, "_"); # This is necessary
774 $place_doc_obj->add_utf8_metadata($place_image_section, "DocumentType", "Image");
775 $place_doc_obj->add_utf8_metadata($place_image_section, "Title", $place_image_name);
776 $place_doc_obj->add_utf8_metadata($place_image_section, "ImagePath", $place_image_large_file_href);
777
778 $place_images_html .= "<tr><td valign=\"top\"><a href=\"_gwcgi_?a=d&d=p$place_id.$place_image_section\"><img src=\"$place_image_small_file_href\"/></a></td><td valign=\"top\"><a href=\"_gwcgi_?a=d&d=p$place_id.$place_image_section\"><span class=\"cictext\">$place_image_name</span></a></td></tr>\n";
779 }
780 else {
781 $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";
782 }
783 }
784 }
785
786 &new_metadata_entry($place_doc_obj, "PlaceImagesHTML", "<table>" . $place_images_html . "</table>");
787
788 $place_doc_obj->add_utf8_text($place_doc_obj->get_top_section(), "Some dummy text.");
789 $self->{'processor'}->process($place_doc_obj);
790 $self->{'num_processed'}++;
791
792 # Build mappings for creating the static macrofiles
793 $place_id_to_name_mapping{$place_doc_obj->get_OID()} = $place_name;
794 push(@{$place_type_to_ids_mapping{$place_type}}, $place_doc_obj->get_OID());
795 }
796
797 &write_bilevel_static_browser_macrofile("types", \%place_type_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
798 &write_bilevel_static_browser_macrofile("styles", \%place_style_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
799 &write_bilevel_static_browser_macrofile("dates", \%place_date_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
800 &write_bilevel_static_browser_macrofile("functions", \%place_function_to_ids_mapping, \%place_id_to_name_mapping, \%place_id_to_institution_name_mapping);
801}
802
803
804sub process_designers
805{
806 my $self = shift(@_);
807 my $dbh = shift(@_);
808 my $fail_log_handle = $self->{'failhandle'};
809
810 # Prepare SQL statement for getting all the Architects from the Place table
811 my $designer_sql_statement = "SELECT Architect_Name,Entry_ID FROM tblConstruction_and_dates";
812 my $designer_sql_handle = $dbh->prepare($designer_sql_statement);
813 $designer_sql_handle->{LongReadLen} = 65536;
814 $designer_sql_handle->execute() or die "Could not execute SQL statement.";
815
816 # Prepare SQL statement for getting the Place name
817 my $place_name_sql_statement = "SELECT Current_name FROM tblPlace WHERE Entry_ID=?";
818 my $place_name_sql_handle = $dbh->prepare($place_name_sql_statement);
819
820 # Prepare SQL statement for getting the Place institution
821 my $place_institution_sql_statement = "SELECT Institution_Name FROM tblInstitution,tblPlace WHERE tblInstitution.Institution_ID=tblPlace.Institution_ID and tblPlace.Entry_ID=?";
822 my $place_institution_sql_handle = $dbh->prepare($place_institution_sql_statement);
823
824 # Prepare SQL statement for getting the Place "date of construction"
825 my $place_construction_date_sql_statement = "SELECT Date FROM tblConstruction_and_Dates WHERE Entry_ID=?";
826 my $place_construction_date_sql_handle = $dbh->prepare($place_construction_date_sql_statement);
827
828 # Prepare SQL statement for getting the Place non-PDF images
829 my $place_images_sql_statement = "SELECT Location FROM tblImages WHERE FileType=1 AND Location NOT LIKE '%.pdf' AND Entry_ID=?";
830 my $place_images_sql_handle = $dbh->prepare($place_images_sql_statement);
831 $place_images_sql_handle->{LongReadLen} = 65536;
832
833 # Get a list of all the designers, and the places they worked on
834 my %designer_name_to_place_ids_mapping;
835 my %designer_name_to_id_mapping;
836 my %designer_id_to_name_mapping;
837 my $designer_count = 0;
838 while (my $designer_hashref = $designer_sql_handle->fetchrow_hashref) {
839 my $designer_names_string = $designer_hashref->{"Architect_Name"};
840 next if !defined($designer_names_string);
841 foreach my $designer_name (split(/;/, $designer_names_string)) {
842 $designer_name =~ s/\(.*?\)//g;
843 $designer_name =~ s/^\s*//;
844 $designer_name =~ s/\s*$//;
845
846 if (!defined($designer_name_to_id_mapping{$designer_name})) {
847 $designer_count++;
848 $designer_name_to_id_mapping{$designer_name} = "d" . $designer_count;
849 }
850
851 $designer_id_to_name_mapping{$designer_name_to_id_mapping{$designer_name}} = $designer_name;
852 push(@{$designer_name_to_place_ids_mapping{$designer_name}}, $designer_hashref->{"Entry_ID"});
853 }
854 }
855
856 # Create a document object for each designer
857 foreach my $designer_name (keys %designer_name_to_place_ids_mapping) {
858 my $designer_id = $designer_name_to_id_mapping{$designer_name};
859 # print STDERR " Designer $designer_id\n";
860 my $designer_doc_obj = new doc($self->{'filename'} . "-", "indexed_doc");
861 $designer_doc_obj->set_OID($designer_id);
862 &new_metadata_entry($designer_doc_obj, "DocumentType", "Designer");
863
864 &new_metadata_entry($designer_doc_obj, "Designer_name", $designer_name);
865
866 my $designer_places_list_html = "";
867 foreach my $designer_place_id (@{$designer_name_to_place_ids_mapping{$designer_name}}) {
868 # Get place name
869 $place_name_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
870 my $designer_place_name = $place_name_sql_handle->fetchrow();
871
872 # Get place institution name
873 $place_institution_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
874 my $designer_place_institution_name = $place_institution_sql_handle->fetchrow();
875
876 # Get place date of construction
877 $place_construction_date_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
878 my $designer_place_construction_date_value = $place_construction_date_sql_handle->fetchrow() || "";
879
880 # Get the first non-PDF image for this place
881 my $designer_place_image_small_file_href;
882 $place_images_sql_handle->execute($designer_place_id) or die "Could not execute SQL statement.";
883 my $designer_place_image_location = $place_images_sql_handle->fetchrow();
884 if (defined($designer_place_image_location)) {
885 $designer_place_image_small_file_href = $self->generate_place_image_variant($designer_doc_obj, $designer_place_image_location, "small");
886 }
887 else {
888 # There is no non-PDF image for this place
889 $designer_place_image_small_file_href = "_httpcollection_/images/no_image-small.jpg";
890 }
891
892 $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";
893 }
894
895 &new_metadata_entry($designer_doc_obj, "DesignerPlacesListHTML", "<table>" . $designer_places_list_html . "</table>");
896
897 $designer_doc_obj->add_utf8_text($designer_doc_obj->get_top_section(), "Some dummy text.");
898 $self->{'processor'}->process($designer_doc_obj);
899 $self->{'num_processed'}++;
900 }
901
902 # Write the designers.dm macrofile
903 &write_static_browser_macrofile("designers", \%designer_id_to_name_mapping);
904}
905
906
907sub new_metadata_entry
908{
909 my ($doc_obj, $metadata_name, $metadata_value) = (@_);
910
911 # Don't bother with empty metadata
912 return if ($metadata_value eq "");
913
914 # Spaces aren't allowed in metadata names
915 $metadata_name =~ s/ /_/g;
916
917 # Anything from the database is ISO 8859-1 encoded, so convert to UTF-8
918 $metadata_value = &unicode::ascii2utf8(\$metadata_value);
919
920 # Remove '#' characters around links
921 if ($metadata_value =~ /\#(.*?)\#/) {
922 $metadata_value = $1;
923 }
924
925 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), $metadata_name, $metadata_value);
926}
927
928
929sub rtf_to_html
930{
931 my $rtf_string = shift(@_);
932 $rtf_string =~ s/\{(.*?)\}//g;
933 $rtf_string =~ s/\\rquote /'/g; # ' # (for Emacs)
934 $rtf_string =~ s/\\pard//g;
935 $rtf_string =~ s/\\par/<br \/>/g;
936 $rtf_string =~ s/\\i0 /<\/i>/g;
937 $rtf_string =~ s/\\i /<i>/g;
938 $rtf_string =~ s/\\~/ /g;
939 $rtf_string =~ s/\\([A-Za-z0-9]+)//g;
940 $rtf_string =~ s/\}//g;
941
942 # Assume non-ASCII is ISO 8859-1, and convert into HTML entities
943 while ($rtf_string =~ /\\'([a-z0-9][a-z0-9])/) {
944 my $dec = hex($1);
945 $rtf_string =~ s/\\'$1/&#$dec\;/;
946 }
947
948 return $rtf_string;
949}
950
951
952sub get_place_image_dimensions
953{
954 my $self = shift(@_);
955 my $place_image_file_path = shift(@_);
956 my $fail_log_handle = $self->{'failhandle'};
957
958 # Make sure the place image file actually exists
959 if (!-f $place_image_file_path) {
960 print STDERR "<ProcessingError n='$place_image_file_path' p='CICPlug' r='Does not exist'>\n" if ($self->{'gli'});
961 print STDERR "Error: Image $place_image_file_path does not exist.\n";
962 print $fail_log_handle "Error: Image $place_image_file_path does not exist.\n";
963 return;
964 }
965 my $place_image_file_date = (stat($place_image_file_path))[9];
966
967 # Check if this place image has already been identified by looking for a ".info" file in the same directory
968 my $place_image_info_file_path = $place_image_file_path . ".info";
969 if (-f $place_image_info_file_path) {
970 # A ".info" file exists, so read the cached place image information from it
971 open(PLACE_IMAGE_INFO_FILE, "<$place_image_info_file_path");
972 my @place_image_info = <PLACE_IMAGE_INFO_FILE>;
973 close(PLACE_IMAGE_INFO_FILE);
974
975 # Read the cached place image file date and check that it matches
976 my $cached_place_image_file_date = $place_image_info[0];
977 $cached_place_image_file_date =~ s/\n$//;
978 if ($cached_place_image_file_date == $place_image_file_date) {
979 # It does match, so use the cached information from the ".info" file instead of re-identifying the file
980 my $place_image_width = $place_image_info[1];
981 $place_image_width =~ s/\n$//;
982 my $place_image_height = $place_image_info[2];
983 $place_image_height =~ s/\n$//;
984 return ($place_image_width, $place_image_height);
985 }
986 }
987
988 # We haven't already identified the place image, so do it now
989 print STDERR "Identifying place image $place_image_file_path...\n";
990 my $identify_command = "identify -format \"%w %h\" \"$place_image_file_path\"";
991 my $identify_result = `$identify_command`;
992 print "Identify result: $identify_result\n" if ($self->{'verbosity'} > 2);
993
994 # Check that the output is what we're expecting
995 if ($identify_result !~ /(\d+) (\d+)/) {
996 print STDERR "<ProcessingError n='$place_image_file_path' p='CICPlug' r='Could not identify'>\n" if ($self->{'gli'});
997 print STDERR "Error: Place image $place_image_file_path could not be identified.\n";
998 print $fail_log_handle "Error: Place image $place_image_file_path could not be identified.\n";
999 return;
1000 }
1001
1002 # Parse the place image width and height from the output
1003 my $place_image_width = $1;
1004 my $place_image_height = $2;
1005
1006 # Write the place image info file so we don't have to identify this exact image again in the future
1007 open(PLACE_IMAGE_INFO_FILE, ">$place_image_info_file_path");
1008 print PLACE_IMAGE_INFO_FILE "$place_image_file_date\n";
1009 print PLACE_IMAGE_INFO_FILE "$place_image_width\n";
1010 print PLACE_IMAGE_INFO_FILE "$place_image_height\n";
1011 close(PLACE_IMAGE_INFO_FILE);
1012 return ($place_image_width, $place_image_height);
1013}
1014
1015
1016sub generate_place_image_variant
1017{
1018 my $self = shift(@_);
1019 my ($doc_obj, $place_image_location, $place_image_variant_size) = (@_);
1020 my $fail_log_handle = $self->{'failhandle'};
1021
1022 # Convert the server location of the file into the local location of the file
1023 my $place_image_file_path = $place_image_location;
1024 $place_image_file_path =~ s/^[A-Z]:/$self->{'images_directory'}/;
1025
1026 # Get the width and height of the place image
1027 my ($place_image_width, $place_image_height) = $self->get_place_image_dimensions($place_image_file_path);
1028 if (!defined($place_image_width) || !defined($place_image_height)) {
1029 # An error has occurred (error message generated by get_place_image_dimensions())
1030 return;
1031 }
1032 my $place_image_file_date = (stat($place_image_file_path))[9];
1033
1034 # Generate the path of the place image variant (in the cache directory)
1035 my $place_image_variant_file_suffix = "-$place_image_variant_size." . $self->{$place_image_variant_size . '_image_type'};
1036 my $place_image_variant_file_path = $place_image_location;
1037 $place_image_variant_file_path =~ s/^[A-Z]:/$self->{'cache_directory'}/;
1038 $place_image_variant_file_path =~ s/^(.+)(\..*)/$1$place_image_variant_file_suffix/;
1039 my ($place_image_variant_file_name) = ($place_image_variant_file_path =~ /^.+\\(.+)$/);
1040
1041 # Only scale down the place image if it is bigger than the desired width
1042 my $place_image_variant_desired_width = $self->{$place_image_variant_size . '_image_width'};
1043 if ($place_image_width > $place_image_variant_desired_width) {
1044 # Only generate the place image variant if it doesn't already exist, or if the place image is newer
1045 if (!-f $place_image_variant_file_path || $place_image_file_date > (stat($place_image_variant_file_path))[9]) {
1046 print STDERR "Generating place image variant $place_image_variant_file_path...\n";
1047 my ($place_image_variant_directory) = ($place_image_variant_file_path =~ /^(.+)\\.+$/);
1048 &util::mk_all_dir($place_image_variant_directory);
1049 my $place_image_variant_options = "-scale $place_image_variant_desired_width " . $self->{$place_image_variant_size . '_image_options'};
1050 my $convert_command = "convert $place_image_variant_options \"$place_image_file_path\" \"$place_image_variant_file_path\"";
1051 my $convert_result = `$convert_command`;
1052 }
1053 }
1054 else {
1055 # The desired width is bigger than the place image, so we just use the original
1056 $place_image_variant_file_path = $place_image_file_path;
1057 }
1058
1059 my ($place_image_variant_width, $place_image_variant_height) = $self->get_place_image_dimensions($place_image_variant_file_path);
1060 if (!defined($place_image_variant_width) || !defined($place_image_variant_height)) {
1061 # An error has occurred (error message generated by get_place_image_dimensions())
1062 return;
1063 }
1064
1065 # Associate the place image variant file
1066 $doc_obj->associate_file($place_image_variant_file_path, $place_image_variant_file_name, undef, $doc_obj->get_top_section());
1067
1068 # Add various bits of metadata for the place image variant
1069 my $place_image_variant_href = "_httpcollection_/index/assoc/{Or}{[parent(Top):assocfilepath],[assocfilepath]}/" . $place_image_variant_file_name;
1070 $place_image_variant_href =~ s/ /%20/g;
1071 return $place_image_variant_href;
1072}
1073
1074
1075sub write_static_browser_macrofile
1076{
1077 my $static_browser_package_name = shift(@_);
1078 my $id_to_name_mapping = shift(@_);
1079
1080 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_name.dm";
1081 print STDERR "Writing $static_browser_macrofile_path...\n";
1082 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
1083 &write_static_browser_macros($static_browser_package_name, $id_to_name_mapping);
1084 close(BROWSER_MACROFILE);
1085}
1086
1087
1088sub write_static_browser_macros
1089{
1090 my $static_browser_package_name = shift(@_);
1091 my $id_to_name_mapping = shift(@_);
1092 my $id_to_extra_mapping = shift(@_);
1093
1094 print BROWSER_MACROFILE "package $static_browser_package_name\n\n";
1095 print BROWSER_MACROFILE "_cicstaticbrowser_ {\n";
1096
1097 my %letter_to_ids_mapping;
1098 foreach my $id (keys %$id_to_name_mapping) {
1099 my $name = $id_to_name_mapping->{$id};
1100 my ($letter) = ($name =~ /([A-Za-z0-9])/);
1101 push(@{$letter_to_ids_mapping{$letter}}, $id);
1102 }
1103
1104 print BROWSER_MACROFILE "<center><b>";
1105 foreach my $letter (split(//, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) {
1106 if (defined($letter_to_ids_mapping{$letter})) {
1107 print BROWSER_MACROFILE "<a href=\"#$letter\">$letter</a>&nbsp;";
1108 }
1109 else {
1110 print BROWSER_MACROFILE "$letter&nbsp;";
1111 }
1112 }
1113 print BROWSER_MACROFILE "</b></center>\n";
1114
1115 print BROWSER_MACROFILE "<table cellpadding=\"0\" cellspacing=\"0\" width=\"_pagewidth_\">\n";
1116 foreach my $letter (sort(keys %letter_to_ids_mapping)) {
1117 my @letter_ids = @{$letter_to_ids_mapping{$letter}};
1118 &write_static_browser_macros_chunk($letter, \@letter_ids, $id_to_name_mapping, $id_to_extra_mapping);
1119 }
1120 print BROWSER_MACROFILE "</table>\n";
1121
1122 print BROWSER_MACROFILE "}\n";
1123}
1124
1125
1126sub write_static_browser_macros_chunk
1127{
1128 my $chunk_title = shift(@_);
1129 my $chunk_ids_ref = shift(@_);
1130 my $id_to_name_mapping = shift(@_);
1131 my $id_to_extra_mapping = shift(@_);
1132
1133 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>";
1134
1135 my %full_name_to_id_mapping;
1136 foreach my $id (@{$chunk_ids_ref}) {
1137 my $full_name = $id_to_name_mapping->{$id};
1138 if (defined($id_to_extra_mapping)) {
1139 $full_name .= " " . $id_to_extra_mapping->{$id};
1140 }
1141 $full_name_to_id_mapping{$full_name} = $id;
1142 }
1143
1144 my @full_names = sort(keys(%full_name_to_id_mapping));
1145 my $half_point = ((scalar(@full_names) % 2 == 0) ? scalar(@full_names) / 2 : (scalar(@full_names) + 1) / 2);
1146 for (my $i = 0; $i < $half_point; $i++) {
1147 print BROWSER_MACROFILE "<tr>";
1148
1149 my $id = $full_name_to_id_mapping{$full_names[$i]};
1150 my $name = $id_to_name_mapping->{$id};
1151 $name =~ s/'/&apos;/g; # ' # (for Emacs)
1152 my $extra = $id_to_extra_mapping->{$id} || "";
1153 print BROWSER_MACROFILE "<td valign=\"top\"><a href=\"_gwcgi_?a=d&d=$id\">$name</a>$extra</td>";
1154
1155 print BROWSER_MACROFILE "<td valign=\"top\">";
1156 if (defined($full_names[$i+$half_point])) {
1157 $id = $full_name_to_id_mapping{$full_names[$i+$half_point]};
1158 $name = $id_to_name_mapping->{$id};
1159 $name =~ s/'/&apos;/g; # ' # (for Emacs)
1160 $extra = $id_to_extra_mapping->{$id} || "";
1161 print BROWSER_MACROFILE "<a href=\"_gwcgi_?a=d&d=$id\">$name</a>$extra";
1162 }
1163 print BROWSER_MACROFILE "</td>";
1164
1165 print BROWSER_MACROFILE "</tr>";
1166 }
1167}
1168
1169
1170sub write_bilevel_static_browser_macrofile
1171{
1172 my $static_browser_package_root = shift(@_);
1173 my $category_to_ids_mapping = shift(@_);
1174 my $id_to_name_mapping = shift(@_);
1175 my $id_to_extra_mapping = shift(@_);
1176
1177 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_root.dm";
1178 print STDERR "Writing $static_browser_macrofile_path...\n";
1179 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
1180
1181 foreach my $category (keys(%{$category_to_ids_mapping})) {
1182 my $static_browser_package_name = $static_browser_package_root . $category;
1183 $static_browser_package_name =~ s/\W//g;
1184
1185 my %id_to_name_mapping_for_category = ();
1186 foreach my $id (@{$category_to_ids_mapping->{$category}}) {
1187 $id_to_name_mapping_for_category{$id} = $id_to_name_mapping->{$id};
1188 }
1189 &write_static_browser_macros($static_browser_package_name, \%id_to_name_mapping_for_category, $id_to_extra_mapping);
1190 }
1191
1192 close(BROWSER_MACROFILE);
1193}
1194
1195
1196sub write_state_browser_macrofile
1197{
1198 my $static_browser_package_name = shift(@_);
1199 my $state_to_ids_mapping = shift(@_);
1200 my $id_to_name_mapping = shift(@_);
1201
1202 my $static_browser_macrofile_path = "$ENV{'GSDLHOME'}\\collect\\cic-hcap\\macros\\$static_browser_package_name.dm";
1203 print STDERR "Writing $static_browser_macrofile_path...\n";
1204 open(BROWSER_MACROFILE, ">$static_browser_macrofile_path") or die "Error: Could not write to $static_browser_macrofile_path.\n";
1205 print BROWSER_MACROFILE "package $static_browser_package_name\n\n";
1206 print BROWSER_MACROFILE "_cicstaticbrowser_ {\n";
1207
1208 print BROWSER_MACROFILE "<table cellpadding=\"0\" cellspacing=\"0\" width=\"_pagewidth_\">\n";
1209 foreach my $state (sort(keys(%state_name_to_abbr_mapping))) {
1210 my $state_abbr = $state_name_to_abbr_mapping{$state};
1211 print BROWSER_MACROFILE "_cicstate" . $state_abbr . "_\n";
1212 }
1213 print BROWSER_MACROFILE "</table>\n";
1214 print BROWSER_MACROFILE "}\n";
1215
1216 foreach my $state (sort(keys(%state_name_to_abbr_mapping))) {
1217 my $state_abbr = $state_name_to_abbr_mapping{$state};
1218 print BROWSER_MACROFILE "\n_cicstate" . $state_abbr . "_ {";
1219 my @state_ids = ();
1220 if (defined($state_to_ids_mapping->{$state})) {
1221 @state_ids = @{$state_to_ids_mapping->{$state}};
1222 }
1223 &write_static_browser_macros_chunk($state, \@state_ids, $id_to_name_mapping, undef);
1224 if (!defined($state_to_ids_mapping->{$state})) {
1225 print BROWSER_MACROFILE "<tr><td colspan=\"2\" valign=\"top\">No institutions for this state</td></tr>";
1226 }
1227 print BROWSER_MACROFILE "}\n";
1228 }
1229
1230 close(BROWSER_MACROFILE);
1231}
1232
1233
12341;
Note: See TracBrowser for help on using the repository browser.