<?php
if (empty($_SESSION)) {
  session_start();
}
date_default_timezone_set('Europe/Paris');
// change if you want no inpact
$GLOBALS['config']['onlyLocalServer'] = false;
// soshot only accept request by 127.0.0.1
$GLOBALS['config']['NoWebPage'] = false;
// No form for post url only acces by GET method
$GLOBALS['config']['maxErrorBeforeBan'] = 3;
// After 3 criticla error ban user
$GLOBALS['config']['banTime'] = 60;
// Ban for 60 minutes
$GLOBALS['config']['defaultUrl'] = 'https://google.com';
// default url for form
$GLOBALS['config']['defaultThumbSize'] = '120x90';
// default size for thumbnail
$GLOBALS['config']['onlyThumb'] = true;
// generate only thumbnail or generate thumb nail + 1280x1024 image
$GLOBALS['config']['thumbSize'] = array(1 => '100x80', '120x90', '200x160', '300x240', '400x320', '500x400');
// list of available size for thumb

if (!file_exists('cache/config/genConf.php')) {
  install();
}

require 'cache/config/genConf.php';
$ui = '';

if (($GLOBALS['config']['onlyLocalServer'] === true && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1') || checkIfBan() === true) {
  header("HTTP/1.0 404 Not Found");
  echo "<h1>404 Not Found</h1>";
  echo "The page that you have requested could not be found.";
  exit();
}

if ($GLOBALS['config']['NoWebPage'] === true && empty($_GET)) {
  header("HTTP/1.0 404 Not Found");
  echo "<h1>404 Not Found</h1>";
  echo "The page that you have requested could not be found.";
  exit();
}

if (get_magic_quotes_gpc()) {
  function stripslashes_deep($value) {
    $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    return $value;
  }

  $_POST = array_map('stripslashes_deep', $_POST);
  $_GET = array_map('stripslashes_deep', $_GET);
  $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
}

function testExistImg($file) {
  if ($GLOBALS['config']['onlyThumb'] === true) {
    if (file_exists($file . '_thumb.png')) {
      return true;
    } else {
      return false;
    }
  } else {
    if (file_exists($file . '_thumb.png') && file_exists($file . '.png')) {
      return true;
    } else {
      return false;
    }
  }
}

function launchScript($url, $md5Url, $width, $waitForResult = false) {
  $md5Url = escapeshellarg($md5Url);
  $url = escapeshellarg($url);
  $width = escapeshellarg($width);
  if ($waitForResult === false) {
    exec('bin/thumb_server.sh ' . $url . ' ' . $md5Url . ' ' . $width . ' ' . (bool)$GLOBALS['config']['onlyThumb'] . ' > /dev/null &', $result);
  } else {
    exec('bin/thumb_server.sh ' . $url . ' ' . $md5Url . ' ' . $width . ' ' . (bool)$GLOBALS['config']['onlyThumb'] . ' 1', $result);
  }
  return $result;
}

function testValidUrl($url) {
  if (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED)) {
    $url = parse_url($url);
    if (!in_array($url['scheme'], array('http', 'https'))) {
      return array('msg' => 'Url must be start by http or https.');
    }
    return true;
  } else {
    return array('msg' => 'Url are not valid.');
  }
}

function genToken() {
  $token = sha1(uniqid(rand(), true) . '_' . mt_rand());
  $_SESSION['token'] = $token;
  return $token;
}

function verifToken($token) {
  if ($token !== $_SESSION['token']) {
    ban();
    die('So Long, and Thanks for All the Fish.');
  }
}

function checkIfBan() {
  require 'cache/logs/banUser.php';
  $userIp = $_SERVER['REMOTE_ADDR'];
  if (isset($banList[$userIp]) && $banList[$userIp]['nbBan'] >= $GLOBALS['config']['maxErrorBeforeBan'] && $banList[$userIp]['lastBan'] + $GLOBALS['config']['banTime'] > time()) {
    return true;
  } elseif (isset($banList[$userIp]) && $banList[$userIp]['lastBan'] + $GLOBALS['config']['banTime'] < time()) {
    unban();
    return false;
  } else {
    return false;
  }
}

function ban() {
  require 'cache/logs/banUser.php';
  $userIp = $_SERVER['REMOTE_ADDR'];
  if (isset($banList[$userIp])) {
    $banList[$userIp]['lastBan'] = time();
    $banList[$userIp]['nbBan']++;
  } else {
    $banList[$userIp]['lastBan'] = time();
    $banList[$userIp]['nbBan'] = 1;
  }
  file_put_contents('cache/logs/banUser.php', "<?php\n\$banList=" . var_export($banList, true) . ";\n?>");
}

function unBan() {
  require 'cache/logs/banUser.php';
  $userIp = $_SERVER['REMOTE_ADDR'];
  unset($banList[$userIp]);
  file_put_contents('cache/logs/banUser.php', "<?php\n\$banList=" . var_export($banList, true) . ";\n?>");
}

function install() {
  if (!is_writable('cache')) {
    die('Make dir "cache" writable');
  }
  if (!mkdir('cache/config', 0705)) {
    die('Error on create dir "cache/config".');
  }
  if (!mkdir('cache/img', 0705)) {
    die('Error on create dir "cache/img".');
  }
  if (!mkdir('cache/logs', 0705)) {
    die('Error on create dir "cache/logs".');
  }
  if (!mkdir('cache/tmp', 0705)) {
    die('Error on create dir "cache/tmp".');
  }
  $salt = sha1(uniqid(rand(), true) . '_' . mt_rand());
  $serverKey = substr(sha1(uniqid(rand(), true) . '_' . mt_rand() . $salt), 0, 12);
  $encryptServerKey = sha1($serverKey . $salt);

  if (!is_file('cache/config/genConf.php')) {
    file_put_contents('cache/config/genConf.php', "<?php\n\$GLOBALS['config']['serverKey'] = '$encryptServerKey';\n\$GLOBALS['config']['salt'] = '$salt';\n?>");
  }
  if (!is_file('cache/logs/banUser.php')) {
    file_put_contents('cache/logs/banUser.php', "<?php\n\n?>");
  }
  if (!is_file('cache/logs/log.php')) {
    touch('cache/logs/log.php');
  }
  echo '<div>This is the key for generate thumbnail whith GET method. Save it, this key is secret, don\'t share it. <p class="alert">', $serverKey, '</p></div>';
  checkInstall();
}

function checkInstall() {
  if (!is_file('.htaccess')) {
    file_put_contents('.htaccess', "AddDefaultCharset UTF-8\nOptions -Indexes\nDirectoryIndex index.php index.html\nFileETag none\nSetOutputFilter DEFLATE\n");
  }
  if (!is_file('cache/logs/.htaccess')) {
    file_put_contents('cache/logs/.htaccess', "Allow from none\nDeny from all\n");
  }
  if (!is_file('cache/config/.htaccess')) {
    file_put_contents('cache/config/.htaccess', "Allow from none\nDeny from all\n");
  }
  if (!is_file('bin/.htaccess')) {
    file_put_contents('bin/.htaccess', "Allow from none\nDeny from all\n");
  }
}

checkInstall();
if ($_GET) {
  $ui = $_GET;
  unset($_GET);
  if (empty($ui['key']) || empty($ui['url'])) {
    die('Are you Ken ?');
  }
  if (sha1($ui['key'] . $GLOBALS['config']['salt']) !== $GLOBALS['config']['serverKey']) {
    ban();
    die('I take a chips and give it to Godzilla. I print a shoes and .............. KAMOULOX ! Well done Jean Pierre.');
  }

  $ui['url'] = urldecode($ui['url']);
  $testUrl = testValidUrl($ui['url']);
  if ($testUrl !== true) {
    echo $testUrl['msg'];
    exit();
  }

  $defUrl = $ui['url'];
  if (isset($ui['s']) && (int)$ui['s']) {
    $width = $GLOBALS['config']['thumbSize'][$ui['s']];
  } else {
    $width = $GLOBALS['config']['defaultThumbSize'];
  }

  $md5Url = md5($defUrl);
  $file = 'cache/img/' . $md5Url;

  if (testExistImg($file) !== true || isset($ui['fr']) && (int)$ui['fr'] === 1) {
    if (isset($ui['iw']) && (int)$ui['iw'] === 1) {
      launchScript($defUrl, $md5Url, $width, true);
    } else {
      $res = launchScript($defUrl, $md5Url, $width);
      header("Content-type: image/png");
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
      echo file_get_contents('bin/loadingGen.png');
      exit();
    }
  }
  header("Content-type: image/png");
  header('Expires: ', gmdate('D, d M Y H:i:s', time()) . ' GMT');
  if (!empty($ui['t']) && $ui['t'] === 'full') {
    echo file_get_contents($file . '.png');
  } else {
    echo file_get_contents($file . '_thumb.png');
  }
  exit();
}

if ($_POST) {
  $ui = $_POST;
  unset($_POST);
  if (empty($ui['url'])) {
    die('No url, no thumb');
  }
  verifToken($ui['token']);

  $ui['url'] = urldecode($ui['url']);

  $testUrl = testValidUrl($ui['url']);
  if ($testUrl !== true) {
    echo $testUrl['msg'];
    exit();
  }

  $defUrl = $ui['url'];

  if (isset($ui['s']) && (int)$ui['s']) {
    $width = $GLOBALS['config']['thumbSize'][$ui['s']];
  } else {
    $width = $GLOBALS['config']['defaultThumbSize'];
  }

  $md5Url = md5($defUrl);
  $file = 'cache/img/' . $md5Url;

  if (testExistImg($file) !== true || isset($ui['fr']) && (int)$ui['fr'] === 1) {
    launchScript($defUrl, $md5Url, $width, true);
  }
  $success = array('normal' => $file . '.png', 'thumb' => $file . '_thumb.png');
}

if (empty($defUrl)) {
  $defUrl = $GLOBALS['config']['defaultUrl'];
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>KT WebThumb</title>
    <meta name="description" content="My web thumbnailer">
    <link rel="stylesheet" href="inc/style.css">
  </head>
  <body>
    <form method="post">
      <p>
        <input type="url" placeholder="<?php echo $defUrl; ?>" value="<?php echo $defUrl; ?>" name="url"/>
      </p>
      <p>
        <label>Size</label>
        <select name="s">
          <?php
          foreach ($GLOBALS['config']['thumbSize'] as $key => $value) {
            if ($value === $GLOBALS['config']['defaultThumbSize']) {
              echo '<option value="', $key, '" selected="selected">', $value, '</option>';
            } else {
              echo '<option value="', $key, '">', $value, '</option>';
            }
          }
          ?>
        </select>
        <label>Force refresh</label>
        <input type="checkbox" value="1" name="fr" />
      </p>
      <p>
        <input type="hidden" name="token" value="<?php echo genToken(); ?>" />
        <input type="submit" value="Generate"/>
      </p>
      <p class="info">
        <a href="http://forge.leslibres.org/projects/soshot">Homepage</a>
      </p>
    </form>
    <div id="result">
      <?php
      if (!empty($success)) {
        if ($GLOBALS['config']['onlyThumb'] === true) {
          echo '<img src="', $success['thumb'], '?r=', time(), '"/>';
        } else {
          echo '<a href="', $success['normal'], '"><img src="', $success['thumb'], '?r=', time(), '"/></a>';
        }
      }
      ?>
    </div>
  </body>
</html>
