Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Updated for new PluginCompression file.
Browse files Browse the repository at this point in the history
Adapted for new class layout, varible and method names, etc.
Also added additional check on exec command return code that should catch and warn on any failed compression or extraction.
  • Loading branch information
snw35 committed Oct 5, 2016
1 parent f1201ca commit 0389ee0
Showing 1 changed file with 173 additions and 54 deletions.
227 changes: 173 additions & 54 deletions core/src/plugins/action.compression/PluginCompression.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,33 @@ class PluginCompression extends Plugin
* @throws \Pydio\Core\Exception\ActionNotFoundException
* @throws \Pydio\Core\Exception\AuthRequiredException
*/

// Multi-platform function taken from stackoverflow
// http://stackoverflow.com/questions/12424787/how-to-check-if-a-shell-command-exists-from-php
// Check that a command exists on the system for use with exec
public function command_exists ($command)
{
$whereIsCommand = (PHP_OS == 'WINNT') ? 'where' : 'which';
$process = proc_open(
"$whereIsCommand $command",
array(
0 => array("pipe", "r"), //STDIN
1 => array("pipe", "w"), //STDOUT
2 => array("pipe", "w"), //STDERR
),
$pipes
);
if ($process !== false) {
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
return $stdout != '';
}
return false;
}

public function receiveAction(\Psr\Http\Message\ServerRequestInterface &$requestInterface, \Psr\Http\Message\ResponseInterface &$responseInterface)
{
/** @var \Pydio\Core\Model\ContextInterface $ctx */
Expand All @@ -78,9 +105,9 @@ public function receiveAction(\Psr\Http\Message\ServerRequestInterface &$request
$responseInterface = $responseInterface->withBody($serializableStream);

switch ($requestInterface->getAttribute("action")) {

case "compression":

$archiveName = InputFilter::decodeSecureMagic($httpVars["archive_name"], InputFilter::SANITIZE_FILENAME);
$archiveFormat = $httpVars["type_archive"];
$tabTypeArchive = array(".tar", ".tar.gz", ".tar.bz2");
Expand Down Expand Up @@ -140,51 +167,107 @@ public function receiveAction(\Psr\Http\Message\ServerRequestInterface &$request
$postMessageStatus($messages["compression.17"], Task::STATUS_FAILED);
throw new PydioException($messages["compression.17"]);
}
try {
$tmpArchiveName = tempnam(ApplicationState::getAjxpTmpDir(), "tar-compression") . ".tar";
$archive = new PharData($tmpArchiveName);
} catch (Exception $e) {
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw $e;
}
$counterCompression = 0;
//THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP
$tabAllFiles = array_combine($tabAllRecursiveFiles, $tabFilesNames);
foreach ($tabAllFiles as $fullPath => $fileName) {
// Builds a shell command that changes to the workspace location in the filesystem, and then
// compresses with tar and any parallel compression utilities that are installed.
if ($this->command_exists("tar")) {
$FileNames = array();
$FolderNames = array();
foreach ($nodes as $node) {
$nodeUrl = $node->getUrl();
if (is_file($nodeUrl) && filesize($nodeUrl) < $maxAuthorizedSize) {
array_push($FileNames, escapeshellarg(substr($nodeUrl, $currentDirUrlLength)));
}
if (is_dir($nodeUrl)) {
array_push($FolderNames, escapeshellarg(substr($nodeUrl, $currentDirUrlLength)));
}
}
if ($archiveFormat == ".tar.gz") {
if ($this->command_exists("pigz")) {
$tarCommand = "tar -I pigz -cf ";
} else {
$tarCommand = "tar -czf ";
}
} elseif ($archiveFormat == ".tar.bz2") {
if ($this->command_exists("lbzip2")) {
$tarCommand = "tar -I lbzip2 -cf ";
} elseif ($this->command_exists("pbzip2")) {
$tarCommand = "tar -I pbzip2 -cf ";
} else {
$tarCommand = "tar -cjf ";
}
} elseif ($archiveFormat == ".tar") {
$tarCommand = "tar -cf ";
} else {
file_put_contents($progressCompressionFileName, "Error : " . $messages["compression.15"]);
throw new PydioException($messages["compression.15"]);
}
$changeDirCommand = "cd " . MetaStreamWrapper::getRealFSReference($currentDirUrl) . " && ";
$compressCommand = $changeDirCommand . $tarCommand . escapeshellarg($archiveName) . " " . implode(" ", $FolderNames) . " " . implode(" ", $FileNames);
$cmdExitCode = 0;
$cmdOutput = '';
exec($compressCommand, $cmdOutput, $cmdExitCode);
if ($cmdExitCode > 0) {
file_put_contents($progressCompressionFileName, "Error : " . $messages["compression.15"]);
throw new PydioException($messages["compression.15"]);
}
} else {
// If tar command is not found, compress with PHP Phar instead
try {
$archive->addFile(MetaStreamWrapper::getRealFSReference($fullPath), $fileName);
$counterCompression++;
$percent = round(($counterCompression / count($tabAllFiles)) * 100, 0, PHP_ROUND_HALF_DOWN);
$postMessageStatus(sprintf($messages["compression.6"], $percent . " %"), Task::STATUS_RUNNING, $percent);
$tmpArchiveName = tempnam(ApplicationState::getAjxpTmpDir(), "tar-compression") . ".tar";
$archive = new PharData($tmpArchiveName);
} catch (Exception $e) {
unlink($tmpArchiveName);
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw $e;
}
}
$finalArchive = $tmpArchiveName;
if ($typeArchive != ".tar") {
$archiveTypeCompress = substr(strrchr($typeArchive, "."), 1);
$postMessageStatus(sprintf($messages["compression.7"], strtoupper($archiveTypeCompress)), Task::STATUS_RUNNING);
if ($archiveTypeCompress == "gz") {
$archive->compress(Phar::GZ);
} elseif ($archiveTypeCompress == "bz2") {
$archive->compress(Phar::BZ2);
$counterCompression = 0;
//THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP
$tabAllFiles = array_combine($tabAllRecursiveFiles, $tabFilesNames);
foreach ($tabAllFiles as $fullPath => $fileName) {
try {
$archive->addFile(MetaStreamWrapper::getRealFSReference($fullPath), $fileName);
$counterCompression++;
$percent = round(($counterCompression / count($tabAllFiles)) * 100, 0, PHP_ROUND_HALF_DOWN);
$postMessageStatus(sprintf($messages["compression.6"], $percent . " %"), Task::STATUS_RUNNING, $percent);
} catch (Exception $e) {
unlink($tmpArchiveName);
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw $e;
}
}
$finalArchive = $tmpArchiveName;
if ($typeArchive != ".tar") {
$archiveTypeCompress = substr(strrchr($typeArchive, "."), 1);
$postMessageStatus(sprintf($messages["compression.7"], strtoupper($archiveTypeCompress)), Task::STATUS_RUNNING);
if ($archiveTypeCompress == "gz") {
$archive->compress(Phar::GZ);
} elseif ($archiveTypeCompress == "bz2") {
$archive->compress(Phar::BZ2);
}
$finalArchive = $tmpArchiveName . "." . $archiveTypeCompress;
}
$finalArchive = $tmpArchiveName . "." . $archiveTypeCompress;
}

$newNode = new AJXP_Node($currentDirUrl . $archiveName);
$destArchive = $newNode->getRealFile();
rename($finalArchive, $destArchive);
Controller::applyHook("node.before_create", array($newNode, filesize($destArchive)));

if (file_exists($tmpArchiveName)) {
unlink($tmpArchiveName);
unlink(substr($tmpArchiveName, 0, -4));
}
Controller::applyHook("node.change", array(null, $newNode, false), true);
$postMessageStatus("Finished", Task::STATUS_COMPLETE);
break;

// End of Phar compression section
}

$newNode = new AJXP_Node($currentDirUrl . $archiveName);
$destArchive = $newNode->getRealFile();
rename($finalArchive, $destArchive);
Controller::applyHook("node.before_create", array($newNode, filesize($destArchive)));
if (file_exists($tmpArchiveName)) {
unlink($tmpArchiveName);
unlink(substr($tmpArchiveName, 0, -4));
}
Controller::applyHook("node.change", array(null, $newNode, false), true);
$postMessageStatus("Finished", Task::STATUS_COMPLETE);

break;

case "extraction":
Expand Down Expand Up @@ -238,29 +321,65 @@ public function receiveAction(\Psr\Http\Message\ServerRequestInterface &$request

mkdir($currentDirUrl . $onlyFileName, 0777, true);
chmod(MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), 0777);
try {
$archive = new PharData(MetaStreamWrapper::getRealFSReference($currentAllPydioPath));
$fichiersArchive = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharCurrentAllPydioPath));
foreach ($fichiersArchive as $file) {
$fileGetPathName = $file->getPathname();
if ($file->isDir()) {
continue;

// Builds a command that will use any parallel extraction utilities installed to extract an archive file though tar.
if ($this->command_exists("tar")) {
if ($pathInfoCurrentAllPydioPath == "gz") {
if ($this->command_exists("pigz")) {
$tarCommand = "tar -I pigz -xf ";
} else {
$tarCommand = "tar -xzf ";
}
$fileNameInArchive = substr(strstr($fileGetPathName, $fileArchive), strlen($fileArchive) + 1);
try {
$archive->extractTo(MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), $fileNameInArchive, false);
} catch (Exception $e) {
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw new PydioException($e);
} elseif ($pathInfoCurrentAllPydioPath == "bz2") {
if ($this->command_exists("lbzip2")) {
$tarCommand = "tar -I lbzip2 -xf ";
} elseif ($this->command_exists("pbzip2")) {
$tarCommand = "tar -I pbzip2 -xf ";
} else {
$tarCommand = "tar -xjf ";
}
} elseif ($pathInfoCurrentAllPydioPath == "tar") {
$tarCommand = "tar -xf ";
} else {
file_put_contents($progressExtractFileName, "Error : " . $messages["compression.15"]);
throw new PydioException($messages["compression.15"]);
}
$extractCommand = $tarCommand . escapeshellarg(MetaStreamWrapper::getRealFSReference($currentDirUrl . $fileArchive)) . " -C " . escapeshellarg(MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName));
$cmdExitCode = 0;
$cmdOutput = '';
exec($extractCommand, $cmdOutput, $cmdExitCode);
if ($cmdExitCode > 0) {
file_put_contents($progressExtractFileName, "Error : " . $messages["compression.15"]);
throw new PydioException($messages["compression.15"]);
}
} else {
// If tar command is not found, extract using PHP Phar instead
try {
$archive = new PharData(MetaStreamWrapper::getRealFSReference($currentAllPydioPath));
$fichiersArchive = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharCurrentAllPydioPath));
foreach ($fichiersArchive as $file) {
$fileGetPathName = $file->getPathname();
if ($file->isDir()) {
continue;
}
$fileNameInArchive = substr(strstr($fileGetPathName, $fileArchive), strlen($fileArchive) + 1);
try {
$archive->extractTo(MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), $fileNameInArchive, false);
} catch (Exception $e) {
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw new PydioException($e);
}
$counterExtract++;
$progress = round(($counterExtract / $archive->count()) * 100, 0, PHP_ROUND_HALF_DOWN);
$postMessageStatus(sprintf($messages["compression.13"], $progress . "%"), Task::STATUS_RUNNING, $progress);
}
$counterExtract++;
$progress = round(($counterExtract / $archive->count()) * 100, 0, PHP_ROUND_HALF_DOWN);
$postMessageStatus(sprintf($messages["compression.13"], $progress . "%"), Task::STATUS_RUNNING, $progress);
} catch (Exception $e) {
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw new PydioException($e);
}
} catch (Exception $e) {
$postMessageStatus($e->getMessage(), Task::STATUS_FAILED);
throw new PydioException($e);
// End of Phar extraction section
}

$postMessageStatus("Done", Task::STATUS_COMPLETE, 100);
$newNode = new AJXP_Node($currentDirUrl . $onlyFileName);
$nodesDiff = new NodesDiff();
Expand Down

0 comments on commit 0389ee0

Please sign in to comment.