On Tue, May 24, 2005 at 01:04:16AM -0300, Felipe Augusto van de Wiel (faw) wrote: > > Christian Perrier wrote: > > > :: OK, it seems we have found the right man, now, who will > :: gather together all the existing bricks and come with > :: a very nice translation status framework revamping.... > > My hope is that I can help on this subject. :o)
As Christian said at some point, I am one of the former dl10n author (along with Denis Barbier). I would love to help you guys, but I'm afraid it won't be possible. I'm completely overhelmed and swamped in much to much projects. I attach a mail I got a while ago about implementing dl10n-html that I wasn't able to answer yet. There was a prototype implementation I didn't even read yet. Shame on me. (Miguel is ok for the public answer to his mail). I guess you guys will do a much better work if you consider me out of the picture. Sorry for that and have fun, Mt.
--- Begin Message --------BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello Martin, As I talked to you a few months ago I'm working with dl10n-stats scripts. It's unfinished yet, but i'll worked on it, it need to revise totals, finish headers and debug all. It's hardly based on dl10n-txt. Now I'm working in web page headers, the common part on debian pages, do you know if exist a templates for it? I've seen on debian-www but i think it's a big dependence. How had you do them before machine crash? I've attached the actual dl10n-stats file to you. Thanks. - -- e-mail: Miguel Gea Milvaques <debian(@nospam)miguelgea.com Blog: http://www.livejournal.com/users/xerakko/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCdHJmNTNQylgICMQRAqW5AJ9VG7DoboNPx4/DIbLnvH0f+lJAWwCfftyg Jd2yLgu4rql/vorQLDEoq8I= =Bd2i -----END PGP SIGNATURE-----#! /usr/bin/perl -w # dl10n-stats -- Debian l10n statistics # # Copyright (C) 2004 Martin Quinson # # 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. use strict; use Getopt::Long; #to parse the args use Time::Local 'timelocal'; # to compute bug ages my $progname= $0; $progname= $& if $progname =~ m,[^/]+$,; my $VERSION = "3.0"; #External Version Number my $BANNER = "Debian l10n infrastructure -- textual statistics extractor v$VERSION"; # Version Banner - text form my $DB_FILE="./data/status"; my $STATUS_FILE='./data/status.$lang'; my $list_file=undef; my $take_debian=0; my $fmt = "po,podebconf"; my $mask_done = 0; my $show_empty = 1; my $show_status = 0; my $show_total = 0; my $assume_bts = 0; my $output_fmt = 0; my $showmsg = 1; my %ffile; my %ftransl; my %fstatus; my %trcolor; my $trinic="p"; my @sections=qw(main contrib non-free); my $section; my @trans_s=qw(todo done underway); my $trans_stat; my $tpercent="0\%"; my $view=1; use Debian::L10n::Db; sub syntax_msg { my $msg = shift; if (defined $msg) { print "$progname: $msg\n"; } else { print "$BANNER\n"; } print "Syntax: $0 [options] [lang]+ General options: -h, --help display short help text -V, --version display version and exit Package selection: --debian Only take debian specific packages --list=file Only handle the packages listed in the provided file -t,--todo Display only when the translation is NOT completed -e,--empty Display even if there is no translation to this language Informations to display: --total Show only summary for the lang, not each package details -s,--status Show status (hard to read when there is more than one format) --trans-stat=ts Show only packages which translation is [underway/todo/done] --show=fmt Show only selected format (instead of $fmt) -a,--assume-bts Assume that the content bugs in the BTS were applied. --output=format Set output format using one html or text. Default is text. --section=sect Show only 'sect' section. Database to use: --db=DB_FILE use DB_FILE as database file (instead of $DB_FILE) --sdb=STATUS_FILE use STATUS_FILE as status file (instead of $STATUS_FILE) "; if (defined $msg) { exit 1; } else { exit 0; } } # Display Version Banner # Options: -V|--version, --print-version sub banner { if ($_[0] eq 'print-version') { print "$VERSION\n"; } else { print "$BANNER\n"; } exit 0; } # Hash used to process commandline options my %opthash = (# ------------------ general options "help|h" => \&syntax_msg, "version|V" => \&banner, "print-version" => \&banner, # ------------------ configuration options "todo|t" => \$mask_done, "empty|e" => \$show_empty, "status|s" => \$show_status, "total" => \$show_total, "assume-bts|a" => \$assume_bts, "output=s" => \$output_fmt, "trans-stat=s" => \$trans_stat, "section=s" => \$section, "debian" => \$take_debian, "show=s" => \$fmt, "db=s" => \$DB_FILE, "sdb=s" => \$STATUS_FILE, "list=s" => \$list_file, ); # init commandline parser Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); # process commandline options GetOptions(%opthash) or syntax_msg("error parsing options"); $show_status = 1 if ($assume_bts); if (defined $section) [EMAIL PROTECTED]($section); foreach my $kkkk (@sections) {print "sec=".$kkkk;}} @trans_s=split(/,/,$trans_stat); if ($output_fmt eq "html") { $output_fmt = 1; $showmsg = 0; # Set the number of lines in a formated page. my $old = select STDOUT; $= = 9999999; select $old; } # die ('Error: trans-stat value must be one on todo/underway/done\n') unless $trans_stat eq "todo" || $trans_stat eq "underway" || $trans_stat eq "done"; if ($output_fmt eq "text") { $output_fmt = 0; $showmsg = 1; } #----------------------------------------------------------------------------- # The main program #----------------------------------------------------------------------------- ### ### initialisation ### (@ARGV > 0) or &syntax_msg("Nothing to do !"); my $arg; my @todo_lang; while ($arg = shift @ARGV) { push @todo_lang,$arg; } my $data = Debian::L10n::Db->new(); print STDERR "Read the database..." if ($showmsg == 1); $data->read($DB_FILE); print STDERR " done.\n" if ($showmsg == 1); my @todo_pkg; if (defined($list_file)) { print STDERR "Get the package list from $list_file\n" if ($showmsg == 1); open LIST, "$list_file" || die "Impossible to read the list file $list_file\n"; while (<LIST>) { chomp; next unless $_; s/ //g; if ($data->has_package($_)) { push @todo_pkg, $_; # print STDERR "['$_' added]\n"; } # else { # print STDERR "['$_' is not in the DB, skipped]\n"; # } } close LIST; } else { @todo_pkg = sort $data->list_packages(); } my ($pkg,%p,%d,$man,$status); my (%total); my ($man_en_total,$man_fr_total); my %parts; map {$parts{$_} = 1} split (/,/, $fmt); my @poparts=qw(po templates podebconf); my $format_top; my $format2; if ($output_fmt == 0) { $format_top = "format STDOUT_T = \n". ' '.($parts{'po'}?'______________________':'').($parts{'templates'}?'______________________':'').($parts{'podebconf'}?'______________________':'').($parts{'man'}?'_______':'')."\n". ' __________________|'.($parts{'po'}?'_________po__________|':'').($parts{'templates'}?'______templates______|':'').($parts{'podebconf'}?'_____po-debconf______|':'').($parts{'man'}?' # man |':'')."\n". '|______name________|'.($parts{'po'}?'__%__|____details____|':'').($parts{'templates'}?'__%__|____details____|':'').($parts{'podebconf'}?'__%__|____details____|':'').($parts{'man'}?'_______|':'')."\n". ".\n"; eval ($format_top); } if ($output_fmt == 1) { # print "<html><body>\n"; # $format_top = "format STDOUT_T = \n"; $format2="<table summary=\"Table with packages in section\" border=\"1\"><tbody><tr>". "<th><\/th>".($parts{'po'}?"<th colspan=4 align=center>po<\/th>":'').($parts{'templates'}?"<th colspan=4 align=center>templates<\/th>":'').($parts{'podebconf'}?"<th colspan=4 align=center>po-debconf<\/th>":'').($parts{'man'}?"<th># man<\/th>":'')."</tr>\n". "<tr><th align=center>Package<\/th>".($parts{'po'}?"<th align=center>Score<\/th><th align=center>File<\/th><th>Translator<\/th><th>Status</th>":'').($parts{'templates'}?"<th>%<\/th><th>templates<\/th>":'').($parts{'podebconf'}?"<th align=center>Score<\/th><th align=center>File<\/th><th align=center>Translator<\/th><th align=center>Status<\/th>":'').($parts{'man'}?"<th><\/th>":'')."<\/tr>\n\n"; } die $@ if $@; my $format = "format STDOUT = \n"; if ($output_fmt == 0) { $format .= '|@<<<<<<<<<<<<<<<< |'; foreach my $part (@poparts) { $format .= '@||| |@||||||||||||| |' if ($parts{$part}); } $format .= '@||||| |' if $parts{'man'}; $format .= "@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n".'$pkg, '; foreach my $part (@poparts) { $format .= '$p{\''.$part.'\'},$d{\''.$part.'\'}, ' if ($parts{$part}); } $format .= ' $man, ' if $parts{'man'}; $format .= ' $status'." ;\n.\n"; } if ($output_fmt == 1) { $format .='<tr><td [EMAIL PROTECTED]> @* </td>'; foreach my $part (@poparts) { $format .= "<td align=center [EMAIL PROTECTED]> @* @* </td><td [EMAIL PROTECTED]> @* </td><td [EMAIL PROTECTED]> @* </td><td [EMAIL PROTECTED]> @* </td>" if ($parts{$part}); } $format .="<td [EMAIL PROTECTED]> @* </td>" if $parts{'man'}; $format .="</tr>"; $format .= "\n".'$trcolor{\'inic\'},$pkg, '; foreach my $part (@poparts) { $format .= '$trcolor{\''.$part.'\'},$p{\''.$part.'\'},$d{\''.$part.'\'},$trcolor{\''.$part.'\'}, $ffile{\''.$part.'\'},$trcolor{\''.$part.'\'}, $ftransl{\''.$part.'\'},$trcolor{\''.$part.'\'} ,$fstatus{\''.$part.'\'}, ' if ($parts{$part}); } $format .= ' $man, ' if $parts{'man'}; $format .= ";\n.\n"; } # print $format; eval $format; die $@ if $@; map { my $lang=$_; my $statusDBname = "$STATUS_FILE"; # print STDERR "Handle $lang\n" if (scalar @todo_lang > 1); $statusDBname =~ s/\$lang/$lang/g; my $statusDB = Debian::L10n::Db->new(); $statusDB->read($statusDBname,0) if $show_status; if ($output_fmt == 0) { print "Status of the ".($take_debian?"debian ":"")."packages ".($mask_done?"to do ":"")."in $lang\n\n" unless $show_total; } my %total; my $sec; my $realsec=''; my $sali; foreach $sec (@sections) { print "<h3>Section: ".$sec."</h3>"; print $format2; foreach $pkg (@todo_pkg) { # print STDERR "consider $pkg\n"; # Take only packages having material next unless $data->has_po($pkg) || $data->has_templates($pkg) || $data->has_podebconf($pkg) || $data->has_man($pkg) || $show_empty; $realsec=$data->section($pkg); #if ($data->section($pkg) =~/\//) { if (defined $realsec) { if ($realsec =~/\//) { $realsec=~ s/\/.*//; } else { $realsec="main"; } } next unless defined $realsec; next unless $sec eq $realsec; my $pdc_data; foreach my $part (@poparts) { $ffile{$part}='---'; $ftransl{$part}='---'; } foreach my $part (@poparts) { # $fstatus{$part}=''; my $has_part="has_$part"; #$p{$part}=''; #$d{$part}=''; if ($parts{$part} && $data->$has_part($pkg)) { foreach $pdc_data (@{$data->$part($pkg)}) { if(@{$pdc_data}[1] eq $lang ) { if (defined @{$pdc_data}[4]) { [EMAIL PROTECTED]; [EMAIL PROTECTED]; $ftransl{$part} =~ s/<.*>//; # Extract translator name. $ftransl{$part} .= " "; while ($ffile{$part}=~ /\//) { $ffile{$part} =~ s/^.*\///; } # print "Trad: ".$transl; } } } } } # Take only debian packages if ($take_debian) { next if ($data->has_upstream($pkg) && $data->upstream($pkg) ne "debian"); next unless ($data->has_version($pkg)); next if ($data->version($pkg) =~ m/-/); } # Take only packages having material in this language (unless --empty) my $found=0; $man=' '; my (%score,%ori); $status=''; $trinic='n'; foreach my $part (@poparts) { # $fstatus{$part}=''; $trcolor{$part}="\#ffffff"; my $has_part="has_$part"; $p{$part}=''; $d{$part}=''; if ($parts{$part} && $data->$has_part($pkg)) { my $bts_reported=0; # $status .= "$part("; $score{$part} = '---'; if ($show_status && $statusDB->has_package($pkg) && $statusDB->has_status($pkg)) { foreach my $statusline (@{$statusDB->status($pkg)}) { my ($kind,$file,$date,$status_from_db,$translator,$url,$bug_nb) = @{$statusline}; if ($kind eq $part) { my $days = "??"; if ($date =~ m/^(\d{4})-(\d\d)-(\d\d) (\d*):(\d*):(\d*)/) { # 2003-07-26 $days = sprintf "%.0f", (time - timelocal ($6,$5,$4,$3,$2-1,$1)) / (60 * 60 * 24); } if (! (defined $bug_nb)) {$bug_nb="";} $status .= "<a href=$url>$status_from_db, \#$bug_nb<\/a> ($days days)"; $bts_reported = 1 if ($status_from_db =~ m/bts/i) || ($status_from_db =~ m/done/i || ($status_from_db =~ m/lcfc/i)) ; } } } $status .= ' '; $status =~ s/ \)/)/; $status =~ s/\'\}//; $status =~ s/$part\(\)//; $fstatus{$part}=$status; foreach my $line (@{$data->$part($pkg)}){ my ($pofile, $langfound, $stat) = @{$line}; if ($langfound eq $lang) { $score{$part} = $stat; if ($mask_done) { unless (($assume_bts && $bts_reported) || (output_percent($stat) eq '100%')) { $found = 1; } } else { $found = 1; } } elsif ($langfound eq '_') { $ori{$part} = add_stat($stat, $ori{$part}); } } if ($score{$part} eq '---' && defined($ori{$part})) { $score{$part} = $ori{$part}; $found = 1 if $show_empty && !($assume_bts && $bts_reported); } # print STDERR "show_empty=$show_empty; assume_bts=$assume_bts; bts_reported=$bts_reported; found=$found\n"; $p{$part}=output_percent($score{$part}); $d{$part}=output_details($score{$part}); $tpercent="0\%"; $tpercent=$p{$part}; if (!($tpercent =~/\%/)) { $tpercent="0%"; } $tpercent=~ s/\%//; $trcolor{$part}="\#ffffff"; if ($tpercent > 0 ) {$trcolor{$part}="\#ff0000";} if ($tpercent > 20) {$trcolor{$part}="\#ff9200";} if ($tpercent > 35) {$trcolor{$part}="\#ffdb00";} if ($tpercent > 50) {$trcolor{$part}="\#dbff00";} if ($tpercent > 65) {$trcolor{$part}="\#92ff00";} if ($tpercent > 75) {$trcolor{$part}="\#00ff00";} $view=0; foreach my $trans (@trans_s) { if ($tpercent == 100 && $trans eq "done" ) { $view=1; } if ($tpercent < 100 && $tpercent > 0 && $trans eq "underway" ) { $view=2; } if ($tpercent == 0 && $trans eq "todo" ) { $view=3; } } if ($trinic eq "n") { $trcolor{'inic'}=$trcolor{$part}; $trinic="y"; } if (defined $score{$part} && $score{$part} ne '---') { if ($assume_bts) { my $stat_to_add=$score{$part}; if ($bts_reported) { $stat_to_add =~ /([0-9]*)t([0-9]*)f([0-9]*)u/; $stat_to_add = ($1+$2+$3)."t0f0u"; } $total{$part} = add_stat($stat_to_add,$total{$part}) if ($view); } else { $total{$part} = add_stat($score{$part},$total{$part}) if ($view); } } } } # Search for mans if ($parts{'man'} && $data->has_man($pkg)) { my $en=0; my $fr=0; foreach my $line (@{$data->man($pkg)}){ my ($name, $langfound) = @{$line}; $en++ if ($langfound eq 'english'); $fr++ if ($langfound eq 'french'); } $man="$fr/$en"; $man_fr_total += $fr; $man_en_total += $en; $found = 1 unless $mask_done && $fr == $en ; } write if ($found && !$show_total && $view); } # } if ($show_total) { print "$lang: "; foreach my $part (@poparts) { print "$part(" .output_percent($total{$part}).";" .output_details($total{$part}).") " if ($parts{$part}); } print "\n"; } else { if ($output_fmt == 0) { print "|__________________|"; foreach my $part (@poparts) { print "_____|_______________|" if $parts{$part}; } print "_______|" if $parts{'man'}; print "\n"; } $pkg = "TOTAL ($lang)"; foreach my $part (@poparts) { $p{$part}=output_percent($total{$part}); $d{$part}=output_details($total{$part}); } $man="$man_fr_total/$man_en_total" if $parts{'man'}; if ($assume_bts) { $status = " Assuming that all bugs reported were applied"; } else { $status = ""; } write; # borra percentatges foreach my $part (@poparts) { $total{$part}=''; $p{$part}=''; $d{$part}=''; } if ($output_fmt == 0) { print "|__________________|"; foreach my $part (@poparts) { print "_____|_______________|" if $parts{$part}; } print "_______|" if $parts{'man'}; print "\n\n\n"; } if ($output_fmt == 1) { print "<\/tbody><\/table>"; } } if ($output_fmt == 0) { print "When there is some ---, that means that the material exists, but is not \n". "translated to this language and that some issue (in pot file or DB) prevent to find the amount of string.\n\n"; print "Significance of the 'details' columns:\n". " [# translated strings]/[# fuzzy translation]/[# untranslated strings]\n\n"; if ($parts{'man'}) { print "Significance of the 'man' column: [# french pages]/[# english pages]\n"; print "WARNING: 'french' is hardcoded in that script for now.\n"; print "WARNING: do not trust the stats about man for now.\n"; } } } } @todo_lang; sub add_stat { my $new=shift; my $old=shift; return $new unless defined($old); $new =~ /([0-9]*)t([0-9]*)f([0-9]*)u/; my ($nt,$nf,$nu) = ($1||0, $2||0, $3||0); $old =~ /([0-9]*)t([0-9]*)f([0-9]*)u/; my ($ot,$of,$ou) = ($1||0, $2||0, $3||0); my $res= ($nt+$ot)."t".($nf+$of)."f".($nu+$ou)."u"; # print STDERR "$new + $old = $res\n"; return $res; } sub output_percent { my $stats=shift||""; my $t = "0"; my $u = "0"; my $f = "0"; my $percent; if ($stats =~ /([0-9]*)t/) { $t=$1; } if ($stats =~ /([0-9]*)u/) { $u=$1; } if ($stats =~ /([0-9]*)f/) { $f=$1; } $percent = calc_percent($t,$t+$u+$f); if ($percent eq "NaN" || $percent == 0) { return ''; } return "$percent\%"; } sub output_details { my $stats = shift||""; my $t = "0"; my $u = "0"; my $f = "0"; my $percent; if ($stats =~ /([0-9]*)t/) { $t=$1; } if ($stats =~ /([0-9]*)u/) { $u=$1; } if ($stats =~ /([0-9]*)f/) { $f=$1; } return ($t+$f+$u == 0 ? $stats : "$t/$f/$u"); } sub calc_percent{ my $up=shift; my $down=shift; my $res; if ($down==0) { return "NaN"; } $res = $up/$down*100; $res =~ s/^([0-9]*)\..*/$1/; return $res; }
--- End Message ---
signature.asc
Description: Digital signature