#! /usr/bin/perl # webwml-stattrans - Debian web site translation statistics # Copyright (c) 2001 Martin Schulze and others # 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 # (at your option) 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 POSIX qw(strftime); use Getopt::Std; # These modules reside under webwml/Perl use lib ($0 =~ m|(.*)/|, $1 or ".") ."/Perl"; use Local::Cvsinfo; use Webwml::Langs; use Webwml::TransCheck; use Webwml::TransIgnore; use Debian::L10n::Db ('%LanguageList'); use Net::Domain qw(hostfqdn); use JSON; $| = 1; $opt_h = "/srv/www.debian.org/webwml/english/devel/website/stats"; $opt_w = "/srv/www.debian.org/webwml"; $opt_p = "*.(wml|src)"; $opt_t = ''; $opt_v = 0; $opt_d = "u"; $opt_l = undef; $opt_b = ""; # Base URL, if not debian.org # path of web stats JSON data $opt_f = "/srv/www.debian.org/webwml/stats.json"; getopts('h:w:b:p:t:vd:l:f:') || die; # Replace filename globbing by Perl regexps $opt_p =~ s/\./\\./g; $opt_p =~ s/\?/./g; $opt_p =~ s/\*/.*/g; $opt_p =~ s/$/\$/g; %config = ( 'htmldir' => $opt_h, 'wmldir' => $opt_w, 'wmlpat' => $opt_p, 'title' => $opt_t, 'verbose' => $opt_v, 'difftype'=> $opt_d, 'hit_file'=> $opt_f, ); my $l = Webwml::Langs->new($opt_w); my %langs = $l->name_iso(); my $transignore = Webwml::TransIgnore->new($opt_w); my $cvs = Local::Cvsinfo->new(); $cvs->options( recursive => 1, matchfile => [ $config{'wmlpat'} ], skipdir => [ "template" ], ); $cvs->readinfo("$config{'wmldir'}/english"); foreach (@{$transignore->global()}) { $cvs->removefile("$config{'wmldir'}/english/$_"); } my $altcvs = Local::Cvsinfo->new(); $altcvs->options( recursive => 1, matchfile => [ $config{'wmlpat'} ], skipdir => [ "template" ], ); $max_versions = 5; $min_versions = 1; $date = strftime "%a %b %e %H:%M:%S %Y %z", localtime; my %original; my %transversion; my %version; my %files; my %sizes; print "Loading the coordination status databases\n" if ($config{verbose}); my %status_db = (); opendir (DATADIR, "$opt_w/english/international/l10n/data") or die "Cannot open directory $opt_w/english/international/l10n/data: $!\n"; foreach (readdir (DATADIR)) { # Only check the status files next unless ($_ =~ m/^status\.(.*)$/); my $l = $1; next if (!defined $LanguageList{uc $l}); if (-r "$opt_w/english/international/l10n/data/status.$l") { $status_db{$LanguageList{uc $l}} = Debian::L10n::Db->new(); $status_db{$LanguageList{uc $l}}->read("$opt_w/english/international/l10n/data/status.$l", 0); } } closedir (DATADIR); sub linklist { my ($file, $lang) = @_; my $add = ""; if ($status_db{$lang}->has_package('www.debian.org') and $status_db{$lang}->has_status('www.debian.org')) { foreach my $statusline (@{$status_db{$lang}->status('www.debian.org')}) { my ($type, $statfile, $date, $status, $translator, $list, $url, $bug_nb) = @{$statusline}; if ($file eq $statfile) { $date =~ s/\s*\+0000$//; $list =~ /^(\d\d\d\d)-(\d\d)-(\d\d\d\d\d)$/; $add = "$status"; $add = "$add$translator$date"; } } } $add = '' if (!length $add); return $add; } # Count wml files in given directory # sub getwmlfiles { my $lang = shift; my $dir = "$config{'wmldir'}/$lang"; my $cutfrom = length ($config{'wmldir'})+length($lang)+2; my $count = 0; my $size = 0; my $is_english = ($lang eq "english")?1:0; my ( $file, $v ); my @listfiles; print "$lang " if ($config{verbose}); if (! -d "$dir") { print "$0: can't find $dir! Skipping ...\n"; return; } if ($is_english) { @listfiles = @{$cvs->files()}; } else { $altcvs->reset(); $altcvs->readinfo($dir); @listfiles = @{$altcvs->files()}; } foreach my $f (@listfiles) { $file = substr ($f, $cutfrom); next if $transignore->is_global($file); $files{$file} = 1; $wmlfiles{$lang} .= " " . $file; my $transcheck = Webwml::TransCheck->new("$dir/$file"); if ($transcheck->revision()) { $transversion{"$lang/$file"} = $transcheck->revision(); $original{"$lang/$file"} ||= $transcheck->original(); } if ($is_english) { $version{"$lang/$file"} = $cvs->revision($f); } else { $version{"$lang/$file"} = $altcvs->revision($f); if (!$transcheck->revision()) { $transcheckenglish = Webwml::TransCheck->new("english/$file"); if (!$transcheckenglish->revision() and (-e "english/$file")) { $transversion{"$lang/$file"} = "1.1"; $original{"$lang/$file"} = "english"; } else { $original{"english/$file"} = $lang; $transversion{"english/$file"} ||= "1.1"; } } } if ($transcheck->maintainer()) { $maintainer{"$lang/$file"} = $transcheck->maintainer(); } $count++; $sizes{$file} = (stat "".($original{"english/$file"}||"english")."/".$file)[7]; $size += $sizes{$file}; } $wmlfiles{$lang} .= " "; $wml{$lang} = $count; $wml_s{$lang} = $size; } sub get_color { my $percent = shift; if ($percent < 50) { return sprintf ("#FF%02x00", (255/50) * $percent); } else { return sprintf ("#%02xFF00", (255/50) * (100 - $percent)); } } sub check_translation { my ($translation, $version, $file) = @_; my ( @version_numbers, $major_number, $last_number ); my ( @translation_numbers, $major_translated_number, $last_translated_number ); if ( $version && $translation ) { @version_numbers = split /\./,$version; $major_number = $version_numbers[0]; $last_number = pop @version_numbers; die "Invalid CVS revision for $file: $version\n" unless ($major_number =~ /\d+/ && $last_number =~ /\d+/); @translation_numbers = split /\./,$translation; $major_translated_number = $translation_numbers[0]; $last_translated_number = pop @translation_numbers; die "Invalid translation revision for $file: $translation\n" unless ($major_translated_number =~ /\d+/ && $last_translated_number =~ /\d+/); # Here we compare the original version with the translated one and print # a note for the user if their first or last numbers are too far apart # From translation-check.wml if ( $major_number != $major_translated_number ) { return 'This translation is too out of date'; } elsif ( $last_number - $last_translated_number < 0 ) { return 'Wrong translation version'; } elsif ( $last_number - $last_translated_number >= $max_versions ) { return 'This translation is too out of date'; } elsif ( $last_number - $last_translated_number >= $min_versions ) { return 'The original is newer than this translation'; } } elsif ( !$version && $translation) { return 'The original no longer exists'; } return ""; } print "Collecting data in: " if ($config{'verbose'}); if ($opt_l) { getwmlfiles ($opt_l); getwmlfiles ('english'); } else { foreach $lang (keys %langs) { getwmlfiles ($lang); } } print "\n" if ($config{'verbose'}); my @search_in; if ($opt_l) { @search_in = ( 'english', $opt_l ); } else { @search_in = sort keys %langs; } # Compute stats about gettext files print "Computing statistics in gettext files... " if ($config{'verbose'}); my ( %po_translated, %po_fuzzy, %po_untranslated, %po_total ); my ( %percent_po_t, %percent_po_u, %percent_po_f ); foreach $lang (@search_in) { next if $lang eq 'english'; $po_translated{"total"}{$lang} = $po_fuzzy{"total"}{$lang} = $po_untranslated{"total"}{$lang} = 0; $percent_po_t{'total'}{$lang} = 0; $percent_po_f{'total'}{$lang} = 0; $percent_po_u{'total'}{$lang} = 100; if (! -d "$opt_w/$lang/po") { print "$0: can't find $opt_w/$lang/po! Skipping ...\n"; next; } my @status = qx,LC_ALL=C make -C $opt_w/$lang/po stats 2>&1,; foreach $line (@status) { chomp $line; next if($line =~ /make: (Enter|Leav)ing directory/); ($domain = $line) =~ s/\..*//; $po_translated{$domain}{$lang} = ($line =~ /(\d+) translated/ ? $1 : "0"); $po_fuzzy{$domain}{$lang} = ($line =~ /(\d+) fuzzy/ ? $1 : "0"); $po_untranslated{$domain}{$lang} = ($line =~ /(\d+) untranslated/ ? $1 : "0"); $po_total{$domain} = $po_translated{$domain}{$lang} + $po_fuzzy{$domain}{$lang} + $po_untranslated{$domain}{$lang}; $po_translated{"total"}{$lang} += $po_translated{$domain}{$lang}; $po_fuzzy{"total"}{$lang} += $po_fuzzy{$domain}{$lang}; $po_untranslated{"total"}{$lang} += $po_untranslated{$domain}{$lang}; if ($po_total{$domain} > 0) { $percent_po_t{$domain}{$lang} = int ($po_translated{$domain}{$lang}/$po_total{$domain} * 100 + .5); $percent_po_f{$domain}{$lang} = int ($po_fuzzy{$domain}{$lang}/$po_total{$domain} * 100 + .5); $percent_po_u{$domain}{$lang} = int ($po_untranslated{$domain}{$lang}/$po_total{$domain} * 100 + .5); } else { $percent_po_t{$domain}{$lang} = 0; $percent_po_f{$domain}{$lang} = 0; $percent_po_u{$domain}{$lang} = 0; # or 100 if po/ doesn't exist } } $po_total{"total"} = $po_translated{"total"}{$lang} + $po_fuzzy{"total"}{$lang} + $po_untranslated{"total"}{$lang}; if ($po_total{'total'} > 0) { $percent_po_t{'total'}{$lang} = int ($po_translated{'total'}{$lang}/$po_total{'total'} * 100 + .5); $percent_po_f{'total'}{$lang} = int ($po_fuzzy{'total'}{$lang}/$po_total{'total'} * 100 + .5); $percent_po_u{'total'}{$lang} = int ($po_untranslated{'total'}{$lang}/$po_total{'total'} * 100 + .5); } } print "done.\n" if ($config{'verbose'}); # =============== Create HTML files =============== mkdir ($config{'htmldir'}, 02775) if (! -d $config{'htmldir'}); # Read website hit statistics, if available my %hits; my $file_sorter = sub($$) { $_[0] cmp $_[1] }; if ($config{'hit_file'}) { printf("Retrieving hit data from [%s].\n", $config{'hit_file'}) if ($config{'verbose'}); open( my $fh, '<', $config{'hit_file'} ); local $/; my $json = <$fh>; close $fh; if ($json) { my $perl = JSON::from_json($json, {utf8 => 1}); foreach my $e (@{$perl}) { my ($count, $url) = @$e; last if $count < 3; # URLS with 2 or 1 hits are most likely mistakes; let's not waste RAM on them $hits{substr($url, 1)} = $count; } } if (%hits) { $file_sorter = sub($$) { my ($a, $b) = @_; $a =~ s/\.wml$//o; $b =~ s/\.wml$//o; $hits{$b} <=> $hits{$a} }; } else { print "Tables will be sorted alphabetically.\n" if ($config{'verbose'}); } } else { print "No hit file specified. Tables will be sorted alphabetically.\n" if ($config{'verbose'}); } my @filenames = sort $file_sorter keys %files; my $nfiles = scalar @filenames; $nsize += $sizes{$_} foreach (@filenames); my $firstdifftype; my $seconddifftype; if ($config{'difftype'} eq 'u') { $firstdifftype = 'u'; $seconddifftype = 'h'; } else { $firstdifftype = 'h'; $seconddifftype = 'u'; } sub alioth_cvs_file_url { my ($path) = @_; return sprintf( 'http://anonscm.debian.org/viewvc/webwml/webwml/%s', $path ); } sub alioth_cvs_log_url { my ($path) = @_; return alioth_cvs_file_url($path); } sub alioth_cvs_diff_url { my ( $path, $r1, $r2, $diff_format ) = @_; return alioth_cvs_file_url($path) . sprintf( '?r1=%s;r2=%s;diff_format=%s', $r1, $r2, $diff_format ); } sub alioth_cvs_view_url { my ($path) = @_; return alioth_cvs_file_url($path) . '?view=markup'; } sub alioth_cvs_raw_url { my ($path) = @_; return alioth_cvs_file_url($path) . '?view=co'; } print "Creating files: " if ($config{'verbose'}); foreach $lang (@search_in) { my @processed_langs = ($langs{$lang}); @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh"; foreach $l (@processed_langs) { print "$l.wml " if ($config{'verbose'}); $t_body = $u_body = $ui_body = $un_body = $uu_body = $o_body = ""; $translated{$lang} = $outdated{$lang} = $untranslated{$lang} = 0; # get stats about files foreach $file (@filenames) { next if ($file eq ""); (my $base = $file) =~ s/\.wml$//; my $hits = exists $hits{$base} ? $hits{$base}.' hits' : 'hit count N/A'; my $todo = ''; $todo = linklist($file, $lang) if defined $status_db{$lang}; # Translated pages or already WIP in translation list if ((index ($wmlfiles{$lang}, " $file ") >= 0) or (($todo ne '') and ($transversion{"$lang/$file"} ne $version{"$orig/$file"}))) { $translated{$lang}++; $translated_s{$lang} += $sizes{$file}; $orig = $original{"$lang/$file"} || "english"; # Outdated translations $msg = check_translation ($transversion{"$lang/$file"}, $version{"$orig/$file"}, "$lang/$file"); if (length ($msg) or (($todo ne '') and ($transversion{"$lang/$file"} ne $version{"$orig/$file"}))) { $o_body .= ""; if (($file !~ /\.wml$/) || ($file eq "devel/wnpp/wnpp.wml")) { $o_body .= sprintf "%s", $file; } else { $o_body .= sprintf "%s", $hits, $base, $base; } my $stattd = sprintf 'Click to fetch diffstat data\' onClick="setDiffstat(\'%s\', \'%s\', \'%s\', this)">+/-', $file, $transversion{"$lang/$file"}, $version{"$orig/$file"}; my $statspan = sprintf '(Click to fetch diffstat data\' onClick="setDiffstat(\'%s\', \'%s\', \'%s\', this)">+/-)', $file, $transversion{"$lang/$file"}, $version{"$orig/$file"}; if (!defined $status_db{$lang}) { $o_body .= sprintf "%s", $msg; $o_body .= $stattd; } if ($msg eq 'Wrong translation version' || $msg eq 'The original no longer exists') { if (defined $status_db{$lang}) { $o_body .= sprintf "%d (%.2f ‰)", $sizes{$file}, $sizes{$file}/$nsize * 1000; } else { $o_body .= ""; } } else { if (defined $status_db{$lang}) { if ($transversion{"$lang/$file"} ne ''){ $o_body .= sprintf 'Unified diff\' href="%s">%s → %s ', alioth_cvs_diff_url( "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, 'u' ), $transversion{"$lang/$file"}, $version{"$orig/$file"}; $o_body .= sprintf 'Colored diff\' href="%s">%s → %s ', alioth_cvs_diff_url( "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, 'h' ), $transversion{"$lang/$file"}, $version{"$orig/$file"}; $o_body .= "$statspan"; } else { $o_body .= sprintf "%d (%.2f ‰)", $sizes{$file}, $sizes{$file}/$nsize * 1000; } } else { $o_body .= sprintf "%s\ ->\ %s", alioth_cvs_diff_url( "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, $firstdifftype ), $transversion{"$lang/$file"}, $version{"$orig/$file"}; $o_body .= sprintf "%s\ ->\ %s", alioth_cvs_diff_url( "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, $seconddifftype ), $transversion{"$lang/$file"}, $version{"$orig/$file"}; } } $o_body .= sprintf "[L]", $msg, alioth_cvs_log_url("$orig/$file"), $version{"$orig/$file"}; $o_body .= sprintf "[V]\ ", alioth_cvs_view_url("$lang/$file"); $o_body .= sprintf "[F]", alioth_cvs_raw_url("$lang/$file"); $o_body .= sprintf "%s", $maintainer{"$lang/$file"} || ""; $o_body .= $todo if (defined $status_db{$lang}); $o_body .= "\n"; $outdated{$lang}++; $outdated_s{$lang} += $sizes{$file}; # Up-to-date translations } else { if (($file !~ /\.wml$/) || ($file eq "devel/wnpp/wnpp.wml")) { $t_body .= sprintf "
  • %s
  • \n", $file; } else { $t_body .= sprintf "
  • %s
  • \n", $hits, $base, $l, $base; } } } # Untranslated pages else { my $u_tmp; if (($file !~ /\.wml$/) || ($file eq "devel/wnpp/wnpp.wml")) { $u_tmp = sprintf "%s \n", $file; } else { $u_tmp = sprintf "%s  (%s)%d(%.2f ‰)\n", $hits, $base, $base, $version{"$orig/$file"}, $sizes{$file}, $sizes{$file}/$nsize * 1000; } if (($file =~ /international\//) && ($file !~ /international\/index.wml$/) && ($file !~ /international\/l10n\//)) { $ui_body .=$u_tmp; } elsif ((($file =~ /(News|events|security|vote)\/[0-9]{4}\//) && ($file !~ /index.wml$/)) || ($file =~ /(News\/weekly\/[0-9]{4}\/|security\/undated)/)) { $un_body .= $u_tmp; } elsif (($file =~ /(consultants|users\/(com|edu|gov|org))\//) && ($file !~ /index.wml$/)) { $uu_body .=$u_tmp; } else { $u_body .= $u_tmp; } $untranslated{$lang}++; $untranslated_s{$lang} += $sizes{$file}; } } # this is where we discard the files that the translation directory contains # but which don't exist in the English directory # print "extra files: ".$wml{$lang}-$translated{$lang}."\n"; $wml{$lang} = $translated{$lang}; $wml_s{$lang} = $translated_s{$lang}; $translated{$lang} = $translated{$lang} - $outdated{$lang}; $translated_s{$lang} = $translated_s{$lang} - $outdated_s{$lang}; if ($nfiles > 0) { $percent_a{$lang} = $wml{$lang}/$nfiles * 100; } else { $percent_a{$lang} = 0; } if ($nsize > 0) { $percent_as{$lang} = $wml_s{$lang}/$nsize * 100; } else { $percent_as{$lang} = 0; } if ($wml{$lang} > 0) { $percent_t{$lang} = $translated{$lang}/$wml{$lang} * 100; } else { $percent_t{$lang} = 0; } if ($wml_s{$lang} > 0) { $percent_ts{$lang} = $translated_s{$lang}/$wml_s{$lang} * 100; } else { $percent_ts{$lang} = 0; } $percent_o{$lang} = 100 - $percent_t{$lang}; $percent_os{$lang} = 100 - $percent_ts{$lang}; $percent_u{$lang} = 100 - $percent_a{$lang}; $percent_us{$lang} = 100 - $percent_as{$lang}; if (open (HTML, ">$config{'htmldir'}/$l.wml")) { printf HTML "#use wml::debian::template title=\"<:=\$trans{\$CUR_ISO_LANG}{%s}:>\"\n", $lang; print HTML "#use wml::debian::toc\n"; print HTML "\n\n"; $color = get_color ($percent_a{$lang}); printf HTML 'Translation summary for <:=$trans{$CUR_ISO_LANG}{'.$lang.'} :>" style="background-color: %s; width: 100%; font-weight: bold; margin: 0; text-align: center;">'."\n", $color; print HTML "\n"; print HTML ''."\n\n"; printf HTML '', $wml{$lang}, $percent_a{$lang}; printf HTML '', $translated{$lang}, $percent_t{$lang}; printf HTML '', $outdated{$lang}, $percent_o{$lang}; printf HTML '', $untranslated{$lang}, $percent_u{$lang}; print HTML "\n"; print HTML "\n"; printf HTML '', $wml_s{$lang}, $percent_as{$lang}; printf HTML '', $translated_s{$lang}, $percent_ts{$lang}; printf HTML '', $outdated_s{$lang}, $percent_os{$lang}; printf HTML '', $nsize-$wml_s{$lang}, $percent_us{$lang}; print HTML "\n"; print HTML "
    TranslatedUp to dateOutdatedNot translated
    %d files (%.1f%%)%d files (%.1f%%)%d files (%.1f%%)%d files (%.1f%%)
    %d bytes (%.1f%%)%d bytes (%.1f%%)%d bytes (%.1f%%)%d bytes (%.1f%%)
    \n"; # Make the table of content print HTML "\n"; if (%hits) { print HTML '

    Note: the lists of pages are sorted by popularity. Hover over the page name to see the number of hits.'; print HTML "

    \n"; } # outputs the content if ($o_body) { print HTML 'Outdated translations'."\n"; print HTML "\n"; print HTML ''."\n"; if (defined $status_db{$lang}) { print HTML ''; } else { print HTML ''."\n"; print HTML ''."\n"; if ($opt_d eq "u") { print HTML ''; } elsif ($opt_d eq "h") { print HTML ''; } else { print HTML ''; } } print HTML ''; print HTML ''; print HTML ''; if (defined $status_db{$lang}) { print HTML ''; print HTML ''; print HTML ''; } print HTML "\n"; print HTML $o_body; print HTML "
    FileDiffCommentDiffstatUnified diffColored diffColored diffUnified diffDiffLogTranslationMaintainerStatusTranslatorDate
    \n"; } if ($u_body) { print HTML 'General pages not translated'."\n"; print HTML 'Untranslated general pages">'."\n"; print HTML $u_body; print HTML "
    \n"; } if ($un_body) { print HTML 'News items not translated'."\n"; print HTML 'Untranslated news items">'."\n"; print HTML $un_body; print HTML "
    \n"; } if ($uu_body) { print HTML 'Consultant/user pages not translated'."\n"; print HTML 'Untranslated consultant/user pages">'."\n"; print HTML $uu_body; print HTML "
    \n"; } if ($ui_body) { print HTML 'International pages not translated'."\n"; print HTML 'Untranslated international pages">'."\n"; print HTML $ui_body; print HTML "
    \n"; } if ($t_body) { print HTML 'Translated pages (up-to-date)'."\n"; print HTML "
      \n"; print HTML $t_body; print HTML "
    \n"; } # outputs the gettext stats if ($lang ne 'english') { print HTML 'Translated templates (PO files)'."\n"; print HTML 'PO Translation Statistics" width="100%">'."\n"; print HTML ''."\n"; print HTML ''."\n"; print HTML ''."\n"; print HTML ''."\n"; print HTML ''."\n"; foreach my $domain (sort keys %po_total) { next if $domain eq 'total'; print HTML ""; $color_t = get_color ($percent_po_t{$domain}{$lang}); $color_f = get_color (100 - $percent_po_f{$domain}{$lang}); $color_u = get_color (100 - $percent_po_u{$domain}{$lang}); print HTML ""; printf HTML "", $color_t, $po_translated{$domain}{$lang}, $percent_po_t{$domain}{$lang}; printf HTML "", $color_f, $po_fuzzy{$domain}{$lang}, $percent_po_f{$domain}{$lang}; printf HTML "", $color_u, $po_untranslated{$domain}{$lang}, $percent_po_u{$domain}{$lang}; printf HTML "", $po_total{$domain}; print HTML "\n"; } print HTML "\n"; print HTML ''; $color_t = get_color ($percent_po_t{'total'}{$lang}); $color_f = get_color (100 - $percent_po_f{'total'}{$lang}); $color_u = get_color (100 - $percent_po_u{'total'}{$lang}); printf HTML "", $color_t, $po_translated{'total'}{$lang}, $percent_po_t{'total'}{$lang}; printf HTML "", $color_f, $po_fuzzy{'total'}{$lang}, $percent_po_f{'total'}{$lang}; printf HTML "", $color_u, $po_untranslated{'total'}{$lang}, $percent_po_u{'total'}{$lang}; printf HTML "", $po_total{'total'}; print HTML "\n"; print HTML "
    FileUp to dateFuzzyUntranslatedTotal
    $domain.$langs{$lang}.po%d (%s%%)%d (%s%%)%d (%s%%)%d
         
    Total:%d (%d%%)%d (%d%%)%d (%d%%)%d
    \n"; } print HTML '
    Created with webwml-stattrans
    ' . "\n"; close (HTML); } else { print "Can't open $config{'htmldir'}/$l.wml\n"; } } } print "\n" if ($config{'verbose'}); # =============== Creating index.html =============== print "Creating index.wml... " if ($config{'verbose'}); open (HTMLI, ">$config{'htmldir'}/index.wml") || die "Can't open $config{'htmldir'}/index.wml"; print HTMLI "#use wml::debian::stats_tags\n"; printf HTMLI "#use wml::debian::template title=\"%s\"\n\n", $config{'title'}; print HTMLI '

    Translated web pages

    '."\n"; printf HTMLI "

    \n",($wml{'english'}+$untranslated{'english'}); print HTMLI 'Translation Statistics by Page Count" class="stattrans">'."\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI ""; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ""; print HTMLI ""; foreach $lang (@search_in) { my @processed_langs = ($langs{$lang}); @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh"; foreach $l (@processed_langs) { $color_a = get_color ($percent_a{$lang}); $color_t = get_color ($percent_t{$lang}); $color_o = get_color (100 - $percent_o{$lang}); $color_u = get_color (100 - $percent_u{$lang}); print HTMLI ""; printf HTMLI "", $l, $lang, $l; printf HTMLI "", $color_a, $wml{$lang}, $percent_a{$lang}; printf HTMLI "", $color_t, $translated{$lang}, $percent_t{$lang}; printf HTMLI "", $color_o, $outdated{$lang}, $percent_o{$lang}; printf HTMLI "", $color_u, $untranslated{$lang}, $percent_u{$lang}; print HTMLI "\n"; } } print HTMLI ""; print HTMLI "
    LanguageTranslationsUp to dateOutdatedNot translated
    <:=\$trans{\$CUR_ISO_LANG}{%s} :> (%s)%d(%.1f%%)%d(%.1f%%)%d(%.1f%%)%d(%.1f%%)
    \n"; print HTMLI '

    Translated web pages (by size)

    '."\n"; printf HTMLI "

    \n",($wml_s{'english'}+$untranslated_s{'english'}); print HTMLI 'Translation Statistics by Page Size" class="stattrans">'."\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI ""; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ""; print HTMLI ""; foreach $lang (@search_in) { my @processed_langs = ($langs{$lang}); @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh"; foreach $l (@processed_langs) { $color_a = get_color ($percent_a{$lang}); $color_t = get_color ($percent_t{$lang}); $color_o = get_color (100 - $percent_o{$lang}); $color_u = get_color (100 - $percent_u{$lang}); print HTMLI ""; printf HTMLI "", $l, $lang, $l; printf HTMLI "", $color_a, $wml_s{$lang}, $percent_as{$lang}; printf HTMLI "", $color_t, $translated_s{$lang}, $percent_ts{$lang}; printf HTMLI "", $color_o, $outdated_s{$lang}, $percent_os{$lang}; printf HTMLI "", $color_u, $wml_s{"english"}+$untranslated_s{'english'}-$wml_s{$lang}, $percent_us{$lang}; print HTMLI "\n"; } } print HTMLI ""; print HTMLI "
    LanguageTranslationsUp to dateOutdatedNot translated
    <:=\$trans{\$CUR_ISO_LANG}{%s} :> (%s)%d(%.1f%%)%d(%.1f%%)%d(%.1f%%)%d(%.1f%%)
    \n"; print HTMLI '

    Translated templates (PO files)

    '."\n"; printf HTMLI "

    \n",$po_total{'total'}; print HTMLI 'PO Translation Statistics"class="stattrans">'."\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI "\n"; print HTMLI ""; print HTMLI ""; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ''."\n"; print HTMLI ""; print HTMLI ""; foreach $lang (@search_in) { next if $lang eq 'english'; my @processed_langs = ($langs{$lang}); @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh"; foreach $l (@processed_langs) { print HTMLI ""; printf HTMLI "", $l, $lang, $l; $color_t = get_color ($percent_po_t{'total'}{$lang}); $color_f = get_color (100 - $percent_po_f{'total'}{$lang}); $color_u = get_color (100 - $percent_po_u{'total'}{$lang}); printf HTMLI "", $color_t, $po_translated{'total'}{$lang}, $percent_po_t{'total'}{$lang}; printf HTMLI "", $color_f, $po_fuzzy{'total'}{$lang}, $percent_po_f{'total'}{$lang}; printf HTMLI "", $color_u, $po_untranslated{'total'}{$lang}, $percent_po_u{'total'}{$lang}; print HTMLI "\n"; } } print HTMLI ""; print HTMLI "
    LanguageUp to dateFuzzyNot translated
    <:=\$trans{\$CUR_ISO_LANG}{%s} :> (%s)%d(%d%%)%d(%d%%)%d(%d%%)
    \n"; print HTMLI '
    Created with webwml-stattrans
    ' . "\n"; close (HTMLI); print "done.\n" if ($config{'verbose'}); # Note: # Translated pages on ll.html may be higher than in index.html. # This is due to the fact that some english pages were removed. # printf "%s\n", join ("\n", keys %version); # printf "%s - %s\n", $version{'german/devel/index'}, $version{'english/devel/index'};