#!/usr/bin/php
<?
// submit_audio.php - automated audio submission to Voxforge.org
// Copyright (C) 2007  Jesse D. Guardiani
//
// 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 2
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
// --------------------------------------------------------------------------------
// This script does four things:
// 1.) .tgz audio dir
// 2.) Login to voxforge forum
// 3.) Upload .tgz to forum via HTTP POST
// 4.) Delete .tgz

$login_url = "http://www.voxforge.org/home/login";
$production_upload_url = "http://www.voxforge.org/home/downloads/audio/model-repository/audio-speech-files";
$testing_upload_url    = "http://www.voxforge.org/home/downloads/audio2/voxforgeivr";
$upload_url = $production_upload_url;
$file_a = array(); // contains paths for all files we create at runtime. used for cleanup.

main(); // The is The End, my friend.


function main() {
  global $argv;
  global $login_url;
  global $upload_url;

  set_time_limit(1800); // run for 30 minutes, max

  $session_dir = $argv[1];
  $session_id  = basename($session_dir);
  $tar_gz_path = "/tmp/$session_id.tgz";

  if (count($argv) != 2) crash(1,"usage: submit_audio.php /path/to/audio/dir/to/submit");

  exec("rm -f my_cookies.txt");
  if (tar_gz($session_dir,$tar_gz_path) !== 0) crash(6,"ERROR: tar failed");
  
  $result = login($login_url);
  if (!$result) crash(2,'ERROR: login failed');
  $login_status = parse_login($result);
  if ($login_status) echo "$login_status\n";
  else crash(3,"ERROR: cannot parse login result; login probably failed");

  $result = upload($upload_url,$session_id,$tar_gz_path,$session_dir);
  if (!$result) crash(4,'ERROR: upload failed');
  $upload_status = parse_upload($result);
  if ($upload_status) echo "$upload_status\n";
  else crash(5,"ERROR: cannot parse upload result; upload probably failed");

  // Move successfully submitted dir to a different subdirectory to make it 
  // easy to see at a glance which dirs have been successfully submitted.
  $parent_dir = dirname($session_dir);
  $parent_of_parent_dir = dirname($parent_dir);
  exec("mv $session_dir $parent_of_parent_dir/submitted/");
  
  cleanup();
  exit(0); // Happy
}

function crash($code,$msg) {
  global $argv;

  cleanup();
  echo "$msg\n";

  $session_dir = $argv[1];
  $mailmsg = <<<EOTXT
    ERROR while submitting directory "$session_dir"!
    msg="$msg"
EOTXT;
  mail('voxforge-ivr@guardiani.us',"voxforge-ivr ERROR!",$mailmsg);

  exit(intval($code));
}

function tar_gz($orig,$dest) {
  global $file_a;

  $file_a[] = $dest;
  $code     = 0;
  $out      = array();

  $target_dir = basename($orig);
  $parent_dir = dirname($orig);
  exec("tar -czf $dest -C $parent_dir $target_dir",$out,$code);
  return $code;
}

function cleanup() {
  global $file_a;
  foreach ($file_a as $path) System("rm -f $path"); // FIXME: yes, I'm trusting this path. bad programmer. no biscuit.
}

function login($url) {
  $post_a = array(
    'op'         => 'auth',
    'method'     => 'login',
    'username'   => 'voxforge-ivr',
    'identifier' => 'X4voxforge2007@bert',
    'submit'     => 'login',
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
  curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
  curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_a);
  $result = curl_exec($ch);

  /* To quote curl_errno documentation:
       Returns the error number for the last cURL operation on the resource ch, or 0 (zero) if no error occurred. */
  if (curl_errno($ch)) {
    error_log('ERROR: curl_exec,msg="'.curl_error($ch).'"');
    return false;
  }

  curl_close($ch);
  return $result;
}

function upload($url,$session_id,$tar_gz_path,$session_dir) {
  $body_s  = '';
  $body_s .= file_get_contents("$session_dir/README");
  $body_s .= "<h2>License:</h2>\n";
  $body_s .= file_get_contents("$session_dir/LICENSE");
  $body_s .= "<h2>Transcriptions (i.e. the prompts file):</h2>\n";
  $body_s .= file_get_contents("$session_dir/prompts");
  $body_s = preg_replace("/\n/m","<br>\n",$body_s);
  $post_a = array(
    'func'        => 'editSave',
    'assetId'     => 'new',
    'class'       => 'WebGUI::Asset::Post::Thread',
    'proceed'     => 'showConfirmation',
    'title'       => "voxforge-ivr-$session_id",
    'content'     => $body_s,
    '__storageId_action' => 'upload',
    'storageId_file' => "@$tar_gz_path",
    'subscribe'   => '1',
    'submit'      => 'save',
  );

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
  curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
  curl_setopt($ch, CURLOPT_TIMEOUT, 28800);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_VERBOSE, 1);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_a);
  $result = curl_exec($ch);

  /* To quote curl_errno documentation:
       Returns the error number for the last cURL operation on the resource ch, or 0 (zero) if no error occurred. */
  if (curl_errno($ch)) {
    error_log('ERROR: curl_exec,msg="'.curl_error($ch).'"');
    return false;
  }

  curl_close($ch);
  return $result;
}

function parse_login($subject) {
  $matches = array();
  if (preg_match('/(Hello) <a href=".+">(.+)<\/a>/im',$subject,$matches)) return $matches[1];
  return false;
}

function parse_upload($subject) {
  $matches = array();
  if (preg_match('/(Your post has been received)/im',$subject,$matches)) return $matches[1];
  return false;
}

?>
