view faptool.php @ 1120:b2bca5f6d0ff default tip

Cosmetic cleanup: remove trailing whitespace.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 13 Dec 2020 13:47:13 +0200
parents 0a2117349f46
children
line wrap: on
line source

#!/usr/bin/php
<?php
//
// FAPWeb - Simple Web-based Demoparty Management System
// Special entry/preview/etc backend management commandline utility
// (C) Copyright 2014-2017 Tecnic Software productions (TNSP)
//
if (!file_exists(realpath(dirname(__FILE__))."/mconfig.inc.php"))
{
  die(
    "ERROR: Missing site configuration file. Please copy ".
    "'mconfig.inc.php.example' to 'mconfig.inc.php' and ".
    "edit it as needed.\n");
}

require_once "mconfig.inc.php";
require_once "msite.inc.php";


function wtGetExecutable($name, $path = FALSE)
{
  if (stChkSetting($name."_exe"))
    return stGetSetting($name."_exe");
  else
    return $name;
}


function wtGetExecutableArgs($name)
{
  if (stChkSetting($name."_args"))
    return " ".stGetSetting($name."_args")." ";
  else
    return "";
}


function wtConvertImage($inFilename, $outFilename, $outDim, $outFormat, $outQuality, $thumb, $useGfxConv)
{
  global $setPreviewPath;
  $isTemp = FALSE;

  if ($useGfxConv)
  {
    // Oh great .. we need gfxconv here because Imagick handles ILBM like shit
    $tmpFilename = tempnam($setPreviewPath, "tmp");
    $isTemp = TRUE;
    if (wtExec(wtGetExecutable("gfxconv"),
      wtGetExecutableArgs("gfxconv").
      escapeshellarg($inFilename)." -f png -o ".escapeshellarg($tmpFilename),
      0) === FALSE)
      return FALSE;

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

  // Create conversion entity
  $img = new Imagick($tmpFilename);
  if ($img === FALSE)
  {
    echo "ERROR: Oh noes! ImageMagick could not digest the file '".$tmpFilename."' (".$inFilename.")\n";
    return FALSE;
  }

  if ($outDim !== 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->setImageExtent($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->setImageExtent($outDim[0], $outDim[1]);
    }
  }

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

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


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

  return wtExec(
    wtGetExecutable("openmpt123")
    ,
    "--force --quiet ".
    "--samplerate ".$sfreq." ".
    "--channels ".$schannels." ".
    "--end-time ".($sduration)." ".
    wtGetExecutableArgs("openmpt123").
    escapeshellarg($inFilename)." -o ".escapeshellarg($outFilename),
    0);
}


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

  $optStr = "";
  foreach ($outOpts as $okey => $oval)
    $optStr .= $okey." ".$oval." ";

  return wtExec(
    wtGetExecutable("avconv"),
    wtGetExecutableArgs("avconv").
    "-y -v 1 -t ".intval($sduration)." ".
    "-i ".escapeshellarg($inFilename).
    " ".$optStr." -ac ".$schannels.
    " -map_metadata -1 ".
    escapeshellarg($outFilename));
}


function wtEntryToSource($compo, $inFilename, $edata, $entryFilename, &$outData, &$outFilename, $force)
{
  // Does compo preview type match this file class?
  if ($edata["class"] != $compo["preview_type"])
    return FALSE;

  switch ($edata["class"])
  {
    case EFILE_AUDIO: $fext = "wav"; break;
    case EFILE_IMAGE: $fext = "png"; break;
    default:
      return FALSE;
  }

  $outFilename = stReplaceFileExt($entryFilename, "_preview.".$fext);
  if (!$force && file_exists($outFilename) && filemtime($outFilename) >= filemtime($entryFilename))
    return TRUE;

  printf("GENERATING: %s -> %s\n", $inFilename, $outFilename);

  switch ($edata["class"])
  {
    case EFILE_AUDIO:
      if ($edata["mime"] == "audio/x-mod")
        $res = wtRenderSample($inFilename, $outFilename);
      else
        $res = wtConvertSample($inFilename, $outFilename,
          array("-f" => "wav"));
      break;

    case EFILE_IMAGE:
      $res = wtConvertImage(
        $inFilename,
        $outFilename,
        FALSE, "PNG", 9,
        FALSE, ($edata["mime"] == "gfx"));
        break;
  }

  return $res;
}


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

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

    case "RAR":
      $exe = wtGetExecutable("rar");
      $args = "x -w".escapeshellarg($path)." ".escapeshellarg($filename);
      break;

    case "7ZIP":
      $exe = wtGetExecutable("7z");
      $args = "x -o".escapeshellarg($path)." ".escapeshellarg($filename);
      break;

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

  // Delete any pre-existing directory
  wtPurgeDir($path);

  // Create temporary directory for unpacking
  wtMakeDir($path, 0755);

  // Save current working directory and chdir to target
  $cwd = getcwd();
  if (!is_dir($path) || chdir($path) === FALSE)
  {
    echo "ERROR: Failed to chdir to '".$path."', can't unpack archive.\n";
    return FALSE;
  }

  // Unpack archive
  $ret = wtExec($exe, $args);

  // Return to stored cwd
  chdir($cwd);
  return $ret;
}


function wtHandleEntryPreview($compo, $entry, $mode)
{
  global $fileTypeData, $setEntryPath;

  // Get current preview file(s) data
  if (!stGetPreviewFileData($compo, $entry, $pdata))
    return FALSE;

  // Get entry file data
  $efile = stFetchSQL("SELECT * FROM files WHERE deleted=0 AND id=".$entry["file_id"]);

  // Check preview file(s) status
  if ($mode == "sta" || $mode == "lis")
  {
    printf(" %03d | %s%s%s | %-40s | %-5s | %s\n",
      $entry["id"],
      ($efile !== FALSE) ? "E" : ".",
      isset($pdata["file"]) ? "P" : ".",
      $pdata["valid"] ? "V" : ".",
      substr($entry["name"]." by ".$entry["author"], 0, 40),
      isset($pdata["file"]) ? $pdata["file"]["filetype"] : "",
      isset($pdata["file"]) ? $pdata["file"]["filename"] : ""
      );
    return TRUE;
  }
  else
  if ($mode != "gen" && $mode != "upd")
    die("ERROR: Unsupported previews mode ".$mode."\n");

  $force = ($mode == "upd");

  // Check validity of previews
  if ($pdata["valid"] && !$force)
    return TRUE;

  // Okay, no valid previews .. lets see what we can do ..
  // First, check if we have a source preview file
  if (!isset($pdata["file"]))
  {
    // No source preview, check if we have entry file either?
    if ($efile === FALSE)
    {
      echo
        "INFO: No entry file for ".wtNiceName($compo, $entry, $efile).
        ", can't attempt to generate preview.\n";
      return FALSE;
    }

    // Actual entry filename + path
    $filename = stMakePath(FALSE, TRUE, array($setEntryPath, $compo["cpath"], $efile["filename"]));
    if (!file_exists($filename))
    {
      echo "ERROR: Entry file '".$filename."' for ".wtNiceName($compo, $entry, FALSE)." does not exist!\n";
      return FALSE;
    }

    // Preview source file does not exist, let's see ..
    $edata = stProbeFileInfo($filename, TRUE);
    if ($edata === FALSE)
    {
      echo
        "ERROR: Invalid/unsupported file type for entry ".wtNiceName($compo, $entry, $efile)."\n";
      return FALSE;
    }

    $found = FALSE;
    if ($edata["class"] == EFILE_ARCHIVE)
    {
      // Entry is an archive file ..
      $path = stMakePath(FALSE, FALSE, array($setEntryPath, "UNPACKS", $efile["filename"]));

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

      // Scan through files ...
      $dir = opendir($path);
      while (($dentry = readdir($dir)) !== FALSE)
      {
        $fname = $path."/".$dentry;
        if ($dentry != "." && $dentry != "..")
        {
          if (is_dir($fname))
            echo "XXX: ".$dentry." :: ".$fname."\n";
          else
          if (is_file($fname) &&
            ($mdata = stProbeFileInfo($fname, TRUE)) !== FALSE &&
            ($found = wtEntryToSource($compo, $fname, $mdata, $filename, $pdata, $outFilename, $force)) === TRUE)
            break;
        }
      }

      // Cleanup
      closedir($dir);
      wtPurgeDir($path);
    }
    else
    if ($edata["class"] == $compo["preview_type"])
    {
      // Single file
      $found = wtEntryToSource($compo, $filename, $edata, $filename, $pdata, $outFilename, $force);
    }

    if (!$found)
    {
      echo "WARNING: Could not generate preview from entry ".wtNiceName($compo, $entry, $efile)."\n";
      return FALSE;
    }

    $inFilename = $outFilename;
  }
  else
    $inFilename = stMakePath(FALSE, TRUE, array($setEntryPath, $compo["cpath"], $pdata["file"]["filename"]));

  // Check validity vs.
  if (!$force)
  {
    $valid = TRUE;
    $inMTime = filemtime($inFilename);
    foreach ($pdata["files"] as $stype => $sdata)
    {
      if (!file_exists($sdata["file"]) || filemtime($sdata["file"]) < $inMTime)
      {
        $valid = FALSE;
        break;
      }
    }
    if ($valid)
      return TRUE;
  }

  //
  // Either we now have a "user specified" source file or
  // a generated source file - in any case, now convert it
  // to the final form(s).
  //
  switch ($compo["preview_type"])
  {
    case EFILE_AUDIO:
      // Convert to each specified sample type (MP3, Ogg, etc.)
      foreach (stGetSetting("sampleTypes") as $stype => $sopts)
      {
        wtConvertSample(
          $inFilename,
          $pdata["files"][$stype]["file"],
          $sopts
          );
      }
      break;

    case EFILE_IMAGE:
      // Images we convert to bigger image and thumbnail
      wtConvertImage(
        $inFilename,
        $pdata["files"]["image"]["file"],
        stGetSetting("previewImageSize"),
        stGetSetting("previewImageType"),
        stGetSetting("previewImageQuality"),
        FALSE, FALSE);

      wtConvertImage(
        $inFilename,
        $pdata["files"]["thumb"]["file"],
        stGetSetting("previewThumbSize"),
        stGetSetting("previewThumbType"),
        stGetSetting("previewThumbQuality"),
        TRUE, FALSE);
      break;
  }

  return TRUE;
}


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


//
// Crop a filename to specified length
//
function wtCropFilename($filename, $len)
{
  if ($len !== FALSE && strlen($filename) > $len)
  {
    // Check if the filename has a path and attempt
    // to get the filename extension
    $fext = "";
    $dpos = strrpos($filename, "/");
    if (($spos = strrpos($filename, ".")) !== FALSE &&
      ($dpos === FALSE || $dpos < $spos))
      $fext = substr($filename, $spos);

    // Is the filename extension too long, if yes, just dump it
    if (strlen($fext) >= $len)
      $fext = "";

    return substr($filename, 0, $len - strlen($fext) - 1).$fext;
  }
  else
    return $filename;
}


//
// Recursively goes through directory/files and subdirectories,
// cropping file/dir names to specified length.
//
function wtCropFilenamesRec($path, $len)
{
  $dir = opendir($path);
  while (($dentry = readdir($dir)) !== FALSE)
  {
    $fname = $path."/".$dentry;
    $nname = $path."/".wtCropFilename($dentry, $len);
    if ($dentry != "." && $dentry != "..")
    {
      if (is_dir($fname))
      {
        wtCropFilenamesRec($fname, $len);
        if (rename($fname, $nname) === FALSE)
        {
          echo "ERROR: Could not rename DIR '".$fname."' -> '".$nname."'.\n";
          return FALSE;
        }
      }
      else
      if (is_file($fname) && rename($fname, $nname) === FALSE)
      {
        echo "ERROR: Could not rename FILE '".$fname."' -> '".$nname."'.\n";
        return FALSE;
      }
    }
  }
  closedir($dir);
}


function wtUnpackEntry($compo, $entry, $pathPrefix, $useOrig, $cropNames, $copyOnly)
{
  global $setEntryPath;

  // Get latest file for the entry
  if (($efile = stFetchSQL("SELECT * FROM files WHERE deleted=0 AND id=".$entry["file_id"])) === FALSE)
  {
    echo "INFO: No entry file for ".wtNiceName($compo, $entry, $efile)."\n";
    return FALSE;
  }

  // Create source file full path
  $filename = stMakePath(FALSE, TRUE, array($setEntryPath, $compo["cpath"], $efile["filename"]));

  // Check if the file exists
  if (!file_exists($filename))
  {
    echo "ERROR: Entry file '".$filename."' for ".wtNiceName($compo, $entry, FALSE)." does not exist!\n";
    return FALSE;
  }

  // Get file data
  $edata = stProbeFileInfo($filename, TRUE);
  if ($edata === FALSE)
  {
    echo
      "ERROR: Invalid/unsupported file type for entry ".wtNiceName($compo, $entry, $efile)."\n";
    return FALSE;
  }

  // Make information file contents
  $sbinfo = [
    "FAP Entry Information",
    "=====================",
    "Compo  : ".$compo["name"]." (ID #".$compo["id"].")",
    "Entry  : '".$entry["name"]."' by ".$entry["author"]." (ID #".$entry["id"].")",
    "Show # : ".($entry["show_id"] > 0 ? $entry["show_id"] : "NOT SET!"),
  ];

  if (strlen($entry["info"]) > 0)
  {
    $sbinfo[] = "";
    $sbinfo[] = "INFO:";
    foreach (preg_split("/\r\n|\n|\r/", $entry["info"]) as $sline)
      $sbinfo[] = $sline;
  }

  if (strlen($entry["notes"]) > 0)
  {
    $sbinfo[] = "";
    $sbinfo[] = "INTERNAL NOTES:";
    foreach (preg_split("/\r\n|\n|\r/", $entry["notes"]) as $sline)
      $sbinfo[] = $sline;
  }

  $sbinfo[] = "";
  $sbinfoStr = implode("\n", $sbinfo);

  // Create the destination directory
  if (wtMakeDir(stMakePath(FALSE, FALSE, array($pathPrefix, $compo["cpath"])), 0755) === FALSE)
    return FALSE;

  // Form the destination path and/or filename
  if ($copyOnly)
    $dstFileBase = $useOrig ? $efile["origname"] : $efile["filename"];
  else
    $dstFileBase = wtCropFilename($entry["show_id"]."-".($useOrig ? $efile["origname"] : $efile["filename"]), $cropNames);

  $dstPath = stMakePath(FALSE, FALSE, array($pathPrefix, $compo["cpath"], stReplaceFileExt($dstFileBase, "")));

  // Handle based on class/type and whether we are just copying or not
  if ($copyOnly)
  {
    $dstFilename = stMakePath(FALSE, FALSE, array($pathPrefix, $compo["cpath"], $dstFileBase));
    if (copy($filename, $dstFilename) === FALSE)
    {
      echo "ERROR: Failed to copy '".$filename."' to '".$dstFilename."'\n";
      return FALSE;
    }
  }
  else
  if ($edata["class"] == EFILE_ARCHIVE)
  {
    // Entry is an archive file, so unpack it
    if (wtUnpackArchiveTo($edata["id"], $filename, $dstPath) === FALSE)
      return FALSE;

    // Crop the filenames from the unpacked archive, if we need to
    if ($cropNames !== FALSE)
      wtCropFilenamesRec($dstPath, $cropNames);

  }
  else
  {
    // We have a single file (or copyOnly mode)
    if (wtMakeDir($dstPath, 0755) === FALSE)
      return FALSE;

    $dstFilename = stMakePath(FALSE, FALSE, array($dstPath, wtCropFilename($efile["origname"], $cropNames)));
    if (copy($filename, $dstFilename) === FALSE)
    {
      echo "ERROR: Failed to copy '".$filename."' to '".$dstFilename."'\n";
      return FALSE;
    }
  }

  $dstFilename = stMakePath(FALSE, FALSE, array($dstPath, "fapinfo.txt"));
  if (@file_put_contents($dstFilename, $sbinfoStr) === FALSE)
  {
    echo "ERROR: Failed to output '".$dstFilename."'\n";
    return FALSE;
  }

  return TRUE;
}


//
// Misc helper functions
//

function wtNiceName($compo, $entry, $efile = FALSE)
{
  return sprintf(
    "%d: %s by %s%s",
    $entry["id"],
    $entry["name"],
    $entry["author"],
    ($efile !== FALSE) ? " [".$efile["filename"]." / TYPE: '".$efile["filetype"]."']" : "");
}


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 wtPurgeDir($path)
{
  if ($path != "" && $path !== FALSE && file_exists($path) && is_dir($path))
  {
//    echo "PURGING: ".$path."\n";
    foreach (scandir($path) as $file)
    if ($file !== "." && $file !== "..")
    {
      $sub = $path."/".$file;
      if (is_dir($sub))
        wtPurgeDir($sub);
      else
        unlink($sub);
    }
    rmdir($path);
  }
}


function wtMakeDir($path, $perm)
{
  if (!file_exists($path))
  {
    echo "INFO: Creating ".$path."\n";
    if (mkdir($path, $perm, TRUE) === FALSE)
      die("Could not create directory '".$path."'\n");
  }
}


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

  echo "Checking for missing directories ...\n";
  wtMakeDir($setEntryPath, $setEntryPathPerms);
  wtMakeDir($setPreviewPath, $setPrevPathPerms);

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


function wtPrintCompoHeader($compo)
{
  global $setTermWidth;
  printf("==%'=-".($setTermWidth-2)."s\n",
    sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40))
    );
}


function wtPrintDivider($chr = "-")
{
  global $setTermWidth;
  echo str_repeat($chr, $setTermWidth)."\n";
}


function wtShowHelp()
{
  global $argv;
  echo
    "faptool - Do stuff with FAPWeb database\n".
    "(C) Copyright 2014-2017 ccr/TNSP\n".
    "\n".
    "Usage: ".$argv[0]." <command> [args]\n".
    "Where command is one of following:\n".
    "\n".
    "  init\n".
    "     Create directories for entries and previews, if needed.\n".
    "\n".
/*
    "  clean [delete|crap]\n".
    "     Clean files marked to be deleted and 'stale' files. This includes\n".
    "     any old or stale preview files and entry files.\n".
    "     Without 'delete' parameter just checks and shows what would deleted.\n".
    "     'crap' parameter will purge EVERYTHING that is NOT in the database,\n".
    "     e.g. any other files, like temp files, etc. DANGEROUS IF YOU DO NOT\n".
    "     KNOW WHAT YOU ARE DOING!!!!!\n".
    "\n".
*/
    "  probe <filename> [filename2 ..]\n".
    "     Probe specified file for file information.\n".
    "\n".
    "  previews <cmd> [args]\n".
    "    Where <cmd> is one of:\n".
    "    status [cid]  - List files and show what is missing, etc. (All or <cid>)\n".
    "    generate   - Generate preview files that are missing OR out of date.\n".
    "               (older then preview source file OR entry file where appropriate)\n".
    "\n".
    "  entry <cmd> [args]\n".
    "    status [cid]  - List entries for all compos or <cid>.\n".
    "    unpack <path> - Create subdirs and copy all entries UNPACKED there.\n".
    "    release <path> - Like unpack, but just copies files (does not unpack archives).\n".
    "\n".
    "    add <cid> <filename> - Add a new entry with file.\n".
    "       Entry info + notes for internal use will be prompted.\n".
    "    pre <eid> <filename> - Add file as preview for entry id.\n".
    "    del <eid> - Delete entry (does not delete files).\n".
/*
    "\n".
    "    package <lha|zip|rar|7z>\n".
    "       Repackages/packages entries (unpacks first if archive),\n".
    "       and adds generated infofile.txt to packages.\n".
*/
    "\n";
}


function wtSigHandler($signo)
{
  global $flagQuit;
  switch ($signo)
  {
    case SIGTERM:
      mgFatal("Received SIGTERM.\n");
      break;

    case SIGQUIT:
    case SIGINT:
      $flagQuit = TRUE;
      break;
  }
}


//
// Main program starts
//
stCheckCLIExec();
if ($argc < 2)
{
  wtShowHelp();
  exit;
}

pcntl_signal(SIGTERM, "wtSigHandler");
pcntl_signal(SIGHUP,  "wtSigHandler");
pcntl_signal(SIGQUIT, "wtSigHandler");
pcntl_signal(SIGINT,  "wtSigHandler");

// 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
$setTermWidth = 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 are not defined in mconfig.inc.php!\n");
}


// Act according to specified command
switch (stCArgLC(1, 3))
{
  case "-?": case "--h":
    wtShowHelp();
    exit;
    break;

  case "ini":
    //
    // Initialize the data directories etc
    //
    echo "INFO: Checking for missing directories ...\n";
    wtInitializeDirs();
    break;

  case "pro":
    //
    // Probe specified files
    //
    if ($argc < 2)
      die("No filename specified.\n");

    if (($finfo = finfo_open()) === FALSE)
      die("Internal error. Failed to initialize finfo().");

    for ($i = 2; $i < $argc; $i++)
    {
      // Probe one file
      $filename = $argv[$i];
      $sdata = @finfo_file($finfo, $filename, FILEINFO_NONE);
      $smime = @finfo_file($finfo, $filename, FILEINFO_MIME_TYPE);

      echo
        "\n".
        "File   : ".$filename."\n".
        "Probed : ".$sdata."\n".
        "Mime   : ".$smime."\n";

      if (($info = stProbeFileInfo($filename, TRUE)) !== FALSE)
      {
        $tmp = array();
        foreach ($info as $ikey => $ival)
          $tmp[] = $ikey."='".$ival."'";

        echo "Data   : ".implode(", ", $tmp)."\n";
      }
    }

    finfo_close($finfo);
    break;

  case "cle":
    //
    // File cleanup / deletion
    //
    $mode = stCArgLC(2, 3);
    switch ($mode)
    {
      case "del":
      case FALSE:
        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)
        {
          wtPrintCompoHeader($compo);
          wtPrintDivider();

          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["deleted"] != 0)
              {
                echo "X";
              }
            }
          }
          echo "\n";
          wtPrintDivider();
        }
        break;

      case "cra":
        echo "Not implemented. :D\n";
        break;

      default:
        die("ERROR! Invalid entry sub-command '".stCArg(2)."'.\n");
        break;
    }
    break;

  case "ent":
    //
    // Entry files handling
    //
    $mode = stCArgLC(2, 3);
    switch ($mode)
    {
      case "sta":
      case "lis":
        $sql = (stCArg(3) !== FALSE) ? " AND id=".intval(stCArg(3)) : "";
        foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL".$sql) as $compo)
        if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
        {
          wtPrintCompoHeader($compo);
          wtPrintDivider();

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

          wtPrintDivider();
        }
        break;

      case "unp":
        if (($setPrefix = stCArg(3)) === FALSE)
          die("Unpack needs a destination path.\n");

        foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
        foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
        {
//          wtUnpackEntry($compo, $entry, $setPrefix, TRUE, 32, FALSE);
          wtUnpackEntry($compo, $entry, $setPrefix, TRUE, FALSE, FALSE);
        }
        break;

      case "rel":
        if (($setPrefix = stCArg(3)) === FALSE)
          die("Releases needs a destination path.\n");

        if (!file_exists($setPrefix) || is_dir($setPrefix))
        {
          // Create new one
          wtMakeDir($setPrefix, 0755);

          // Create results.txt if it does not exist
          $resultsFile = stMakePath(FALSE, TRUE, array($setPrefix, "results.txt"));
          if (!file_exists($resultsFile))
          {
            // Use a header file if it exists
            $resultsHeader = "results.logo";
            if (file_exists($resultsHeader) && is_file($resultsHeader))
              $resultsText = file_get_contents($resultsHeader);
            else
            {
              $resultsText = $pageTitle." results";
              $resultsText .= "\n".str_repeat("=", strlen($resultsText))."-- -\n\n";
            }

            file_put_contents(
              $resultsFile,
              $resultsText.stGetCompoResultsASCIIStr(FALSE, 0)
              );
          }

          foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
          foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
          {
            wtUnpackEntry($compo, $entry, $setPrefix, TRUE, FALSE, TRUE);
          }
        }
        break;

      case "pac":
        echo "Not implemented. :D\n";
        break;

      case "add":
        echo "Not implemented. :D\n";
        break;

      default:
        if ($mode == FALSE)
          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 = stCArgLC(2, 3);
    switch ($mode)
    {
      case "gen":
      case "upd":
      case "sta":
      case "lis":
        $sql = (stCArg(3) !== FALSE) ? " AND id=".intval(stCArg(3)) : "";
        foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL".$sql) as $compo)
        if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
        {
          wtPrintCompoHeader($compo);
          printf(
            "PrevType : %s\n",
            $previewTypeList[$compo["preview_type"]][0]);

          if ($mode == "sta" || $mode == "lis")
          {
            printf(" %-3s | %-3s | %-40s |\n",
              "#ID", "EPV", "Entry name/author");
          }

          wtPrintDivider("-");

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

          wtPrintDivider("=");
        }
        if ($mode == "sta" || $mode == "lis")
        {
          echo "Flags: E = Entry has file, P = Has preview file, V = Generated previews are up to date.\n";
        }
        break;

      default:
        if ($mode == FALSE)
          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;
}

/* Dummy
{

}
*/
?>