More refactorings.

This commit is contained in:
Lars Jung 2014-05-15 13:04:37 +02:00
parent fc8a0589dd
commit c40fac67d0
9 changed files with 279 additions and 332 deletions

View file

@ -16,7 +16,7 @@ class Api {
$options = $this->app->get_options(); $options = $this->app->get_options();
list($action) = use_request_params(array("action")); $action = use_request_param("action");
if ($action === "get") { if ($action === "get") {
@ -24,50 +24,54 @@ class Api {
if (has_request_param("options")) { if (has_request_param("options")) {
use_request_params("options"); use_request_param("options");
$response["options"] = $this->app->get_options(); $response["options"] = $this->app->get_options();
} }
if (has_request_param("types")) { if (has_request_param("types")) {
use_request_params("types"); use_request_param("types");
$response["types"] = $this->app->get_types(); $response["types"] = $this->app->get_types();
} }
if (has_request_param("langs")) { if (has_request_param("langs")) {
use_request_params("langs"); use_request_param("langs");
$response["langs"] = $this->app->get_l10n_list(); $response["langs"] = $this->app->get_l10n_list();
} }
if (has_request_param("l10n")) { if (has_request_param("l10n")) {
list($iso_codes) = use_request_params("l10nCodes", "l10n"); use_request_param("l10n");
$iso_codes = use_request_param("l10nCodes");
$iso_codes = explode(":", $iso_codes); $iso_codes = explode(":", $iso_codes);
$response["l10n"] = $this->app->get_l10n($iso_codes); $response["l10n"] = $this->app->get_l10n($iso_codes);
} }
if (has_request_param("checks")) { if (has_request_param("checks")) {
use_request_params("checks"); use_request_param("checks");
$response["checks"] = $this->app->get_server_checks(); $response["checks"] = $this->app->get_server_checks();
} }
if (has_request_param("server")) { if (has_request_param("server")) {
use_request_params("server"); use_request_param("server");
$response["server"] = $this->app->get_server_details(); $response["server"] = $this->app->get_server_details();
} }
if (has_request_param("custom")) { if (has_request_param("custom")) {
list($abs_href) = use_optional_request_params("customHref", "custom"); use_request_param("custom");
$abs_href = use_request_param("customHref", null);
$response["custom"] = $this->app->get_customizations($abs_href); $response["custom"] = $this->app->get_customizations($abs_href);
} }
if (has_request_param("items")) { if (has_request_param("items")) {
list($abs_href, $what) = use_optional_request_params("itemsHref", "itemsWhat", "items"); use_request_param("items");
$abs_href = use_request_param("itemsHref", null);
$what = use_request_param("itemsWhat", null);
$what = is_numeric($what) ? intval($what, 10) : 1; $what = is_numeric($what) ? intval($what, 10) : 1;
$response["items"] = $this->app->get_items($abs_href, $what); $response["items"] = $this->app->get_items($abs_href, $what);
} }
@ -91,15 +95,19 @@ class Api {
json_fail(2, "thumbnails not supported"); json_fail(2, "thumbnails not supported");
} }
list($type, $src_abs_href, $mode, $width, $height) = use_request_params(array("type", "href", "mode", "width", "height")); $type = use_request_param("type");
$src_url = use_request_param("href");
$mode = use_request_param("mode");
$width = use_request_param("width");
$height = use_request_param("height");
$thumb = new Thumb($this->app); $thumb = new Thumb($this->app);
$thumb_href = $thumb->thumb($type, $src_abs_href, $mode, $width, $height); $thumb_url = $thumb->thumb($type, $src_url, $mode, $width, $height);
if ($thumb_href === null) { if ($thumb_url === null) {
json_fail(3, "thumbnail creation failed"); json_fail(3, "thumbnail creation failed");
} }
json_exit(array("absHref" => $thumb_href)); json_exit(array("absHref" => $thumb_url));
} }
@ -107,7 +115,9 @@ class Api {
json_fail(1, "downloads disabled", !$options["download"]["enabled"]); json_fail(1, "downloads disabled", !$options["download"]["enabled"]);
list($as, $type, $hrefs) = use_request_params(array("as", "type", "hrefs")); $as = use_request_param("as");
$type = use_request_param("type");
$hrefs = use_request_param("hrefs");
normalized_require_once("Archive.php"); normalized_require_once("Archive.php");
$archive = new Archive($this->app); $archive = new Archive($this->app);
@ -129,7 +139,7 @@ class Api {
else if ($action === "upload") { else if ($action === "upload") {
list($href) = use_request_params(array("href")); $href = use_request_param("href");
json_fail(1, "wrong HTTP method", strtolower($_SERVER["REQUEST_METHOD"]) !== "post"); json_fail(1, "wrong HTTP method", strtolower($_SERVER["REQUEST_METHOD"]) !== "post");
json_fail(2, "something went wrong", !array_key_exists("userfile", $_FILES)); json_fail(2, "something went wrong", !array_key_exists("userfile", $_FILES));
@ -139,10 +149,10 @@ class Api {
json_fail(3, "something went wrong [" . $userfile["error"] . "]", $userfile["error"] !== 0); json_fail(3, "something went wrong [" . $userfile["error"] . "]", $userfile["error"] !== 0);
json_fail(4, "folders not supported", file_get_contents($userfile["tmp_name"]) === "null"); json_fail(4, "folders not supported", file_get_contents($userfile["tmp_name"]) === "null");
$upload_dir = $this->app->get_abs_path($href); $upload_dir = $this->app->to_path($href);
$code = $this->app->get_http_code($href); $code = $this->app->get_http_code($href);
json_fail(5, "upload dir no h5ai folder or ignored", $code !== App::$MAGIC_SEQUENCE || $this->app->is_ignored($upload_dir)); json_fail(5, "upload dir no h5ai folder or ignored", $code !== MAGIC_SEQUENCE || $this->app->is_ignored($upload_dir));
$dest = $upload_dir . "/" . utf8_encode($userfile["name"]); $dest = $upload_dir . "/" . utf8_encode($userfile["name"]);
@ -157,7 +167,7 @@ class Api {
json_fail(1, "deletion disabled", !$options["delete"]["enabled"]); json_fail(1, "deletion disabled", !$options["delete"]["enabled"]);
list($hrefs) = use_request_params(array("hrefs")); $hrefs = use_request_param("hrefs");
$hrefs = explode("|:|", trim($hrefs)); $hrefs = explode("|:|", trim($hrefs));
$errors = array(); $errors = array();
@ -169,9 +179,9 @@ class Api {
$code = $this->app->get_http_code($d); $code = $this->app->get_http_code($d);
if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { if ($code == MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
$abs_path = $this->app->get_abs_path($href); $abs_path = $this->app->to_path($href);
if (!unlink($abs_path)) { if (!unlink($abs_path)) {
$errors[] = $href; $errors[] = $href;
@ -191,16 +201,17 @@ class Api {
json_fail(1, "renaming disabled", !$options["rename"]["enabled"]); json_fail(1, "renaming disabled", !$options["rename"]["enabled"]);
list($href, $name) = use_request_params(array("href", "name")); $href = use_request_param("href");
$name = use_request_param("name");
$d = normalize_path(dirname($href), true); $d = normalize_path(dirname($href), true);
$n = basename($href); $n = basename($href);
$code = $this->app->get_http_code($d); $code = $this->app->get_http_code($d);
if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { if ($code == MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
$abs_path = $this->app->get_abs_path($href); $abs_path = $this->app->to_path($href);
$folder = normalize_path(dirname($abs_path)); $folder = normalize_path(dirname($abs_path));
if (!rename($abs_path, $folder . "/" . $name)) { if (!rename($abs_path, $folder . "/" . $name)) {

View file

@ -2,110 +2,28 @@
class App { class App {
public static $MAGIC_SEQUENCE = "={{pkg.name}}=";
public static $FILE_PREFIX = "_{{pkg.name}}";
private static $MIN_PHP_VERSION = "5.3.0";
private static $RE_DELIMITER = "|"; private static $RE_DELIMITER = "|";
private static $CACHE_DIR = "cache";
private $is_win_os, $is_supported_php, private $options;
$server_name, $server_version,
$app_abs_path, $root_abs_path,
$app_abs_href, $root_abs_href,
$abs_href, $abs_path,
$options;
public static function from_env() { public function __construct() {
$server_name = null; $this->options = load_commented_json(APP_PATH . "/conf/options.json");
$server_version = null;
if (preg_match("#^(.*?)/(.*?)(?: |$)#", strtolower(getenv("SERVER_SOFTWARE")), $matches)) {
$server_name = $matches[1];
$server_version = $matches[2];
}
$app_abs_path = normalize_path(dirname(dirname(dirname(dirname(__FILE__)))));
$script_name = getenv("SCRIPT_NAME");
if ($server_name === "lighttpd") {
$script_name = preg_replace("#^.*//#", "/", $script_name);
}
$app_abs_href = dirname(dirname(dirname($script_name)));
$url_parts = parse_url(getenv("REQUEST_URI"));
$abs_href = $url_parts["path"];
return new App($server_name, $server_version, $app_abs_path, $app_abs_href, $abs_href);
} }
public function __construct($server_name, $server_version, $app_abs_path, $app_abs_href, $abs_href) { public function get_options() {
$this->is_win_os = strtolower(substr(PHP_OS, 0, 3)) === "win"; return $this->options;
$this->is_supported_php = version_compare(PHP_VERSION, App::$MIN_PHP_VERSION) >= 0;
$this->server_name = strtolower($server_name);
$this->server_version = strtolower($server_version);
$this->app_abs_path = normalize_path($app_abs_path);
$this->root_abs_path = normalize_path(dirname($this->app_abs_path));
$this->app_abs_href = normalize_path($app_abs_href, true);
$this->root_abs_href = normalize_path(dirname($this->app_abs_href), true);
$this->abs_href = normalize_path($abs_href, true);
$this->abs_path = $this->get_abs_path($this->abs_href);
// echo("<pre>");
// var_dump($this);
// exit();
$this->options = load_commented_json($this->app_abs_path . "/conf/options.json");
} }
public function get_root_abs_path() { public function to_url($path, $trailing_slash = true) {
return $this->root_abs_path; $rel_path = substr($path, strlen(ROOT_PATH));
} $parts = explode("/", $rel_path);
public function get_root_abs_href() {
return $this->root_abs_href;
}
public function get_app_abs_href() {
return $this->app_abs_href;
}
public function get_cache_abs_path() {
return $this->app_abs_path . '/' . App::$CACHE_DIR;
}
public function get_cache_abs_href() {
return $this->app_abs_href . App::$CACHE_DIR . '/';
}
public function get_abs_href($abs_path = null, $trailing_slash = true) {
if ($abs_path === null) {
return $this->abs_href;
}
$abs_path = substr($abs_path, strlen($this->root_abs_path));
$parts = explode("/", $abs_path);
$encoded_parts = array(); $encoded_parts = array();
foreach ($parts as $part) { foreach ($parts as $part) {
if ($part) { if ($part) {
@ -113,19 +31,14 @@ class App {
} }
} }
return normalize_path($this->root_abs_href . implode("/", $encoded_parts), $trailing_slash); return normalize_path(ROOT_URL . implode("/", $encoded_parts), $trailing_slash);
} }
public function get_abs_path($abs_href = null) { public function to_path($url) {
if ($abs_href === null) { $rel_url = substr($url, strlen(ROOT_URL));
return $this->abs_path; return normalize_path(ROOT_PATH . "/" . rawurldecode($rel_url));
}
$abs_href = substr($abs_href, strlen($this->root_abs_href));
return normalize_path($this->root_abs_path . "/" . rawurldecode($abs_href));
} }
@ -149,71 +62,64 @@ class App {
public function read_dir($path) { public function read_dir($path) {
$content = array(); $names = array();
if (is_dir($path)) { if (is_dir($path)) {
if ($dir = opendir($path)) { if ($dir = opendir($path)) {
while (($file = readdir($dir)) !== false) { while (($name = readdir($dir)) !== false) {
if (!$this->is_ignored($file) && !$this->is_ignored($this->get_abs_href($path) . $file)) { if (!$this->is_ignored($name) && !$this->is_ignored($this->to_url($path) . $name)) {
$content[] = $file; $names[] = $name;
} }
} }
closedir($dir); closedir($dir);
} }
} }
return $content; return $names;
} }
public function get_options() { public function get_http_code($url) {
return $this->options; $path = $this->to_path($url);
}
if (!is_dir($path) || strpos($path, '../') || strpos($path, '/..') || $path == '..') {
public function get_http_code($abs_href) {
$abs_path = $this->get_abs_path($abs_href);
if (!is_dir($abs_path) || strpos($abs_path, '../') || strpos($abs_path, '/..') || $abs_path == '..') {
return 500; return 500;
} }
foreach ($this->options["view"]["indexFiles"] as $if) { foreach ($this->options["view"]["indexFiles"] as $if) {
if (file_exists($abs_path . "/" . $if)) { if (file_exists($path . "/" . $if)) {
return 200; return 200;
} }
} }
$p = $abs_path; while ($path !== ROOT_PATH) {
while ($p !== $this->root_abs_path) { if (@is_dir($path . "/_h5ai/server")) {
if (@is_dir($p . "/_h5ai/server")) {
return 200; return 200;
} }
$pp = normalize_path(dirname($p)); $parent_path = normalize_path(dirname($path));
if ($pp === $p) { if ($parent_path === $path) {
return 200; return 200;
} }
$p = $pp; $path = $parent_path;
} }
return App::$MAGIC_SEQUENCE; return MAGIC_SEQUENCE;
} }
public function get_generic_json() { public function get_generic_json() {
return json_encode(array("items" => $this->get_items($this->abs_href, 1))) . "\n"; return json_encode(array("items" => $this->get_items(CURRENT_URL, 1))) . "\n";
} }
public function get_items($abs_href, $what) { public function get_items($url, $what) {
$code = $this->get_http_code($abs_href); $code = $this->get_http_code($url);
if ($code != App::$MAGIC_SEQUENCE) { if ($code !== MAGIC_SEQUENCE) {
return array(); return array();
} }
$cache = array(); $cache = array();
$folder = Item::get($this, $this->get_abs_path($abs_href), $cache); $folder = Item::get($this, $this->to_path($url), $cache);
// add content of subfolders // add content of subfolders
if ($what >= 2 && $folder !== null) { if ($what >= 2 && $folder !== null) {
@ -242,7 +148,7 @@ class App {
public function get_fallback() { public function get_fallback() {
$cache = array(); $cache = array();
$folder = Item::get($this, $this->abs_path, $cache); $folder = Item::get($this, CURRENT_PATH, $cache);
$items = $folder->get_content($cache); $items = $folder->get_content($cache);
uasort($items, array("Item", "cmp")); uasort($items, array("Item", "cmp"));
@ -257,7 +163,7 @@ class App {
if ($folder->get_parent($cache)) { if ($folder->get_parent($cache)) {
$html .= "<tr>"; $html .= "<tr>";
$html .= "<td><img src='" . $this->app_abs_href . "client/icons/96/folder-parent.png' alt='folder-parent'/></td>"; $html .= "<td><img src='" . APP_URL . "client/icons/96/folder-parent.png' alt='folder-parent'/></td>";
$html .= "<td><a href='..'>Parent Directory</a></td>"; $html .= "<td><a href='..'>Parent Directory</a></td>";
$html .= "<td></td>"; $html .= "<td></td>";
$html .= "<td></td>"; $html .= "<td></td>";
@ -268,8 +174,8 @@ class App {
$type = $item->is_folder ? "folder" : "default"; $type = $item->is_folder ? "folder" : "default";
$html .= "<tr>"; $html .= "<tr>";
$html .= "<td><img src='" . $this->app_abs_href . "client/icons/96/" . $type . ".png' alt='" . $type . "'/></td>"; $html .= "<td><img src='" . APP_URL . "client/icons/96/" . $type . ".png' alt='" . $type . "'/></td>";
$html .= "<td><a href='" . $item->abs_href . "'>" . basename($item->abs_path) . "</a></td>"; $html .= "<td><a href='" . $item->url . "'>" . basename($item->path) . "</a></td>";
$html .= "<td>" . date("Y-m-d H:i", $item->date) . "</td>"; $html .= "<td>" . date("Y-m-d H:i", $item->date) . "</td>";
$html .= "<td>" . ($item->size !== null ? intval($item->size / 1000) . " KB" : "" ) . "</td>"; $html .= "<td>" . ($item->size !== null ? intval($item->size / 1000) . " KB" : "" ) . "</td>";
$html .= "</tr>"; $html .= "</tr>";
@ -283,19 +189,19 @@ class App {
public function get_types() { public function get_types() {
return load_commented_json($this->app_abs_path . "/conf/types.json"); return load_commented_json(APP_PATH . "/conf/types.json");
} }
public function get_l10n_list() { public function get_l10n_list() {
$langs = array(); $langs = array();
$l10nDir = $this->app_abs_path . "/conf/l10n"; $l10n_path = APP_PATH . "/conf/l10n";
if (is_dir($l10nDir)) { if (is_dir($l10n_path)) {
if ($dir = opendir($l10nDir)) { if ($dir = opendir($l10n_path)) {
while (($file = readdir($dir)) !== false) { while (($file = readdir($dir)) !== false) {
if (ends_with($file, ".json")) { if (ends_with($file, ".json")) {
$translations = load_commented_json($l10nDir . "/" . $file); $translations = load_commented_json($l10n_path . "/" . $file);
$langs[basename($file, ".json")] = $translations["lang"]; $langs[basename($file, ".json")] = $translations["lang"];
} }
} }
@ -313,16 +219,16 @@ class App {
$iso_codes = func_get_args(); $iso_codes = func_get_args();
} }
$result = array(); $results = array();
foreach ($iso_codes as $iso_code) { foreach ($iso_codes as $iso_code) {
if ($iso_code !== "") { if ($iso_code !== "") {
$file = $this->app_abs_path . "/conf/l10n/" . $iso_code . ".json"; $file = APP_PATH . "/conf/l10n/" . $iso_code . ".json";
$result[$iso_code] = load_commented_json($file); $results[$iso_code] = load_commented_json($file);
$result[$iso_code]["isoCode"] = $iso_code; $results[$iso_code]["isoCode"] = $iso_code;
} }
} }
return $result; return $results;
} }
@ -330,35 +236,35 @@ class App {
$results = array(); $results = array();
$results["path_index"] = $this->app_abs_href . "server/php/index.php"; $results["path_index"] = INDEX_URL;
$results["path_cache_writable"] = @is_writable($this->get_cache_abs_path()); $results["path_cache_writable"] = @is_writable(CACHE_PATH);
$results["php_version"] = PHP_VERSION; $results["php_version"] = PHP_VERSION;
$results["php_version_supported"] = $this->is_supported_php; $results["php_version_supported"] = IS_PHP_VERSION_SUPPORTED;
$results["php_exif"] = function_exists("exif_thumbnail"); $results["php_exif"] = function_exists("exif_thumbnail");
$gd = false; $php_jpg = false;
if (function_exists("gd_info")) { if (function_exists("gd_info")) {
$gdinfo = gd_info(); $infos = gd_info();
$gd = array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"]; $php_jpg = array_key_exists("JPG Support", $infos) && $infos["JPG Support"] || array_key_exists("JPEG Support", $infos) && $infos["JPEG Support"];
} }
$results["php_jpg"] = $gd; $results["php_jpg"] = $php_jpg;
$check_cmd = $this->is_win_os ? "which" : "command -v"; $check_cmd = IS_WIN_OS ? "which" : "command -v";
foreach (array("tar", "zip", "convert", "ffmpeg", "avconv", "du") as $c) { foreach (array("tar", "zip", "convert", "ffmpeg", "avconv", "du") as $cmd) {
$results["cmd_" . $c] = @preg_match("#" . $c . "(.exe)?$#i", exec_cmd($check_cmd . " " . $c)) > 0; $results["cmd_" . $cmd] = @preg_match("#" . $cmd . "(.exe)?$#i", exec_cmd($check_cmd . " " . $cmd)) > 0;
} }
$results["cmd_ffmpeg_or_avconv"] = $results["cmd_ffmpeg"] || $results["cmd_avconv"]; $results["cmd_ffmpeg_or_avconv"] = $results["cmd_ffmpeg"] || $results["cmd_avconv"];
$results["is_win_os"] = $this->is_win_os; $results["is_win_os"] = IS_WIN_OS;
$results["is_supported_php"] = $this->is_supported_php; $results["is_supported_php"] = IS_PHP_VERSION_SUPPORTED;
$results["server_name"] = $this->server_name; $results["server_name"] = SERVER_NAME;
$results["server_version"] = $this->server_version; $results["server_version"] = SERVER_VERSION;
$results["app_abs_path"] = $this->app_abs_path; $results["app_url"] = APP_URL;
$results["root_abs_path"] = $this->root_abs_path; $results["app_path"] = APP_PATH;
$results["app_abs_href"] = $this->app_abs_href; $results["root_url"] = ROOT_URL;
$results["root_abs_href"] = $this->root_abs_href; $results["root_path"] = ROOT_PATH;
$results["abs_href"] = $this->abs_href; $results["current_url"] = CURRENT_URL;
$results["abs_path"] = $this->abs_path; $results["current_path"] = CURRENT_PATH;
$results["options"] = $this->options; $results["options"] = $this->options;
return $results; return $results;
@ -370,13 +276,13 @@ class App {
return array( return array(
"backend" => "php", "backend" => "php",
"api" => true, "api" => true,
"name" => $this->server_name, "name" => SERVER_NAME,
"version" => $this->server_version "version" => SERVER_VERSION
); );
} }
public function get_customizations($abs_href) { public function get_customizations($url) {
if (!$this->options["custom"]["enabled"]) { if (!$this->options["custom"]["enabled"]) {
return array( return array(
@ -385,32 +291,32 @@ class App {
); );
} }
$abs_path = $this->get_abs_path($abs_href); $path = $this->to_path($url);
$file = $abs_path . "/" . App::$FILE_PREFIX . ".header.html";
$file = $path . "/" . FILE_PREFIX . ".header.html";
$header = is_readable($file) ? file_get_contents($file) : null; $header = is_readable($file) ? file_get_contents($file) : null;
$file = $abs_path . "/" . App::$FILE_PREFIX . ".footer.html"; $file = $path . "/" . FILE_PREFIX . ".footer.html";
$footer = is_readable($file) ? file_get_contents($file) : null; $footer = is_readable($file) ? file_get_contents($file) : null;
$p = $abs_path;
while ($header === null || $footer === null) { while ($header === null || $footer === null) {
if ($header === null) { if ($header === null) {
$file = $p . "/" . App::$FILE_PREFIX . ".headers.html"; $file = $path . "/" . FILE_PREFIX . ".headers.html";
$header = is_readable($file) ? file_get_contents($file) : null; $header = is_readable($file) ? file_get_contents($file) : null;
} }
if ($footer === null) { if ($footer === null) {
$file = $p . "/" . App::$FILE_PREFIX . ".footers.html"; $file = $path . "/" . FILE_PREFIX . ".footers.html";
$footer = is_readable($file) ? file_get_contents($file) : null; $footer = is_readable($file) ? file_get_contents($file) : null;
} }
if ($p === $this->root_abs_path) { if ($path === ROOT_PATH) {
break; break;
} }
$pp = normalize_path(dirname($p)); $parent_path = normalize_path(dirname($path));
if ($pp === $p) { if ($parent_path === $path) {
break; break;
} }
$p = $pp; $path = $parent_path;
} }
return array( return array(

View file

@ -15,12 +15,12 @@ class Archive {
} }
public function output($type, $hrefs) { public function output($type, $urls) {
$this->dirs = array(); $this->dirs = array();
$this->files = array(); $this->files = array();
$this->add_hrefs($hrefs); $this->add_hrefs($urls);
if (count($this->dirs) === 0 && count($this->files) === 0) { if (count($this->dirs) === 0 && count($this->files) === 0) {
return 500; return 500;
@ -44,7 +44,7 @@ class Archive {
private function shell_cmd($cmd) { private function shell_cmd($cmd) {
$cmd = str_replace("[ROOTDIR]", escapeshellarg($this->app->get_abs_path()), $cmd); $cmd = str_replace("[ROOTDIR]", escapeshellarg(CURRENT_PATH), $cmd);
$cmd = str_replace("[DIRS]", count($this->dirs) ? implode(" ", array_map("escapeshellarg", $this->dirs)) : "", $cmd); $cmd = str_replace("[DIRS]", count($this->dirs) ? implode(" ", array_map("escapeshellarg", $this->dirs)) : "", $cmd);
$cmd = str_replace("[FILES]", count($this->files) ? implode(" ", array_map("escapeshellarg", $this->files)) : "", $cmd); $cmd = str_replace("[FILES]", count($this->files) ? implode(" ", array_map("escapeshellarg", $this->files)) : "", $cmd);
try { try {
@ -133,27 +133,27 @@ class Archive {
if ($fd = fopen($file, 'rb')) { if ($fd = fopen($file, 'rb')) {
while (!feof($fd)) { while (!feof($fd)) {
print fread($fd, Archive::$SEGMENT_SIZE); print fread($fd, Archive::$SEGMENT_SIZE);
ob_flush(); @ob_flush();
flush(); @flush();
} }
fclose($fd); fclose($fd);
} }
} }
private function add_hrefs($hrefs) { private function add_hrefs($urls) {
foreach ($hrefs as $href) { foreach ($urls as $href) {
$d = normalize_path(dirname($href), true); $d = normalize_path(dirname($href), true);
$n = basename($href); $n = basename($href);
$code = $this->app->get_http_code($d); $code = $this->app->get_http_code($d);
if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { if ($code === MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
$real_file = $this->app->get_abs_path($href); $real_file = $this->app->to_path($href);
$archived_file = preg_replace("!^" . preg_quote(normalize_path($this->app->get_abs_path(), true)) . "!", "", $real_file); $archived_file = preg_replace("!^" . preg_quote(normalize_path(CURRENT_PATH, true)) . "!", "", $real_file);
if (is_dir($real_file)) { if (is_dir($real_file)) {
$this->add_dir($real_file, $archived_file); $this->add_dir($real_file, $archived_file);
@ -175,9 +175,9 @@ class Archive {
private function add_dir($real_dir, $archived_dir) { private function add_dir($real_dir, $archived_dir) {
$code = $this->app->get_http_code($this->app->get_abs_href($real_dir)); $code = $this->app->get_http_code($this->app->to_url($real_dir));
if ($code == App::$MAGIC_SEQUENCE) { if ($code === MAGIC_SEQUENCE) {
$this->dirs[] = $archived_dir; $this->dirs[] = $archived_dir;
$files = $this->app->read_dir($real_dir); $files = $this->app->read_dir($real_dir);

View file

@ -13,55 +13,55 @@ class Item {
return 1; return 1;
} }
return strcasecmp($item1->abs_path, $item2->abs_path); return strcasecmp($item1->path, $item2->path);
} }
public static function get($app, $abs_path, &$cache) { public static function get($app, $path, &$cache) {
if (!starts_with($abs_path, $app->get_root_abs_path())) { if (!starts_with($path, ROOT_PATH)) {
error_log("ILLEGAL REQUEST: " . $abs_path . ", " . $app->get_root_abs_path()); error_log("ILLEGAL REQUEST: " . $path . ", " . ROOT_PATH);
return null; return null;
} }
if (is_array($cache) && array_key_exists($abs_path, $cache)) { if (is_array($cache) && array_key_exists($path, $cache)) {
return $cache[$abs_path]; return $cache[$path];
} }
$item = new Item($app, $abs_path); $item = new Item($app, $path);
if (is_array($cache)) { if (is_array($cache)) {
$cache[$abs_path] = $item; $cache[$path] = $item;
} }
return $item; return $item;
} }
public $app, public $app,
$abs_path, $abs_href, $path, $url,
$date, $size, $date, $size,
$is_folder, $is_folder,
$is_content_fetched; $is_content_fetched;
private function __construct($app, $abs_path) { private function __construct($app, $path) {
$this->app = $app; $this->app = $app;
$this->abs_path = normalize_path($abs_path); $this->path = normalize_path($path, false);
$this->is_folder = is_dir($this->abs_path); $this->is_folder = is_dir($this->path);
$this->abs_href = $this->app->get_abs_href($abs_path, $this->is_folder); $this->url = $this->app->to_url($path, $this->is_folder);
$this->date = @filemtime($this->abs_path); $this->date = @filemtime($this->path);
if ($this->is_folder) { if ($this->is_folder) {
$this->size = null; $this->size = null;
$options = $app->get_options(); $options = $app->get_options();
if ($options["foldersize"]["enabled"]) { if ($options["foldersize"]["enabled"]) {
$cmd = str_replace("[DIR]", escapeshellarg($this->abs_path), Item::$FOLDER_SIZE_CMD); $cmd = str_replace("[DIR]", escapeshellarg($this->path), Item::$FOLDER_SIZE_CMD);
$this->size = intval(preg_replace("/\s.*$/", "", exec_cmd($cmd)), 10) * 1024; $this->size = intval(preg_replace("#\s.*$#", "", exec_cmd($cmd)), 10) * 1024;
} }
} else { } else {
$this->size = @filesize($this->abs_path); $this->size = @filesize($this->path);
} }
$this->is_content_fetched = false; $this->is_content_fetched = false;
@ -71,13 +71,13 @@ class Item {
public function to_json_object() { public function to_json_object() {
$obj = array( $obj = array(
"absHref" => $this->abs_href, "absHref" => $this->url,
"time" => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript) "time" => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript)
"size" => $this->size "size" => $this->size
); );
if ($this->is_folder) { if ($this->is_folder) {
$obj["status"] = $this->app->get_http_code($this->abs_href); $obj["status"] = $this->app->get_http_code($this->url);
$obj["content"] = $this->is_content_fetched; $obj["content"] = $this->is_content_fetched;
} }
@ -87,9 +87,9 @@ class Item {
public function get_parent(&$cache) { public function get_parent(&$cache) {
$parent_abs_path = normalize_path(dirname($this->abs_path)); $parent_path = normalize_path(dirname($this->path), false);
if ($parent_abs_path !== $this->abs_path && starts_with($parent_abs_path, $this->app->get_root_abs_path())) { if ($parent_path !== $this->path && starts_with($parent_path, ROOT_PATH)) {
return Item::get($this->app, $parent_abs_path, $cache); return Item::get($this->app, $parent_path, $cache);
} }
return null; return null;
} }
@ -97,21 +97,21 @@ class Item {
public function get_content(&$cache) { public function get_content(&$cache) {
$content = array(); $items = array();
if ($this->app->get_http_code($this->abs_href) !== App::$MAGIC_SEQUENCE) { if ($this->app->get_http_code($this->url) !== MAGIC_SEQUENCE) {
return $content; return $items;
} }
$files = $this->app->read_dir($this->abs_path); $files = $this->app->read_dir($this->path);
foreach ($files as $file) { foreach ($files as $file) {
$item = Item::get($this->app, $this->abs_path . "/" . $file, $cache); $item = Item::get($this->app, $this->path . "/" . $file, $cache);
$content[$item->abs_path] = $item; $items[$item->path] = $item;
} }
$this->is_content_fetched = true; $this->is_content_fetched = true;
return $content; return $items;
} }
} }

View file

@ -21,33 +21,33 @@ class Thumb {
public function __construct($app) { public function __construct($app) {
$this->app = $app; $this->app = $app;
$this->thumbs_path = $this->app->get_cache_abs_path() . "/" . Thumb::$THUMB_CACHE; $this->thumbs_path = CACHE_PATH . "/" . Thumb::$THUMB_CACHE;
$this->thumbs_href = $this->app->get_cache_abs_href() . Thumb::$THUMB_CACHE; $this->thumbs_href = CACHE_URL . Thumb::$THUMB_CACHE;
} }
public function thumb($type, $source_abs_href, $mode, $width, $height) { public function thumb($type, $source_url, $mode, $width, $height) {
$source_abs_path = $this->app->get_abs_path($source_abs_href); $source_path = $this->app->to_path($source_url);
if ($type === "img") { if ($type === "img") {
$capture_abs_path = $source_abs_path; $capture_path = $source_path;
} else if ($type === "mov") { } else if ($type === "mov") {
$capture_abs_path = $this->capture(Thumb::$FFMPEG_CMD, $source_abs_path); $capture_path = $this->capture(Thumb::$FFMPEG_CMD, $source_path);
if ($capture_abs_path === null) { if ($capture_path === null) {
$capture_abs_path = $this->capture(Thumb::$AVCONV_CMD, $source_abs_path); $capture_path = $this->capture(Thumb::$AVCONV_CMD, $source_path);
} }
} else if ($type === "doc") { } else if ($type === "doc") {
$capture_abs_path = $this->capture(Thumb::$CONVERT_CMD, $source_abs_path); $capture_path = $this->capture(Thumb::$CONVERT_CMD, $source_path);
} }
return $this->thumb_href($capture_abs_path, $mode, $width, $height); return $this->thumb_href($capture_path, $mode, $width, $height);
} }
private function thumb_href($source_abs_path, $mode, $width, $height) { private function thumb_href($source_path, $mode, $width, $height) {
if (!file_exists($source_abs_path)) { if (!file_exists($source_path)) {
return null; return null;
} }
@ -55,50 +55,50 @@ class Thumb {
@mkdir($this->thumbs_path, 0755, true); @mkdir($this->thumbs_path, 0755, true);
} }
$name = "thumb-" . sha1("$source_abs_path-$width-$height-$mode") . ".jpg"; $name = "thumb-" . sha1("$source_path-$width-$height-$mode") . ".jpg";
$thumb_abs_path = $this->thumbs_path . "/" . $name; $thumb_path = $this->thumbs_path . "/" . $name;
$thumb_abs_href = $this->thumbs_href . "/" . $name; $thumb_url = $this->thumbs_href . "/" . $name;
if (!file_exists($thumb_abs_path) || filemtime($source_abs_path) >= filemtime($thumb_abs_path)) { if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) {
$image = new Image(); $image = new Image();
$et = false; $et = false;
$opts = $this->app->get_options(); $opts = $this->app->get_options();
if ($opts["thumbnails"]["exif"] === true && function_exists("exif_thumbnail")) { if ($opts["thumbnails"]["exif"] === true && function_exists("exif_thumbnail")) {
$et = @exif_thumbnail($source_abs_path); $et = @exif_thumbnail($source_path);
} }
if($et !== false) { if($et !== false) {
file_put_contents($thumb_abs_path, $et); file_put_contents($thumb_path, $et);
$image->set_source($thumb_abs_path); $image->set_source($thumb_path);
$image->normalize_exif_orientation($source_abs_path); $image->normalize_exif_orientation($source_path);
} else { } else {
$image->set_source($source_abs_path); $image->set_source($source_path);
} }
$image->thumb($mode, $width, $height); $image->thumb($mode, $width, $height);
$image->save_dest_jpeg($thumb_abs_path, 80); $image->save_dest_jpeg($thumb_path, 80);
} }
return file_exists($thumb_abs_path) ? $thumb_abs_href : null; return file_exists($thumb_path) ? $thumb_url : null;
} }
private function capture($cmd, $source_abs_path) { private function capture($cmd, $source_path) {
if (!file_exists($source_abs_path)) { if (!file_exists($source_path)) {
return null; return null;
} }
$capture_abs_path = $this->thumbs_path . "/capture-" . sha1($source_abs_path) . ".jpg"; $capture_path = $this->thumbs_path . "/capture-" . sha1($source_path) . ".jpg";
if (!file_exists($capture_abs_path) || filemtime($source_abs_path) >= filemtime($capture_abs_path)) { if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) {
$cmd = str_replace("[SOURCE]", escapeshellarg($source_abs_path), $cmd); $cmd = str_replace("[SOURCE]", escapeshellarg($source_path), $cmd);
$cmd = str_replace("[TARGET]", escapeshellarg($capture_abs_path), $cmd); $cmd = str_replace("[TARGET]", escapeshellarg($capture_path), $cmd);
exec_cmd($cmd); exec_cmd($cmd);
} }
return file_exists($capture_abs_path) ? $capture_abs_path : null; return file_exists($capture_path) ? $capture_path : null;
} }
} }

View file

@ -1,14 +1,25 @@
<?php <?php
putenv("LANG=en_US.UTF-8");
date_default_timezone_set("UTC");
normalized_require_once("util.php");
normalized_require_once("App.php");
normalized_require_once("Item.php");
function create_app() { function refl($id, $obj) {
$s = "<pre class='refl'>";
$s .= $id . " " . var_export($obj, true);
$s .= "</pre>\n";
echo($s);
}
function init() {
putenv("LANG=en_US.UTF-8");
date_default_timezone_set("UTC");
define("MIN_PHP_VERSION", "5.3.0");
define("IS_PHP_VERSION_SUPPORTED", version_compare(PHP_VERSION, MIN_PHP_VERSION) >= 0);
define("IS_WIN_OS", strtolower(substr(PHP_OS, 0, 3)) === "win");
$server_name = null; $server_name = null;
$server_version = null; $server_version = null;
@ -17,23 +28,67 @@ function create_app() {
$server_name = $matches[1]; $server_name = $matches[1];
$server_version = $matches[2]; $server_version = $matches[2];
} }
define("SERVER_NAME", $server_name);
$app_abs_path = normalize_path(dirname(dirname(dirname(dirname(__FILE__))))); define("SERVER_VERSION", $server_version);
$script_name = getenv("SCRIPT_NAME"); $script_name = getenv("SCRIPT_NAME");
if ($server_name === "lighttpd") { if (SERVER_NAME === "lighttpd") {
$script_name = preg_replace("#^.*//#", "/", $script_name); $script_name = preg_replace("#^.*//#", "/", $script_name);
} }
$app_abs_href = dirname(dirname(dirname($script_name))); define("APP_URL", normalize_path(dirname(dirname(dirname($script_name))), true));
define("APP_PATH", normalize_path(dirname(dirname(dirname(dirname(__FILE__)))), false));
define("ROOT_URL", normalize_path(dirname(APP_URL), true));
define("ROOT_PATH", normalize_path(dirname(APP_PATH), false));
$url_parts = parse_url(getenv("REQUEST_URI")); $url_parts = parse_url(getenv("REQUEST_URI"));
$abs_href = $url_parts["path"]; $cur_url = normalize_path($url_parts["path"], true);
$rel_url = substr($cur_url, strlen(ROOT_URL));
$cur_path = normalize_path(ROOT_PATH . "/" . rawurldecode($rel_url));
if (!is_dir($cur_path)) {
$cur_url = normalize_path(dirname($cur_url), true);
$cur_path = normalize_path(dirname($cur_path), false);
}
define("CURRENT_URL", $cur_url);
define("CURRENT_PATH", $cur_path);
return new App($server_name, $server_version, $app_abs_path, $app_abs_href, $abs_href); define("MAGIC_SEQUENCE", "={{pkg.name}}=");
define("FILE_PREFIX", "_{{pkg.name}}");
define("INDEX_URL", normalize_path(APP_URL . "server/php/index.php", false));
define("CACHE_URL", normalize_path(APP_URL . "cache", true));
define("CACHE_PATH", normalize_path(APP_PATH . "/cache", false));
// refl('DEFINED', array(
// "PHP_VERSION " => PHP_VERSION,
// "PHP_OS " => PHP_OS,
// "MIN_PHP_VERSION " => MIN_PHP_VERSION,
// "IS_PHP_VERSION_SUPPORTED " => IS_PHP_VERSION_SUPPORTED,
// "IS_WIN_OS " => IS_WIN_OS,
// "SERVER_NAME " => SERVER_NAME,
// "SERVER_VERSION " => SERVER_VERSION,
// "APP_URL " => APP_URL,
// "APP_PATH " => APP_PATH,
// "ROOT_URL " => ROOT_URL,
// "ROOT_PATH " => ROOT_PATH,
// "CURRENT_URL " => CURRENT_URL,
// "CURRENT_PATH " => CURRENT_PATH,
// "MAGIC_SEQUENCE " => MAGIC_SEQUENCE,
// "FILE_PREFIX " => FILE_PREFIX,
// "INDEX_URL " => INDEX_URL,
// "CACHE_URL " => CACHE_URL,
// "CACHE_PATH " => CACHE_PATH
// ));
// exit();
} }
init();
$app = create_app(); normalized_require_once("util.php");
normalized_require_once("App.php");
normalized_require_once("Item.php");
$app = new App();
if (has_request_param("action")) { if (has_request_param("action")) {
@ -47,10 +102,7 @@ if (has_request_param("action")) {
} else { } else {
header("Content-type: text/html;charset=utf-8"); header("Content-type: text/html;charset=utf-8");
define("FALLBACK", $app->get_fallback());
global $HREF, $FALLBACK;
$HREF = $app->get_app_abs_href();
$FALLBACK = $app->get_fallback();
normalized_require_once("page.php"); normalized_require_once("page.php");
} }

View file

@ -1,6 +1,6 @@
- var href = "<?php global $HREF; echo $HREF; ?>" - var url = "<?= APP_URL ?>"
- var fallback = "<?php global $FALLBACK; echo $FALLBACK; ?>" - var fallback = "<?= FALLBACK ?>"
doctype 5 doctype 5
//if lt IE 9 //if lt IE 9
@ -15,15 +15,15 @@ html.no-js.browser( lang="en" )
title index · styled with {{pkg.name}} {{pkg.version}} ({{pkg.url}}) title index · styled with {{pkg.name}} {{pkg.version}} ({{pkg.url}})
meta( name="description", content="index styled with {{pkg.name}} {{pkg.version}} ({{pkg.url}})" ) meta( name="description", content="index styled with {{pkg.name}} {{pkg.version}} ({{pkg.url}})" )
meta( name="viewport", content="width=device-width" ) meta( name="viewport", content="width=device-width" )
link( rel="shortcut icon", href!="#{href}client/images/app-16x16.ico" ) link( rel="shortcut icon", href!="#{url}client/images/app-16x16.ico" )
link( rel="apple-touch-icon-precomposed", type="image/png", href!="#{href}client/images/app-48x48.png" ) link( rel="apple-touch-icon-precomposed", type="image/png", href!="#{url}client/images/app-48x48.png" )
link( rel="apple-touch-icon-precomposed", sizes="57x57", type="image/png", href!="#{href}client/images/app-57x57.png" ) link( rel="apple-touch-icon-precomposed", sizes="57x57", type="image/png", href!="#{url}client/images/app-57x57.png" )
link( rel="apple-touch-icon-precomposed", sizes="72x72", type="image/png", href!="#{href}client/images/app-72x72.png" ) link( rel="apple-touch-icon-precomposed", sizes="72x72", type="image/png", href!="#{url}client/images/app-72x72.png" )
link( rel="apple-touch-icon-precomposed", sizes="114x114", type="image/png", href!="#{href}client/images/app-114x114.png" ) link( rel="apple-touch-icon-precomposed", sizes="114x114", type="image/png", href!="#{url}client/images/app-114x114.png" )
link( rel="apple-touch-icon-precomposed", sizes="144x144", type="image/png", href!="#{href}client/images/app-144x144.png" ) link( rel="apple-touch-icon-precomposed", sizes="144x144", type="image/png", href!="#{url}client/images/app-144x144.png" )
link( rel="stylesheet", href="//fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic,700italic|Ubuntu:300italic,700italic,300,700" ) link( rel="stylesheet", href="//fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic,700italic|Ubuntu:300italic,700italic,300,700" )
link( rel="stylesheet", href!="#{href}client/css/styles.css" ) link( rel="stylesheet", href!="#{url}client/css/styles.css" )
script( src!="#{href}client/js/scripts.js" ) script( src!="#{url}client/js/scripts.js" )
body body

View file

@ -1,11 +1,5 @@
<?php <?php
function normalize_path($path, $trailing_slash = false) {
$path = str_replace("\\", "/", $path);
return preg_match("#^(\w:)?/$#", $path) ? $path : (rtrim($path, "/") . ($trailing_slash ? "/" : ""));
}
function json_exit($obj = array()) { function json_exit($obj = array()) {
$obj["code"] = 0; $obj["code"] = 0;
@ -26,37 +20,17 @@ function has_request_param($key) {
return array_key_exists($key, $_REQUEST); return array_key_exists($key, $_REQUEST);
} }
function use_request_params($keys) { define("NO_DEFAULT", "__NO_DEFAULT_VALUE__");
function use_request_param($key, $default = NO_DEFAULT) {
if (!is_array($keys)) { if (!array_key_exists($key, $_REQUEST)) {
$keys = func_get_args(); json_fail(101, "parameter '$key' is missing", $default === NO_DEFAULT);
return $default;
} }
$values = array(); $value = $_REQUEST[$key];
foreach ($keys as $key) { unset($_REQUEST[$key]);
json_fail(101, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST)); return $value;
$values[] = $_REQUEST[$key];
unset($_REQUEST[$key]);
}
return $values;
}
function use_optional_request_params($keys) {
if (!is_array($keys)) {
$keys = func_get_args();
}
$values = array();
foreach ($keys as $key) {
if (array_key_exists($key, $_REQUEST)) {
$values[] = $_REQUEST[$key];
unset($_REQUEST[$key]);
} else {
$values[] = null;
}
}
return $values;
} }
function starts_with($sequence, $head) { function starts_with($sequence, $head) {

View file

@ -1,10 +1,14 @@
<?php <?php
function normalize_path($path, $trailing_slash = false) {
$path = preg_replace("#\\+|/+#", "/", $path);
return preg_match("#^(\w:)?/$#", $path) ? $path : (rtrim($path, "/") . ($trailing_slash ? "/" : ""));
}
function normalized_require_once($lib) { function normalized_require_once($lib) {
$path = dirname(__FILE__) . "/inc/" . $lib; require_once(normalize_path(dirname(__FILE__) . "/inc/" . $lib, false));
$path = preg_replace("#\\+|/+#", "/", $path);
require_once($path);
} }
normalized_require_once("main.php"); normalized_require_once("main.php");