view faptool.php @ 912:514d460c60a9

Fixes, etc.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 27 Nov 2014 10:58:41 +0200
parents 5d7e525b0eb5
children eda104823649
line wrap: on
line source

#!/usr/bin/php
<?
require_once "mconfig.inc.php";
require_once "msite.inc.php";

stCheckCLIExec();


function wtExec($exe, $args, $expect = 0)
{
  echo "@@EXEC: ".$exe." ".$args."\n";
  exec(escapeshellcmd($exe)." ".$args, $output, $code);
  if ($code !== $expect)
  {
    echo
      "Error executing ".$exe.": ".$code."\n".$args."\n".
      "------------------------------------------------\n".
      implode("\n", $output).
      "------------------------------------------------\n";
    return FALSE;
  }
  return TRUE;
}


function wtExecOrDie($exe, $args)
{
  if (wtExec($exe, $args) === false)
    die();
}


function wtConvertImage($inFilename, $inFileType, $outFilename, $setDim, $setFormat, $setQuality, $thumb)
{
  global $setPreviewPath;
  $isTemp = FALSE;

  if (($outDim = stGetSetting($setDim)) === FALSE ||
      ($outFormat = stGetSetting($osetFormat)) === FALSE ||
      ($outQuality = stGetSetting($setQuality)) === FALSE)
  {
    die("Missing one of res/format/quality settings for '".$outFilename."'\n");
  }

  if ($inFileType == "gfx")
  {
    // Oh great .. we need gfxconv here because Imagick handles ILBM like shit
    $filename = tempnam($setPreviewPath, "tmp");
    $isTemp = TRUE;
    if (wtExec(
      "/usr/local/bin/gfxconv",
      escapeshellarg($inFilename)." -f png -o ".escapeshellarg($filename)) === false)
      return FALSE;

    if (!file_exists($filename))
    {
      echo "ERROR: gfxconv did not output a temporary conversion inbetween.\n";
      return FALSE;
    }
    
  }
  else
    $filename = $inFilename;

  // convert -resize 640x480 -background black -gravity center -extent 640x480
  //         -unsharp "0x0.75+0.75+0.008" lol.lbm -quality 95 test.jpg
  
  // Create conversion entity
  $img = new Imagick($filename);
  if ($img === false)
  {
    echo "ERROR: Oh noes! ImageMagick could not digest the file '".$filename."' (".$inFilename.")\n";
    return FALSE;
  }

  // Get dimensions, setup background  
  $dim = $img->getImageGeometry();
  $img->setBackgroundColor(imagick::COLOR_BLACK);
  $img->setGravity(imagick::GRAVITY_CENTER);

  // Act based on image size vs. desired size and $thumb mode
  if ($thumb || $dim["width"] > $outDim[0] || $dim["height"] > $outDim[1])
  {
    // Image is larger
    $img->resizeImage($outDim[0], $outDim[1], Imagick::FILTER_QUADRATIC, 1);
    $img->setExtent($outDim[0], $outDim[1]);
    $img->normalizeImage();
    $img->unsharpMaskImage(0, 0.5, 1, 0.05);
  }
  else
  if ($dim["width"] < $outDim[0] || $dim["height"] < $outDim[1])
  {
    // Image is smaller than requested dimension(s)?
    $img->resizeImage($outDim[0], $outDim[1], Imagick::FILTER_POINT, 1);
    $img->setExtent($outDim[0], $outDim[1]);
  }

  $img->setFormat($outFormat);
  $img->setCompressionQuality($outQuality);

  $img->stripImage();
  $img->writeImage($outFilename);
  $img->removeImage();
}


function wtRenderSample($inFilename, $outFilename)
{
  $sfreq     = intval(stGetSetting("sampleFreq"));
  $sduration = intval(stGetSetting("sampleDuration"));
  $schannels = intval(stGetSetting("sampleChannels"));

  return wtExec(
    "/usr/local/bin/openmpt123"
    ,
    "--quiet --render ".
    "--samplerate ".$sfreq." ".
    "--channels ".$schannels." ".
    "--playtime ".$sduration." ".
    escapeshellarg($inFilename)." -o ".escapeshellarg($outFilename));
}


function wtConvertSample($inFilename, $outFilename, $opts)
{
  $sfreq     = intval(stGetSetting("sampleFreq"));
  $sduration = intval(stGetSetting("sampleDuration"));
  $schannels = intval(stGetSetting("sampleChannels"));

  foreach ($opts as $okey => $oval)
    $optStr .= $okey." ".$oval." ";
  
  return wtExec(
    "/usr/local/bin/avconv",
    "-y -t ".intval($sduration)." ".
    "-i ".escapeshellarg($inFilename).
    " ".$optStr." -ac ".$schannels.
    " -map_metadata -1 ".
    escapeshellarg($outFilename));
}


function wtPurgeDir($path)
{
  if (file_exists($path))
    wtExecOrDie("/bin/echo", "-fR ".escapeshellarg($path));
}


function wtUnpackArchiveTo($atype, $filename, $path)
{
  // Check file type before doing anything
  echo "Preparing to unpack archive file '".$filename."' ...\n";
  switch ($atype)
  {
    case "LHA":
      $exe = "/usr/bin/lha";
      $args = "e ".escapeshellarg($filename);
      break;

    case "ZIP":
      $exe = "/usr/bin/unzip";
      $args = "-d ".escapeshellarg($path)." ".escapeshellarg($filename);
      break;

    case "RAR":
      $exe = "/usr/bin/rar";
      $args = "e ".escapeshellarg($filename);
      break;

    default:
      echo "Unsupported archive file type: ".$atype."\n";
      return FALSE;
  }

  // Create temporary directory
  wtPurgeDir($path);
  stMakeDir($path, 0700);

  if (!is_dir($path) || chdir($path) === false)
  {
    echo "Failed to chdir to '".$path."', can't unpack archive.\n";
    return FALSE;
  }

  // Unpack archive
  return wtExec($exe, $args);
}


function wtScanArchive($efile, $filename)
{
  global $setEntryPath;

  $path = stMakePath(FALSE, FALSE, array($setEntryPath, "UNPACKS", $filename));

  echo "Attempting to scan archive file '".$filename."' ...\n";

  if (wtUnpackArchiveTo($efile["filetype"], $filename, $path) === false)
    return FALSE;

  // Scan through files ...
  $dir = opendir($path);
  while (($dentry = readdir($dir)) !== false)
  {
  }
  closedir($dir);

  wtPurgeDir($path);
  return TRUE;
}


function wtHandleEntryPreview($compo, $entry, $mode)
{
  // Get current preview file data
  if (!stGetPreviewFileData($compo, $entry, $pdata))
    return FALSE;

  if ($entry["file_id"] != 0)
    $efile = stFetchSQL("SELECT * FROM files WHERE deleted=0 AND id=".$entry["file_id"]);
  else
    $efile = FALSE;

  // Check preview file(s) status
  if ($mode == "sta")
  {
    printf(" %03d | %s%s%s | %-40s | %-5s | %s\n",
      $entry["id"],
      ($efile !== false) ? "1" : ".",
      isset($pdata["file"]) ? "2" : ".",
      $pdata["valid"] ? "3" : ".",
      $entry["name"]." by ".$entry["author"],
      isset($pdata["file"]) ? $pdata["file"]["filetype"] : "",
      isset($pdata["file"]) ? $pdata["file"]["filename"] : ""
      );
  }
  else
  if ($mode == "upd")
  {
/*
  if (previewSourceFile does not exist)
  {
    if (entry is module file)
    {
      render sample
    }
    else
    if (entry is image file)
    {
      convert image
    }
    else
    if (entry is archive)
    {
      if compo preview type is image, scan archive for images ..
    }
  }

  if (previewFiles older than previewSourceFile)
  {
    if (source == audio)
      convert via avconv
    else
    if (source == image)
      convert via imagick
  }

  // Based on compo / entry preview type ..
  
  // Convert preview image file, if any
  // Create thumbnail for it, too
  wtConvertImage($inFilename, $outFilename,
    "previewImageSize", "previewImageType",
    "previewImageQuality", FALSE);

  wtConvertImage($inFilename, $outFilename,
    "previewThumbSize", "previewThumbType",
    "previewThumbQuality", TRUE);
*/
  }
  else
    die("OMG!\n");
}


function wtHandleEntry($compo, $entry, $mode)
{
}


//
// Create directories
//
function stMakeDir($path, $perm)
{
  if (!file_exists($path))
  {
    echo " - Creating ".$path."\n";
    if (mkdir($path, $perm, TRUE) === false)
      die("Could not create directory '".$path."'\n");
  }
}


function stInitializeDirs()
{
  global
    $setEntryPath, $setPreviewPath, $setThumbDir,
    $setEntryPathPerms, $setPrevPathPerms;

  echo "Checking for missing directories ...\n";
  stMakeDir($setEntryPath, $setEntryPathPerms);
  stMakeDir($setPreviewPath, $setPrevPathPerms);
  stMakeDir(stMakePath(FALSE, FALSE, array($setPreviewPath, $setThumbDir)), $setPrevPathPerms);

  foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
  {
    stMakeDir(stMakePath(FALSE, FALSE, array($setEntryPath, $compo["cpath"])), $setEntryPathPerms);
  }
}


//
// Main program starts
//
if ($argc < 2)
{
  echo
    "faptool - Do stuff with FAPWeb database\n".
    "(C) Copyright 2014 ccr/TNSP\n".
    "\n".
    "Usage: ".$argv[0]." <mode> [args]\n".
    "Where mode is one of following:\n".
    "\n".
    "  init\n".
    "     Create directories for entries and previews, if needed.\n".
    "\n".
    "  clean [delete]\n".
    "     Clean files marked to be deleted. This includes any old\n".
    "     or stale preview files and entry files.\n".
    "     Without 'delete' parameter just checks and shows what would\n".
    "     be deleted, but with it ACTUALLY DELETES THE FILES, SO BE CAREFUL!\n".
    "\n".
    "  previews <cmd> [args]\n".
    "    Where <cmd> is one of:\n".
    "    status   - List files and show what is missing, etc.\n".
    "\n".
    "  entry <cmd> [args]\n".
    "    status   - List entries for all compos.\n".
    "    unpack   - Create subdirs and unpack archives under them.\n".
    "\n";
  exit;
}

// Try to connect to database
$spec = stGetSetting("sqlDB");
if (($db = stConnectSQLDBSpec($spec)) === false)
  die("Could not connect to SQL database '".$spec."'.\n");

echo "Using database spec '".$spec."'.\n";

// Fetch non-"hardcoded" settings from SQL database
stReloadSettings();

// Set some globals for our benefit
$setWidth = 75;
$setEntryPath = stGetSetting("entryPath");
$setPreviewPath = stGetSetting("previewPath");
$setPreviewURL = stGetSetting("previewURL");
$setThumbDir = stGetSetting("thumbnailSubDir");
$setEntryPathPerms = stGetSetting("entryPathPerms");
$setPrevPathPerms = stGetSetting("previewPathPerms");

if ($setEntryPath === FALSE || $setPreviewPath === FALSE ||
    $setPreviewURL === FALSE || $setThumbDir === FALSE ||
    $setEntryPathPerms === FALSE || $setPrevPathPerms === FALSE)
{
  die("Some required settings not defined in mconfig.inc.php!\n");
}


// Act according to specified command
switch (substr(stCArgLC(1), 0, 3))
{
  case "ini":
    //
    // Initialize the data directories etc
    //
    stInitializeDirs();
    break;

  case "cle":
    $doDelete = (stCArgLC(2) == "delete");
    foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
    if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
    {
      printf(
        "==%'=-".($setWidth-2)."s\n".
        sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40))
        );
      echo str_repeat("-", $setWidth)."\n";

      foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
      {
        foreach (stExecSQL("SELECT * FROM files WHERE entry_id=".$entry["id"]) as $efile)
        {
          if ($efile["delete"] != 0)
          {
            echo "X";
          }
        }
      }
      echo "\n";
      echo str_repeat("-", $setWidth)."\n";
    }
    break;

  case "ent":
    //
    // Entry files handling
    //
    $mode = substr(stCArgLC(2), 0, 3);
    switch ($mode)
    {
      case "unp":
      case "sta":
        foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
        if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
        {
          printf(
            "==%'=-".($setWidth-2)."s\n".
            sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40))
            );
          echo str_repeat("-", $setWidth)."\n";

          foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
            wtHandleEntry($compo, $entry, $mode);

          echo str_repeat("-", $setWidth)."\n";
        }
        break;

      case "pac":
        break;

      case "add":
        break;

      default:
        if ($mode == "")
          die("ERROR! Entry command requires a sub-command argument.\n");
        else
          die("ERROR! Invalid entry sub-command '".stCArg(2)."'.\n");
        break;
    }
    break;

  case "pre":
    //
    // Preview files handling
    //
    $mode = substr(stCArgLC(2), 0, 3);
    switch ($mode)
    {
      case "upd":
      case "sta":
        foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
        if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
        {
          printf(
            "==%'=-".($setWidth-2)."s\n".
            "PrevType : %s\n",
            sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40)),
            $previewTypeList[$compo["preview_type"]][0]);
          
          printf(" %-3s | %-3s | %-40s |\n",
            "#ID", "FLG", "Entry name/author");
          
          echo str_repeat("-", $setWidth)."\n";

          foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
            wtHandleEntryPreview($compo, $entry, $mode);

          echo str_repeat("=", $setWidth)."\n\n";
        }
        break;

      case "add":
        break;

      default:
        if ($mode == "")
          die("ERROR! Previews command requires a sub-command argument.\n");
        else
          die("ERROR! Invalid previews sub-command '".stCArg(2)."'.\n");
        break;
    }
    break;

  default:
    echo "ERROR! Invalid operation mode '".stCArg(1)."'.\n";
    break;
}

?>