/[webwml]/webwml/stattrans.pl
ViewVC logotype

Contents of /webwml/stattrans.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.110 - (show annotations) (download)
Mon Jun 18 09:30:04 2012 UTC (11 months ago) by porridge
Branch: MAIN
Changes since 1.109: +16 -4 lines
File MIME type: text/plain
Mention the host and time for hit data on stats pages.
1 #! /usr/bin/perl
2
3 # webwml-stattrans - Debian web site translation statistics
4 # Copyright (c) 2001 Martin Schulze <joey@debian.org> and others
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 use POSIX qw(strftime);
21 use Getopt::Std;
22
23 # These modules reside under webwml/Perl
24 use lib ($0 =~ m|(.*)/|, $1 or ".") ."/Perl";
25 use Local::Cvsinfo;
26 use Webwml::Langs;
27 use Webwml::TransCheck;
28 use Webwml::TransIgnore;
29 use Debian::L10n::Db ('%LanguageList');
30 use Net::Domain qw(hostfqdn);
31
32 BEGIN {
33 $dde_available = 0;
34 eval {
35 require JSON;
36 require LWP::Simple;
37 LWP::Simple->import;
38 $dde_available = 1;
39 }; if ($@) {
40 warn "One or more modules required for DDE support failed to load: $@\n";
41 }
42 }
43
44
45 $| = 1;
46
47 $opt_h = "/srv/www.debian.org/webwml/english/devel/website/stats";
48 $opt_w = "/srv/www.debian.org/webwml";
49 $opt_p = "*.(wml|src)";
50 $opt_t = '<stats_title>';
51 $opt_v = 0;
52 $opt_d = "u";
53 $opt_l = undef;
54 $opt_b = ""; # Base URL, if not debian.org
55 # URL of JSON data or path to plaintext file with lines: "1299999 /doc/index\n"
56 $opt_f = "http://dde.debian.net/dde/q/static/porridge/stats?t=json";
57 getopts('h:w:b:p:t:vd:l:f:') || die;
58 # Replace filename globbing by Perl regexps
59 $opt_p =~ s/\./\\./g;
60 $opt_p =~ s/\?/./g;
61 $opt_p =~ s/\*/.*/g;
62 $opt_p =~ s/$/\$/g;
63 %config = (
64 'htmldir' => $opt_h,
65 'wmldir' => $opt_w,
66 'wmlpat' => $opt_p,
67 'title' => $opt_t,
68 'verbose' => $opt_v,
69 'difftype'=> $opt_d,
70 'hit_file'=> $opt_f,
71 );
72
73 my $l = Webwml::Langs->new($opt_w);
74 my %langs = $l->name_iso();
75
76 my $transignore = Webwml::TransIgnore->new($opt_w);
77
78 my $cvs = Local::Cvsinfo->new();
79 $cvs->options(
80 recursive => 1,
81 matchfile => [ $config{'wmlpat'} ],
82 skipdir => [ "template" ],
83 );
84 $cvs->readinfo("$config{'wmldir'}/english");
85 foreach (@{$transignore->global()}) {
86 $cvs->removefile("$config{'wmldir'}/english/$_");
87 }
88
89 my $altcvs = Local::Cvsinfo->new();
90 $altcvs->options(
91 recursive => 1,
92 matchfile => [ $config{'wmlpat'} ],
93 skipdir => [ "template" ],
94 );
95
96 $max_versions = 5;
97 $min_versions = 1;
98
99
100 $date = strftime "%a %b %e %H:%M:%S %Y %z", localtime;
101
102 my %original;
103 my %transversion;
104 my %version;
105 my %files;
106 my %sizes;
107
108 print "Loading the coordination status databases\n" if ($config{verbose});
109 my %status_db = ();
110 opendir (DATADIR, "$opt_w/english/international/l10n/data")
111 or die "Cannot open directory $opt_w/english/international/l10n/data: $!\n";
112 foreach (readdir (DATADIR)) {
113 # Only check the status files
114 next unless ($_ =~ m/^status\.(.*)$/);
115 my $l = $1;
116 next if (!defined $LanguageList{uc $l});
117 if (-r "$opt_w/english/international/l10n/data/status.$l") {
118 $status_db{$LanguageList{uc $l}} = Debian::L10n::Db->new();
119 $status_db{$LanguageList{uc $l}}->read("$opt_w/english/international/l10n/data/status.$l", 0);
120 }
121 }
122 closedir (DATADIR);
123
124 sub linklist {
125 my ($file, $lang) = @_;
126 my $add = "";
127 if ($status_db{$lang}->has_package('www.debian.org')
128 and $status_db{$lang}->has_status('www.debian.org')) {
129 foreach my $statusline (@{$status_db{$lang}->status('www.debian.org')}) {
130 my ($type, $statfile, $date, $status, $translator, $list, $url, $bug_nb) = @{$statusline};
131 if ($file eq $statfile) {
132 $date =~ s/\s*\+0000$//;
133 $list =~ /^(\d\d\d\d)-(\d\d)-(\d\d\d\d\d)$/;
134 $add = "<a href=\"http://lists.debian.org/debian-l10n-$lang/$1/debian-l10n-$lang-$1$2/msg$3.html\">$status</a>";
135 $add = "<td>$add</td><td>$translator</td><td>$date</td>";
136 }
137 }
138 }
139 $add = '<td></td><td></td><td></td>' if (!length $add);
140 return $add;
141 }
142
143 # Count wml files in given directory
144 #
145 sub getwmlfiles
146 {
147 my $lang = shift;
148 my $dir = "$config{'wmldir'}/$lang";
149 my $cutfrom = length ($config{'wmldir'})+length($lang)+2;
150 my $count = 0;
151 my $size = 0;
152 my $is_english = ($lang eq "english")?1:0;
153 my ( $file, $v );
154 my @listfiles;
155
156 print "$lang " if ($config{verbose});
157 if (! -d "$dir") {
158 print "$0: can't find $dir! Skipping ...\n";
159 return;
160 }
161 if ($is_english) {
162 @listfiles = @{$cvs->files()};
163 } else {
164 $altcvs->reset();
165 $altcvs->readinfo($dir);
166 @listfiles = @{$altcvs->files()};
167 }
168 foreach my $f (@listfiles) {
169 $file = substr ($f, $cutfrom);
170 next if $transignore->is_global($file);
171 $files{$file} = 1;
172 $wmlfiles{$lang} .= " " . $file;
173 my $transcheck = Webwml::TransCheck->new("$dir/$file");
174 if ($transcheck->revision()) {
175 $transversion{"$lang/$file"} = $transcheck->revision();
176 $original{"$lang/$file"} ||= $transcheck->original();
177 }
178 if ($is_english) {
179 $version{"$lang/$file"} = $cvs->revision($f);
180 } else {
181 $version{"$lang/$file"} = $altcvs->revision($f);
182 if (!$transcheck->revision()) {
183 $transcheckenglish = Webwml::TransCheck->new("english/$file");
184 if (!$transcheckenglish->revision() and (-e "english/$file")) {
185 $transversion{"$lang/$file"} = "1.1";
186 $original{"$lang/$file"} = "english";
187 } else {
188 $original{"english/$file"} = $lang;
189 $transversion{"english/$file"} ||= "1.1";
190 }
191 }
192 }
193 if ($transcheck->maintainer()) {
194 $maintainer{"$lang/$file"} = $transcheck->maintainer();
195 }
196 $count++;
197 $sizes{$file} = (stat "".($original{"english/$file"}||"english")."/".$file)[7];
198 $size += $sizes{$file};
199 }
200 $wmlfiles{$lang} .= " ";
201 $wml{$lang} = $count;
202 $wml_s{$lang} = $size;
203 }
204
205 sub get_color
206 {
207 my $percent = shift;
208
209 if ($percent < 50) {
210 return sprintf ("#FF%02x00", (255/50) * $percent);
211 } else {
212 return sprintf ("#%02xFF00", (255/50) * (100 - $percent));
213 }
214 }
215
216 sub check_translation
217 {
218 my ($translation, $version, $file) = @_;
219 my ( @version_numbers, $major_number, $last_number );
220 my ( @translation_numbers, $major_translated_number, $last_translated_number );
221
222 if ( $version && $translation ) {
223 @version_numbers = split /\./,$version;
224 $major_number = $version_numbers[0];
225 $last_number = pop @version_numbers;
226 die "Invalid CVS revision for $file: $version\n"
227 unless ($major_number =~ /\d+/ && $last_number =~ /\d+/);
228
229 @translation_numbers = split /\./,$translation;
230 $major_translated_number = $translation_numbers[0];
231 $last_translated_number = pop @translation_numbers;
232 die "Invalid translation revision for $file: $translation\n"
233 unless ($major_translated_number =~ /\d+/ && $last_translated_number =~ /\d+/);
234
235 # Here we compare the original version with the translated one and print
236 # a note for the user if their first or last numbers are too far apart
237 # From translation-check.wml
238
239 if ( $major_number != $major_translated_number ) {
240 return '<gettext domain="stats">This translation is too out of date</gettext>';
241 } elsif ( $last_number - $last_translated_number < 0 ) {
242 return '<gettext domain="stats">Wrong translation version</gettext>';
243 } elsif ( $last_number - $last_translated_number >= $max_versions ) {
244 return '<gettext domain="stats">This translation is too out of date</gettext>';
245 } elsif ( $last_number - $last_translated_number >= $min_versions ) {
246 return '<gettext domain="stats">The original is newer than this translation</gettext>';
247 }
248 } elsif ( !$version && $translation) {
249 return '<gettext domain="stats">The original no longer exists</gettext>';
250 }
251 return "";
252 }
253
254 print "Collecting data in: " if ($config{'verbose'});
255 if ($opt_l) {
256 getwmlfiles ($opt_l);
257 getwmlfiles ('english');
258 } else {
259 foreach $lang (keys %langs) {
260 getwmlfiles ($lang);
261 }
262 }
263 print "\n" if ($config{'verbose'});
264
265 my @search_in;
266 if ($opt_l) {
267 @search_in = ( 'english', $opt_l );
268 } else {
269 @search_in = sort keys %langs;
270 }
271
272 # Compute stats about gettext files
273 print "Computing statistics in gettext files... " if ($config{'verbose'});
274 my ( %po_translated, %po_fuzzy, %po_untranslated, %po_total );
275 my ( %percent_po_t, %percent_po_u, %percent_po_f );
276 foreach $lang (@search_in) {
277 next if $lang eq 'english';
278 $po_translated{"total"}{$lang} = $po_fuzzy{"total"}{$lang} = $po_untranslated{"total"}{$lang} = 0;
279 $percent_po_t{'total'}{$lang} = 0;
280 $percent_po_f{'total'}{$lang} = 0;
281 $percent_po_u{'total'}{$lang} = 100;
282 if (! -d "$opt_w/$lang/po") {
283 print "$0: can't find $opt_w/$lang/po! Skipping ...\n";
284 next;
285 }
286 my @status = qx,LC_ALL=C make -C $opt_w/$lang/po stats 2>&1 1>/dev/null,;
287 foreach $line (@status) {
288 chomp $line;
289 ($domain = $line) =~ s/\..*//;
290 $po_translated{$domain}{$lang} = ($line =~ /(\d+) translated/ ? $1 : "0");
291 $po_fuzzy{$domain}{$lang} = ($line =~ /(\d+) fuzzy/ ? $1 : "0");
292 $po_untranslated{$domain}{$lang} = ($line =~ /(\d+) untranslated/ ? $1 : "0");
293
294 $po_total{$domain} = $po_translated{$domain}{$lang} + $po_fuzzy{$domain}{$lang} + $po_untranslated{$domain}{$lang};
295
296 $po_translated{"total"}{$lang} += $po_translated{$domain}{$lang};
297 $po_fuzzy{"total"}{$lang} += $po_fuzzy{$domain}{$lang};
298 $po_untranslated{"total"}{$lang} += $po_untranslated{$domain}{$lang};
299
300 if ($po_total{$domain} > 0) {
301 $percent_po_t{$domain}{$lang} = int ($po_translated{$domain}{$lang}/$po_total{$domain} * 100 + .5);
302 $percent_po_f{$domain}{$lang} = int ($po_fuzzy{$domain}{$lang}/$po_total{$domain} * 100 + .5);
303 $percent_po_u{$domain}{$lang} = int ($po_untranslated{$domain}{$lang}/$po_total{$domain} * 100 + .5);
304 } else {
305 $percent_po_t{$domain}{$lang} = 0;
306 $percent_po_f{$domain}{$lang} = 0;
307 $percent_po_u{$domain}{$lang} = 0; # or 100 if po/ doesn't exist
308 }
309 }
310 $po_total{"total"} = $po_translated{"total"}{$lang} + $po_fuzzy{"total"}{$lang} + $po_untranslated{"total"}{$lang};
311
312 if ($po_total{'total'} > 0) {
313 $percent_po_t{'total'}{$lang} = int ($po_translated{'total'}{$lang}/$po_total{'total'} * 100 + .5);
314 $percent_po_f{'total'}{$lang} = int ($po_fuzzy{'total'}{$lang}/$po_total{'total'} * 100 + .5);
315 $percent_po_u{'total'}{$lang} = int ($po_untranslated{'total'}{$lang}/$po_total{'total'} * 100 + .5);
316 }
317 }
318 print "done.\n" if ($config{'verbose'});
319
320 # =============== Create HTML files ===============
321 mkdir ($config{'htmldir'}, 02775) if (! -d $config{'htmldir'});
322
323 # Read website hit statistics, if available
324 my %hits;
325 my $hits_hostname;
326 my $hits_datetime;
327 my $file_sorter = sub($$) { $_[0] cmp $_[1] };
328 if ($config{'hit_file'} and $config{'hit_file'} =~ m{^(f|ht)tps?://} and ! $dde_available) {
329 warn "Disabling fetching of hit data.\n";
330 $config{'hit_file'} = undef;
331 }
332 if ($config{'hit_file'}) {
333 if ($config{'hit_file'} =~ m{^(f|ht)tps?://}) {
334 printf("Retrieving hit data from [%s].\n", $config{'hit_file'}) if ($config{'verbose'});
335 my $json = LWP::Simple::get($config{'hit_file'});
336 if ($json) {
337 my $perl = JSON::from_json($json, {utf8 => 1});
338 my %metadata = %{$perl->{'m'}};
339 $hits_hostname = $metadata{'hostname'} || undef;
340 $hits_datetime = defined $metadata{'Last-Modified'} ? strftime "%Y-%m-%d %T GMT", gmtime $metadata{'Last-Modified'} : undef;
341 foreach my $e (@{$perl->{'r'}}) {
342 my ($count, $url) = @$e;
343 last if $count < 3; # URLS with 2 or 1 hits are most likely mistakes; let's not waste RAM on them
344 $hits{substr($url, 1)} = $count;
345 }
346 } else {
347 warn "Retrieving hit data failed.\n";
348 }
349 } else {
350 $hits_hostname = hostfqdn;
351 $hits_datetime = strftime "%Y-%m-%d %T %Z", localtime;
352 open(HITS, $config{'hit_file'}) or die sprintf("Opening hit file [%s] failed: $!", $config{'hit_file'});
353 printf "Reading hit file [%s]\n", $config{'hit_file'} if ($config{'verbose'});
354 foreach my $hit_line (<HITS>) {
355 chomp $hit_line;
356 $hit_line =~ /^\s*(\d+)\s+(.*)/ or warn sprintf("unrecognized hit file [%s] line [%s]", $config{'hit_file'}, $hit_line);
357 my ($count, $url) = ($1, $2);
358 last if $count < 3; # URLS with 2 or 1 hits are most likely mistakes; let's not waste RAM on them
359 $hits{substr($url, 1)} = $count;
360 }
361 close(HITS) or die sprintf("Closing hit file [%s] failed: $!", $config{'hit_file'});
362 }
363 if (%hits) {
364 $file_sorter = sub($$) {
365 my ($a, $b) = @_;
366 $a =~ s/\.wml$//o;
367 $b =~ s/\.wml$//o;
368 $hits{$b} <=> $hits{$a}
369 };
370 } else {
371 print "Tables will be sorted alphabetically.\n" if ($config{'verbose'});
372 }
373 } else {
374 print "No hit file specified. Tables will be sorted alphabetically.\n" if ($config{'verbose'});
375 }
376
377 my @filenames = sort $file_sorter keys %files;
378 my $nfiles = scalar @filenames;
379 $nsize += $sizes{$_} foreach (@filenames);
380
381 my $firstdifftype;
382 my $seconddifftype;
383 if ($config{'difftype'} eq 'u') {
384 $firstdifftype = 'u';
385 $seconddifftype = 'h';
386 } else {
387 $firstdifftype = 'h';
388 $seconddifftype = 'u';
389 }
390
391 print "Creating files: " if ($config{'verbose'});
392 foreach $lang (@search_in) {
393 my @processed_langs = ($langs{$lang});
394 @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh";
395 foreach $l (@processed_langs) {
396 print "$l.wml " if ($config{'verbose'});
397
398 $charset{$lang};
399 open (wmlrc,"$opt_w/$lang/.wmlrc") ;
400 while (<wmlrc>) {
401 if ( /^-D CHARSET=(.*)$/ ) {
402 $charset{$lang} = $1;
403 }
404 }
405 close wmlrc ;
406
407 $t_body = $u_body = $ui_body = $un_body = $uu_body = $o_body = "";
408 $translated{$lang} = $outdated{$lang} = $untranslated{$lang} = 0;
409
410 # get stats about files
411 foreach $file (@filenames) {
412 next if ($file eq "");
413 (my $base = $file) =~ s/\.wml$//;
414 my $hits = exists $hits{$base} ? $hits{$base}.' <gettext domain="stats">hits</gettext>' : '<gettext domain="stats">hit count N/A</gettext>';
415 my $todo = '<td></td><td></td><td></td>';
416 $todo = linklist($file, $lang) if defined $status_db{$lang};
417 # Translated pages or already WIP in translation list
418 if ((index ($wmlfiles{$lang}, " $file ") >= 0) or (($todo ne '<td></td><td></td><td></td>') and ($transversion{"$lang/$file"} ne $version{"$orig/$file"}))) {
419 $translated{$lang}++;
420 $translated_s{$lang} += $sizes{$file};
421 $orig = $original{"$lang/$file"} || "english";
422 # Outdated translations
423 $msg = check_translation ($transversion{"$lang/$file"}, $version{"$orig/$file"}, "$lang/$file");
424 if (length ($msg) or (($todo ne '<td></td><td></td><td></td>') and ($transversion{"$lang/$file"} ne $version{"$orig/$file"}))) {
425 $o_body .= "<tr>";
426 if (($file !~ /\.wml$/)
427 || ($file eq "devel/wnpp/wnpp.wml")) {
428 $o_body .= sprintf "<td>%s</td>", $file;
429 } else {
430 $o_body .= sprintf "<td><a title=\"%s\" href=\"$opt_b/%s\">%s</a></td>", $hits, $base, $base;
431 }
432 my $stattd = sprintf '<td style=\'font-family: monospace\' title=\'<gettext domain="stats">Click to fetch diffstat data</gettext>\' onClick="setDiffstat(\'%s\', \'%s\', \'%s\', this)">+/-</td>', $file, $transversion{"$lang/$file"}, $version{"$orig/$file"};
433 my $statspan = sprintf '(<span style=\'font-family: monospace\' title=\'<gettext domain="stats">Click to fetch diffstat data</gettext>\' onClick="setDiffstat(\'%s\', \'%s\', \'%s\', this)">+/-</span>)', $file, $transversion{"$lang/$file"}, $version{"$orig/$file"};
434 if (!defined $status_db{$lang}) {
435 $o_body .= sprintf "<td>%s</td>", $msg;
436 $o_body .= $stattd;
437 }
438 if ($msg eq '<gettext domain="stats">Wrong translation version</gettext>' || $msg eq '<gettext domain="stats">The original no longer exists</gettext>') {
439 if (defined $status_db{$lang}) {
440 $o_body .= sprintf "<td>%d (%.2f&nbsp;&permil;)</td>", $sizes{$file}, $sizes{$file}/$nsize * 1000;
441 } else {
442 $o_body .= "<td></td><td></td>";
443 }
444 } else {
445 if (defined $status_db{$lang}) {
446 if ($transversion{"$lang/$file"} ne ''){
447 $o_body .= sprintf '<td><a title=\'<gettext domain="stats">Unified diff</gettext>\' href="http://alioth.debian.org/scm/viewvc.php/webwml/%s?root=webwml&amp;view=diff&amp;r1=%s&amp;r2=%s&amp;diff_format=u">%s&nbsp;→&nbsp;%s</a> ',
448 "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, $transversion{"$lang/$file"}, $version{"$orig/$file"};
449 $o_body .= sprintf '<a title=\'<gettext domain="stats">Colored diff</gettext>\' href="http://alioth.debian.org/scm/viewvc.php/webwml/%s?root=webwml&amp;view=diff&amp;r1=%s&amp;r2=%s&amp;diff_format=h">%s&nbsp;→&nbsp;%s</a> ',
450 "$orig/$file", $transversion{"$lang/$file"}, $version{"$orig/$file"}, $transversion{"$lang/$file"}, $version{"$orig/$file"};
451 $o_body .= "$statspan</td>";
452 } else {
453 $o_body .= sprintf "<td>%d (%.2f&nbsp;&permil;)</td>", $sizes{$file}, $sizes{$file}/$nsize * 1000;
454 }
455 } else {
456 $o_body .= sprintf "<td><a href=\"http://alioth.debian.org/scm/viewvc.php/webwml/$orig/%s?root=webwml\&amp;view=diff\&amp;r1=%s\&amp;r2=%s\&amp;diff_format=%s\">%s\&nbsp;->\&nbsp;%s</a></td>",
457 $file, $transversion{"$lang/$file"}, $version{"$orig/$file"}, $firstdifftype, $transversion{"$lang/$file"}, $version{"$orig/$file"};
458 $o_body .= sprintf "<td><a href=\"http://alioth.debian.org/scm/viewvc.php/webwml/$orig/%s?root=webwml\&amp;view=diff\&amp;r1=%s\&amp;r2=%s\&amp;diff_format=%s\">%s\&nbsp;->\&nbsp;%s</a></td>",
459 $file, $transversion{"$lang/$file"}, $version{"$orig/$file"}, $seconddifftype, $transversion{"$lang/$file"}, $version{"$orig/$file"};
460 }
461 }
462 $o_body .= sprintf "<td><a title=\"%s\" href=\"http://alioth.debian.org/scm/viewvc.php/webwml/$orig/%s?root=webwml#rev%s\">[L]</a></td>", $msg, $file, $version{"$orig/$file"};
463 $o_body .= sprintf "<td><a href=\"http://alioth.debian.org/scm/viewvc.php/webwml/%s/%s?root=webwml\&amp;view=markup\">[V]</a>\&nbsp;", $lang, $file;
464 $o_body .= sprintf "<a href=\"http://alioth.debian.org/scm/viewvc.php/*checkout*/webwml/%s/%s?root=webwml\">[F]</a></td>", $lang, $file;
465 $o_body .= sprintf "<td align=center>%s</td>", $maintainer{"$lang/$file"} || "";
466 $o_body .= $todo if (defined $status_db{$lang});
467 $o_body .= "</tr>\n";
468 $outdated{$lang}++;
469 $outdated_s{$lang} += $sizes{$file};
470 # Up-to-date translations
471 } else {
472 if (($file !~ /\.wml$/)
473 || ($file eq "devel/wnpp/wnpp.wml")) {
474 $t_body .= sprintf "<li>%s</li>\n", $file;
475 } else {
476 $t_body .= sprintf "<li><a title=\"%s\" href=\"$opt_b/%s.%s.html\">%s</a></li>\n", $hits, $base, $l, $base;
477 }
478 }
479 }
480 # Untranslated pages
481 else {
482 my $u_tmp;
483 if (($file !~ /\.wml$/)
484 || ($file eq "devel/wnpp/wnpp.wml")) {
485 $u_tmp = sprintf "<tr><td>%s</td><td>&nbsp;</td></tr>\n", $file;
486 } else {
487 $u_tmp = sprintf "<tr><td><a title=\"%s\" href=\"$opt_b/%s\">%s&nbsp;&nbsp;(%s)</a></td><td align=\"right\">%d</td><td>(%.2f&nbsp;&permil;)</td></tr>\n", $hits, $base, $base, $version{"$orig/$file"}, $sizes{$file}, $sizes{$file}/$nsize * 1000;
488 }
489 if (($file =~ /international\//) &&
490 (($file !~ /international\/index.wml$/) ||
491 ($file !~ /international\/l10n\//))) {
492 $ui_body .=$u_tmp;
493 } elsif ((($file =~ /(News|events|security|vote)\/[0-9]{4}\//) &&
494 ($file !~ /index.wml$/)) ||
495 ($file =~ /(News\/weekly\/[0-9]{4}\/|security\/undated)/)) {
496 $un_body .= $u_tmp;
497 } elsif (($file =~ /(consultants|users\/(com|edu|gov|org))\//) &&
498 ($file !~ /index.wml$/)) {
499 $uu_body .=$u_tmp;
500 } else {
501 $u_body .= $u_tmp;
502 }
503 $untranslated{$lang}++;
504 $untranslated_s{$lang} += $sizes{$file};
505 }
506 }
507
508
509 # this is where we discard the files that the translation directory contains
510 # but which don't exist in the English directory
511 # print "extra files: ".$wml{$lang}-$translated{$lang}."\n";
512 $wml{$lang} = $translated{$lang};
513 $wml_s{$lang} = $translated_s{$lang};
514 $translated{$lang} = $translated{$lang} - $outdated{$lang};
515 $translated_s{$lang} = $translated_s{$lang} - $outdated_s{$lang};
516
517 if ($nfiles > 0) {
518 $percent_a{$lang} = $wml{$lang}/$nfiles * 100;
519 } else {
520 $percent_a{$lang} = 0;
521 }
522 if ($nsize > 0) {
523 $percent_as{$lang} = $wml_s{$lang}/$nsize * 100;
524 } else {
525 $percent_as{$lang} = 0;
526 }
527 if ($wml{$lang} > 0) {
528 $percent_t{$lang} = $translated{$lang}/$wml{$lang} * 100;
529 } else {
530 $percent_t{$lang} = 0;
531 }
532 if ($wml_s{$lang} > 0) {
533 $percent_ts{$lang} = $translated_s{$lang}/$wml_s{$lang} * 100;
534 } else {
535 $percent_ts{$lang} = 0;
536 }
537 $percent_o{$lang} = 100 - $percent_t{$lang};
538 $percent_os{$lang} = 100 - $percent_ts{$lang};
539 $percent_u{$lang} = 100 - $percent_a{$lang};
540 $percent_us{$lang} = 100 - $percent_as{$lang};
541
542 if (open (HTML, ">$config{'htmldir'}/$l.wml")) {
543 printf HTML "#use wml::debian::template title=\"<:=\$trans{\$CUR_ISO_LANG}{%s}:>\"\n", $lang;
544 print HTML "#use wml::debian::toc\n";
545 print HTML "<script src='diffstat.js' type='text/javascript'></script>\n\n";
546 $color = get_color ($percent_a{$lang});
547
548 printf HTML '<table summary="<gettext domain="stats">Translation summary for</gettext> <:=$trans{$CUR_ISO_LANG}{'.$lang.'} :>" style="background-color: %s; width: 100%; font-weight: bold; margin: 0; text-align: center;">'."\n", $color;
549 print HTML "<colgroup span=\"4\" width=\"25%\"></colgroup>\n";
550
551 print HTML '<tr><th><gettext domain="stats">Translated</gettext></th><th><gettext domain="stats">Up to date</gettext></th><th><gettext domain="stats">Outdated</gettext></th><th><gettext domain="stats">Not translated</gettext></th></tr>'."\n<tr>\n";
552 printf HTML '<td>%d <gettext domain="stats">files</gettext> (%.1f%%)</td>', $wml{$lang}, $percent_a{$lang};
553 printf HTML '<td>%d <gettext domain="stats">files</gettext> (%.1f%%)</td>', $translated{$lang}, $percent_t{$lang};
554 printf HTML '<td>%d <gettext domain="stats">files</gettext> (%.1f%%)</td>', $outdated{$lang}, $percent_o{$lang};
555 printf HTML '<td>%d <gettext domain="stats">files</gettext> (%.1f%%)</td>', $untranslated{$lang}, $percent_u{$lang};
556 print HTML "</tr>\n";
557 print HTML "<tr>\n";
558 printf HTML '<td>%d <gettext domain="stats">bytes</gettext> (%.1f%%)</td>', $wml_s{$lang}, $percent_as{$lang};
559 printf HTML '<td>%d <gettext domain="stats">bytes</gettext> (%.1f%%)</td>', $translated_s{$lang}, $percent_ts{$lang};
560 printf HTML '<td>%d <gettext domain="stats">bytes</gettext> (%.1f%%)</td>', $outdated_s{$lang}, $percent_os{$lang};
561 printf HTML '<td>%d <gettext domain="stats">bytes</gettext> (%.1f%%)</td>', $nsize-$wml_s{$lang}, $percent_us{$lang};
562 print HTML "</tr>\n";
563 print HTML "</table>\n";
564
565 # Make the table of content
566 print HTML "<toc-display/>\n";
567 if (%hits) {
568 print HTML '<p><gettext domain="stats">Note: the lists of pages are sorted by popularity. Hover over the page name to see the number of hits.</gettext>';
569 if (defined $hits_hostname and defined $hits_datetime) {
570 printf HTML ' <stats_hit_source "%s" "%s">', $hits_hostname, $hits_datetime;
571 }
572 print HTML "</p>\n";
573 }
574
575 # outputs the content
576 if ($o_body) {
577 print HTML '<toc-add-entry name="outdated"><gettext domain="stats">Outdated translations</gettext></toc-add-entry>'."\n";
578 print HTML "<table summary=\"Outdated translations\" border=0 cellpadding=1 cellspacing=1>\n";
579 print HTML '<tr><th><gettext domain="stats">File</gettext></th>'."\n";
580 if (defined $status_db{$lang}) {
581 print HTML '<th><gettext domain="stats">Diff</gettext></th>';
582 } else {
583 print HTML '<th><gettext domain="stats">Comment</gettext></th>'."\n";
584 print HTML '<th><gettext domain="stats">Diffstat</gettext></th>'."\n";
585 if ($opt_d eq "u") { print HTML '<th><gettext domain="stats">Unified diff</gettext></th><th><gettext domain="stats">Colored diff</gettext></th>'; }
586 elsif ($opt_d eq "h") { print HTML '<th><gettext domain="stats">Colored diff</gettext></th><th><gettext domain="stats">Unified diff</gettext></th>'; }
587 else { print HTML '<th><gettext domain="stats">Diff</gettext></th>'; }
588 }
589 print HTML '<th><gettext domain="stats">Log</gettext></th>';
590 print HTML '<th><gettext domain="stats">Translation</gettext></th>';
591 print HTML '<th><gettext domain="stats">Maintainer</gettext></th>';
592 if (defined $status_db{$lang}) {
593 print HTML '<th><gettext domain="stats">Status</gettext></th>';
594 print HTML '<th><gettext domain="stats">Translator</gettext></th>';
595 print HTML '<th><gettext domain="stats">Date</gettext></th>';
596 }
597 print HTML "</tr>\n";
598 print HTML $o_body;
599 print HTML "</table>\n";
600 }
601 if ($u_body) {
602 print HTML '<toc-add-entry name="untranslated"><gettext domain="stats">General pages not translated</gettext></toc-add-entry>'."\n";
603 print HTML '<table summary="<gettext domain="stats">Untranslated general pages</gettext>">'."\n";
604 print HTML $u_body;
605 print HTML "</table>\n";
606 }
607 if ($un_body) {
608 print HTML '<toc-add-entry name="untranslated-news"><gettext domain="stats">News items not translated</gettext></toc-add-entry>'."\n";
609 print HTML '<table summary="<gettext domain="stats">Untranslated news items</gettext>">'."\n";
610 print HTML $un_body;
611 print HTML "</table>\n";
612 }
613 if ($uu_body) {
614 print HTML '<toc-add-entry name="untranslated-user"><gettext domain="stats">Consultant/user pages not translated</gettext></toc-add-entry>'."\n";
615 print HTML '<table summary="<gettext domain="stats">Untranslated consultant/user pages</gettext>">'."\n";
616 print HTML $uu_body;
617 print HTML "</table>\n";
618 }
619 if ($ui_body) {
620 print HTML '<toc-add-entry name="untranslated-l10n"><gettext domain="stats">International pages not translated</gettext></toc-add-entry>'."\n";
621 print HTML '<table summary="<gettext domain="stats">Untranslated international pages</gettext>">'."\n";
622 print HTML $ui_body;
623 print HTML "</table>\n";
624 }
625 if ($t_body) {
626 print HTML '<toc-add-entry name="uptodate"><gettext domain="stats">Translated pages (up-to-date)</gettext></toc-add-entry>'."\n";
627 print HTML "<ul class=\"discless\">\n";
628 print HTML $t_body;
629 print HTML "</ul>\n";
630 }
631 # outputs the gettext stats
632 if ($lang ne 'english') {
633 print HTML '<toc-add-entry name="gettext"><gettext domain="stats">Translated templates (PO files)</gettext></toc-add-entry>'."\n";
634 print HTML '<table summary="<gettext domain="stats">PO Translation Statistics</gettext>" width="100%">'."\n";
635 print HTML '<tr><th><gettext domain="stats">File</gettext></th>'."\n";
636 print HTML '<th><gettext domain="stats">Up to date</gettext></th>'."\n";
637 print HTML '<th><gettext domain="stats">Fuzzy</gettext></th>'."\n";
638 print HTML '<th><gettext domain="stats">Untranslated</gettext></th>'."\n";
639 print HTML '<th><gettext domain="stats">Total</gettext></th></tr>'."\n";
640 foreach my $domain (sort keys %po_total) {
641 next if $domain eq 'total';
642 print HTML "<tr>";
643
644 $color_t = get_color ($percent_po_t{$domain}{$lang});
645 $color_f = get_color (100 - $percent_po_f{$domain}{$lang});
646 $color_u = get_color (100 - $percent_po_u{$domain}{$lang});
647
648 print HTML "<td>$domain.$langs{$lang}.po</td>";
649 printf HTML "<td style=\"background-color: %s\" align=right>%d (%s%%)</td>", $color_t, $po_translated{$domain}{$lang}, $percent_po_t{$domain}{$lang};
650 printf HTML "<td style=\"background-color: %s\" align=right>%d (%s%%)</td>", $color_f, $po_fuzzy{$domain}{$lang}, $percent_po_f{$domain}{$lang};
651 printf HTML "<td style=\"background-color: %s\" align=right>%d (%s%%)</td>", $color_u, $po_untranslated{$domain}{$lang}, $percent_po_u{$domain}{$lang};
652 printf HTML "<td align=right>%d</td>", $po_total{$domain};
653 print HTML "</tr>\n";
654 }
655 print HTML "<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
656 print HTML '<tr><th><gettext domain="stats">Total:</gettext></th>';
657 $color_t = get_color ($percent_po_t{'total'}{$lang});
658 $color_f = get_color (100 - $percent_po_f{'total'}{$lang});
659 $color_u = get_color (100 - $percent_po_u{'total'}{$lang});
660 printf HTML "<td style=\"background-color: %s\" align=right>%d (%d%%)</td>", $color_t, $po_translated{'total'}{$lang}, $percent_po_t{'total'}{$lang};
661 printf HTML "<td style=\"background-color: %s\" align=right>%d (%d%%)</td>", $color_f, $po_fuzzy{'total'}{$lang}, $percent_po_f{'total'}{$lang};
662 printf HTML "<td style=\"background-color: %s\" align=right>%d (%d%%)</td>", $color_u, $po_untranslated{'total'}{$lang}, $percent_po_u{'total'}{$lang};
663 printf HTML "<td align=right>%d</td>", $po_total{'total'};
664 print HTML "</tr>\n";
665 print HTML "</table>\n";
666 }
667
668 print HTML '<address><gettext domain="stats">Created with</gettext> <a href="http://alioth.debian.org/scm/viewvc.php/webwml/stattrans.pl?view=markup&amp;root=webwml">webwml-stattrans</a></address>'."\n";
669 close (HTML);
670 } else {
671 print "Can't open $config{'htmldir'}/$l.wml\n";
672 }
673 }
674 }
675 print "\n" if ($config{'verbose'});
676
677 # =============== Creating index.html ===============
678 print "Creating index.wml... " if ($config{'verbose'});
679
680 open (HTMLI, ">$config{'htmldir'}/index.wml")
681 || die "Can't open $config{'htmldir'}/index.wml";
682
683 print HTMLI "#use wml::debian::stats_tags\n";
684 printf HTMLI "#use wml::debian::template title=\"%s\"\n\n", $config{'title'};
685 print HTMLI '<h2><gettext domain="stats">Translated web pages</gettext></h2>'."\n";
686 printf HTMLI "<p><stats_pages %d></p>\n",($wml{'english'}+$untranslated{'english'});
687
688 print HTMLI '<table summary="<gettext domain="stats">Translation Statistics by Page Count</gettext>" class="stattrans">'."\n";
689 print HTMLI "<colgroup width=\"20%\">\n";
690 print HTMLI "<col>\n";
691 print HTMLI "</colgroup>";
692 print HTMLI "<colgroup width=\"10%\">\n";
693 print HTMLI "<col width=\"10%\">\n";
694 print HTMLI "<col width=\"10%\">\n";
695 print HTMLI "<col width=\"10%\">\n";
696 print HTMLI "<col width=\"10%\">\n";
697 print HTMLI "<col width=\"10%\">\n";
698 print HTMLI "<col width=\"10%\">\n";
699 print HTMLI "<col width=\"10%\">\n";
700 print HTMLI "<col width=\"10%\">\n";
701 print HTMLI "</colgroup>";
702 print HTMLI "<thead>";
703 print HTMLI '<tr><th><gettext domain="stats">Language</gettext></th>'."\n";
704 print HTMLI '<th colspan="2"><gettext domain="stats">Translations</gettext></th>'."\n";
705 print HTMLI '<th colspan="2"><gettext domain="stats">Up to date</gettext></th>'."\n";
706 print HTMLI '<th colspan="2"><gettext domain="stats">Outdated</gettext></th>'."\n";
707 print HTMLI '<th colspan="2"><gettext domain="stats">Not translated</gettext></th></tr>'."\n";
708 print HTMLI "</thead>";
709 print HTMLI "<tbody>";
710 foreach $lang (@search_in) {
711 my @processed_langs = ($langs{$lang});
712 @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh";
713 foreach $l (@processed_langs) {
714 $color_a = get_color ($percent_a{$lang});
715 $color_t = get_color ($percent_t{$lang});
716 $color_o = get_color (100 - $percent_o{$lang});
717 $color_u = get_color (100 - $percent_u{$lang});
718
719 print HTMLI "<tr>";
720 printf HTMLI "<th><a href=\"%s\"><:=\$trans{\$CUR_ISO_LANG}{%s} :></a> (%s)</th>", $l, $lang, $l;
721 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_a, $wml{$lang}, $percent_a{$lang};
722 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_t, $translated{$lang}, $percent_t{$lang};
723 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_o, $outdated{$lang}, $percent_o{$lang};
724 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_u, $untranslated{$lang}, $percent_u{$lang};
725 print HTMLI "</tr>\n";
726 }
727 }
728 print HTMLI "</tbody>";
729 print HTMLI "</table>\n";
730
731 print HTMLI '<h2><gettext domain="stats">Translated web pages (by size)</gettext></h2>'."\n";
732 printf HTMLI "<p><stats_bytes %d></p>\n",($wml_s{'english'}+$untranslated_s{'english'});
733
734 print HTMLI '<table summary="<gettext domain="stats">Translation Statistics by Page Size</gettext>" class="stattrans">'."\n";
735 print HTMLI "<colgroup span=\"1\">\n";
736 print HTMLI "<col width=\"20%\">\n";
737 print HTMLI "</colgroup>";
738 print HTMLI "<colgroup span=\"8\">\n";
739 print HTMLI "<col width=\"13%\">\n";
740 print HTMLI "<col width=\"7%\">\n";
741 print HTMLI "<col width=\"13%\">\n";
742 print HTMLI "<col width=\"7%\">\n";
743 print HTMLI "<col width=\"13%\">\n";
744 print HTMLI "<col width=\"7%\">\n";
745 print HTMLI "<col width=\"13%\">\n";
746 print HTMLI "<col width=\"7%\">\n";
747 print HTMLI "</colgroup>";
748 print HTMLI "<thead>";
749 print HTMLI '<tr><th><gettext domain="stats">Language</gettext></th>'."\n";
750 print HTMLI '<th colspan="2"><gettext domain="stats">Translations</gettext></th>'."\n";
751 print HTMLI '<th colspan="2"><gettext domain="stats">Up to date</gettext></th>'."\n";
752 print HTMLI '<th colspan="2"><gettext domain="stats">Outdated</gettext></th>'."\n";
753 print HTMLI '<th colspan="2"><gettext domain="stats">Not translated</gettext></th></tr>'."\n";
754 print HTMLI "</thead>";
755 print HTMLI "<tbody>";
756
757 foreach $lang (@search_in) {
758 my @processed_langs = ($langs{$lang});
759 @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh";
760 foreach $l (@processed_langs) {
761 $color_a = get_color ($percent_a{$lang});
762 $color_t = get_color ($percent_t{$lang});
763 $color_o = get_color (100 - $percent_o{$lang});
764 $color_u = get_color (100 - $percent_u{$lang});
765
766 print HTMLI "<tr>";
767 printf HTMLI "<th><a href=\"%s\"><:=\$trans{\$CUR_ISO_LANG}{%s} :></a> (%s)</th>", $l, $lang, $l;
768 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_a, $wml_s{$lang}, $percent_as{$lang};
769 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_t, $translated_s{$lang}, $percent_ts{$lang};
770 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_o, $outdated_s{$lang}, $percent_os{$lang};
771 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%.1f%%)</td>", $color_u, $wml_s{"english"}+$untranslated_s{'english'}-$wml_s{$lang}, $percent_us{$lang};
772 print HTMLI "</tr>\n";
773 }
774 }
775 print HTMLI "</tbody>";
776 print HTMLI "</table>\n";
777
778 print HTMLI '<h2><gettext domain="stats">Translated templates (PO files)</gettext></h2>'."\n";
779 printf HTMLI "<p><stats_strings %d></p>\n",$po_total{'total'};
780
781 print HTMLI '<table summary="<gettext domain="stats">PO Translation Statistics</gettext>"class="stattrans">'."\n";
782 print HTMLI "<colgroup span=\"1\"width=\"28%\">\n";
783 print HTMLI "</colgroup>";
784 print HTMLI "<colgroup span=\"6\" width=\"12%\">\n";
785 print HTMLI "<col width=\"12%\">\n";
786 print HTMLI "<col width=\"12%\">\n";
787 print HTMLI "<col width=\"12%\">\n";
788 print HTMLI "<col width=\"12%\">\n";
789 print HTMLI "<col width=\"12%\">\n";
790 print HTMLI "<col width=\"12%\">\n";
791 print HTMLI "</colgroup>";
792 print HTMLI "<thead>";
793 print HTMLI '<tr><th><gettext domain="stats">Language</gettext></th>'."\n";
794 print HTMLI '<th colspan="2"><gettext domain="stats">Up to date</gettext></th>'."\n";
795 print HTMLI '<th colspan="2"><gettext domain="stats">Fuzzy</gettext></th>'."\n";
796 print HTMLI '<th colspan="2"><gettext domain="stats">Not translated</gettext></th></tr>'."\n";
797 print HTMLI "</thead>";
798 print HTMLI "<tbody>";
799 foreach $lang (@search_in) {
800 next if $lang eq 'english';
801 my @processed_langs = ($langs{$lang});
802 @processed_langs = ("zh-cn", "zh-tw") if $langs{$lang} eq "zh";
803 foreach $l (@processed_langs) {
804 print HTMLI "<tr>";
805 printf HTMLI "<th><a href=\"%s#gettext\"><:=\$trans{\$CUR_ISO_LANG}{%s} :></a> (%s)</th>", $l, $lang, $l;
806 $color_t = get_color ($percent_po_t{'total'}{$lang});
807 $color_f = get_color (100 - $percent_po_f{'total'}{$lang});
808 $color_u = get_color (100 - $percent_po_u{'total'}{$lang});
809 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%d%%)</td>", $color_t, $po_translated{'total'}{$lang}, $percent_po_t{'total'}{$lang};
810 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%d%%)</td>", $color_f, $po_fuzzy{'total'}{$lang}, $percent_po_f{'total'}{$lang};
811 printf HTMLI "<td style=\"background-color: %s\">%d</td><td>(%d%%)</td>", $color_u, $po_untranslated{'total'}{$lang}, $percent_po_u{'total'}{$lang};
812 print HTMLI "</tr>\n";
813 }
814 }
815
816 print HTMLI "</tbody>";
817 print HTMLI "</table>\n";
818
819 print HTMLI '<address><gettext domain="stats">Created with</gettext> <a href="http://alioth.debian.org/scm/viewvc.php/webwml/stattrans.pl?view=markup&amp;root=webwml">webwml-stattrans</a></address>'."\n";
820 close (HTMLI);
821
822 print "done.\n" if ($config{'verbose'});
823
824 # Note:
825 # Translated pages on ll.html may be higher than in index.html.
826 # This is due to the fact that some english pages were removed.
827
828 # printf "%s\n", join ("\n", keys %version);
829 # printf "%s - %s\n", $version{'german/devel/index'}, $version{'english/devel/index'};

  ViewVC Help
Powered by ViewVC 1.1.5