[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/po/ -> translation.php (source)

   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('--', '&#45;&#45;', $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('--', '&#45;&#45;', $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();


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7