Metadata.pm (3237B)
1 #!/usr/bin/env perl 2 3 # LSG::Metadata - metadata parser for the LSG 4 # Written by lumidify <nobody@lumidify.org> 5 # 6 # To the extent possible under law, the author has dedicated 7 # all copyright and related and neighboring rights to this 8 # software to the public domain worldwide. This software is 9 # distributed without any warranty. 10 # 11 # You should have received a copy of the CC0 Public Domain 12 # Dedication along with this software. If not, see 13 # <http://creativecommons.org/publicdomain/zero/1.0/>. 14 15 package LSG::Metadata; 16 use strict; 17 use warnings; 18 use utf8; 19 use open qw< :encoding(UTF-8) >; 20 binmode STDIN, ":encoding(UTF-8)"; 21 binmode STDOUT, ":encoding(UTF-8)"; 22 binmode STDERR, ":encoding(UTF-8)"; 23 use File::Find; 24 use File::Spec::Functions qw(catfile catdir splitdir); 25 use File::Path; 26 use LSG::Config qw($config); 27 28 sub parse_metadata_file { 29 my $in = shift; 30 my %tmp_fm = (); 31 while (<$in> =~ /^([^:]*):(.*)$/) { 32 $tmp_fm{$1} = $2; 33 if (eof) {last} 34 } 35 return \%tmp_fm; 36 } 37 38 sub parse_metadata { 39 if (!(-f)) {return}; 40 my $fullname = $File::Find::name; 41 # Strip "pages/" from dirname 42 my @dirs = splitdir($File::Find::dir); 43 my $dirname = catdir(@dirs[1..$#dirs]); 44 my $basename = substr($_, 0, $#_-2); 45 # Note: this will only work if language codes are two chars 46 my $lang = substr($_, -2); 47 my $pageid = $basename; 48 if ($dirname) {$pageid = catfile($dirname, $basename)}; 49 open(my $in, "<", $_) or die "Can't open $fullname: $!"; 50 my %tmp_md = %{parse_metadata_file($in)}; 51 close($in); 52 my $modified_date = (stat($_))[9]; 53 $config->{"metadata"}->{$pageid}->{"modified"}->{$lang} = $modified_date; 54 if (!exists($tmp_md{"template"})) { 55 die "ERROR: $fullname does not specify a template\n"; 56 } 57 if (!exists($config->{"templates"}->{$tmp_md{"template"} . ".$lang.html"})) { 58 die "ERROR: $fullname: template " . $tmp_md{"template"} . " does not exist\n"; 59 } 60 # Note: if different templates are specified for different languages, 61 # the one from the last language analyzed is used. 62 # FIXME: change this - if different templates are specified for different langs, 63 # the template isn't checked for existance in other langs 64 # Wait, why not just use the actual template given? It's stored in $config->{"metadata"} anyways 65 $config->{"metadata"}->{$pageid}->{"template"} = $tmp_md{"template"}; 66 foreach my $md_id (split / /, $config->{"templates"}->{$tmp_md{"template"} . ".$lang.html"}->{"metadata"}) { 67 if (!exists($tmp_md{$md_id})) { 68 die "ERROR: $fullname does not include \"$md_id\" metadata\n"; 69 } 70 } 71 foreach my $md_id (keys %tmp_md) { 72 $config->{"metadata"}->{$pageid}->{$lang}->{$md_id} = $tmp_md{$md_id}; 73 } 74 $config->{"metadata"}->{$pageid}->{"dirname"} = $dirname; 75 $config->{"metadata"}->{$pageid}->{"basename"} = $basename; 76 } 77 78 sub gen_metadata_hash { 79 find(\&parse_metadata, "pages/"); 80 } 81 82 sub check_metadata_langs { 83 my $not_found; 84 foreach my $pageid (keys %{$config->{"metadata"}}) { 85 $not_found = ""; 86 foreach my $lang (keys %{$config->{"langs"}}) { 87 if (!exists($config->{"metadata"}->{$pageid}->{$lang})) { 88 $not_found .= " $lang"; 89 } 90 } 91 if ($not_found) { 92 die("ERROR: languages \"$not_found\" not found for $pageid\n"); 93 } 94 } 95 } 96 97 sub init_metadata { 98 gen_metadata_hash(); 99 check_metadata_langs(); 100 } 101 102 1;