[ Index ] |
|
Code source de Horde 3.1.3 |
1 #!/usr/bin/php -q 2 <?php 3 /** 4 * Translation helper application for the Horde framework. 5 * 6 * For usage information call: 7 * ./translation.php help 8 * 9 * $Horde: horde/po/translation.php,v 1.91.2.16 2006/05/23 02:13:43 selsky Exp $ 10 */ 11 12 function footer() 13 { 14 global $c, $curdir; 15 16 $c->writeln(); 17 $c->writeln('Please report any bugs to i18n@lists.horde.org.'); 18 19 chdir($curdir); 20 exit; 21 } 22 23 function usage() 24 { 25 global $options, $c; 26 27 if (count($options[1]) && 28 ($options[1][0] == 'help' && !empty($options[1][1]) || 29 !empty($options[1][0]) && in_array($options[1][0], array('commit', 'compendium', 'extract', 'init', 'make', 'merge')))) { 30 if ($options[1][0] == 'help') { 31 $cmd = $options[1][1]; 32 } else { 33 $cmd = $options[1][0]; 34 } 35 $c->writeln('Usage:' . ' translation.php [options] ' . $cmd . ' [command-options]'); 36 if (!empty($cmd)) { 37 $c->writeln(); 38 $c->writeln('Command options:'); 39 } 40 switch ($cmd) { 41 case 'cleanup': 42 $c->writeln(' -l, --locale=ll_CC Use only this locale.'); 43 $c->writeln(' -m, --module=MODULE Cleanup PO files only for this (Horde) module.'); 44 break; 45 case 'commit': 46 case 'commit-help': 47 $c->writeln(' -l, --locale=ll_CC Use this locale.'); 48 $c->writeln(' -m, --module=MODULE Commit translations only for this (Horde) module.'); 49 $c->writeln(' -M, --message=MESSAGE Use this commit message instead of the default ones.'); 50 $c->writeln(' -n, --new This is a new translation, commit also CREDITS,'); 51 $c->writeln(' CHANGES and nls.php.dist.'); 52 break; 53 case 'compendium': 54 $c->writeln(' -a, --add=FILE Add this PO file to the compendium. Useful to'); 55 $c->writeln(' include a compendium from a different branch to'); 56 $c->writeln(' the generated compendium.'); 57 $c->writeln(' -d, --directory=DIR Create compendium in this directory.'); 58 $c->writeln(' -l, --locale=ll_CC Use this locale.'); 59 break; 60 case 'extract': 61 $c->writeln(' -m, --module=MODULE Generate POT file only for this (Horde) module.'); 62 break; 63 case 'init': 64 $c->writeln(' -l, --locale=ll_CC Use this locale.'); 65 $c->writeln(' -m, --module=MODULE Create a PO file only for this (Horde) module.'); 66 $c->writeln(' -c, --compendium=FILE Use this compendium file instead of the default'); 67 $c->writeln(' one (compendium.po in the horde/po directory).'); 68 $c->writeln(' -n, --no-compendium Don\'t use a compendium.'); 69 break; 70 case 'make': 71 $c->writeln(' -l, --locale=ll_CC Use only this locale.'); 72 $c->writeln(' -m, --module=MODULE Build MO files only for this (Horde) module.'); 73 $c->writeln(' -c, --compendium=FILE Merge new translations to this compendium file'); 74 $c->writeln(' instead of the default one (compendium.po in the'); 75 $c->writeln(' horde/po directory.'); 76 $c->writeln(' -n, --no-compendium Don\'t merge new translations to the compendium.'); 77 $c->writeln(' -s, --statistics Save translation statistics in a local file.'); 78 break; 79 case 'make-help': 80 case 'update-help': 81 $c->writeln(' -l, --locale=ll_CC Use only this locale.'); 82 $c->writeln(' -m, --module=MODULE Update help files only for this (Horde) module.'); 83 break; 84 case 'merge': 85 $c->writeln(' -l, --locale=ll_CC Use this locale.'); 86 $c->writeln(' -m, --module=MODULE Merge PO files only for this (Horde) module.'); 87 $c->writeln(' -c, --compendium=FILE Use this compendium file instead of the default'); 88 $c->writeln(' one (compendium.po in the horde/po directory).'); 89 $c->writeln(' -n, --no-compendium Don\'t use a compendium.'); 90 break; 91 case 'update': 92 $c->writeln(' -l, --locale=ll_CC Use this locale.'); 93 $c->writeln(' -m, --module=MODULE Update only this (Horde) module.'); 94 $c->writeln(' -c, --compendium=FILE Use this compendium file instead of the default'); 95 $c->writeln(' one (compendium.po in the horde/po directory).'); 96 $c->writeln(' -n, --no-compendium Don\'t use a compendium.'); 97 break; 98 } 99 } else { 100 $c->writeln('Usage:' . ' translation.php [options] command [command-options]'); 101 $c->writeln(str_repeat(' ', String::length('Usage:')) . ' translation.php [help|-h|--help] [command]'); 102 $c->writeln(); 103 $c->writeln('Helper application to create and maintain translations for the Horde'); 104 $c->writeln('framework and its applications.'); 105 $c->writeln('For an introduction read the file README in this directory.'); 106 $c->writeln(); 107 $c->writeln('Commands:'); 108 $c->writeln(' help Show this help message.'); 109 $c->writeln(' compendium Rebuild the compendium file. Warning: This overwrites the'); 110 $c->writeln(' current compendium.'); 111 $c->writeln(' extract Generate PO template (.pot) files.'); 112 $c->writeln(' init Create one or more PO files for a new locale. Warning: This'); 113 $c->writeln(' overwrites the existing PO files of this locale.'); 114 $c->writeln(' merge Merge the current PO file with the current PO template file.'); 115 $c->writeln(' update Run extract and merge sequent.'); 116 $c->writeln(' update-help Extract all new and changed entries from the English XML help'); 117 $c->writeln(' file and merge them with the existing ones.'); 118 $c->writeln(' cleanup Cleans the PO files up from untranslated and obsolete entries.'); 119 $c->writeln(' make Build binary MO files from the specified PO files.'); 120 $c->writeln(' make-help Mark all entries in the XML help file being up-to-date and'); 121 $c->writeln(' prepare the file for the next execution of update-help. You'); 122 $c->writeln(' should only run make-help AFTER update-help and revising the'); 123 $c->writeln(' help file.'); 124 $c->writeln(' commit Commit translations to the CVS server.'); 125 $c->writeln(' commit-help Commit help files to the CVS server.'); 126 } 127 $c->writeln(); 128 $c->writeln('Options:'); 129 $c->writeln(' -b, --base=/PATH Full path to the (Horde) base directory that should be'); 130 $c->writeln(' used.'); 131 $c->writeln(' -d, --debug Show error messages from the executed binaries.'); 132 $c->writeln(' -h, --help Show this help message.'); 133 $c->writeln(' -t, --test Show the executed commands but don\'t run anything.'); 134 } 135 136 function check_binaries() 137 { 138 global $gettext_version, $c; 139 140 $c->writeln('Searching gettext binaries...'); 141 require_once 'System.php'; 142 foreach (array('gettext', 'msgattrib', 'msgcat', 'msgcomm', 'msgfmt', 'msginit', 'msgmerge', 'xgettext') as $binary) { 143 echo $binary . '... '; 144 $GLOBALS[$binary] = System::which($binary); 145 if ($GLOBALS[$binary]) { 146 $c->writeln($c->green('found: ') . $GLOBALS[$binary]); 147 } else { 148 $c->writeln($c->red('not found')); 149 footer(); 150 } 151 } 152 $c->writeln(); 153 154 $out = ''; 155 exec($GLOBALS['gettext'] . ' --version', $out, $ret); 156 $split = explode(' ', $out[0]); 157 echo 'gettext version: ' . $split[count($split) - 1]; 158 $gettext_version = explode('.', $split[count($split) - 1]); 159 if ($gettext_version[0] == 0 && $gettext_version[1] < 12) { 160 $GLOBALS['php_support'] = false; 161 $c->writeln(); 162 $c->writeln($c->red('Warning: ') . 'Your gettext version is too old and does not support PHP natively.'); 163 $c->writeln('Not all strings will be extracted.'); 164 } else { 165 $GLOBALS['php_support'] = true; 166 $c->writeln($c->green(' ' . 'OK')); 167 } 168 $c->writeln(); 169 } 170 171 function search_file($file, $dir = '.', $local = false) 172 { 173 static $ff; 174 if (!isset($ff)) { 175 $ff = &new File_Find(); 176 } 177 178 if (substr($file, 0, 1) != DS) { 179 $file = "/$file/"; 180 } 181 182 if ($local) { 183 $files = $ff->glob($file, $dir, 'perl'); 184 $files = array_map(create_function('$file', 'return "' . $dir . DS . '" . $file;'), $files); 185 return $files; 186 } else { 187 return $ff->search($file, $dir, 'perl'); 188 } 189 } 190 191 function search_ext($ext, $dir = '.', $local = false) 192 { 193 return search_file(".+\\.$ext\$", $dir, $local); 194 } 195 196 function get_po_files($dir) 197 { 198 $langs = search_ext('po', $dir); 199 if (($key = array_search($dir . DS . 'messages.po', $langs)) !== false) { 200 unset($langs[$key]); 201 } 202 if (($key = array_search($dir . DS . 'compendium.po', $langs)) !== false) { 203 unset($langs[$key]); 204 } 205 return $langs; 206 } 207 208 function get_languages($dir) 209 { 210 global $curdir; 211 212 chdir($dir); 213 $langs = get_po_files('po'); 214 $langs = array_map(create_function('$lang', 'return str_replace("po" . DS, "", str_replace(".po", "", $lang));'), $langs); 215 chdir($curdir); 216 return $langs; 217 } 218 219 function search_applications() 220 { 221 $dirs = array(); 222 $horde = false; 223 if (@is_dir(BASE . DS . 'po')) { 224 $dirs[] = BASE; 225 $horde = true; 226 } 227 $dh = @opendir(BASE); 228 if ($dh) { 229 while ($entry = @readdir($dh)) { 230 $dir = BASE . DS . $entry; 231 if (is_dir($dir) && 232 substr($entry, 0, 1) != '.' && 233 fileinode(HORDE_BASE) != fileinode($dir)) { 234 $sub = opendir($dir); 235 if ($sub) { 236 while ($subentry = readdir($sub)) { 237 if ($subentry == 'po' && is_dir($dir . DS . $subentry)) { 238 $dirs[] = $dir; 239 if ($entry == 'horde') { 240 $horde = true; 241 } 242 break; 243 } 244 } 245 } 246 } 247 } 248 if (!$horde) { 249 array_unshift($dirs, HORDE_BASE); 250 } 251 } 252 253 return $dirs; 254 } 255 256 function strip_horde($file) 257 { 258 if (is_array($file)) { 259 return array_map(create_function('$file', 'return strip_horde($file);'), $file); 260 } else { 261 return str_replace(BASE . DS, '', $file); 262 } 263 } 264 265 function xtract() 266 { 267 global $cmd_options, $apps, $dirs, $debug, $test, $c, $gettext_version, $silence, $curdir; 268 269 foreach ($cmd_options[0] as $option) { 270 switch ($option[0]) { 271 case 'h': 272 usage(); 273 footer(); 274 case 'm': 275 case '--module': 276 $module = $option[1]; 277 break; 278 } 279 } 280 require_once 'Horde/Array.php'; 281 if ($GLOBALS['php_support']) { 282 $language = 'PHP'; 283 } else { 284 $language = 'C++'; 285 } 286 for ($i = 0; $i < count($dirs); $i++) { 287 if (!empty($module) && $module != $apps[$i]) { 288 continue; 289 } 290 printf('Extracting from %s... ', $apps[$i]); 291 chdir($dirs[$i]); 292 if ($apps[$i] == 'horde') { 293 $files = search_ext('php', '.', true); 294 foreach (array('admin', 'framework', 'lib', 'services', 'templates', 'util', 'config' . DS . 'themes') as $search_dir) { 295 $files = array_merge($files, search_ext('(php|inc|js)', $search_dir)); 296 } 297 $files = array_merge($files, search_ext('dist', 'config')); 298 $sh = $GLOBALS['xgettext'] . ' --language=' . $language . 299 ' --from-code=iso-8859-1 --keyword=_ --sort-output --copyright-holder="Horde Project"'; 300 if ($gettext_version[0] > 0 || $gettext_version[1] > 11) { 301 $sh .= ' --msgid-bugs-address="dev@lists.horde.org"'; 302 } 303 $file = $dirs[$i] . DS . 'po' . DS . $apps[$i] . '.pot'; 304 if (file_exists($file) && !is_writable($file)) { 305 $c->writeln($c->red(sprintf('%s is not writable.', $file))); 306 footer(); 307 } 308 $tmp_file = $file . '.tmp.pot'; 309 $sh .= ' -o ' . $tmp_file . ' ' . implode(' ', $files); 310 if (@file_exists($dirs[$i] . '/po/translation.php')) { 311 $sh .= ' po/translation.php'; 312 } 313 if (!$debug) { 314 $sh .= $silence; 315 } 316 if ($debug || $test) { 317 $c->writeln('Executing:'); 318 $c->writeln($sh); 319 } 320 if (!$test) exec($sh); 321 } else { 322 $files = search_ext('(php|inc|js)'); 323 $files = array_filter($files, create_function('$file', 'return substr($file, 0, 9) != "." . DS . "config" . DS;')); 324 $files = array_merge($files, search_ext('dist', 'config')); 325 $sh = $GLOBALS['xgettext'] . ' --language=' . $language . 326 ' --keyword=_ --sort-output --force-po --copyright-holder="Horde Project"'; 327 if ($gettext_version[0] > 0 || $gettext_version[1] > 11) { 328 $sh .= ' --msgid-bugs-address="dev@lists.horde.org"'; 329 } 330 $file = 'po' . DS . $apps[$i] . '.pot'; 331 if (file_exists($file) && !is_writable($file)) { 332 $c->writeln($c->red(sprintf('%s is not writable.', $file))); 333 footer(); 334 } 335 $tmp_file = $file . '.tmp.pot'; 336 $sh .= ' -o ' . $tmp_file . ' ' . implode(' ', $files) . ($debug ? '' : $silence); 337 if ($debug || $test) { 338 $c->writeln('Executing:'); 339 $c->writeln($sh); 340 } 341 if (!$test) exec($sh); 342 } 343 if (file_exists($tmp_file)) { 344 $files = search_ext('html', 'templates'); 345 if (!$test) $tmp = fopen($file . '.templates', 'w'); 346 foreach ($files as $template) { 347 $fp = fopen($template, 'r'); 348 $lineno = 0; 349 while (($line = fgets($fp, 4096)) !== false) { 350 $lineno++; 351 $offset = 0; 352 while (($left = strpos($line, '<gettext>', $offset)) !== false) { 353 $left += 9; 354 $buffer = ''; 355 $linespan = 0; 356 while (($end = strpos($line, '</gettext>', $left)) === false) { 357 $buffer .= substr($line, $left); 358 $left = 0; 359 $line = fgets($fp, 4096); 360 $linespan++; 361 if ($line === false) { 362 $c->writeln($c->red(sprintf("<gettext> tag not closed in file %s.\nOpening tag found in line %d.", $template, $lineno))); 363 break 2; 364 } 365 } 366 $buffer .= substr($line, $left, $end - $left); 367 if (!$test) { 368 fwrite($tmp, "#: $template:$lineno\n"); 369 fwrite($tmp, 'msgid "' . str_replace(array('"', "\n"), array('\"', "\\n\"\n\""), $buffer) . "\"\n"); 370 fwrite($tmp, 'msgstr ""' . "\n\n"); 371 } 372 $offset = $end + 10; 373 } 374 } 375 fclose($fp); 376 } 377 fclose($tmp); 378 $sh = $GLOBALS['msgcomm'] . " --more-than=0 --sort-output \"$tmp_file\" \"$file.templates\" --output-file \"$tmp_file\"" . $silence; 379 if ($debug || $test) { 380 $c->writeln('Executing:'); 381 $c->writeln($sh); 382 } 383 if (!$test) { 384 exec($sh); 385 unlink($file . '.templates'); 386 } 387 if (file_exists($file)) { 388 $diff = array_diff(file($tmp_file), file($file)); 389 $diff = preg_grep('/^"POT-Creation-Date:/', $diff, PREG_GREP_INVERT); 390 } 391 } 392 if (!file_exists($file) || count($diff)) { 393 @unlink($file); 394 rename($tmp_file, $file); 395 $c->writeln($c->green('updated')); 396 } else { 397 @unlink($tmp_file); 398 $c->writeln($c->bold('not changed')); 399 } 400 chdir($curdir); 401 } 402 } 403 404 function merge() 405 { 406 global $cmd_options, $apps, $dirs, $debug, $test, $c; 407 408 $compendium = ' --compendium="' . BASE . DS . 'po' . DS . 'compendium.po"'; 409 foreach ($cmd_options[0] as $option) { 410 switch ($option[0]) { 411 case 'h': 412 usage(); 413 footer(); 414 case 'l': 415 case '--locale': 416 $lang = $option[1]; 417 break; 418 case 'm': 419 case '--module': 420 $module = $option[1]; 421 break; 422 case 'c': 423 case '--compendium': 424 $compendium = ' --compendium=' . $option[1]; 425 break; 426 case 'n': 427 case '--no-compendium': 428 $compendium = ''; 429 break; 430 } 431 } 432 if (!isset($lang) && !empty($compendium)) { 433 $c->writeln($c->red('Error: ' . 'No locale specified.')); 434 $c->writeln(); 435 usage(); 436 footer(); 437 } 438 439 cleanup(); 440 441 for ($i = 0; $i < count($dirs); $i++) { 442 if (!empty($module) && $module != $apps[$i]) { 443 continue; 444 } 445 $c->writeln(sprintf('Merging translation for module %s...', $c->bold($apps[$i]))); 446 $dir = $dirs[$i] . DS . 'po' . DS; 447 if (empty($lang)) { 448 $langs = get_languages($dirs[$i]); 449 } else { 450 if (!@file_exists($dir . $lang . '.po')) { 451 $c->writeln('Skipped...'); 452 $c->writeln(); 453 continue; 454 } 455 $langs = array($lang); 456 } 457 foreach ($langs as $locale) { 458 $c->writeln(sprintf('Merging locale %s... ', $c->bold($locale))); 459 $sh = $GLOBALS['msgmerge'] . ' --update -v' . $compendium . ' "' . $dir . $locale . '.po" "' . $dir . $apps[$i] . '.pot"'; 460 if ($debug || $test) { 461 $c->writeln('Executing:'); 462 $c->writeln($sh); 463 } 464 if (!$test) exec($sh); 465 $c->writeln($c->green('done')); 466 } 467 } 468 } 469 470 function status() 471 { 472 return; 473 global $cmd_options, $apps, $dirs, $debug, $test, $c; 474 475 $output = "status.html"; 476 foreach ($cmd_options[0] as $option) { 477 switch ($option[0]) { 478 case 'h': 479 usage(); 480 footer(); 481 case 'l': 482 case '--locale': 483 $lang = $option[1]; 484 break; 485 case 'm': 486 case '--module': 487 $module = $option[1]; 488 break; 489 case 'o': 490 case '--output': 491 $output = $option[1]; 492 break; 493 } 494 } 495 for ($i = 0; $i < count($dirs); $i++) { 496 if (!empty($module) && $module != $apps[$i]) { 497 continue; 498 } 499 $c->writeln(sprintf('Generating status for module %s...', $c->bold($apps[$i]))); 500 if (empty($lang)) { 501 $langs = get_languages($dirs[$i]); 502 } else { 503 if (!@file_exists($dirs[$i] . DS . 'po' . DS . $lang . '.po')) { 504 $c->writeln('Skipped...'); 505 $c->writeln(); 506 continue; 507 } 508 $langs = array($lang); 509 } 510 foreach ($langs as $locale) { 511 $c->writeln(sprintf('Status for locale %s... ', $c->bold($locale))); 512 } 513 } 514 } 515 516 function compendium() 517 { 518 global $cmd_options, $dirs, $debug, $test, $c, $silence; 519 520 $dir = BASE . DS . 'po' . DS; 521 $add = ''; 522 foreach ($cmd_options[0] as $option) { 523 switch ($option[0]) { 524 case 'h': 525 usage(); 526 footer(); 527 case 'l': 528 case '--locale': 529 $lang = $option[1]; 530 break; 531 case 'd': 532 case '--directory': 533 $dir = $option[1]; 534 break; 535 case 'a': 536 case '--add': 537 $add = ' ' . $option[1]; 538 break; 539 } 540 } 541 if (!isset($lang)) { 542 $c->writeln($c->red('Error: ' . 'No locale specified.')); 543 $c->writeln(); 544 usage(); 545 footer(); 546 } 547 printf('Merging all %s.po files to the compendium... ', $lang); 548 $pofiles = array(); 549 for ($i = 0; $i < count($dirs); $i++) { 550 $pofile = $dirs[$i] . DS . 'po' . DS . $lang . '.po'; 551 if (file_exists($pofile)) { 552 $pofiles[] = $pofile; 553 } 554 } 555 if (!empty($dir) && substr($dir, -1) != DS) { 556 $dir .= DS; 557 } 558 $sh = $GLOBALS['msgcat'] . ' --sort-output ' . implode(' ', $pofiles) . $add . ' > ' . $dir . 'compendium.po ' . ($debug ? '' : $silence); 559 if ($debug || $test) { 560 $c->writeln(); 561 $c->writeln('Executing:'); 562 $c->writeln($sh); 563 } 564 if ($test) { 565 $ret = 0; 566 } else { 567 exec($sh, $out, $ret); 568 } 569 if ($ret == 0) { 570 $c->writeln($c->green('done')); 571 } else { 572 $c->writeln($c->red('failed')); 573 } 574 } 575 576 function init() 577 { 578 global $cmd_options, $apps, $dirs, $debug, $test, $c, $silence; 579 580 foreach ($cmd_options[0] as $option) { 581 switch ($option[0]) { 582 case 'h': 583 usage(); 584 footer(); 585 case 'l': 586 case '--locale': 587 $lang = $option[1]; 588 break; 589 case 'm': 590 case '--module': 591 $module = $option[1]; 592 break; 593 } 594 } 595 if (empty($lang)) { $lang = getenv('LANG'); } 596 for ($i = 0; $i < count($dirs); $i++) { 597 if (!empty($module) && $module != $apps[$i]) { continue; } 598 $package = ucfirst($apps[$i]); 599 $package_u = String::upper($apps[$i]); 600 @include $dirs[$i] . '/lib/version.php'; 601 $version = defined($package_u . '_VERSION') ? constant($package_u . '_VERSION') : '???'; 602 printf('Initializing module %s... ', $apps[$i]); 603 if (!@file_exists($dirs[$i] . '/po/' . $apps[$i] . '.pot')) { 604 $c->writeln($c->red('failed')); 605 $c->writeln(sprintf('%s not found. Run \'translation extract\' first.', $dirs[$i] . DS . 'po' . DS . $apps[$i] . '.pot')); 606 continue; 607 } 608 $dir = $dirs[$i] . DS . 'po' . DS; 609 $sh = $GLOBALS['msginit'] . ' --no-translator -i ' . $dir . $apps[$i] . '.pot ' . 610 (!empty($lang) ? ' -o ' . $dir . $lang . '.po --locale=' . $lang : '') . 611 ($debug ? '' : $silence); 612 if (!empty($lang) && !OS_WINDOWS) { 613 $pofile = $dirs[$i] . '/po/' . $lang . '.po'; 614 $sh .= "; sed 's/PACKAGE package/$package package/' $pofile " . 615 "| sed 's/PACKAGE VERSION/$package $version/' " . 616 "| sed 's/messages for PACKAGE/messages for $package/' " . 617 "| sed 's/Language-Team: none/Language-Team: i18n@lists.horde.org/' " . 618 "> $pofile.tmp"; 619 } 620 if ($debug || $test) { 621 $c->writeln('Executing:'); 622 $c->writeln($sh); 623 } 624 if ($test) { 625 $ret = 0; 626 } else { 627 exec($sh, $out, $ret); 628 } 629 rename($pofile . '.tmp', $pofile); 630 if ($ret == 0) { 631 $c->writeln($c->green('done')); 632 } else { 633 $c->writeln($c->red('failed')); 634 } 635 } 636 } 637 638 function make() 639 { 640 global $cmd_options, $apps, $dirs, $debug, $test, $c, $silence, $redir_err; 641 642 $compendium = BASE . DS . 'po' . DS . 'compendium.po'; 643 $save_stats = false; 644 foreach ($cmd_options[0] as $option) { 645 switch ($option[0]) { 646 case 'h': 647 usage(); 648 footer(); 649 case 'l': 650 case '--locale': 651 $lang = $option[1]; 652 break; 653 case 'm': 654 case '--module': 655 $module = $option[1]; 656 break; 657 case 'c': 658 case '--compendium': 659 $compendium = $option[1]; 660 break; 661 case 'n': 662 case '--no-compendium': 663 $compendium = ''; 664 break; 665 case 's': 666 case '--statistics': 667 $save_stats = true; 668 break; 669 } 670 } 671 $horde = array_search('horde', $dirs); 672 $horde_msg = array(); 673 $stats_array = array(); 674 675 require_once 'Console/Table.php'; 676 $stats = new Console_Table(); 677 $stats->setHeaders(array('Module', 'Language', 'Translated', 'Fuzzy', 'Untranslated')); 678 679 for ($i = 0; $i < count($dirs); $i++) { 680 if (!empty($module) && $module != $apps[$i]) continue; 681 $c->writeln(sprintf('Building MO files for module %s...', $c->bold($apps[$i]))); 682 if (empty($lang)) { 683 $langs = get_languages($dirs[$i]); 684 } else { 685 if (!@file_exists($dirs[$i] . DS . 'po' . DS . $lang . '.po')) { 686 $c->writeln('Skipped...'); 687 $c->writeln(); 688 continue; 689 } 690 $langs = array($lang); 691 } 692 foreach ($langs as $locale) { 693 $c->writeln(sprintf('Building locale %s... ', $c->bold($locale))); 694 $dir = $dirs[$i] . DS . 'locale' . DS . $locale . DS . 'LC_MESSAGES'; 695 if (!is_dir($dir)) { 696 require_once 'System.php'; 697 if ($debug) { 698 $c->writeln(sprintf('Making directory %s', $dir)); 699 } 700 if (!$test && !@System::mkdir("-p $dir")) { 701 $c->writeln($c->red('Warning: ') . sprintf('Could not create locale directory for locale %s:', $locale)); 702 $c->writeln($dir); 703 $c->writeln(); 704 continue; 705 } 706 } 707 708 /* Convert to unix linebreaks. */ 709 $pofile = $dirs[$i] . DS . 'po' . DS . $locale . '.po'; 710 $content = file_get_contents($pofile); 711 712 $content = str_replace("\r", '', $content); 713 $fp = fopen($pofile, 'wb'); 714 fwrite($fp, $content); 715 fclose($fp); 716 717 /* Check PO file sanity. */ 718 $sh = $GLOBALS['msgfmt'] . " --check \"$pofile\"$redir_err"; 719 if ($debug || $test) { 720 $c->writeln('Executing:'); 721 $c->writeln($sh); 722 } 723 if ($test) { 724 $ret = 0; 725 } else { 726 exec($sh, $out, $ret); 727 } 728 if ($ret != 0) { 729 $c->writeln($c->red('Warning: ') . 'an error has occured:'); 730 $c->writeln(implode("\n", $out)); 731 $c->writeln(); 732 if ($apps[$i] == 'horde') { 733 continue 2; 734 } 735 continue; 736 } 737 738 /* Compile MO file. */ 739 $sh = $GLOBALS['msgfmt'] . ' --statistics -o "' . $dir . DS . $apps[$i] . '.mo" '; 740 if ($apps[$i] != 'horde') { 741 $horde_po = $dirs[$horde] . DS . 'po' . DS . $locale . '.po'; 742 if (!@is_readable($horde_po)) { 743 $c->writeln($c->red('Warning: ') . sprintf('the Horde PO file for the locale %s does not exist:', $locale)); 744 $c->writeln($horde_po); 745 $c->writeln(); 746 $sh .= $dirs[$i] . DS . 'po' . DS . $locale . '.po'; 747 } else { 748 $sh = $GLOBALS['msgcomm'] . " --more-than=0 --sort-output \"$pofile\" \"$horde_po\" | $sh -"; 749 } 750 } else { 751 $sh .= $pofile; 752 } 753 $sh .= $redir_err; 754 if ($debug || $test) { 755 $c->writeln('Executing:'); 756 $c->writeln($sh); 757 } 758 $out = ''; 759 if ($test) { 760 $ret = 0; 761 } else { 762 putenv('LANG=en'); 763 exec($sh, $out, $ret); 764 putenv('LANG=' . $GLOBALS['language']); 765 } 766 if ($ret == 0) { 767 $c->writeln($c->green('done')); 768 $messages = array(0, 0, 0); 769 if (preg_match('/(\d+) translated/', $out[0], $match)) { 770 $messages[0] = $match[1]; 771 if (isset($horde_msg[$locale])) { 772 $messages[0] -= $horde_msg[$locale][0]; 773 if ($messages[0] < 0) $messages[0] = 0; 774 } 775 } 776 if (preg_match('/(\d+) fuzzy/', $out[0], $match)) { 777 $messages[1] = $match[1]; 778 if (isset($horde_msg[$locale])) { 779 $messages[1] -= $horde_msg[$locale][1]; 780 if ($messages[1] < 0) $messages[1] = 0; 781 } 782 } 783 if (preg_match('/(\d+) untranslated/', $out[0], $match)) { 784 $messages[2] = $match[1]; 785 if (isset($horde_msg[$locale])) { 786 $messages[2] -= $horde_msg[$locale][2]; 787 if ($messages[2] < 0) $messages[2] = 0; 788 } 789 } 790 if ($apps[$i] == 'horde') { 791 $horde_msg[$locale] = $messages; 792 } 793 $stats_array[$apps[$i]][$locale] = $messages; 794 $stats->addRow(array($apps[$i], $locale, $messages[0], $messages[1], $messages[2])); 795 } else { 796 $c->writeln($c->red('failed')); 797 exec($sh, $out, $ret); 798 $c->writeln(implode("\n", $out)); 799 } 800 if (count($langs) > 1) { 801 continue; 802 } 803 804 /* Merge translation into compendium. */ 805 if (!empty($compendium)) { 806 printf('Merging the PO file for %s to the compendium... ', $c->bold($apps[$i])); 807 if (!empty($dir) && substr($dir, -1) != DS) { 808 $dir .= DS; 809 } 810 $sh = $GLOBALS['msgcat'] . " --sort-output \"$compendium\" \"$pofile\" > \"$compendium.tmp\""; 811 if (!$debug) { 812 $sh .= $silence; 813 } 814 if ($debug || $test) { 815 $c->writeln(); 816 $c->writeln('Executing:'); 817 $c->writeln($sh); 818 } 819 $out = ''; 820 if ($test) { 821 $ret = 0; 822 } else { 823 exec($sh, $out, $ret); 824 } 825 @unlink($compendium); 826 rename($compendium . '.tmp', $compendium); 827 if ($ret == 0) { 828 $c->writeln($c->green('done')); 829 } else { 830 $c->writeln($c->red('failed')); 831 } 832 } 833 $c->writeln(); 834 } 835 } 836 if (empty($module)) { 837 $c->writeln('Results:'); 838 } else { 839 $c->writeln('Results (including Horde):'); 840 } 841 $c->writeln($stats->getTable()); 842 if ($save_stats) { 843 $fp = @fopen('translation_stats.txt', 'w'); 844 if ($fp) { 845 fwrite($fp, serialize($stats_array)); 846 fclose($fp); 847 } 848 } 849 } 850 851 function cleanup($keep_untranslated = false) 852 { 853 global $cmd_options, $apps, $dirs, $debug, $test, $c; 854 855 foreach ($cmd_options[0] as $option) { 856 switch ($option[0]) { 857 case 'h': 858 usage(); 859 footer(); 860 case 'l': 861 case '--locale': 862 $lang = $option[1]; 863 break; 864 case 'm': 865 case '--module': 866 $module = $option[1]; 867 break; 868 } 869 } 870 871 for ($i = 0; $i < count($dirs); $i++) { 872 if (!empty($module) && $module != $apps[$i]) { continue; } 873 $c->writeln(sprintf('Cleaning up PO files for module %s...', $c->bold($apps[$i]))); 874 if (empty($lang)) { 875 $langs = get_languages($dirs[$i]); 876 } else { 877 if (!@file_exists($dirs[$i] . DS . 'po' . DS . $lang . '.po')) { 878 $c->writeln('Skipped...'); 879 $c->writeln(); 880 continue; 881 } 882 $langs = array($lang); 883 } 884 foreach ($langs as $locale) { 885 $c->writeln(sprintf('Cleaning up locale %s... ', $c->bold($locale))); 886 $pofile = $dirs[$i] . DS . 'po' . DS . $locale . '.po'; 887 $sh = $GLOBALS['msgattrib'] . ($keep_untranslated ? '' : ' --translated') . " --no-obsolete --force-po $pofile > $pofile.tmp"; 888 if (!$debug) { 889 $sh .= $silence; 890 } 891 if ($debug || $test) { 892 $c->writeln(); 893 $c->writeln('Executing:'); 894 $c->writeln($sh); 895 } 896 $out = ''; 897 if ($test) { 898 $ret = 0; 899 } else { 900 exec($sh, $out, $ret); 901 } 902 if ($ret == 0) { 903 @unlink($pofile); 904 rename($pofile . '.tmp', $pofile); 905 $c->writeln($c->green('done')); 906 } else { 907 @unlink($pofile . '.tmp', $pofile); 908 $c->writeln($c->red('failed')); 909 } 910 $c->writeln(); 911 } 912 } 913 } 914 915 function commit($help_only = false) 916 { 917 global $cmd_options, $apps, $dirs, $debug, $test, $c; 918 919 $docs = false; 920 foreach ($cmd_options[0] as $option) { 921 switch ($option[0]) { 922 case 'h': 923 usage(); 924 footer(); 925 case 'l': 926 case '--locale': 927 $lang = $option[1]; 928 break; 929 case 'm': 930 case '--module': 931 $module = $option[1]; 932 break; 933 case 'n': 934 case '--new': 935 $docs = true; 936 break; 937 case 'M': 938 case '--message': 939 $msg = $option[1]; 940 break; 941 } 942 } 943 $files = array(); 944 for ($i = 0; $i < count($dirs); $i++) { 945 if (!empty($module) && $module != $apps[$i]) continue; 946 if ($apps[$i] == 'horde') { 947 $dirs[] = $dirs[$i] . DS . 'admin'; 948 $apps[] = 'horde/admin'; 949 if (!empty($module)) { 950 $module = 'horde/admin'; 951 } 952 } 953 if (empty($lang)) { 954 if ($help_only) { 955 $files = array_merge($files, strip_horde(search_ext('xml', $dirs[$i] . DS . 'locale'))); 956 } else { 957 $files = array_merge($files, strip_horde(get_po_files($dirs[$i] . DS . 'po'))); 958 $files = array_merge($files, strip_horde(search_file('^[a-z]{2}_[A-Z]{2}', $dirs[$i] . DS . 'locale', true))); 959 } 960 } else { 961 if ($help_only) { 962 if (!@file_exists($dirs[$i] . DS . 'locale' . DS . $lang . DS . 'help.xml')) continue; 963 } else { 964 if (!@file_exists($dirs[$i] . '/po/' . $lang . '.po')) continue; 965 $files[] = strip_horde($dirs[$i] . DS . 'po' . DS . $lang . '.po'); 966 } 967 $files[] = strip_horde($dirs[$i] . DS . 'locale' . DS . $lang); 968 } 969 if ($docs && !$help_only && $apps[$i]) { 970 $files[] = strip_horde($dirs[$i] . DS . 'docs'); 971 if ($apps[$i] == 'horde') { 972 $horde_conf = $dirs[array_search('horde', $dirs)] . DS . 'config' . DS; 973 $files[] = strip_horde($horde_conf . 'nls.php.dist'); 974 } 975 } 976 } 977 chdir(BASE); 978 if (count($files)) { 979 if ($docs) { 980 $c->writeln('Adding new files to repository:'); 981 $sh = 'cvs add'; 982 foreach ($files as $file) { 983 if (strstr($file, 'locale') || strstr($file, '.po')) { 984 $sh .= " $file"; 985 $c->writeln($file); 986 } 987 } 988 $sh .= '; cvs add'; 989 foreach ($files as $file) { 990 if (strstr($file, 'locale')) { 991 if ($help_only) { 992 $sh .= ' ' . $file . DS . '*.xml'; 993 $c->writeln($file . DS . '*.xml'); 994 } else { 995 $sh .= ' ' . $file . DS . '*.xml ' . $file . DS . 'LC_MESSAGES'; 996 $c->writeln($file . DS . "*.xml\n$file" . DS . 'LC_MESSAGES'); 997 } 998 } 999 } 1000 if (!$help_only) { 1001 $sh .= '; cvs add'; 1002 foreach ($files as $file) { 1003 if (strstr($file, 'locale')) { 1004 $add = $file . DS . 'LC_MESSAGES' . DS . '*.mo'; 1005 $sh .= ' ' . $add; 1006 $c->writeln($add); 1007 } 1008 } 1009 } 1010 $c->writeln(); 1011 if ($debug || $test) { 1012 $c->writeln('Executing:'); 1013 $c->writeln($sh); 1014 } 1015 if (!$test) system($sh); 1016 $c->writeln(); 1017 } 1018 $c->writeln('Committing:'); 1019 $c->writeln(implode(' ', $files)); 1020 if (!empty($lang)) { 1021 $lang = ' ' . $lang; 1022 } 1023 if (empty($msg)) { 1024 if ($docs) { 1025 $msg = "Add$lang translation."; 1026 } elseif ($help_only) { 1027 $msg = "Update$lang help file."; 1028 } else { 1029 $msg = "Update$lang translation."; 1030 } 1031 } 1032 $sh = 'cvs commit -m "' . $msg . '" ' . implode(' ', $files); 1033 if ($debug || $test) { 1034 $c->writeln('Executing:'); 1035 $c->writeln($sh); 1036 } 1037 if (!$test) system($sh); 1038 } 1039 } 1040 1041 function update_help() 1042 { 1043 global $cmd_options, $dirs, $apps, $debug, $test, $last_error_msg, $c; 1044 1045 foreach ($cmd_options[0] as $option) { 1046 switch ($option[0]) { 1047 case 'h': 1048 usage(); 1049 footer(); 1050 case 'l': 1051 case '--locale': 1052 $lang = $option[1]; 1053 break; 1054 case 'm': 1055 case '--module': 1056 $module = $option[1]; 1057 break; 1058 } 1059 } 1060 $files = array(); 1061 for ($i = 0; $i < count($dirs); $i++) { 1062 if (!empty($module) && $module != $apps[$i]) { continue; } 1063 if (!is_dir("$dirs[$i]/locale")) continue; 1064 if ($apps[$i] == 'horde') { 1065 $dirs[] = $dirs[$i] . DS . 'admin'; 1066 $apps[] = 'horde/admin'; 1067 if (!empty($module)) { 1068 $module = 'horde/admin'; 1069 } 1070 } 1071 if (empty($lang)) { 1072 $files = search_file('help.xml', $dirs[$i] . DS . 'locale'); 1073 } else { 1074 $files = array($dirs[$i] . DS . 'locale' . DS . $lang . DS . 'help.xml'); 1075 } 1076 $file_en = $dirs[$i] . DS . 'locale' . DS . 'en_US' . DS . 'help.xml'; 1077 if (!@file_exists($file_en)) { 1078 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('There doesn\'t yet exist a help file for %s.', $c->bold($apps[$i])))); 1079 $c->writeln(); 1080 continue; 1081 } 1082 foreach ($files as $file_loc) { 1083 $locale = substr($file_loc, 0, strrpos($file_loc, DS)); 1084 $locale = substr($locale, strrpos($locale, DS) + 1); 1085 if ($locale == 'en_US') continue; 1086 if (!@file_exists($file_loc)) { 1087 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('The %s help file for %s doesn\'t yet exist. Creating a new one.', $c->bold($locale), $c->bold($apps[$i])))); 1088 $dir_loc = substr($file_loc, 0, -9); 1089 if (!is_dir($dir_loc)) { 1090 require_once 'System.php'; 1091 if ($debug || $test) { 1092 $c->writeln(sprintf('Making directory %s', $dir_loc)); 1093 } 1094 if (!$test && !@System::mkdir("-p $dir_loc")) { 1095 $c->writeln($c->red('Warning: ') . sprintf('Could not create locale directory for locale %s:', $locale)); 1096 $c->writeln($dir_loc); 1097 $c->writeln(); 1098 continue; 1099 } 1100 } 1101 if ($debug || $test) { 1102 $c->writeln(wordwrap(sprintf('Copying %s to %s', $file_en, $file_loc))); 1103 } 1104 if (!$test && !@copy($file_en, $file_loc)) { 1105 $c->writeln($c->red('Warning: ') . sprintf('Could not copy %s to %s', $file_en, $file_loc)); 1106 } 1107 $c->writeln(); 1108 continue; 1109 } 1110 $c->writeln(sprintf('Updating %s help file for %s.', $c->bold($locale), $c->bold($apps[$i]))); 1111 $fp = fopen($file_loc, 'r'); 1112 $line = fgets($fp); 1113 fclose($fp); 1114 if (!strstr($line, '<?xml')) { 1115 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('The help file %s didn\'t start with <?xml', $file_loc))); 1116 $c->writeln(); 1117 continue; 1118 } 1119 $encoding = ''; 1120 if (preg_match('/encoding=(["\'])([^\\1]+)\\1/', $line, $match)) { 1121 $encoding = $match[2]; 1122 } 1123 $doc_en = domxml_open_file($file_en); 1124 if (!is_object($doc_en)) { 1125 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('There was an error opening the file %s. Try running translation.php with the flag -d to see any error messages from the xml parser.', $file_en))); 1126 $c->writeln(); 1127 continue 2; 1128 } 1129 $doc_loc = domxml_open_file($file_loc); 1130 if (!is_object($doc_loc)) { 1131 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('There was an error opening the file %s. Try running translation.php with the flag -d to see any error messages from the xml parser.', $file_loc))); 1132 $c->writeln(); 1133 continue; 1134 } 1135 $doc_new = domxml_new_doc('1.0'); 1136 $help_en = $doc_en->document_element(); 1137 $help_loc = $doc_loc->document_element(); 1138 $help_new = $help_loc->clone_node(); 1139 $entries_loc = array(); 1140 $entries_new = array(); 1141 $count_uptodate = 0; 1142 $count_new = 0; 1143 $count_changed = 0; 1144 $count_unknown = 0; 1145 foreach ($doc_loc->get_elements_by_tagname('entry') as $entry) { 1146 $entries_loc[$entry->get_attribute('id')] = $entry; 1147 } 1148 foreach ($doc_en->get_elements_by_tagname('entry') as $entry) { 1149 $id = $entry->get_attribute('id'); 1150 if (array_key_exists($id, $entries_loc)) { 1151 if ($entries_loc[$id]->has_attribute('md5') && 1152 md5($entry->get_content()) != $entries_loc[$id]->get_attribute('md5')) { 1153 $comment = $doc_loc->create_comment(" English entry:\n" . str_replace('--', '--', $doc_loc->dump_node($entry))); 1154 $entries_loc[$id]->append_child($comment); 1155 $entry_new = $entries_loc[$id]->clone_node(true); 1156 $entry_new->set_attribute('state', 'changed'); 1157 $count_changed++; 1158 } else { 1159 if (!$entries_loc[$id]->has_attribute('state')) { 1160 $comment = $doc_loc->create_comment(" English entry:\n" . str_replace('--', '--', $doc_loc->dump_node($entry))); 1161 $entries_loc[$id]->append_child($comment); 1162 $entry_new = $entries_loc[$id]->clone_node(true); 1163 $entry_new->set_attribute('state', 'unknown'); 1164 $count_unknown++; 1165 } else { 1166 $entry_new = $entries_loc[$id]->clone_node(true); 1167 $count_uptodate++; 1168 } 1169 } 1170 } else { 1171 $entry_new = $entry->clone_node(true); 1172 $entry_new->set_attribute('state', 'new'); 1173 $count_new++; 1174 } 1175 $entries_new[] = $entry_new; 1176 } 1177 $doc_new->append_child($doc_new->create_comment(' $' . 'Horde$ ')); 1178 foreach ($entries_new as $entry) { 1179 $help_new->append_child($entry); 1180 } 1181 $c->writeln(wordwrap(sprintf('Entries: %d total, %d up-to-date, %d new, %d changed, %d unknown', 1182 $count_uptodate + $count_new + $count_changed + $count_unknown, 1183 $count_uptodate, $count_new, $count_changed, $count_unknown))); 1184 $doc_new->append_child($help_new); 1185 $output = $doc_new->dump_mem(true, $encoding); 1186 if ($debug || $test) { 1187 $c->writeln(wordwrap(sprintf('Writing updated help file to %s.', $file_loc))); 1188 } 1189 if (!$test) { 1190 $fp = fopen($file_loc, 'w'); 1191 $line = fwrite($fp, $output); 1192 fclose($fp); 1193 } 1194 $c->writeln(sprintf('%d bytes written.', strlen($output))); 1195 $c->writeln(); 1196 } 1197 } 1198 } 1199 1200 function make_help() 1201 { 1202 global $cmd_options, $dirs, $apps, $debug, $test, $c; 1203 1204 foreach ($cmd_options[0] as $option) { 1205 switch ($option[0]) { 1206 case 'h': 1207 usage(); 1208 footer(); 1209 case 'l': 1210 case '--locale': 1211 $lang = $option[1]; 1212 break; 1213 case 'm': 1214 case '--module': 1215 $module = $option[1]; 1216 break; 1217 } 1218 } 1219 $files = array(); 1220 for ($i = 0; $i < count($dirs); $i++) { 1221 if (!empty($module) && $module != $apps[$i]) continue; 1222 if (!is_dir("$dirs[$i]/locale")) continue; 1223 if ($apps[$i] == 'horde') { 1224 $dirs[] = $dirs[$i] . DS . 'admin'; 1225 $apps[] = 'horde/admin'; 1226 if (!empty($module)) { 1227 $module = 'horde/admin'; 1228 } 1229 } 1230 if (empty($lang)) { 1231 $files = search_file('help.xml', $dirs[$i] . DS . 'locale'); 1232 } else { 1233 $files = array($dirs[$i] . DS . 'locale' . DS . $lang . DS . 'help.xml'); 1234 } 1235 $file_en = $dirs[$i] . DS . 'locale' . DS . 'en_US' . DS . 'help.xml'; 1236 if (!@file_exists($file_en)) { 1237 continue; 1238 } 1239 foreach ($files as $file_loc) { 1240 if (!@file_exists($file_loc)) { 1241 $c->writeln('Skipped...'); 1242 $c->writeln(); 1243 continue; 1244 } 1245 $locale = substr($file_loc, 0, strrpos($file_loc, DS)); 1246 $locale = substr($locale, strrpos($locale, DS) + 1); 1247 if ($locale == 'en_US') continue; 1248 $c->writeln(sprintf('Updating %s help file for %s.', $c->bold($locale), $c->bold($apps[$i]))); 1249 $fp = fopen($file_loc, 'r'); 1250 $line = fgets($fp); 1251 fclose($fp); 1252 if (!strstr($line, '<?xml')) { 1253 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('The help file %s didn\'t start with <?xml', $file_loc))); 1254 $c->writeln(); 1255 continue; 1256 } 1257 $encoding = ''; 1258 if (preg_match('/encoding=(["\'])([^\\1]+)\\1/', $line, $match)) { 1259 $encoding = $match[2]; 1260 } 1261 $doc_en = domxml_open_file($file_en); 1262 if (!is_object($doc_en)) { 1263 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('There was an error opening the file %s. Try running translation.php with the flag -d to see any error messages from the xml parser.', $file_en))); 1264 $c->writeln(); 1265 continue 2; 1266 } 1267 $doc_loc = domxml_open_file($file_loc); 1268 if (!is_object($doc_loc)) { 1269 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('There was an error opening the file %s. Try running translation.php with the flag -d to see any error messages from the xml parser.', $file_loc))); 1270 $c->writeln(); 1271 continue; 1272 } 1273 $help_loc = $doc_loc->document_element(); 1274 $md5_en = array(); 1275 $count_all = 0; 1276 $count = 0; 1277 foreach ($doc_en->get_elements_by_tagname('entry') as $entry) { 1278 $md5_en[$entry->get_attribute('id')] = md5($entry->get_content()); 1279 } 1280 foreach ($doc_loc->get_elements_by_tagname('entry') as $entry) { 1281 foreach ($entry->child_nodes() as $child) { 1282 if ($child->node_type() == XML_COMMENT_NODE && strstr($child->node_value(), 'English entry')) { 1283 $entry->remove_child($child); 1284 } 1285 } 1286 $count_all++; 1287 $id = $entry->get_attribute('id'); 1288 if (!array_key_exists($id, $md5_en)) { 1289 $c->writeln(wordwrap($c->red('Warning: ') . sprintf('No entry with the id "%s" exists in the original help file.', $id))); 1290 } else { 1291 $entry->set_attribute('md5', $md5_en[$id]); 1292 $entry->set_attribute('state', 'uptodate'); 1293 $count++; 1294 } 1295 } 1296 $output = $doc_loc->dump_mem(true, $encoding); 1297 if (!$test) { 1298 $fp = fopen($file_loc, 'w'); 1299 $line = fwrite($fp, $output); 1300 fclose($fp); 1301 } 1302 $c->writeln(sprintf('%d of %d entries marked as up-to-date', $count, $count_all)); 1303 $c->writeln(); 1304 } 1305 } 1306 } 1307 1308 $curdir = getcwd(); 1309 define('DS', DIRECTORY_SEPARATOR); 1310 1311 $language = getenv('LANG'); 1312 if (empty($language)) { 1313 $language = getenv('LANGUAGE'); 1314 } 1315 1316 @define('HORDE_BASE', dirname(__FILE__) . '/..'); 1317 require_once HORDE_BASE . '/lib/core.php'; 1318 require_once 'Horde/CLI.php'; 1319 1320 $c = &new Horde_CLI(); 1321 if (!$c->runningFromCLI()) { 1322 $c->fatal('This script must be run from the command line.'); 1323 } 1324 $c->init(); 1325 1326 $c->writeln($c->bold('---------------------------')); 1327 $c->writeln($c->bold('Horde translation generator')); 1328 $c->writeln($c->bold('---------------------------')); 1329 1330 /* Sanity checks */ 1331 if (!extension_loaded('gettext')) { 1332 $c->writeln($c->red('Gettext extension not found!')); 1333 footer(); 1334 } 1335 1336 $c->writeln('Loading libraries...'); 1337 $libs_found = true; 1338 1339 foreach (array('Console_Getopt' => 'Console/Getopt.php', 1340 'Console_Table' => 'Console/Table.php', 1341 'File_Find' => 'File/Find.php') 1342 as $class => $file) { 1343 echo $class . '... '; 1344 @include $file; 1345 if (class_exists($class)) { 1346 $c->writeln($c->green('OK')); 1347 } else { 1348 $c->writeln($c->red(sprintf('%s not found.', $class))); 1349 $libs_found = false; 1350 } 1351 } 1352 1353 if (!$libs_found) { 1354 $c->writeln(); 1355 $c->writeln('Make sure that you have PEAR installed and in your include path.'); 1356 $c->writeln('include_path: ' . ini_get('include_path')); 1357 footer(); 1358 } 1359 $c->writeln(); 1360 1361 /* Commandline parameters */ 1362 $args = Console_Getopt::readPHPArgv(); 1363 $options = Console_Getopt::getopt($args, 'b:dht', array('base=', 'debug', 'help', 'test')); 1364 if (PEAR::isError($options) && $args[0] == $_SERVER['PHP_SELF']) { 1365 array_shift($args); 1366 $options = Console_Getopt::getopt($args, 'b:dht', array('base=', 'debug', 'help', 'test')); 1367 } 1368 if (PEAR::isError($options)) { 1369 $c->writeln($c->red('Getopt Error: ' . str_replace('Console_Getopt:', '', $options->getMessage()))); 1370 $c->writeln(); 1371 usage(); 1372 footer(); 1373 } 1374 if (empty($options[0][0]) && empty($options[1][0])) { 1375 $c->writeln($c->red('Error: ' . 'No command specified.')); 1376 $c->writeln(); 1377 usage(); 1378 footer(); 1379 } 1380 $debug = false; 1381 $test = false; 1382 foreach ($options[0] as $option) { 1383 switch ($option[0]) { 1384 case 'b': 1385 case '--base': 1386 if (substr($option[1], -1) == DS) { 1387 $option[1] = substr($option[1], 0, -1); 1388 } 1389 define('BASE', $option[1]); 1390 break; 1391 case 'd': 1392 case '--debug': 1393 $debug = true; 1394 break; 1395 case 't': 1396 case '--test': 1397 $test = true; 1398 break; 1399 case 'h': 1400 case '--help': 1401 usage(); 1402 footer(); 1403 } 1404 } 1405 if (!$debug) { 1406 ini_set('error_reporting', false); 1407 } 1408 if (!defined('BASE')) { 1409 define('BASE', HORDE_BASE); 1410 } 1411 if ($options[1][0] == 'help') { 1412 usage(); 1413 footer(); 1414 } 1415 $silence = $debug || OS_WINDOWS ? '' : ' 2> /dev/null'; 1416 $redir_err = OS_WINDOWS ? '' : ' 2>&1'; 1417 $options_list = array( 1418 'cleanup' => array('hl:m:', array('module=', 'locale=')), 1419 'commit' => array('hl:m:nM:', array('module=', 'locale=', 'new', 'message=')), 1420 'commit-help'=> array('hl:m:nM:', array('module=', 'locale=', 'new', 'message=')), 1421 'compendium' => array('hl:d:a:', array('locale=', 'directory=', 'add=')), 1422 'extract' => array('hm:', array('module=')), 1423 'init' => array('hl:m:nc:', array('module=', 'locale=', 'no-compendium', 'compendium=')), 1424 'merge' => array('hl:m:c:n', array('module=', 'locale=', 'compendium=', 'no-compendium')), 1425 'make' => array('hl:m:c:ns', array('module=', 'locale=', 'compendium=', 'no-compendium', 'statistics')), 1426 'make-help' => array('hl:m:', array('module=', 'locale=')), 1427 'update' => array('hl:m:c:n', array('module=', 'locale=', 'compendium=', 'no-compendium')), 1428 'update-help'=> array('hl:m:', array('module=', 'locale=')), 1429 'status' => array('hl:m:o:', array('module=', 'locale=', 'output=')) 1430 ); 1431 $options_arr = $options[1]; 1432 $cmd = array_shift($options_arr); 1433 if (array_key_exists($cmd, $options_list)) { 1434 $cmd_options = Console_Getopt::getopt($options_arr, $options_list[$cmd][0], $options_list[$cmd][1]); 1435 if (PEAR::isError($cmd_options)) { 1436 $c->writeln($c->red('Error: ' . str_replace('Console_Getopt:', '', $cmd_options->getMessage()))); 1437 $c->writeln(); 1438 usage(); 1439 footer(); 1440 } 1441 } 1442 1443 /* Searching applications */ 1444 check_binaries(); 1445 1446 $c->writeln(sprintf('Searching Horde applications in %s', BASE)); 1447 $dirs = search_applications(); 1448 1449 if ($debug) { 1450 $c->writeln('Found directories:'); 1451 $c->writeln(implode("\n", $dirs)); 1452 } 1453 1454 $apps = strip_horde($dirs); 1455 $apps[0] = 'horde'; 1456 $c->writeln(wordwrap(sprintf('Found applications: %s', implode(', ', $apps)))); 1457 $c->writeln(); 1458 1459 switch ($cmd) { 1460 case 'cleanup': 1461 case 'commit': 1462 case 'compendium': 1463 case 'merge': 1464 $cmd(); 1465 break; 1466 case 'commit-help': 1467 commit(true); 1468 break; 1469 case 'extract': 1470 xtract(); 1471 break; 1472 case 'init': 1473 init(); 1474 $c->writeln(); 1475 merge(); 1476 break; 1477 case 'make': 1478 cleanup(true); 1479 $c->writeln(); 1480 make(); 1481 break; 1482 case 'make-help': 1483 make_help(); 1484 break; 1485 case 'update': 1486 xtract(); 1487 $c->writeln(); 1488 merge(); 1489 break; 1490 case 'update-help': 1491 update_help(); 1492 break; 1493 case 'status': 1494 // xtract(); 1495 merge(); 1496 // status(); 1497 break; 1498 default: 1499 $c->writeln($c->red('Error: ') . sprintf('Unknown command: %s', $cmd)); 1500 $c->writeln(); 1501 usage(); 1502 footer(); 1503 } 1504 1505 footer();
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |