Toolserver:Translatewiki.net interface/list builder.php

This page was moved from the Toolserver wiki.
Toolserver has been replaced by Toolforge. As such, the instructions here may no longer work, but may still be of historical interest.
Please help by updating examples, links, template links, etc. If a page is still relevant, move it to a normal title and leave a redirect.

<?php
/*
 *  
 *  Copyright © Luxo 2010
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *  
 *  
 * ****************************************************************************************************************************
 *  
 *                     repository list script
 *                    """""""""""""""""""""""
 *                     
 *                get list of all toolserver users
 *                               ↓
 * check every user home directory for .translatewiki.yml file
 *                               ↓
 *   get all svn-url's from the .translatewiki.yml file
 *                               ↓
 *            check if the url is already in the list
 *                      ↓                 ↓
 *                    if yes             if no
 *                      ↓                 ↓
 *                      ↓        Load svn-directory
 *                      ↓                 ↓
 *                      ↓        open all .yml files
 *                      ↓                 ↓
 *                      ↓       check if there is a yml file 
 *                      ↓        in the directory, syntax ok,
 *                      ↓       tool name dosn't exist already,
 *                      ↓       url is in user's own ts-repo
 *                      ↓           ↓                  ↓
 *                      ↓        if yes              if no
 *                      ↓           ↓                  ↓              | Send mail to user
 *             write svn url to the new file            → → → → → → → | inform about the problem
 *                                                                    | prohibit send same mail every run
 *                                                                                     ↓
 *                                                                        save mail as md5 in a hash file
 *
 *   
 *  
 * ****************************************************************************************************************************
 * CONFIGURATION
 */
 
 //dir of user's svn-url-list
$dir = "/home/*/.translatewiki.yml";
 
 //error messages (%1$s = username, %2$s = toolname or filename)
 $errormsg[1] = 'Your svn-url is not in your own svn repository. The url should start with <https://svn.toolserver.org/svnroot/%1$s/>';
 $errormsg[2] = 'There are no language-files ending with .yml found in your directory.';
 $errormsg[3] = 'Your language file "%2$s" has not one first child key. There should be only one first child key contained the language (e.g. "en")';
 $errormsg[4] = 'There is already a tool with the name %2$s. Please use a different name.';
 $errormsg[5] = 'The first child key of your file "%2$s" should be a string.';
 $errormsg[6] = 'The content of the first child in your file "%2$s" should be an array.';

 //path of output file
 $outputpath = "/home/luxo/translatewiki/";
  //file name of output file
 $outputname = "translatewiki.yml";
 
 
 //hash file path
 $hashpath = "/home/luxo/translatewiki/";
 //hash file name
 $hashname = "HASH";
 
 

/*
 * END CONFIGURATION
 * ****************************************************************************************************************************
 */
 
require("spyc.php"); //spyc

 
//Print settings
 print("Settings\nUser folder: ".$dir."\n");
 print("Hash file: ".$hashpath.$hashname."\n");
 print("Output file: ".$outputpath.$outputname."\n----\n");

//Get all subdirs in $dir
$files = getUser(glob($dir));

printarray("found files",$files);

//open and check $files
$files = checkFiles($files);

print("write ".count($files)." url's to new translatewiki file\n");

//create new yaml file
createFile($files);

print("finished\n");


//******************** FUNCTIONS **********************************************************************************************

function getOldFile() {
  GLOBAL $outputpath;
  GLOBAL $outputname;
  STATIC $save = NULL;
  if(!$save) {
    $save = Spyc::YAMLLoad($outputpath.$outputname);
  }
  return $save; 
}


function getUser($array){ //get username from file url
  $ret = array();
  foreach($array as $url){
    $user = preg_replace("/\/home\/([^\/]*)\/.*/", "\\1", $url,1);
    $ret[$user] = $url;
  }
  return $ret;
}


function printarray($text,$array=array()) {
  print($text."\n");
  foreach($array as $k => $x) {
    print($k." => ".$x."\n");
  }
  print("\n");
}

function error_handler($data) {
  GLOBAL $errormsg;
  //$data[USER][URL][ERRORNUMBER] = true;
  foreach($data as $user => $cnt) {
    $mail = $user."@toolserver.org";
    $text  = "Hello ".$user.",\n\n";
    $text .= "there has occurred a problem when adding your svn url to the translatewiki export file.\n\n";
    foreach($cnt as $url => $errornumbers) {
      $text .= "URL: ".$url."\n";
      foreach($errornumbers as $number => $x) {
        $text .= "  > ".sprintf($errormsg[$number],$user,$x)."\n";
      }
      $text .= "\n";
    }
    $text .= "\n\n";
    $text .= "Please fix this problem(s) if you like to be added to the file.\n";
    $hash = md5($mail.$text);
    if(hash_handler($hash) == false)
    {
      print("Send mail to $mail \n");
      mail($mail, "translatewiki export file", $text);
      hash_handler($hash,1); //new hash entry
    } else {
      print("Mail to $mail already sent at ".date("r",hash_handler($hash))."\n");
    }
  }
}

function hash_handler($hash,$dir = 0){
  GLOBAL $hashpath;
  GLOBAL $hashname;
  STATIC $hashlist = array();
  if(!$hashlist){
    $hashlist = unserialize(file_get_contents($hashpath.$hashname));
  }
  if($dir == 1) { //new hash
    foreach($hashlist as $k => $c) { //delete hash's older than 30 days
      if(time() - $c > 2592000) {
        unset($hashlist[$k]);
      }
    }
    $hashlist[$hash] = time();
    return file_put_contents($hashpath.$hashname, serialize($hashlist));
  } else { //ask hash
    if($hashlist[$hash]) {
      return $hashlist[$hash];
    } else {
      return false;
    }
  }
}

function checkFiles($files) {
  $error = array();
  $newdata = array();
  $olddata = getOldFile();
  foreach($files as $usr => $fullpath) { //Toolserver User
    $Data = spyc_load_file($fullpath);
    //print_r($Data);
    $userurl = "https://svn.toolserver.org/svnroot/".$usr."/"; //path of the user svn, e.g. https://svn.toolserver.org/svnroot/john
     foreach($Data as $name => $spec) { //Toolserver User's url's
     
      if($spec['i18n_svn']) { //full path of the tool, e.g. https://svn.toolserver.org/svnroot/john/cool/lang
        if(substr($spec['i18n_svn'],-1) != "/") { $spec['i18n_svn'] .= "/"; } //add backslash at the end of the url
        if(substr($spec['i18n_svn'],0,5) != "https") { $spec['i18n_svn'] = "https:".substr($spec['i18n_svn'],5); } //https (if http)   
        
        if($olddata[$name]['i18n_svn'] != $spec['i18n_svn']) {//new url or already listed?
          
          if(!$olddata[$name] OR $spec['contact'] == $olddata[$name]['contact']) { //Does name already exist? Or same user?
            
            if(substr($spec['i18n_svn'],0,strlen($userurl)) == $userurl) {  //if i18n_svn starts with the tooserver svn url > ok

              $files = shell_exec('svn list '.escapeshellcmd($spec['i18n_svn'])); //get list of all files in svn
              //split
              $files = explode("\n",$files);
              $goodfiles = array();
              foreach($files as $file) { //Toolserver user's files
                if(preg_match("/^[^\.].*\.yml$/",trim($file)) == 1) {  //file without dot (.) at the beginning and with .yml at the end
                  //file is ok 
                  $goodfiles[] = $file;
                  $content = file_get_contents($spec['i18n_svn'].$file);
                  if(is_String($content)) {
                    $content = spyc_load_file($content);
                    if(count($content) != 1) {
                      //more than one parent node
                      $error[$usr][$spec['i18n_svn']][3] = $file;
                    }
                    $x = array_keys($content);
                    if(is_string($x[0]) == false) {
                      //language key not a string
                      $error[$usr][$spec['i18n_svn']][5] = $file;
                    }
                    if(is_array($content[$x[0]]) == false) {
                      //content of first child should be a array
                      $error[$usr][$spec['i18n_svn']][6] = $file;
                    }
                  }
                }
              }
              if(count($goodfiles) < 1) { //if there are no good files
                $error[$usr][$spec['i18n_svn']][2] = true;
              }
            } else {
              //url is not in the users toolserver svn
              $error[$usr][$spec['i18n_svn']][1] = true;
            }
          } else {
            //name already exist
            $error[$usr][$spec['i18n_svn']][4] = $name;
          }
        }
      }
      //Entry/No Entry?
      if($newdata[$name]) {
        //name already exist
        $error[$usr][$spec['i18n_svn']][4] = $name;
      }
      if(!$error[$usr][$spec['i18n_svn']]) {
        //Entry
        $newdata[$name]['i18n_svn'] = $spec['i18n_svn'];
        $newdata[$name]['contact'] = $usr;
        $newdata[$name]['format'] = "yaml";
      }
    }
  }
  //user notification about a problem?
  error_handler($error);
  
  //return new data
  return($newdata);
}



function createFile($files) {
  GLOBAL $outputpath;
  GLOBAL $outputname;
  if(is_array($files)) {
    $yaml = Spyc::YAMLDump($files);
    file_put_contents($outputpath.$outputname, $yaml);
  }
}


?>