#!/usr/bin/perl # Copyright 2007 Gérald Sédrati-Dinet # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA use strict; use warnings; use Sleepycat::DbXml 'simple'; use XML::Twig; use Getopt::Long; # Some files will be save under tree hierarchy based on executable location use FindBin qw($Bin); use lib "$Bin"; # Default values my $path2DbEnv = "$Bin/dbxml"; my $theContainer = 'mps.dbxml'; my $output_dir = "$Bin/spikini/mps_departments"; # Parse command line options Getopt::Long::Configure("bundling"); GetOptions( 'path2dbenv|p=s' => \$path2DbEnv, 'container|c=s' => \$theContainer, 'output|o=s' => \$output_dir, 'help|h' => sub { print STDERR <] [-c ] [-o : path to directory of DB XML database default: $Bin/dbxml --container, -c : DB XML container is typically mps (for convenience the final "s" can be omitted, also ".dbxml" can be appended) default: mps.dbxml --output, -o : output directory of spikini pages default: $Bin/spikini/mps_departments --help, -h: print this message USAGE exit 0; } ); $theContainer =~ s/s?(?:\.dbxml)?$/s/; my %department_mps; eval { # Open a container in the db environment my $env = new DbEnv(0); $env->set_cachesize(0, 64 * 1024, 1); $env->open($path2DbEnv, Db::DB_INIT_MPOOL|Db::DB_CREATE|Db::DB_INIT_LOCK|Db::DB_INIT_LOG); my $theMgr = new XmlManager($env); my $container = $theMgr->openContainer("$theContainer.dbxml"); my $query = <<'QUERY'; for $deputy in collection("mps.dbxml")/politician let $constituency := $deputy/infos/constituency order by $constituency/department/number, $constituency/number/string() return { $constituency/department/name/string() } { $constituency/number/string() } { concat($constituency/number/string(), " circonscription (cantons de ", string-join(for $canton in $constituency/cantons/name return $canton/string(), ", "), ")") } { concat("[", $deputy/infos/name/first/string(), " ", $deputy/infos/name/last/string(), "->MemoirePolitique", $deputy/infos/name/wiki/string(), "]") } { $deputy/infos/group/abbreviation/string() } { $deputy/infos/group/name/string() } { string-join(for $tel in $deputy/contact//phone return $tel/string(), "/") } { string-join(for $fax in $deputy/contact//fax return $fax/string(), "/") } { if ($deputy/contact/email) then { $deputy/contact/email/string() } else () } QUERY # Perform the query eval { my $results = $theMgr->query($query); my $value; while( $results->next($value) ) { my %mp_data; my $xml = XML::Twig->new(output_encoding => 'ISO-8859-1')->parse($value); $mp_data{CANTONS} = $xml->root->first_child_text('cantons'); $mp_data{NAME} = $xml->root->first_child_text('name'); $mp_data{PARTY} = $xml->root->first_child_text('party'); $mp_data{GROUP} = $xml->root->first_child_text('group'); $mp_data{TEL} = $xml->root->first_child_text('tel'); $mp_data{FAX} = $xml->root->first_child_text('fax'); my $mail = $xml->root->first_child('email')?$xml->root->first_child_text('email'):'-'; (my $mail_str = $mail) =~ s/@/(à)/o; $mp_data{EMAIL} = ($mail eq '-')?$mail:"[$mail_str->mailto:$mail]\n"; my $dep_name = $xml->root->first_child_text('department'); my $dep_wiki = desaccent($dep_name); my $dep_nb = $xml->root->first_child('department')->att('number'); # Dirty hack so that Corse is correctly sorted $dep_nb =~ s/2([AB])/20$1/o; my $constituency = $xml->root->first_child_text('constituency'); if (exists $department_mps{$dep_nb}) { $department_mps{$dep_nb}->[2]->{$constituency} = \%mp_data; } else { $department_mps{$dep_nb} = [$dep_name, $dep_wiki, {$constituency => \%mp_data}]; } } }; if (my $e = catch std::exception) { warn "Query $query failed\n"; warn $e->what() . "\n"; exit( -1 ); } elsif ($@) { warn "Query $query failed\n"; warn $@; exit( -1 ); } } ; if (my $e = catch std::exception) { warn "Query failed\n"; warn $e->what() . "\n"; exit( -1 ); } elsif ($@) { warn "Query failed\n"; warn $@; exit( -1 ); } # Build spikini page for navigation my $spikini_page = "{{{GroupeMemoirePolitique : coordonnées des députés par département}}}\n\n-----\n\n"; $spikini_page .= join "\n", map {(my $dep_print = $_) =~ s/20([AB])/2$1/o; "- [$department_mps{$_}->[0] ($dep_print)->MemoirePolitiqueDeputes$department_mps{$_}->[1]]"} sort keys %department_mps; $spikini_page .= "\n\n-----\n\nRetour à MemoirePolitiqueAppartenance\n"; # Output spikini page my $spikini_location = "$output_dir/DeputesParDepartement.spikini"; open SPIKINI, ">$spikini_location" or die "Cannot write in file $spikini_location: $!\n"; print SPIKINI $spikini_page; close SPIKINI or die "Error when closing $spikini_location: $!\n"; warn "$spikini_location done\n"; # Build spikini pages for each department foreach my $dep (sort keys %department_mps) { # Dirty hack so that Corse is correctly sorted (my $dep_print = $dep) =~ s/20([AB])/2$1/o; my $spikini_page = "{{{GroupeMemoirePolitique : $department_mps{$dep}->[0] ($dep_print), coordonnées des députés}}}\n\n-----\n\n"; $spikini_page .= "| {{Circonscription}} | {{Député(e)}} | {{Parti}} | {{Télephone(s)}} | {{Fax}} | {{Courriel}} |\n"; foreach my $constituency (sort {(my $num_a)=($a=~/^(\d+)/o);(my $num_b)=($b=~/^(\d+)/o); $num_a <=> $num_b} keys %{$department_mps{$dep}->[2]}) { my $party_wiki; if ($department_mps{$dep}->[2]->{$constituency}->{GROUP} eq "Députés n'appartenant à aucun groupe") { $party_wiki = 'AucunGroupe' } else { ($party_wiki = $department_mps{$dep}->[2]->{$constituency}->{PARTY}) =~ s/^Ap\. //o; $party_wiki = ucfirst(lc($party_wiki)); } $spikini_page .= "| $department_mps{$dep}->[2]->{$constituency}->{CANTONS} | $department_mps{$dep}->[2]->{$constituency}->{NAME} | [$department_mps{$dep}->[2]->{$constituency}->{PARTY}->MemoirePolitiqueDeputes$party_wiki] | $department_mps{$dep}->[2]->{$constituency}->{TEL} | $department_mps{$dep}->[2]->{$constituency}->{FAX} | $department_mps{$dep}->[2]->{$constituency}->{EMAIL} |\n"; } $spikini_page .= "\n\n-----\n\nAutres départements : MemoirePolitiqueDeputesParDepartement\n"; # Output spikini page my $spikini_location = "$output_dir/Deputes$department_mps{$dep}->[1].spikini"; open SPIKINI, ">$spikini_location" or die "Cannot write in file $spikini_location: $!\n"; print SPIKINI $spikini_page; close SPIKINI or die "Error when closing $spikini_location: $!\n"; warn "$spikini_location done\n"; } sub desaccent { my $str = shift; my $mp_name = $str; $str =~ s/À/A/go; $str =~ s/Â/A/go; $str =~ s/Ä/A/go; $str =~ s/É/E/go; $str =~ s/È/E/go; $str =~ s/Ê/E/go; $str =~ s/Ë/E/go; $str =~ s/Í/I/go; $str =~ s/Î/I/go; $str =~ s/Ï/I/go; $str =~ s/Ó/O/go; $str =~ s/Ô/O/go; $str =~ s/Ö/O/go; $str =~ s/Ù/U/go; $str =~ s/Û/U/go; $str =~ s/Ü/U/go; $str =~ s/Ç/C/go; $str =~ s/à/a/go; $str =~ s/â/a/go; $str =~ s/ä/a/go; $str =~ s/é/e/go; $str =~ s/è/e/go; $str =~ s/ê/e/go; $str =~ s/ë/e/go; $str =~ s/í/i/go; $str =~ s/î/i/go; $str =~ s/ï/i/go; $str =~ s/ó/o/go; $str =~ s/ô/o/go; $str =~ s/ö/o/go; $str =~ s/ù/u/go; $str =~ s/û/u/go; $str =~ s/ü/u/go; $str =~ s/ç/c/go; $str =~ s/[ '-]//go; return $str; }