Премини към съдържанието
  • Добре дошли!

    Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

    Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

     

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Phoenix.bg

Архивиране на файлове в h5ai

Препоръчан отговор


Ползвам h5ai, в който активирах модула за архивиране и изтегляне на файлове. Работи стабилно и без грешка! Искам обаче, малко да го променя: вместо генерираният архив (tar или zip) да се изтегля в браузъра, да се записва в конкретна директория на сървъра и с точно определено име.  За изтеглянето на файлове отговаря следния фрагмент в Api.php:

else if ($action === "download") {json_fail(1, "downloads disabled", !$options["download"]["enabled"]);list($as, $type, $hrefs) = use_request_params(array("as", "type", "hrefs"));normalized_require_once("/server/php/inc/Archive.php");$archive = new Archive($this->app);$hrefs = explode("|:|", trim($hrefs));set_time_limit(0);header("Content-Type: application/octet-stream");header("Content-Disposition: attachment; filename="$as"");header("Connection: close");$rc = $archive->output($type, $hrefs);if ($rc !== 0) {json_fail("packaging failed");}exit;}

Самото архивиране/компресиране се изпълнява във Archive.php:

class Archive {private static $SEGMENT_SIZE = 16777216; // 1024 * 1024 * 16 = 16MiBprivate static $TAR_PASSTHRU_CMD = "cd [ROOTDIR] && tar --no-recursion -c -- [DIRS] [FILES]";private static $ZIP_PASSTHRU_CMD = "cd [ROOTDIR] && zip - -- [FILES]";private $app, $dirs, $files;public function __construct($app) {$this->app = $app;}public function output($type, $hrefs) {$this->dirs = array();$this->files = array();$this->add_hrefs($hrefs);if (count($this->dirs) === 0 && count($this->files) === 0) {return 500;}if ($type === "php-tar") {return $this->php_tar($this->dirs, $this->files);} else if ($type === "shell-tar") {return $this->shell_cmd(Archive::$TAR_PASSTHRU_CMD);} else if ($type === "shell-zip") {return $this->shell_cmd(Archive::$ZIP_PASSTHRU_CMD);}return 500;}private function shell_cmd($cmd) {$cmd = str_replace("[ROOTDIR]", escapeshellarg($this->app->get_abs_path()), $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);try {passthru($cmd);} catch (Exeption $err) {return 500;}return 0;}private function php_tar($dirs, $files) {$filesizes = array();$total_size = 512 * count($dirs);foreach (array_keys($files) as $real_file) {$size = filesize($real_file);$filesizes[$real_file] = $size;$total_size += 512 + $size;if ($size % 512 != 0) {$total_size += 512 - ($size % 512);}}header("Content-Length: " . $total_size);foreach ($dirs as $archived_dir) {echo $this->php_tar_header($archived_dir, 0, 0, 5);}foreach ($files as $real_file => $archived_file) {$size = $filesizes[$real_file];echo $this->php_tar_header($archived_file, $size, @filemtime($real_file), 0);$this->print_file($real_file);if ($size % 512 != 0) {echo str_repeat("0", 512 - ($size % 512));}}return 0;}private function php_tar_header($filename, $size, $mtime, $type) {$name = substr(basename($filename), -99);$prefix = substr(normalize_path(dirname($filename)), -154);if ($prefix === '.') {$prefix = '';}$header =str_pad($name, 100, "0") // filename [100]. "00007550" // file mode [8]. "00000000" // uid [8]. "00000000" // gid [8]. str_pad(decoct($size), 11, "0", STR_PAD_LEFT) . "0" // file size [12]. str_pad(decoct($mtime), 11, "0", STR_PAD_LEFT) . "0" // file modification time [12]. " " // checksum [8]. str_pad($type, 1) // file type [1]. str_repeat("0", 100) // linkname [100]. "ustar0" // magic [6]. "00" // version [2]. str_repeat("0", 80) // uname, gname, defmajor, devminor [32 + 32 + 8 + 8]. str_pad($prefix, 155, "0") // filename [155]. str_repeat("0", 12); // fill [12]assert(strlen($header) === 512);// checksum$checksum = array_sum(array_map('ord', str_split($header)));$checksum = str_pad(decoct($checksum), 6, "0", STR_PAD_LEFT) . "0 ";$header = substr_replace($header, $checksum, 148, 8);return $header;}private function print_file($file) {// Send file content in segments to not hit PHP's memory limit (default: 128M)if ($fd = fopen($file, 'rb')) {while (!feof($fd)) {print fread($fd, Archive::$SEGMENT_SIZE);ob_flush();flush();}fclose($fd);}}private function add_hrefs($hrefs) {foreach ($hrefs as $href) {$d = normalize_path(dirname($href), true);$n = basename($href);$code = $this->app->get_http_code($d);if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {$real_file = $this->app->get_abs_path($href);$archived_file = preg_replace("!^" . preg_quote(normalize_path($this->app->get_abs_path(), true)) . "!", "", $real_file);if (is_dir($real_file)) {$this->add_dir($real_file, $archived_file);} else {$this->add_file($real_file, $archived_file);}}}}private function add_file($real_file, $archived_file) {if (is_readable($real_file)) {$this->files[$real_file] = $archived_file;}}private function add_dir($real_dir, $archived_dir) {$code = $this->app->get_http_code($this->app->get_abs_href($real_dir));if ($code == App::$MAGIC_SEQUENCE) {$this->dirs[] = $archived_dir;$files = $this->app->read_dir($real_dir);foreach ($files as $file) {$real_file = $real_dir . "/" . $file;$archived_file = $archived_dir . "/" . $file;if (is_dir($real_file)) {$this->add_dir($real_file, $archived_file);} else {$this->add_file($real_file, $archived_file);}}}}}?>

Накратко, целта е създаденият архив да остава на сървъра в точно определена директория и да не се сваля.

 

В момента работя на h5ai v0.24.0 под режим на компресиране php-tar. Хостинга ми поддържа и shell-tar, но zip не мога да използвам, пък и самите файлове за архивиране са си предварително компресирани...

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

А защо не си напишете обикновено шел скирипт който да върши това?

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

В режим shell-tar става именно това, въпросът е, че не мога да се ориентирам какво точно да променя, за да се записва архива на сървъра и да не се изтегля. Мислех да започна начисто, без да разчитам на кода на h5ai, но изниква друг проблем: как да подам наведнъж всички маркирани за архивиране в h5ai файлове и директории за компресиране на шел скрипта?

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

В режим shell-tar става именно това, въпросът е, че не мога да се ориентирам какво точно да променя, за да се записва архива на сървъра и да не се изтегля. Мислех да започна начисто, без да разчитам на кода на h5ai, но изниква друг проблем: как да подам наведнъж всички маркирани за архивиране в h5ai файлове и директории за компресиране на шел скрипта?

Не ползвайте за база горния пакет, просто направете нещата от нулата. Направете списък на обекти и директории, които искате да архивирате и след това с тар или зип ги съберете в един файл с име и място където ще се запише по ваше желание

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

×
×
  • Добави ново...