External storage handling
[lhc/web/wiklou.git] / maintenance / transstat.php
1 <?php
2 /**
3 * @package MediaWiki
4 * @subpackage Maintenance
5 *
6 * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
7 * @author Ashar Voultoiz <thoane@altern.org>
8 * @bug 2499
9 *
10 * Output is posted from time to time on:
11 * http://meta.wikimedia.org/wiki/Localization_statistics
12 */
13
14 /** */
15 require_once('commandLine.inc');
16 if( isset($options['help']) ) { usage(); die(); }
17 // default output is WikiText
18 if( !isset($options['output']) ) { $options['output']='wiki'; }
19
20
21 /** Print a usage message*/
22 function usage() {
23 print <<<END
24 Usage: php transstat.php [--help] [--output:csv|text|wiki] [--noredundant]
25 --help : this helpful message
26 --output : select an output engine one of:
27 * 'csv' : Comma Separated Values.
28 * 'wiki' : MediaWiki syntax.
29 * 'text' : Text with tabs.
30 Default output is 'wiki'
31 --noredundant : do NOT calculate redundant (takes some time)
32
33
34 END;
35 }
36
37
38 /** A general output object. Need to be overriden */
39 class statsOutput {
40 var $output; // buffer that contain the text
41 function statsOutput() { $this->output='';}
42 function getContent() { return $this->output;}
43
44 function formatPercent($subset, $total, $revert=false, $accuracy=2) {
45 return @sprintf( '%.' . $accuracy . 'f%%', 100 * $subset / $total );
46 }
47
48 // Override the next methods
49 function heading() {}
50 function footer() {}
51 function blockstart() {}
52 function blockend() {}
53 function element($in, $heading=false) {}
54 }
55
56
57 /** Outputs WikiText */
58 class wikiStatsOutput extends statsOutput {
59 function heading() {
60 $this->output .= "{| border=2 cellpadding=4 cellspacing=0 style=\"background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse;\" width=100%\n";
61 }
62 function footer() { $this->output .= "|}\n"; }
63 function blockstart() { $this->output .= "|-\n"; }
64 function blockend() { $this->output .= ''; }
65 function element($in, $heading = false) {
66 $this->output .= ($heading ? '!' : '|') . " $in\n";
67 }
68 function formatPercent($subset, $total, $revert=false, $accuracy=2) {
69 $v = @round(255 * $subset / $total);
70 if($revert) $v = 255 - $v;
71 if($v < 128) {
72 // red to yellow
73 $red = 'FF';
74 $green = sprintf('%02X', 2*$v);
75 } else {
76 // yellow to green
77 $red = sprintf('%02X', 2*(255 -$v) );
78 $green = 'FF';
79 }
80 $blue = '00';
81 $color = $red.$green.$blue;
82
83 $percent = statsOutput::formatPercent($subset, $total, $revert, $accuracy);
84 return 'bgcolor="#'.$color.'" | '.$percent;
85 }
86 }
87
88 /** Output text. To be used on a terminal for example. */
89 class textStatsOutput extends statsOutput {
90 function element($in, $heading = false) {
91 $this->output .= $in."\t";
92 }
93 function blockend(){ $this->output .="\n";}
94 }
95
96 /** csv output. Some people love excel */
97 class csvStatsOutput extends statsOutput {
98 function element($in, $heading = false) {
99 $this->output .= $in.";";
100 }
101 function blockend(){ $this->output .="\n";}
102 }
103
104
105 /** FIXME: This takes an obscene amount of time */
106 if(isset($options['noredundant'])) {
107 function redundant(&$arr) { return 'NC'; }
108 } else {
109 function redundant(&$arr) {
110 global $wgAllMessagesEn;
111
112 $redundant = 0;
113 foreach(array_keys($arr) as $key) {
114 if ( ! array_key_exists( $key, $wgAllMessagesEn) )
115 ++$redundant;
116 }
117 return $redundant;
118 }
119 }
120
121 // Select an output engine
122 switch ($options['output']) {
123 case 'csv':
124 $out = new csvStatsOutput(); break;
125 case 'text':
126 $out = new textStatsOutput(); break;
127 case 'wiki':
128 $out = new wikiStatsOutput(); break;
129 default:
130 usage(); die();
131 break;
132 }
133
134 // available language files
135 $langs = array();
136 $dir = opendir("$IP/languages");
137 while ($file = readdir($dir)) {
138 if (preg_match("/Language(.*?)\.php$/", $file, $m)) {
139 $langs[] = $m[1];
140 }
141 }
142 sort($langs);
143
144 // Cleanup file list
145 foreach($langs as $key => $lang) {
146 if ($lang == 'Utf8' || $lang == '' || $lang == 'Converter')
147 unset($langs[$key]);
148 }
149
150 // Load message and compute stuff
151 $msgs = array();
152 foreach($langs as $lang) {
153 // Since they aren't loaded by default..
154 require_once( 'languages/Language' . $lang . '.php' );
155 $arr = 'wgAllMessages' . $lang;
156 if (@is_array($$arr)) { // Some of them don't have a message array
157 $msgs[$wgContLang->lcfirst($lang)] = array(
158 'total' => count($$arr),
159 'redundant' => redundant($$arr),
160 );
161 } else {
162 $msgs[$wgContLang->lcfirst($lang)] = array(
163 'total' => 0,
164 'redundant' => 0,
165 );
166 }
167 }
168
169 // Top entry
170 $out->heading();
171 $out->blockstart();
172 $out->element('Language', true);
173 $out->element('Translated', true);
174 $out->element('%', true);
175 $out->element('Untranslated', true);
176 $out->element('%', true);
177 $out->element('Redundant', true);
178 $out->element('%', true);
179 $out->blockend();
180
181 // Generate rows
182 foreach($msgs as $lang => $stats) {
183 $out->blockstart();
184 $out->element($wgContLang->getLanguageName(strtr($lang, '_', '-')) . " ($lang)"); // Language
185 $out->element($stats['total'] . '/' . $msgs['en']['total']); // Translated
186 $out->element($out->formatPercent($stats['total'], $msgs['en']['total'])); // % Translated
187 $out->element($msgs['en']['total'] - $stats['total']); // Untranslated
188 $out->element($out->formatPercent($msgs['en']['total'] - $stats['total'], $msgs['en']['total'], true)); // % Untranslated
189 if($stats['redundant'] =='NC') {
190 $out->element('NC');
191 $out->element('NC');
192 } else {
193 $out->element($stats['redundant'] . '/' . $stats['total']); // Redundant
194 $out->element($out->formatPercent($stats['redundant'], $stats['total'],true)); // % Redundant
195 }
196 $out->blockend();
197 }
198 $out->footer();
199
200 // Final output
201 echo $out->getContent();
202 ?>