Permalink
Browse files

Put cross_copy as a proper action. Use TaskService to send in backgro…

…und.
  • Loading branch information...
1 parent daea661 commit 5c330ccefb7972da24bdc67092dc643fd53f5c09 @cdujeu cdujeu committed May 21, 2016
@@ -185,20 +185,6 @@ public static function checkParams(&$parameters, $callbackNode, $xPath)
public static function run(ServerRequestInterface $request, &$actionNode = null)
{
$actionName = $request->getAttribute("action");
- if ($actionName == "cross_copy") {
- $pService = PluginsService::getInstance();
- $actives = $pService->getActivePlugins();
- $accessPlug = $pService->getPluginsByType("access");
- if (count($accessPlug)) {
- foreach ($accessPlug as $key=>$objbect) {
- if ($actives[$objbect->getId()] === true) {
- call_user_func(array($pService->getPluginById($objbect->getId()), "crossRepositoryCopy"), $request->getParsedBody());
- break;
- }
- }
- }
- throw new ActionNotFoundException("cross_copy");
- }
$xPath = self::initXPath(true);
if ($actionNode == null) {
$actions = $xPath->query("actions/action[@name='$actionName']");
Oops, something went wrong.
@@ -613,6 +613,11 @@
</serverCallback>
</processing>
</action>
+ <action name="cross_copy">
+ <processing>
+ <serverCallback methodName="crossRepositoryCopy"/>
+ </processing>
+ </action>
<action name="copy" ctrlDragndropDefault="true">
<gui text="66" title="159" src="editcopy.png" iconClass="icon-copy" hasAccessKey="false">
<context selection="true" dir="" recycle="hidden"
@@ -658,7 +663,7 @@
if(user.canWrite()) this.treeSelector.appendFilterValue(activeRepository, "&lt;"+MessageHash[372]+"&gt;", 'top');
this.treeSelector.setFilterSelectedIndex(0);
this.treeSelector.setFilterChangeCallback(function(e){
- externalRepo = this.filterSelector.getValue();
+ var externalRepo = this.filterSelector.getValue();
var nodeProvider = new RemoteNodeProvider();
nodeProvider.initProvider({tmp_repository_id:externalRepo});
this.resetAjxpRootNode(new AjxpNode("/", false, MessageHash[373], "folder.png", nodeProvider));
@@ -20,18 +20,20 @@
*/
namespace Pydio\Access\Core;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ResponseInterface;
use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Access\Core\Model\Repository;
use Pydio\Access\Core\Model\UserSelection;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Controller\Controller;
use Pydio\Core\Utils\Utils;
-use Pydio\Core\Utils\VarsFilter;
use Pydio\Core\Controller\XMLWriter;
use Pydio\Core\PluginFramework\Plugin;
use Pydio\Core\Services\ConfService;
use Pydio\Core\Utils\TextEncoder;
use Pydio\Log\Core\AJXP_Logger;
+use Pydio\Tasks\Task;
+use Pydio\Tasks\TaskService;
defined('AJXP_EXEC') or die( 'Access not allowed');
@@ -114,15 +116,24 @@ public function makeSharedRepositoryOptions($httpVars, $repository){}
/**
* @param $directoryPath string
* @param $repositoryResolvedOptions array
- * @return integer
- * @throw \Exception
+ * @return int
+ * @throws \Exception
*/
public function directoryUsage($directoryPath, $repositoryResolvedOptions){
throw new \Exception("Current driver does not support recursive directory usage!");
}
- public function crossRepositoryCopy($httpVars)
+ public function crossRepositoryCopy(ServerRequestInterface &$requestInterface, ResponseInterface &$responseInterface)
{
+ $httpVars = $requestInterface->getParsedBody();
+
+ $taskId = $requestInterface->getAttribute("pydio-task-id");
+ if(empty($taskId)){
+ $task = TaskService::actionAsTask("cross_copy", $httpVars);
+ TaskService::getInstance()->enqueueTask($task);
+ return;
+ }
+
ConfService::detectRepositoryStreams(true);
$mess = ConfService::getMessages();
$selection = new UserSelection(ConfService::getRepository());
@@ -164,15 +175,17 @@ public function crossRepositoryCopy($httpVars)
$this->copyOrMoveFile(
$destFile,
$file, $errorMessages, $messages, isSet($httpVars["moving_files"]) ? true: false,
- $srcRepoData, $destRepoData);
+ $srcRepoData, $destRepoData, $taskId);
}
- XMLWriter::header();
- if (count($errorMessages)) {
- XMLWriter::sendMessage(null, join("\n", $errorMessages), true);
+
+ if(!empty($taskId)){
+ if (count($errorMessages)) {
+ TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, implode("\n", $errorMessages));
+ }else{
+ TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_COMPLETE, "");
+ }
}
- XMLWriter::sendMessage(join("\n", $messages), null, true);
- XMLWriter::close();
}
/**
@@ -183,8 +196,9 @@ public function crossRepositoryCopy($httpVars)
* @param bool $move Whether to copy or move
* @param array $srcRepoData Set of data concerning source repository: base_url, recycle option
* @param array $destRepoData Set of data concerning destination repository: base_url, chmod option
+ * @param string $taskId Optional task UUID to update during operation
*/
- protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move = false, $srcRepoData = array(), $destRepoData = array())
+ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move = false, $srcRepoData = array(), $destRepoData = array(), $taskId = null)
{
$srcUrlBase = $srcRepoData['base_url'];
$srcRecycle = $srcRepoData['recycle'];
@@ -197,17 +211,19 @@ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move
Controller::applyHook("dl.localname", array($srcFile, &$localName));
if(!empty($localName)) $bName = $localName;
*/
- $destDir = Utils:: safeDirname($destFile);
+ $destDir = Utils::safeDirname($destFile);
$destFile = $destUrlBase.$destFile;
$realSrcFile = $srcUrlBase.$srcFile;
if (is_dir(dirname($realSrcFile)) && (strpos($destFile, rtrim($realSrcFile, "/") . "/") === 0)) {
$error[] = $mess[101];
+ if(!empty($taskId)) TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, $mess[101]);
return;
}
if (!file_exists($realSrcFile)) {
$error[] = $mess[100].$srcFile;
+ if(!empty($taskId)) TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, $mess[100].$srcFile);
return ;
}
if (!$move) {
@@ -216,6 +232,7 @@ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move
}
if (dirname($realSrcFile) == dirname($destFile) && basename($realSrcFile) == basename($destFile)) {
if ($move) {
+ if(!empty($taskId)) TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, $mess[101]);
$error[] = $mess[101];
return ;
} else {
@@ -249,14 +266,19 @@ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move
$srcNode->setLeaf(false);
if ($move) {
Controller::applyHook("node.before_path_change", array($srcNode));
- if(file_exists($destFile)) $this->deldir($destFile, $destRepoData);
+ if(file_exists($destFile)) {
+ $this->deldir($destFile, $destRepoData);
+ }
$res = rename($realSrcFile, $destFile);
+ if($res!==true){
+ $errors[] = "Error while renaming $realSrcFile to $destFile";
+ }
} else {
- $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles, false, true, $srcRepoData, $destRepoData);
+ $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles, false, true, $srcRepoData, $destRepoData, $taskId);
}
- if (count($errors) || (isSet($res) && $res!==true)) {
- $error[] = $mess[114];
- return ;
+ if (count($errors)) {
+ if (!empty($taskId)) TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, implode(" ", $errors));
+ return;
} else {
$destNode->setLeaf(false);
Controller::applyHook("node.change", array($srcNode, $destNode, !$move));
@@ -278,11 +300,13 @@ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move
\Pydio\Core\Controller\Controller::applyHook("node.change", array($srcNode, $destNode, true));
} catch (\Exception $e) {
$error[] = $e->getMessage();
+ if(!empty($taskId)) TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_FAILED, $e->getMessage());
return ;
}
}
}
+ $successMessage = "";
if ($move) {
// Now delete original
// $this->deldir($realSrcFile); // both file and dir
@@ -292,20 +316,24 @@ protected function copyOrMoveFile($destFile, $srcFile, &$error, &$success, $move
$messagePart = $mess[123]." ".$mess[122];
}
if (is_dir($destFile)) {
- $success[] = $mess[117]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($srcFile))." ".$messagePart;
+ $successMessage = $mess[117]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($srcFile))." ".$messagePart;
} else {
- $success[] = $mess[34]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($srcFile))." ".$messagePart;
+ $successMessage = $mess[34]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($srcFile))." ".$messagePart;
}
} else {
if (RecycleBinManager::recycleEnabled() && $destDir == "/".$srcRecycle) {
RecycleBinManager::fileToRecycle($srcFile);
}
if (isSet($dirRes)) {
- $success[] = $mess[117]." ".TextEncoder::toUTF8(basename($destFile))." ".$mess[73]." ".TextEncoder::toUTF8($destDir)." (".TextEncoder::toUTF8($dirRes)." ".$mess[116].")";
+ $successMessage = $mess[117]." ".TextEncoder::toUTF8(basename($destFile))." ".$mess[73]." ".TextEncoder::toUTF8($destDir)." (".TextEncoder::toUTF8($dirRes)." ".$mess[116].")";
} else {
- $success[] = $mess[34]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($destFile))." ".$mess[73]." ". \Pydio\Core\Utils\TextEncoder::toUTF8($destDir);
+ $successMessage = $mess[34]." ". \Pydio\Core\Utils\TextEncoder::toUTF8(basename($destFile))." ".$mess[73]." ". \Pydio\Core\Utils\TextEncoder::toUTF8($destDir);
}
}
+ $success[] = $successMessage;
+ if(!empty($taskId)){
+ TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_RUNNING, $successMessage);
+ }
}
@@ -343,9 +371,10 @@ protected function filecopy($srcFile, $destFile)
* @param bool $convertSrcFile Boolean
* @param array $srcRepoData Set of data concerning source repository: base_url, recycle option
* @param array $destRepoData Set of data concerning destination repository: base_url, chmod option
+ * @param string $taskId Optional Task ID
* @return int
*/
- protected function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = false, $convertSrcFile = true, $srcRepoData = array(), $destRepoData = array())
+ protected function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = false, $convertSrcFile = true, $srcRepoData = array(), $destRepoData = array(), $taskId = null)
{
$num = 0;
//$verbose = true;
@@ -375,12 +404,20 @@ protected function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = fal
if($convertSrcFile) $tmpPath = AJXP_MetaStreamWrapper::getRealFSReference($srcfile);
else $tmpPath = $srcfile;
if($verbose) echo "Copying '$tmpPath' to '$dstfile'...";
+ if(!empty($taskId)){
+ TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_RUNNING, "Copying ".$srcfile);
+ }
copy($tmpPath, $dstfile);
$success[] = $srcfile;
$num ++;
$this->changeMode($dstfile, $destRepoData);
} catch (\Exception $e) {
- $errors[] = $srcfile;
+ $errors[] = $e->getMessage()." - ".$srcfile;
+ }
+ }else{
+ if($verbose) echo "Skipping file ".$srcfile.", already there.";
+ if(!empty($taskId)){
+ TaskService::getInstance()->updateTaskStatus($taskId, Task::STATUS_RUNNING, "Skipping file ".$srcfile.", already there.");
}
}
} else {
@@ -391,7 +428,7 @@ protected function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = fal
closedir($curdir);
foreach ($recurse as $rec) {
if($verbose) echo "Dircopy $srcfile";
- $num += $this->dircopy($rec["src"], $rec["dest"], $errors, $success, $verbose, $convertSrcFile, $srcRepoData, $destRepoData);
+ $num += $this->dircopy($rec["src"], $rec["dest"], $errors, $success, $verbose, $convertSrcFile, $srcRepoData, $destRepoData, $taskId);
}
}
return $num;
@@ -38,6 +38,10 @@
TaskAPI.updateTaskStatus(this, Task.STATUS_PAUSED);
}
+ stop(){
+ TaskAPI.updateTaskStatus(this, Task.STATUS_COMPLETE);
+ }
+
}
Task.STATUS_PENDING = 1;
@@ -108,6 +112,12 @@
}
}
}.bind(this));
+
+ global.pydio.observe("registry_loaded", function(){
+
+ this.getTasks(true);
+
+ }.bind(this));
}
static enqueueActionTask(label, action, parameters = {}, nodes = [], flags = Task.FLAG_STOPPABLE){
@@ -124,8 +134,8 @@
}
- getTasks(){
- if(this._tasksList == undefined){
+ getTasks(forceRefresh = false){
+ if(this._tasksList == undefined || forceRefresh){
var taskMap = new Map();
TaskAPI.loadTasks(function(tasks){
tasks.map(function(t){taskMap.set(t.id, t)});
@@ -168,14 +178,18 @@
this.state.tasks.forEach(function(t){
if(t.getStatus() == Task.STATUS_COMPLETE) return;
let actions;
- if(t.isStoppable()){
- actions = (<span className="icon-stop" onClick={t.pause.bind(t)}/>);
+ if(t.getStatus() == Task.STATUS_RUNNING){
+ if(t.isStoppable()){
+ actions = (<span className="icon-stop" onClick={t.pause.bind(t)}/>);
+ }
+ }else{
+ actions = (<span className="mdi mdi-close-circle-outline" onClick={t.stop.bind(t)}/>);
}
tasks.push(
<div className="task">
<div className="task_texts">
<div className="task_label">{t.getLabel()}</div>
- <div className="status_message">{t.getStatusMessage()}</div>
+ <div className="status_message" title={t.getStatusMessage()}>{t.getStatusMessage()}</div>
</div>
<div className="task_actions">{actions}</div>
</div>
@@ -102,6 +102,7 @@ public function __construct()
{
$this->status = self::STATUS_PENDING;
$this->parameters = [];
+ $this->flags = 0;
$this->schedule = Schedule::scheduleNow();
}
@@ -60,7 +60,12 @@ public static function getInstance(){
public function enqueueTask(Task $task){
-
+ if(ConfService::backgroundActionsSupported()){
+ Controller::applyTaskInBackground($task);
+ }else{
+ // TODO: Should Run now?
+ // $task->run();
+ }
}
protected function publishTaskUpdate(Task $task){
@@ -83,7 +88,7 @@ protected function publishTaskUpdate(Task $task){
}
- public function enqueueActionAsTask($actionName, $parameters, $repoId = "", $user = "", $nodePathes = []){
+ public static function actionAsTask($actionName, $parameters, $repoId = "", $user = "", $nodePathes = [], $flags = 0){
if (empty($user)) {
if(AuthService::usersEnabled() && AuthService::getLoggedUser() !== null) {
@@ -104,6 +109,7 @@ public function enqueueActionAsTask($actionName, $parameters, $repoId = "", $use
$task->setStatusMessage("Starting...");
$task->setAction($actionName);
$task->setParameters($parameters);
+ $task->setFlags($flags);
if(count($nodePathes)){
array_map(function ($node) use ($task){
$task->attachToNode($node);
@@ -120,10 +126,11 @@ public function enqueueActionAsTask($actionName, $parameters, $repoId = "", $use
* @param integer $status
* @param string $message
* @param bool|null $stoppable
+ * @param integer|null $progress
* @return Task
* @throws PydioException
*/
- public function updateTaskStatus($taskId, $status, $message, $stoppable = null){
+ public function updateTaskStatus($taskId, $status, $message, $stoppable = null, $progress = null){
$t = self::getTaskById($taskId);
if(empty($t)){
throw new PydioException("Cannot find task with this id");
@@ -136,6 +143,9 @@ public function updateTaskStatus($taskId, $status, $message, $stoppable = null){
$f = $stoppable ? $f | Task::FLAG_STOPPABLE : $f;
$t->setFlags($f);
}
+ if($progress !== null){
+ $t->setProgress($progress);
+ }
return self::updateTask($t);
}

0 comments on commit 5c330cc

Please sign in to comment.