Adds support for tarred downloads.

This commit is contained in:
Lars Jung 2012-04-17 23:38:15 +02:00
parent e67c854cb5
commit de92767e5a
22 changed files with 160 additions and 162 deletions

View file

@ -108,40 +108,42 @@ else if ($action === "thumbsrc") {
}
else if ($action === "zip") {
else if ($action === "archive") {
fail(0, "zipped download is disabled", !$options["zipped-download"]["enabled"]);
list($hrefs) = checkKeys(array("hrefs"));
fail(0, "download is disabled", !$options["download"]["enabled"]);
H5ai::req_once("/php/inc/ZipIt.php");
list($format, $hrefs) = checkKeys(array("format", "hrefs"));
$zipit = new ZipIt($h5ai);
H5ai::req_once("/php/inc/Archive.php");
$archive = new Archive($h5ai);
$hrefs = explode(":", trim($hrefs));
$zipFile = $zipit->zip($hrefs);
$target = $archive->create($format, $hrefs);
if (is_string($zipFile)) {
$response = array('status' => 'ok', 'id' => basename($zipFile), 'size' => filesize($zipFile));
if (is_string($target)) {
$response = array('status' => 'ok', 'id' => basename($target), 'size' => filesize($target));
} else {
$response = array('status' => 'failed', 'code' => $zipFile);
$response = array('status' => 'failed', 'code' => $target);
}
echo json_encode($response);
}
else if ($action === "getzip") {
else if ($action === "getarchive") {
list($id) = checkKeys(array("id"));
fail(1, "zipped file not found: " . $id, !preg_match("/^h5ai-zip-/", $id));
fail(0, "download is disabled", !$options["download"]["enabled"]);
$zipFile = str_replace("\\", "/", sys_get_temp_dir()) . "/" . $id;
fail(2, "zipped file not found: " . $id, !file_exists($zipFile));
list($id,$as) = checkKeys(array("id", "as"));
fail(1, "file not found: " . $id, !preg_match("/^h5ai-selection-/", $id));
header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\"");
$target = H5ai::normalize_path(sys_get_temp_dir(), true) . $id;
fail(2, "file not found: " . $id, !file_exists($target));
header("Content-Disposition: attachment; filename=\"$as\"");
header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($zipFile));
header("Content-Length: " . filesize($target));
header("Connection: close");
readfile($zipFile);
readfile($target);
}
@ -152,7 +154,7 @@ else if ($action === "checks") {
'cache' => $h5ai->checks["php"] && $h5ai->checks["cache"],
'thumbs' => $h5ai->checks["php"] && $h5ai->checks["cache"] && $h5ai->checks["gd"],
'temp' => $h5ai->checks["php"] && $h5ai->checks["temp"],
'zips' => $h5ai->checks["php"] && $h5ai->checks["temp"] && $h5ai->checks["zip"]
'download' => $h5ai->checks["php"] && $h5ai->checks["temp"] && $h5ai->checks["archive"]
);
echo json_encode($response);
}

View file

@ -0,0 +1,77 @@
<?php
class Archive {
private $h5ai;
public function __construct($h5ai) {
$this->h5ai = $h5ai;
}
public function create($format, $hrefs) {
$target = H5ai::normalize_path(sys_get_temp_dir(), true) . "h5ai-selection-" . microtime(true) . "-" . rand() . "." . $format;
$archive = new PharData($target);
foreach ($hrefs as $href) {
$d = H5ai::normalize_path(dirname($href), true);
$n = basename($href);
$code = $this->h5ai->getHttpCode($d);
if ($code == 401) {
return $code;
}
if ($code == "h5ai" && !$this->h5ai->ignoreThisFile($n)) {
$realFile = $this->h5ai->getAbsPath($href);
$archivedFile = preg_replace("!^" . $this->h5ai->getRootAbsPath() . "!", "", $realFile);
if (is_dir($realFile)) {
$rcode = $this->addDir($archive, $realFile, $archivedFile);
if ($rcode == 401) {
return $rcode;
}
} else {
$this->addFile($archive, $realFile, $archivedFile);
}
}
}
return filesize($target) ? $target : null;
}
private function addFile($archive, $realFile, $archivedFile) {
if (is_readable($realFile)) {
$archive->addFile($realFile, $archivedFile);
}
}
private function addDir($archive, $realDir, $archivedDir) {
$code = $this->h5ai->getHttpCode($this->h5ai->getAbsHref($realDir));
if ($code == "h5ai") {
$archive->addEmptyDir($archivedDir);
$files = $this->h5ai->readDir($realDir);
foreach ($files as $file) {
$realFile = $realDir . "/" . $file;
$archivedFile = $archivedDir . "/" . $file;
if (is_dir($realFile)) {
$rcode = $this->addDir($archive, $realFile, $archivedFile);
if ($rcode == 401) {
return $rcode;
}
} else {
$this->addFile($archive, $realFile, $archivedFile);
}
}
}
return $code;
}
}
?>

View file

@ -83,7 +83,7 @@ class H5ai {
$this->checks = array(
"php" => version_compare(PHP_VERSION, "5.2.0") >= 0,
"zip" => class_exists("ZipArchive"),
"archive" => class_exists("PharData"),
"gd" => GD_VERSION != "GD_VERSION",
"cache" => is_writable($this->h5aiAbsPath . "/cache"),
"temp" => is_writable(sys_get_temp_dir())

View file

@ -1,89 +0,0 @@
<?php
class ZipIt {
private $h5ai;
public static function isUsable() {
return class_exists("ZipArchive");
}
public function __construct($h5ai) {
$this->h5ai = $h5ai;
}
public function zip($hrefs) {
$zipFile = tempnam(sys_get_temp_dir(), "h5ai-zip-");
$zip = new ZipArchive();
if (!$zip->open($zipFile, ZIPARCHIVE::CREATE)) {
return null;
}
$zip->addEmptyDir("/");
foreach ($hrefs as $href) {
$d = H5ai::normalize_path(dirname($href), true);
$n = basename($href);
$code = $this->h5ai->getHttpCode($d);
if ($code == 401) {
return $code;
}
if ($code == "h5ai" && !$this->h5ai->ignoreThisFile($n)) {
$localFile = $this->h5ai->getAbsPath($href);
$file = preg_replace("!^" . $this->h5ai->getRootAbsPath() . "!", "", $localFile);
if (is_dir($localFile)) {
$rcode = $this->zipDir($zip, $localFile, $file);
if ($rcode == 401) {
return $rcode;
}
} else {
$this->zipFile($zip, $localFile, $file);
}
}
}
$zip->close();
return filesize($zipFile) ? $zipFile : null;
}
private function zipFile($zip, $localFile, $file) {
if (is_readable($localFile)) {
$zip->addFile($localFile, $file);
}
}
private function zipDir($zip, $localDir, $dir) {
$code = $this->h5ai->getHttpCode($this->h5ai->getAbsHref($localDir));
if ($code == 'h5ai') {
$zip->addEmptyDir($dir);
$files = $this->h5ai->readDir($localDir);
foreach ($files as $file) {
$localFile = $localDir . "/" . $file;
$file = $dir . "/" . $file;
if (is_dir($localFile)) {
$rcode = $this->zipDir($zip, $localFile, $file);
if ($rcode == 401) {
return $rcode;
}
} else {
$this->zipFile($zip, $localFile, $file);
}
}
}
return $code;
}
}
?>