#!/usr/bin/php -q <?php /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2011 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.0 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_0.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Thomas Sch�fbeck <tom@php.net> | | Gabor Hojtsy <goba@php.net> | | Mark Kronsbein <mk@php.net> | | Jan Fabry <cheezy@php.net> +----------------------------------------------------------------------+ $Id: revcheck.php 308406 2011-02-16 22:27:57Z yannick $ */ if ($argc < 2 || $argc > 4) { ?> Check the revision of translated files against the actual english xml files, and print statistics Usage: <?php echo $argv[0]; ?> <language-code> [<maintainer>] [--show-uptodate] <language-code> must be a valid language code used in the repository If you specify <maintainer>, the script only checks the files maintained by the person you add here If you specify --show-uptodate option, the script will also show uptodate files in the common file list Read more about Revision comments and related functionality in the PHP Documentation Howto: http://php.net/dochowto <?php exit; } // Long runtime set_time_limit(0); // A file is criticaly "outdated' if define("ALERT_REV", 10); // translation is 10 or more revisions behind the en_US one define("ALERT_SIZE", 3); // translation is 3 or more kB smaller than the en_US one define("ALERT_DATE", -30); // translation is 30 or more days older than the en_US one // Revision marks used to flag files define("REV_UPTODATE", 1); // actual file define("REV_NOREV", 2); // file with revision comment without revision define("REV_CRITICAL", 3); // criticaly old / small / outdated define("REV_OLD", 4); // outdated file define("REV_NOTAG", 5); // file without revision comment define("REV_NOTRANS", 6); // file without translation define("REV_CREDIT", 7); // only used in translators list define("REV_WIP", 8); // only used in translators list $gitOptions="--no-color -n 1"; // Colors used to mark files by status (colors for the above types) $CSS = array( REV_UPTODATE => "act", REV_NOREV => "norev", REV_CRITICAL => "crit", REV_OLD => "old", REV_NOTAG => "wip", REV_NOTRANS => "wip", REV_CREDIT => "wip", REV_WIP => "wip", ); function init_revisions() { global $CSS; return array_fill_keys(array_keys($CSS), 0); } function init_files_by_maint($persons) { $result = array(); foreach($persons as $item) { $result[$item['name']] = init_revisions(); } return $result; } $file_sizes_by_mark = $files_by_mark = init_revisions(); // Initializing variables from parameters $LANG = $argv[1]; $MAINT = ""; $SHOW_UPTODATE = FALSE; if ($argc == 3) { if ($argv[2] == '--show-uptodate') { $SHOW_UPTODATE = TRUE; } else { $MAINT = $argv[2]; } } elseif ($argc == 4) { $MAINT = $argv[2]; $SHOW_UPTODATE = ($argv[3] == '--show-uptodate'); } $DOCDIR=getenv("SCI")."/"; chdir($DOCDIR); $DOCDIR=getcwd()."/"; if (!is_dir($DOCDIR)) { echo "Could not find $DOCDIR\n"; die(); } // ========================================================================= // Functions to get revision info and credits from a file // ========================================================================= function get_last_commit_from_git($file) { global $gitOptions; $cmd="cd `dirname $file` > /dev/null; git log $gitOptions $file|head -1|cut -d' ' -f2; cd - > /dev/null"; $lastcommit=exec($cmd); if (!$lastcommit) { die("Error: Could not retrieve the last commit from git: ".$cmd); } return $lastcommit; } function get_last_revision_from_git($file) { global $DOCDIR; $commit=get_last_commit_from_git($file); if (!$commit) { die("Error: empty commit"); } $tempFile="/tmp/git_rev-list.txt"; if (!is_file($tempFile)) { exec("cd `dirname $DOCDIR` > /dev/null; git rev-list --reverse HEAD > $tempFile; cd - > /dev/null"); } return exec("cd `dirname $file` > /dev/null; grep -n $commit $tempFile | cut -d: -f1; cd - > /dev/null"); } function get_author_from_git($file) { global $gitOptions; return ucwords(strtolower(exec("cd `dirname $file` > /dev/null; git log $gitOptions $file|head -2|grep 'Author:'|sed -e 's|Author: \(.*\) <.*|\\1|g'; cd - > /dev/null"))); } // Grabs the revision tag and stores credits from the file given function get_tags($file, $val = "en-rev") { // Read the first 500 chars. The comment should be at // the begining of the file $fp = @fopen($file, "r") or die ("Unable to read $file."); $line = fread($fp, 500); fclose($fp); // Return if this was needed (it should be there) if ($val == "en-rev") { return get_last_revision_from_git($file); // preg_match("/<!-- .Revision: (\d+) . -->/", $line, $match); // return $match[1]; } // Handle credits (only if no maintainer is specified) if ($val == "\\S*") { global $files_by_maint; // Find credits info, let more credits then one, // using commas as list separator if (preg_match("'<!--\s*CREDITS:\s*(.+)\s*-->'U", $line, $match_credit)) { // Explode with commas a separators $credits = explode(",", $match_credit[1]); // Store all elements foreach ($credits as $num => $credit) { $files_by_maint[trim($credit)][REV_CREDIT]++; } } } global $LANG; // No match before the preg $match = array(); $match[0]=""; $match[1]=get_last_revision_from_git($file);//str_replace($LANG,"en_US",$file)); $match[2]=get_author_from_git($file); $match[3]=""; return $match; // Check for the translations "revision tag" preg_match ("/<!--\s*EN-Revision:\s*(\d+)\s*Maintainer:\s*(" . $val . ")\s*Status:\s*(.+)\s*-->/U", $line, $match ); // The tag with revision number is not found so search // for n/a revision comment (comment where revision is not known) if (count($match) == 0) { preg_match ("'<!--\s*EN-Revision:\s*(n/a)\s*Maintainer:\s*(" . $val . ")\s*Status:\s*(.+)\s*-->'U", $line, $match ); } // Return with found revision info (number, maint, status) return $match; } // get_tags() function end function detect_date_from_git($file) { global $gitOptions; $en_date=strtotime(trim(exec("cd `dirname $file` > /dev/null; git log $gitOptions --date=iso $file|grep Date:|sed -e \"s|Date:||g\"; cd - > /dev/null"))); return $en_date; } // ========================================================================= // Functions to check file status in translated directory, and store info // ========================================================================= // Checks a file, and gather status info function get_file_status($file) { // The information is contained in these global arrays and vars global $DOCDIR, $LANG, $MAINT, $SHOW_UPTODATE, $files_by_mark, $files_by_maint; global $file_sizes_by_mark; global $missing_files, $missing_tags, $using_rev; // Transform english file name to translated file name $trans_file = str_replace("en_US", $LANG, $file); // If we cannot find the file, we push it into the missing files list if (!@file_exists($trans_file)) { $files_by_mark[REV_NOTRANS]++; $trans_name = substr($trans_file, strlen($DOCDIR)); $size = intval(filesize($file)/1024); $missing_files[substr($file, strlen($DOCDIR))] = array( $size ); $file_sizes_by_mark[REV_NOTRANS] += $size; // compute en-tags just if they're needed in the WIP-Table if($using_rev) { $missing_files[$trans_name][] = get_tags($file); } return FALSE; } // No specific maintainer, check for a revision tag if (empty($MAINT)) { $trans_tag = get_tags($trans_file, "\\S*"); } // If we need to check for a specific translator else { // Get translated files tag, with maintainer $trans_tag = get_tags($trans_file, $MAINT); // If this is a file belonging to another // maintainer, than we would not like to // deal with it anymore if (count($trans_tag) == 0) { $trans_tag = get_tags($trans_file, "\\S*"); // We found a tag for another maintainer if (count($trans_tag) > 0) { return FALSE; } } } // Compute sizes and diffs $en_size = intval(filesize($file) / 1024); $trans_size = intval(mb_strlen(file_get_contents($trans_file), 'UTF-8') / 1024); $size_diff = intval($en_size) - intval($trans_size); // If we found no revision tag, then collect this // file in the missing tags list if (count($trans_tag) == 0) { $files_by_mark[REV_NOTAG]++; $file_sizes_by_mark[REV_NOTAG] += $en_size; $missing_tags[] = array(substr($trans_file, strlen($DOCDIR)), $en_size, $trans_size, $size_diff); return FALSE; } // Distribute values in separate vars for further processing list(, $this_rev, $this_maint, $this_status) = $trans_tag; // Get English file revision $en_rev = get_tags($file); // If we have a numeric revision number (not n/a), compute rev. diff if (is_numeric($this_rev)) { $rev_diff = intval($en_rev) - intval($this_rev); $trans_rev = $this_rev; $en_rev = $en_rev; $en_commit = get_last_commit_from_git($file); $trans_commit = get_last_commit_from_git($trans_file); } else { // If we have no numeric revision, make all revision // columns hold the rev from the translated file $rev_diff = $trans_rev = $this_rev; $en_rev = $en_rev; } // Compute times and diffs // $en_date = intval((time() - filemtime($file)) / 86400); $en_date=detect_date_from_git($file); if (!$en_date) { die("Could not detect date"); } $en_date = intval((time() - $en_date) / 86400); $trans_date=detect_date_from_git($trans_file); $trans_date = intval((time() - $trans_date) / 86400); $date_diff = $en_date - $trans_date; // If the file is up-to-date if ($rev_diff === 0 && trim($this_status) === "ready") { $status_mark = REV_UPTODATE; } elseif ($en_rev < $this_rev && $date_diff > 0) { $status_mark = REV_UPTODATE; } // Or make decision on file category by revision, date and size elseif ($rev_diff >= ALERT_REV || $size_diff >= ALERT_SIZE || $date_diff <= ALERT_DATE) { $status_mark = REV_CRITICAL; } elseif ($rev_diff === "n/a") { $status_mark = REV_NOREV; } elseif ($rev_diff === 0) { $status_mark = REV_WIP; } else { $status_mark = REV_OLD; } // Store files by status, and by maintainer too $files_by_mark[$status_mark]++; if (!isset($files_by_maint[$this_maint])) { $files_by_maint[$this_maint]=Array(); } if (!isset($files_by_maint[$this_maint][$status_mark])) { $files_by_maint[$this_maint][$status_mark]=Array(); } $files_by_maint[$this_maint][$status_mark]++; $file_sizes_by_mark[$status_mark] += $en_size; if (REV_UPTODATE === $status_mark && !$SHOW_UPTODATE) { return FALSE; } return array( "full_name" => $file, "short_name" => basename($trans_file), "revision" => array($en_rev, $trans_rev, $rev_diff), "commit" => array($en_commit, $trans_commit), "size" => array($en_size, $trans_size, $size_diff), "date" => array($en_date, $trans_date, $date_diff), "maintainer" => $this_maint, "status" => $this_status, "mark" => $status_mark ); } // get_file_status() function end // ========================================================================= // A function to check directory status in translated directory // ========================================================================= // Check the status of files in a diretory of phpdoc XML files // The English directory is passed to this function to check function get_dir_status($dir,$lang) { global $DOCDIR; // Collect files and diretcories in these arrays $directories = array(); $files = array(); // Open the directory $handle = @opendir($dir); // Walk through all names in the directory while ($file = @readdir($handle)) { if ( (!is_dir($dir.'/' .$file) && !in_array(substr($file, -3), array('xml','ent')) && substr($file, -13) != 'PHPEditBackup' ) || strpos($file, 'entities.') === 0 || $dir == $DOCDIR.'en/chmonly/' || $dir == $DOCDIR.'en/internals/' || $dir == $DOCDIR.'en/internals2/' || $file == 'contributors.ent' || $file == 'contributors.xml' || ($dir == $DOCDIR.'en/appendices/' && ($file == 'reserved.constants.xml' || $file == 'extensions.xml')) || $file == 'README' || $file == 'DO_NOT_TRANSLATE' || $file == 'rsusi.txt' || $file == 'missing-ids.xml' || $file == 'license.xml' || $file == 'master_help.xml' || preg_grep("/scilab_.*_help/",Array($dir)) || $file == 'versions.xml' ) { continue; } if ($file != '.' && $file != '..' && $dir != '/functions') { if (is_dir($dir.'/' .$file)) { $directories[] = $file; } elseif (is_file($dir.'/' .$file)) { if (strpos($dir,"help/$lang")) { $files[] = $file; } } } } // Close the directory @closedir($handle); // Sort files and directories sort($directories); sort($files); // Go through files first $dir_status = array(); foreach ($files as $file) { // If the file status is OK, append the status info if ($file_status = get_file_status($dir.$file)) { $dir_status[] = $file_status; } } // Then go through subdirectories, merging all the info // coming from subdirs to one array foreach ($directories as $file) { // if (sizeof($dir_status) < 1) { // echo $dir.$file; $dir_status = array_merge( $dir_status, get_dir_status($dir.$file.'/',$lang) ); // } } // Return with collected file info in // this dir and subdirectories [if any] return $dir_status; } // get_dir_status() function end // Check for files removed in the EN tree, but still living in the translation function get_old_files($dir) { global $DOCDIR, $LANG; // Collect files and diretcories in these arrays $directories = array(); $files = array(); $special_files = array( // french 'LISEZ_MOI.txt', 'TRADUCTIONS.txt', 'Translators', 'translation.xml' // todo: add all missing languages ); // Open the directory $handle = @opendir($dir); // Walk through all names in the directory while ($file = @readdir($handle)) { // If we found a file with one or two point as a name, // a SVN directory, or an editor backup file skip the file if (preg_match("/^\.{1,2}/", $file) || substr($file, -1) == '~' // Emacs backup file || substr($file, -4) == '.new' ) { continue; } // skip this files if (in_array($file, $special_files)) { continue; } // Collect files and directories if (is_dir($dir.$file)) { $directories[] = $file; } else { $files[] = $file; } } // Close the directory @closedir($handle); // Sort files and directories sort($directories); sort($files); // Go through files first $old_files_status = array(); foreach ($files as $file) { $en_dir = preg_replace("'^".$DOCDIR.$LANG."/'", $DOCDIR."en/", $dir); if (!@file_exists($en_dir.$file) ) { $old_files_status[$dir.$file] = array(0=>intval(filesize($dir.$file)/1024)); } } // Then go through subdirectories, merging all the info // coming from subdirs to one array foreach ($directories as $file) { $old_files_status = array_merge( $old_files_status, get_old_files($dir.$file.'/') ); } return $old_files_status; } // get_old_files() function end // ========================================================================= // Functions to read in the translation.xml file and process contents // ========================================================================= // Get a multidimensional array with tag attributes function parse_attr_string ($tags_attrs) { $tag_attrs_processed = array(); // Go through the tag attributes foreach($tags_attrs as $attrib_list) { // Get attr name and values preg_match_all("!(.+)=\\s*([\"'])\\s*(.+)\\2!U", $attrib_list, $attribs); // Assign all attributes to one associative array $attrib_array = array(); foreach ($attribs[1] as $num => $attrname) { $attrib_array[trim($attrname)] = trim($attribs[3][$num]); } // Collect in order of tags received $tag_attrs_processed[] = $attrib_array; } // Retrun with collected attributes return $tag_attrs_processed; } // parse_attr_string() end // Parse the translation.xml file for // translation related meta information function parse_translation($DOCDIR, $LANG, $MAINT) { global $files_by_mark; // Path to find translation.xml file, set default values, // in case we can't find the translation file $translation_xml = "tools/localization/translation-$LANG.xml"; $output_charset = 'iso-8859-1'; $translation = array( "intro" => "", "persons" => array(), "files" => array(), "allfiles" => array(), ); // Check for file availability, return with default // values, if we cannot find the file if (!@file_exists($translation_xml)) { return array($output_charset, $translation); } // Else go on, and load in the file, replacing all // space type chars with one space $txml = join("", file($translation_xml)); $txml = preg_replace("/\\s+/", " ", $txml); // Get intro text (different for a persons info and // for a whole group info page) if (empty($MAINT)) { preg_match("!<intro>(.+)</intro>!s", $txml, $match); $translation["intro"] = trim($match[1]); } else { $translation["intro"] = "Personal Statistics for ".$MAINT; } // Get encoding for the output, from the translation.xml // file encoding (should be the same as the used encoding // in HTML) preg_match("!<\?xml(.+)\?>!U", $txml, $match); $xmlinfo = parse_attr_string($match); $output_charset = $xmlinfo[1]["encoding"]; // Get persons list preg pattern, only check for a specific // maintainer, if the users asked for it if (empty($MAINT)) { $pattern = "!<person(.+)/\\s?>!U"; } else { $pattern = "!<person([^<]+nick=\"".$MAINT."\".+)/\\s?>!U"; } // Find all persons matching the pattern preg_match_all($pattern, $txml, $matches); $translation['persons'] = parse_attr_string($matches[1]); // Get list of work in progress files if (empty($MAINT)) { // Get all wip files preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches); $translation['files'] = parse_attr_string($matches[1]); // Provide info about number of WIP files $files_by_mark[REV_WIP] += count($translation['files']); } else { // Only check for a specific maintainer, if we were asked to preg_match_all("!<file([^<]+person=\"".$MAINT."\".+)/\\s?>!U", $txml, $matches); $translation['files'] = parse_attr_string($matches[1]); // Other maintainers wip files need to be cleared from // available files list in the future, so store that info too. preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches); $translation['allfiles'] = parse_attr_string($matches[1]); // Provide info about number of WIP files $files_by_mark[REV_WIP] += count($translation['allfiles']); } // Return with collected info in two vars return array($output_charset, $translation); } // parse_translation() function end() // ========================================================================= // Start of the program execution // ========================================================================= // Check for directory validity if (!@is_dir($DOCDIR . $LANG)) { // die("The $LANG language code is not valid"); } // Parse translation.xml file for more information list($charset, $translation) = parse_translation($DOCDIR, $LANG, $MAINT); // Add WIP files to maintainers file count and figure out, // if we need to use optional date and revision columns $using_date = FALSE; $using_rev = FALSE; $files_by_maint = init_files_by_maint($translation['persons']); foreach ($translation["files"] as $num => $fileinfo) { $files_by_maint[$fileinfo["person"]][REV_WIP]++; if (isset($fileinfo["date"])) { $using_date = TRUE; } if (isset($fileinfo["revision"])) { $using_rev = TRUE; } } // Get all files status //$files_status = get_dir_status($DOCDIR."/modules/core/","en_US");//."en/"); $files_status = get_dir_status($DOCDIR,"en_US");//."en/"); // Get all old files in <lang> directory $old_files = get_old_files($DOCDIR.$LANG."/"); $navbar = "<p class=c><a href=\"#intro\">Introduction</a> | " . "<a href=\"#translators\">Translators</a> | " . "<a href=\"#filesummary\">File summary by type</a> | " . "<a href=\"#files\">Files</a> | "; if ( count($translation["files"]) != 0 ) { $navbar .= "<a href=\"#wip\">Work in progress</a> | "; } $navbar .= "<a href=\"#missfiles\">Untranslated files</a> | " . "<a href=\"#oldfiles\">Old files</a></p>\n"; // Figure out generation date $date = date("r"); // ========================================================================= // Start of HTML page // ========================================================================= print <<<END_OF_MULTILINE <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> <html> <head> <title>Scilab documentation Revision-check</title> <meta http-equiv="Content-Type" content="text/html; charset={$charset}"> <style type="text/css"> <!-- h2,td,a,p,a.ref,th { font-family:Arial,Helvetica,sans-serif; font-size:14px; } h2,th,a.ref { color:#FFFFFF; } td,a,p { color:#000000; } h2 { font-size:28px; } th { font-weight:bold; } .blue { background-color:#666699; } .act { background-color:#68D888; } .norev { background-color:#f4a460; } .old { background-color:#eee8aa; } .crit { background-color:#ff6347; } .wip { background-color:#dcdcdc; } .r { text-align:right } .rb { text-align:right; font-weight:bold; } .c { text-align:center } body { margin:0px 0px 0px 0px; background-color:#F0F0F0; } //--> </style> </head> <body> <table width="100%" border="0" cellspacing="0" bgcolor="#666699"> <tr><td> <table width="100%" border="0" cellspacing="1" bgcolor="#9999CC"> <tr><td><h2 class=c>Status of the translated Scilab Manual</h2><p class=c style="font-size:12px;">Generated: {$date} / Language: $LANG<br></p></td></tr> </table> </td></tr> </table> END_OF_MULTILINE; print ($navbar); // ========================================================================= // Intro block goes here // ========================================================================= // If we have an introduction text, print it out, with an anchor if (!empty($translation["intro"])) { echo '<a name="intro"></a>'; echo '<table width="800" align="center"><tr><td class=c>' . $translation['intro'] . '</td></tr></table>'; } // ========================================================================= // Files summary table goes here // ========================================================================= // Do not print out file summary table, if we are printing out a page // for only one maintainer (his personal summary is in the table above) if (empty($MAINT)) { print <<<END_OF_MULTILINE <a name="filesummary"></a> <table width="450" border="0" cellpadding="4" cellspacing="1" align="center"> <tr class=blue> <th>File status type</th> <th>Number of files</th> <th>Percent of files</th> <th>Size of files (kB)</th> <th>Percent of size</th> </tr> END_OF_MULTILINE; $files_sum = array_sum($files_by_mark); $file_sizes_sum = array_sum($file_sizes_by_mark); $file_types = array( array (REV_UPTODATE, "Up to date files"), array (REV_OLD, "Old files"), array (REV_CRITICAL, "Critical files"), array (REV_WIP, "Work in progress"), // array (REV_NOREV, "Files without revision number"), // array (REV_NOTAG, "Files without revision tag"), array (REV_NOTRANS, "Files available for translation") ); foreach ($file_types as $num => $type) { echo "<tr class=".$CSS[$type[0]].">". "<td>".$type[1]."</td>". "<td class=c>".intval($files_by_mark[$type[0]])."</td>". "<td class=c>".number_format($files_by_mark[$type[0]] * 100 / $files_sum, 2 ). "%</td>". "<td class=c>".intval($file_sizes_by_mark[$type[0]])."</td>". "<td class=c>".number_format($file_sizes_by_mark[$type[0]] * 100 / $file_sizes_sum, 2). "%</td></tr>\n"; } echo "<tr class=blue><th>Files total</th><th>$files_sum</th><th>100%</th><th>$file_sizes_sum</th><th>100%</th></tr>\n". "</table>\n<p> </p>\n"; } echo $navbar."<p> </p>\n"; // ========================================================================= // Files table goes here // ========================================================================= if (count($files_status) != 0) { print <<<END_OF_MULTILINE <a name="files"></a> <table width="820" border="0" cellpadding="4" cellspacing="1" align="center"> <tr class=blue> <th rowspan=2>Translated file</th> <th colspan=2>Revision</th> <th colspan=3>Size in kB</th> <th colspan=3>Age in days</th> <th rowspan=2>Maintainer</th> <th rowspan=2>Status</th> </tr> <tr class=blue> <th>en_US</th> <th>$LANG</th> <th>en_US</th> <th>$LANG</th> <th>diff</th> <th>en_US</th> <th>$LANG</th> <th>diff</th> </tr> END_OF_MULTILINE; // This was the previous directory [first] $prev_dir = false; // Go through all files collected foreach ($files_status as $num => $file) { // print_r($file); // die(); // Make the maintainer a link, if we have that maintainer in the list if (isset($maint_by_nick[$file["maintainer"]])) { $file["maintainer"] = '<a href="#maint' . $maint_by_nick[$file["maintainer"]] . '">' . $file["maintainer"] . '</a>'; } // If we have a 'numeric' revision diff and it is not zero, // make a link to the git repository's diff script if ($file["revision"][2] != "n/a" && $file["revision"][2] !== 0) { $url="http://cgit.scilab.org/scilab/diff/?id=" .$file['commit'][0]."d2=".$file['commit'][1]; $file['short_name'] = '<a href="' . $url . '">'. $file["short_name"] . '</a> '; // '<a href="' . $url_ws . '">[NoWS]</a>';-- } // Guess the new directory from the full name of the file $new_dir = dirname($file["full_name"]); // If this is a new directory, put out old dir lines if ($new_dir !== $prev_dir) { if (isset($lines)) { echo $prev_diplay_dir; echo " ($line_number)</th></tr>"; echo $lines; } $lines = ''; $line_number = 0; // Store the new actual directory $prev_dir = $new_dir; } // Drop out the unneeded parts from the dirname, special case for root dir... $display_dir = str_replace(array($DOCDIR), array("", '/'), dirname($file["full_name"])); $prev_diplay_dir = "<tr class=blue><th colspan=12>$display_dir"; // Save the line for the current file (get file name shorter) $lines .= "<tr class={$CSS[$file['mark']]}><td>{$file['short_name']}</td>". "<td> {$file['revision'][0]}</td>" . "<td> {$file['revision'][1]}</td>". "<td class=r>{$file['size'][0]} </td>". "<td class=r>{$file['size'][1]} </td>". "<td class=rb>{$file['size'][2]} </td>". "<td class=r>{$file['date'][0]} </td>". "<td class=r>{$file['date'][1]} </td>". "<td class=rb>{$file['date'][2]} </td>". "<td class=c>{$file['maintainer']}</td>". "<td class=c>".trim($file['status'])."</td></tr>\n"; $line_number++; } // echo the last dir and $lines echo "$prev_diplay_dir ($line_number)</th></tr>"; echo $lines; echo "</table>\n<p> </p>\n$navbar<p> </p>\n"; } // ========================================================================= // Translators table goes here // ========================================================================= // If person list available (valid translation.xml file in lang), print out // the person list, with respect to the maintainer parameter specified if (!empty($translation["persons"])) { print <<<END_OF_MULTILINE <a name="translators"></a> <table width="820" border="0" cellpadding="4" cellspacing="1" align="center"> <tr class=blue> <th rowspan=2>Translator's name</th> <th rowspan=2>Contact email</th> <th colspan=7>Files maintained</th> </tr> <tr> <th class="{$CSS[REV_CREDIT]}" style="color:#000000">cre-<br>dits</th> <th class="{$CSS[REV_UPTODATE]}" style="color:#000000">upto-<br>date</th> <th class="{$CSS[REV_OLD]}" style="color:#000000">old</th> <th class="{$CSS[REV_CRITICAL]}" style="color:#000000">cri-<br>tical</th> <th class="{$CSS[REV_NOREV]}" style="color:#000000">no<br>rev</th> <th class="{$CSS[REV_WIP]}" style="color:#000000">wip</th> <th class="blue">sum</th> </tr> END_OF_MULTILINE; // ' Please leave this comment here // We will collect the maintainers by nick here $maint_by_nick = array(); // Print out a line for each maintainer (with respect to // maintainer setting provided in command line) foreach($translation["persons"] as $num => $person) { // Do not print out this person, if a // specific maintainer info is asked for if (!empty($MAINT) && $person["name"] != $MAINT) { continue; } // Put maintaner number into associative array // [Used in further tables for referencing] $maint_by_nick[$person["name"]] = $num; // Decide on the SVN text and the color of the line if (isset($person["vcs"]) && $person["vcs"] === "yes") { $svnu = "x"; $col = "old"; } else { $svnu = " "; $col = "wip"; } // Try to do some antispam actions $person["email"] = str_replace( "@", "<small>:at:</small>", $person["email"] ); // Get file info for this person if (isset($files_by_maint[$person["name"]])) { $pi = $files_by_maint[$person["name"]]; } else { $pi = array(); } echo "<tr class=$col>" . "<td><a name=\"maint$num\">$person[name]</a></td>" . "<td>$person[email]</td>" . "<td class=c>" . $pi[REV_CREDIT] . "</td>" . "<td class=c>" . $pi[REV_UPTODATE] . "</td>" . "<td class=c>" . $pi[REV_OLD] . "</td>" . "<td class=c>" . $pi[REV_CRITICAL] . "</td>" . "<td class=c>" . $pi[REV_NOREV] . "</td>" . "<td class=c>" . $pi[REV_WIP] . "</td>" . "<th class=blue>" . array_sum($pi) . "</th>" . "</tr>\n"; } echo "</table>\n<p> </p>\n"; } // ========================================================================= // Work in progress table goes here // ========================================================================= // If work-in-progress list is available (valid translation.xml file in lang) if (count($translation["files"]) != 0) { // Print out files table header echo "<a name=\"wip\"></a>\n" . "<table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n" . "<tr class=blue>". "<th>Work in progress files</th>". "<th>Translator</th>". "<th>Type</th>"; // Print out date and revision columns if needed if ($using_date) { echo '<th>Date</th>'; } if ($using_rev) { echo '<th>CO-Revision</th>' . '<th>EN-Revision</th>'; } echo "</tr>\n"; // Go through files, and print out lines for them foreach($translation["files"] as $num => $finfo) { // If we have a valid maintainer, link to the summary if (isset($maint_by_nick[$finfo["person"]])) { $finfo["person"] = '<a href="#maint' . $maint_by_nick[$finfo["person"]] . '">' . $finfo["person"] . '</a>'; } // Print out the line with the first columns echo "<tr class=wip><td>$finfo[name]</td>" . "<td>$finfo[person]</td><td>$finfo[type]</td>"; // If we need the date column, print it out if ($using_date) { echo "<td>$finfo[date]</td>"; } // If we need the revision column, print it out if ($using_rev) { echo "<td>$finfo[revision]</td><td>" . $missing_files[$finfo["name"]][1] . "</td>"; } // End the line echo "</tr>\n"; // Collect files in WIP list $wip_files[$finfo["name"]] = TRUE; } echo "</table>\n<p> </p>\n$navbar<p> </p>\n"; } // Files translated, but without a revision comment $count = count($missing_tags); if ($count > 0) { echo "<a name=\"misstags\"></a>" . "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n". "<tr class=blue><th rowspan=2>Files without Revision-comment ($count files):</th>". "<th colspan=3>Sizes in kB</th></tr>\n". "<tr class=blue><th>en_US</th><th>$LANG</th><th>diff</th></tr>\n"; foreach($missing_tags as $val) { // Shorten the filename (we have directory headers) $short_file = basename($val[0]); // Guess the new directory from the full name of the file $new_dir = dirname($val[0]); // If this is a new directory, put out dir headline if ($new_dir != $prev_dir) { // Print out directory header echo "<tr class=blue><th colspan=4>$new_dir</th></tr>\n"; // Store the new actual directory $prev_dir = $new_dir; } echo "<tr class=wip><td>$short_file</td><td class=r>$val[1]</td>". "<td class=r>$val[2]</td><td class=r>$val[3]</td></tr>\n"; } echo "</table>\n<p> </p>\n$navbar<p> </p>\n"; } // Merge all work in progress files collected $wip_files = array_merge( $translation["files"], // Files for this translator $translation["allfiles"] // Files for all the translators ); // Delete wip entires from available files list foreach ($wip_files as $file) { if (isset($missing_files[$file['name']])) { unset($missing_files[$file['name']]); } } // Files not translated and not "wip" $count = count($missing_files); if ($count > 0) { echo "<a name=\"missfiles\"></a>" . "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n" . "<tr class=blue><th><a name=\"avail\" class=\"ref\">" . " Available for translation</a> ($count files):</th><th>kB</th></tr>\n"; foreach($missing_files as $file => $info) { // Shorten the filename (we have directory headers) $short_file = basename($file); // Guess the new directory from the full name of the file $new_dir = dirname($file); // If this is a new directory, put out dir headline if ($new_dir != $prev_dir) { // Print out directory header if not "." echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n"; // Store the new actual directory $prev_dir = $new_dir; } echo "<tr class=wip><td><a href=\"http://cgit.scilab.org/scilab/tree/scilab/$file\">$short_file</a></td>" . "<td class=r>$info[0]</td></tr>\n"; } echo "</table>\n<p> </p>\n$navbar<p> </p>\n"; } // Files not in EN tree $count = count($old_files); if ($count > 0) { print "<a name=\"oldfiles\"></a>" . "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n" . "<tr class=blue><th><a name=\"notEn\" class=\"ref\">" . " Not in EN Tree</a> ($count files):</th><th>kB</th></tr>\n"; foreach($old_files as $file => $info) { // Shorten the filename (we have directory headers) $short_file = basename($file); // Guess the new directory from the full name of the file $new_dir = dirname($file); // If this is a new directory, put out dir headline if ($new_dir != $prev_dir) { // Print out directory header if not "." echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n"; // Store the new actual directory $prev_dir = $new_dir; } echo "<tr class=wip><td>$short_file</td>" . "<td class=r>$info[0]</td></tr>\n"; } echo "</table>\n<p> </p>\n$navbar<p> </p>\n"; } // All OK, end the file echo "</body>\n</html>\n"; ?>