Make files app use Webdav for most operations
This commit is contained in:
parent
f120846e29
commit
fa2be0750c
22 changed files with 830 additions and 1472 deletions
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Arthur Schiwon <blizzz@owncloud.com>
|
||||
* @author Frank Karlitschek <frank@owncloud.org>
|
||||
* @author Jakob Sack <mail@jakobsack.de>
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
\OC::$server->getSession()->close();
|
||||
|
||||
|
||||
// Get data
|
||||
$dir = isset($_POST['dir']) ? (string)$_POST['dir'] : '';
|
||||
$allFiles = isset($_POST["allfiles"]) ? (string)$_POST["allfiles"] : false;
|
||||
|
||||
// delete all files in dir ?
|
||||
if ($allFiles === 'true') {
|
||||
$files = array();
|
||||
$fileList = \OC\Files\Filesystem::getDirectoryContent($dir);
|
||||
foreach ($fileList as $fileInfo) {
|
||||
$files[] = $fileInfo['name'];
|
||||
}
|
||||
} else {
|
||||
$files = isset($_POST["file"]) ? (string)$_POST["file"] : (string)$_POST["files"];
|
||||
$files = json_decode($files);
|
||||
}
|
||||
$filesWithError = '';
|
||||
|
||||
$success = true;
|
||||
|
||||
//Now delete
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
if (\OC\Files\Filesystem::file_exists($dir . '/' . $file) &&
|
||||
!(\OC\Files\Filesystem::isDeletable($dir . '/' . $file) &&
|
||||
\OC\Files\Filesystem::unlink($dir . '/' . $file))
|
||||
) {
|
||||
$filesWithError .= $file . "\n";
|
||||
$success = false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$filesWithError .= $file . "\n";
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// get array with updated storage stats (e.g. max file size) after upload
|
||||
try {
|
||||
$storageStats = \OCA\Files\Helper::buildFileStorageStatistics($dir);
|
||||
} catch(\OCP\Files\NotFoundException $e) {
|
||||
OCP\JSON::error(['data' => ['message' => 'File not found']]);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
OCP\JSON::success(array("data" => array_merge(array("dir" => $dir, "files" => $files), $storageStats)));
|
||||
} else {
|
||||
OCP\JSON::error(array("data" => array_merge(array("message" => "Could not delete:\n" . $filesWithError), $storageStats)));
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Frank Karlitschek <frank@owncloud.org>
|
||||
* @author Georg Ehrke <georg@owncloud.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
\OC::$server->getSession()->close();
|
||||
|
||||
// Get data
|
||||
$dir = isset($_POST['dir']) ? (string)$_POST['dir'] : '';
|
||||
$file = isset($_POST['file']) ? (string)$_POST['file'] : '';
|
||||
$target = isset($_POST['target']) ? rawurldecode((string)$_POST['target']) : '';
|
||||
|
||||
$l = \OC::$server->getL10N('files');
|
||||
|
||||
if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s - File with this name already exists", array($file)) )));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($target != '' || strtolower($file) != 'shared') {
|
||||
$targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file);
|
||||
$sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
|
||||
try {
|
||||
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {
|
||||
OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file )));
|
||||
} else {
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s", array($file)) )));
|
||||
}
|
||||
} catch (\OCP\Files\NotPermittedException $e) {
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Permission denied") )));
|
||||
} catch (\Exception $e) {
|
||||
OCP\JSON::error(array("data" => array( "message" => $e->getMessage())));
|
||||
}
|
||||
}else{
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s", array($file)) )));
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Andreas Fischer <bantu@owncloud.com>
|
||||
* @author Georg Ehrke <georg@owncloud.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
// Init owncloud
|
||||
global $eventSource;
|
||||
|
||||
\OCP\JSON::checkLoggedIn();
|
||||
\OCP\JSON::callCheck();
|
||||
|
||||
\OC::$server->getSession()->close();
|
||||
|
||||
// Get the params
|
||||
$dir = isset( $_REQUEST['dir'] ) ? '/'.trim((string)$_REQUEST['dir'], '/\\') : '';
|
||||
$fileName = isset( $_REQUEST['filename'] ) ? trim((string)$_REQUEST['filename'], '/\\') : '';
|
||||
|
||||
$l10n = \OC::$server->getL10N('files');
|
||||
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'data' => NULL
|
||||
);
|
||||
|
||||
try {
|
||||
\OC\Files\Filesystem::getView()->verifyPath($dir, $fileName);
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
$result['data'] = [
|
||||
'message' => $ex->getMessage()];
|
||||
OCP\JSON::error($result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\OC\Files\Filesystem::file_exists($dir . '/')) {
|
||||
$result['data'] = array('message' => (string)$l10n->t(
|
||||
'The target folder has been moved or deleted.'),
|
||||
'code' => 'targetnotfound'
|
||||
);
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
$target = $dir.'/'.$fileName;
|
||||
|
||||
if (\OC\Files\Filesystem::file_exists($target)) {
|
||||
$result['data'] = array('message' => (string)$l10n->t(
|
||||
'The name %s is already used in the folder %s. Please choose a different name.',
|
||||
array($fileName, $dir))
|
||||
);
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
$success = false;
|
||||
$templateManager = OC_Helper::getFileTemplateManager();
|
||||
$mimeType = OC_Helper::getMimetypeDetector()->detectPath($target);
|
||||
$content = $templateManager->getTemplate($mimeType);
|
||||
|
||||
try {
|
||||
if($content) {
|
||||
$success = \OC\Files\Filesystem::file_put_contents($target, $content);
|
||||
} else {
|
||||
$success = \OC\Files\Filesystem::touch($target);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$result = [
|
||||
'success' => false,
|
||||
'data' => [
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
];
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
if($success) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($target);
|
||||
OCP\JSON::success(array('data' => \OCA\Files\Helper::formatFileInfo($meta)));
|
||||
return;
|
||||
}
|
||||
|
||||
OCP\JSON::error(array('data' => array( 'message' => $l10n->t('Error when creating the file') )));
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Arthur Schiwon <blizzz@owncloud.com>
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Frank Karlitschek <frank@owncloud.org>
|
||||
* @author Georg Ehrke <georg@owncloud.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
// Init owncloud
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
\OC::$server->getSession()->close();
|
||||
|
||||
// Get the params
|
||||
$dir = isset($_POST['dir']) ? (string)$_POST['dir'] : '';
|
||||
$folderName = isset($_POST['foldername']) ?(string) $_POST['foldername'] : '';
|
||||
|
||||
$l10n = \OC::$server->getL10N('files');
|
||||
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'data' => NULL
|
||||
);
|
||||
|
||||
try {
|
||||
\OC\Files\Filesystem::getView()->verifyPath($dir, $folderName);
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
$result['data'] = [
|
||||
'message' => $ex->getMessage()];
|
||||
OCP\JSON::error($result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\OC\Files\Filesystem::file_exists($dir . '/')) {
|
||||
$result['data'] = array('message' => (string)$l10n->t(
|
||||
'The target folder has been moved or deleted.'),
|
||||
'code' => 'targetnotfound'
|
||||
);
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
$target = $dir . '/' . $folderName;
|
||||
|
||||
if (\OC\Files\Filesystem::file_exists($target)) {
|
||||
$result['data'] = array('message' => $l10n->t(
|
||||
'The name %s is already used in the folder %s. Please choose a different name.',
|
||||
array($folderName, $dir))
|
||||
);
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
if(\OC\Files\Filesystem::mkdir($target)) {
|
||||
if ( $dir !== '/') {
|
||||
$path = $dir.'/'.$folderName;
|
||||
} else {
|
||||
$path = '/'.$folderName;
|
||||
}
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($path);
|
||||
$meta['type'] = 'dir'; // missing ?!
|
||||
OCP\JSON::success(array('data' => \OCA\Files\Helper::formatFileInfo($meta)));
|
||||
exit();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$result = [
|
||||
'success' => false,
|
||||
'data' => [
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
];
|
||||
OCP\JSON::error($result);
|
||||
exit();
|
||||
}
|
||||
|
||||
OCP\JSON::error(array('data' => array( 'message' => $l10n->t('Error when creating the folder') )));
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Christopher Schäpers <kondou@ts.unde.re>
|
||||
* @author Frank Karlitschek <frank@owncloud.org>
|
||||
* @author Jakob Sack <mail@jakobsack.de>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
\OC::$server->getSession()->close();
|
||||
|
||||
$l10n = \OC::$server->getL10N('files');
|
||||
|
||||
$files = new \OCA\Files\App(
|
||||
\OC\Files\Filesystem::getView(),
|
||||
\OC::$server->getL10N('files')
|
||||
);
|
||||
try {
|
||||
$result = $files->rename(
|
||||
isset($_GET['dir']) ? (string)$_GET['dir'] : '',
|
||||
isset($_GET['file']) ? (string)$_GET['file'] : '',
|
||||
isset($_GET['newname']) ? (string)$_GET['newname'] : ''
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
$result = [
|
||||
'success' => false,
|
||||
'data' => [
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if($result['success'] === true){
|
||||
OCP\JSON::success(['data' => $result['data']]);
|
||||
} else {
|
||||
OCP\JSON::error(['data' => $result['data']]);
|
||||
}
|
|
@ -71,7 +71,8 @@
|
|||
folderDropOptions: folderDropOptions,
|
||||
fileActions: fileActions,
|
||||
allowLegacyActions: true,
|
||||
scrollTo: urlParams.scrollto
|
||||
scrollTo: urlParams.scrollto,
|
||||
filesClient: OC.Files.getClient()
|
||||
}
|
||||
);
|
||||
this.files.initialize();
|
||||
|
|
|
@ -575,7 +575,8 @@
|
|||
},
|
||||
actionHandler: function (filename, context) {
|
||||
var dir = context.dir || context.fileList.getCurrentDirectory();
|
||||
var url = context.fileList.getDownloadUrl(filename, dir);
|
||||
var isDir = context.$file.attr('data-type') === 'dir';
|
||||
var url = context.fileList.getDownloadUrl(filename, dir, isDir);
|
||||
|
||||
var downloadFileaction = $(context.$file).find('.fileactions .action-download');
|
||||
|
||||
|
|
|
@ -22,11 +22,12 @@
|
|||
*
|
||||
* @param $el container element with existing markup for the #controls
|
||||
* and a table
|
||||
* @param [options] map of options, see other parameters
|
||||
* @param [options.scrollContainer] scrollable container, defaults to $(window)
|
||||
* @param [options.dragOptions] drag options, disabled by default
|
||||
* @param [options.folderDropOptions] folder drop options, disabled by default
|
||||
* @param [options.detailsViewEnabled=true] whether to enable details view
|
||||
* @param {Object} [options] map of options, see other parameters
|
||||
* @param {Object} [options.scrollContainer] scrollable container, defaults to $(window)
|
||||
* @param {Object} [options.dragOptions] drag options, disabled by default
|
||||
* @param {Object} [options.folderDropOptions] folder drop options, disabled by default
|
||||
* @param {boolean} [options.detailsViewEnabled=true] whether to enable details view
|
||||
* @param {OC.Files.Client} [options.filesClient] files client to use
|
||||
*/
|
||||
var FileList = function($el, options) {
|
||||
this.initialize($el, options);
|
||||
|
@ -73,6 +74,13 @@
|
|||
*/
|
||||
_detailsView: null,
|
||||
|
||||
/**
|
||||
* Files client instance
|
||||
*
|
||||
* @type OC.Files.Client
|
||||
*/
|
||||
filesClient: null,
|
||||
|
||||
/**
|
||||
* Whether the file list was initialized already.
|
||||
* @type boolean
|
||||
|
@ -92,10 +100,17 @@
|
|||
* Array of files in the current folder.
|
||||
* The entries are of file data.
|
||||
*
|
||||
* @type Array.<Object>
|
||||
* @type Array.<OC.Files.FileInfo>
|
||||
*/
|
||||
files: [],
|
||||
|
||||
/**
|
||||
* Current directory entry
|
||||
*
|
||||
* @type OC.Files.FileInfo
|
||||
*/
|
||||
dirInfo: null,
|
||||
|
||||
/**
|
||||
* File actions handler, defaults to OCA.Files.FileActions
|
||||
* @type OCA.Files.FileActions
|
||||
|
@ -149,7 +164,7 @@
|
|||
* When false, clicking on a table header will call reload().
|
||||
* When true, clicking on a table header will simply resort the list.
|
||||
*/
|
||||
_clientSideSort: false,
|
||||
_clientSideSort: true,
|
||||
|
||||
/**
|
||||
* Current directory
|
||||
|
@ -170,6 +185,7 @@
|
|||
* @param options.dragOptions drag options, disabled by default
|
||||
* @param options.folderDropOptions folder drop options, disabled by default
|
||||
* @param options.scrollTo name of file to scroll to after the first load
|
||||
* @param {OC.Files.Client} [options.filesClient] files API client
|
||||
* @private
|
||||
*/
|
||||
initialize: function($el, options) {
|
||||
|
@ -185,6 +201,12 @@
|
|||
if (options.folderDropOptions) {
|
||||
this._folderDropOptions = options.folderDropOptions;
|
||||
}
|
||||
if (options.filesClient) {
|
||||
this.filesClient = options.filesClient;
|
||||
} else {
|
||||
// default client if not specified
|
||||
this.filesClient = OC.Files.getClient();
|
||||
}
|
||||
|
||||
this.$el = $el;
|
||||
if (options.id) {
|
||||
|
@ -209,6 +231,8 @@
|
|||
this.files = [];
|
||||
this._selectedFiles = {};
|
||||
this._selectionSummary = new OCA.Files.FileSummary();
|
||||
// dummy root dir info
|
||||
this.dirInfo = new OC.Files.FileInfo({});
|
||||
|
||||
this.fileSummary = this._createSummary();
|
||||
|
||||
|
@ -359,7 +383,7 @@
|
|||
var highlightState = $tr.hasClass('highlighted');
|
||||
$tr = self.updateRow(
|
||||
$tr,
|
||||
_.extend({isPreviewAvailable: true}, model.toJSON()),
|
||||
model.toJSON(),
|
||||
{updateSummary: true, silent: false, animate: true}
|
||||
);
|
||||
$tr.toggleClass('highlighted', highlightState);
|
||||
|
@ -618,7 +642,7 @@
|
|||
};
|
||||
|
||||
OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, true);
|
||||
OCA.Files.Files.handleDownload(this.getDownloadUrl(files, dir), disableLoadingState);
|
||||
OCA.Files.Files.handleDownload(this.getDownloadUrl(files, dir, true), disableLoadingState);
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -894,16 +918,39 @@
|
|||
self.$el.closest('#app-content').trigger(jQuery.Event('apprendered'));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the icon URL matching the given file info
|
||||
*
|
||||
* @param {OC.Files.FileInfo} fileInfo file info
|
||||
*
|
||||
* @return {string} icon URL
|
||||
*/
|
||||
_getIconUrl: function(fileInfo) {
|
||||
var mimeType = fileInfo.mimetype || 'application/octet-stream';
|
||||
if (mimeType === 'httpd/unix-directory') {
|
||||
// use default folder icon
|
||||
if (fileInfo.mountType === 'shared' || fileInfo.mountType === 'shared-root') {
|
||||
return OC.MimeType.getIconUrl('dir-shared');
|
||||
} else if (fileInfo.mountType === 'external-root') {
|
||||
return OC.MimeType.getIconUrl('dir-external');
|
||||
}
|
||||
return OC.MimeType.getIconUrl('dir');
|
||||
}
|
||||
return OC.MimeType.getIconUrl(mimeType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new table row element using the given file data.
|
||||
* @param {OCA.Files.FileInfo} fileData file info attributes
|
||||
* @param {OC.Files.FileInfo} fileData file info attributes
|
||||
* @param options map of attributes
|
||||
* @return new tr element (not appended to the table)
|
||||
*/
|
||||
_createRow: function(fileData, options) {
|
||||
var td, simpleSize, basename, extension, sizeColor,
|
||||
icon = OC.MimeType.getIconUrl(fileData.mimetype),
|
||||
icon = fileData.icon || this._getIconUrl(fileData),
|
||||
name = fileData.name,
|
||||
// TODO: get rid of type, only use mime type
|
||||
type = fileData.type || 'file',
|
||||
mtime = parseInt(fileData.mtime, 10),
|
||||
mime = fileData.mimetype,
|
||||
|
@ -943,6 +990,14 @@
|
|||
}
|
||||
|
||||
if (fileData.mountType) {
|
||||
// FIXME: HACK: detect shared-root
|
||||
if (fileData.mountType === 'shared' && this.dirInfo.mountType !== 'shared') {
|
||||
// if parent folder isn't share, assume the displayed folder is a share root
|
||||
fileData.mountType = 'shared-root';
|
||||
} else if (fileData.mountType === 'external' && this.dirInfo.mountType !== 'external') {
|
||||
// if parent folder isn't external, assume the displayed folder is the external storage root
|
||||
fileData.mountType = 'external-root';
|
||||
}
|
||||
tr.attr('data-mounttype', fileData.mountType);
|
||||
}
|
||||
|
||||
|
@ -953,24 +1008,16 @@
|
|||
path = this.getCurrentDirectory();
|
||||
}
|
||||
|
||||
if (type === 'dir') {
|
||||
// use default folder icon
|
||||
icon = icon || OC.imagePath('core', 'filetypes/folder');
|
||||
}
|
||||
else {
|
||||
icon = icon || OC.imagePath('core', 'filetypes/file');
|
||||
}
|
||||
|
||||
// filename td
|
||||
td = $('<td class="filename"></td>');
|
||||
|
||||
|
||||
// linkUrl
|
||||
if (type === 'dir') {
|
||||
if (mime === 'httpd/unix-directory') {
|
||||
linkUrl = this.linkTo(path + '/' + name);
|
||||
}
|
||||
else {
|
||||
linkUrl = this.getDownloadUrl(name, path);
|
||||
linkUrl = this.getDownloadUrl(name, path, type === 'dir');
|
||||
}
|
||||
if (this._allowSelection) {
|
||||
td.append(
|
||||
|
@ -996,7 +1043,7 @@
|
|||
basename = '';
|
||||
extension = name;
|
||||
// split extension from filename for non dirs
|
||||
} else if (type !== 'dir' && name.indexOf('.') !== -1) {
|
||||
} else if (mime !== 'httpd/unix-directory' && name.indexOf('.') !== -1) {
|
||||
basename = name.substr(0, name.lastIndexOf('.'));
|
||||
extension = name.substr(name.lastIndexOf('.'));
|
||||
} else {
|
||||
|
@ -1018,7 +1065,7 @@
|
|||
nameSpan.tooltip({placement: 'right'});
|
||||
}
|
||||
// dirs can show the number of uploaded files
|
||||
if (type === 'dir') {
|
||||
if (mime !== 'httpd/unix-directory') {
|
||||
linkElem.append($('<span></span>').attr({
|
||||
'class': 'uploadtext',
|
||||
'currentUploads': 0
|
||||
|
@ -1074,7 +1121,7 @@
|
|||
* Adds an entry to the files array and also into the DOM
|
||||
* in a sorted manner.
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileData map of file attributes
|
||||
* @param {OC.Files.FileInfo} fileData map of file attributes
|
||||
* @param {Object} [options] map of attributes
|
||||
* @param {boolean} [options.updateSummary] true to update the summary
|
||||
* after adding (default), false otherwise. Defaults to true.
|
||||
|
@ -1147,7 +1194,7 @@
|
|||
* Creates a new row element based on the given attributes
|
||||
* and returns it.
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileData map of file attributes
|
||||
* @param {OC.Files.FileInfo} fileData map of file attributes
|
||||
* @param {Object} [options] map of attributes
|
||||
* @param {int} [options.index] index at which to insert the element
|
||||
* @param {boolean} [options.updateSummary] true to update the summary
|
||||
|
@ -1182,7 +1229,7 @@
|
|||
filenameTd.draggable(this._dragOptions);
|
||||
}
|
||||
// allow dropping on folders
|
||||
if (this._folderDropOptions && fileData.type === 'dir') {
|
||||
if (this._folderDropOptions && mime === 'httpd/unix-directory') {
|
||||
filenameTd.droppable(this._folderDropOptions);
|
||||
}
|
||||
|
||||
|
@ -1193,7 +1240,7 @@
|
|||
// display actions
|
||||
this.fileActions.display(filenameTd, !options.silent, this);
|
||||
|
||||
if (fileData.isPreviewAvailable && mime !== 'httpd/unix-directory') {
|
||||
if (mime !== 'httpd/unix-directory') {
|
||||
var iconDiv = filenameTd.find('.thumbnail');
|
||||
// lazy load / newly inserted td ?
|
||||
// the typeof check ensures that the default value of animate is true
|
||||
|
@ -1343,17 +1390,7 @@
|
|||
this._currentFileModel = null;
|
||||
this.$el.find('.select-all').prop('checked', false);
|
||||
this.showMask();
|
||||
if (this._reloadCall) {
|
||||
this._reloadCall.abort();
|
||||
}
|
||||
this._reloadCall = $.ajax({
|
||||
url: this.getAjaxUrl('list'),
|
||||
data: {
|
||||
dir : this.getCurrentDirectory(),
|
||||
sort: this._sort,
|
||||
sortdirection: this._sortDirection
|
||||
}
|
||||
});
|
||||
this._reloadCall = this.filesClient.getFolderContents(this.getCurrentDirectory(), {includeParent: true});
|
||||
if (this._detailsView) {
|
||||
// close sidebar
|
||||
this._updateDetailsView(null);
|
||||
|
@ -1361,24 +1398,19 @@
|
|||
var callBack = this.reloadCallback.bind(this);
|
||||
return this._reloadCall.then(callBack, callBack);
|
||||
},
|
||||
reloadCallback: function(result) {
|
||||
reloadCallback: function(status, result) {
|
||||
delete this._reloadCall;
|
||||
this.hideMask();
|
||||
|
||||
if (!result || result.status === 'error') {
|
||||
// if the error is not related to folder we're trying to load, reload the page to handle logout etc
|
||||
if (result.data.error === 'authentication_error' ||
|
||||
result.data.error === 'token_expired' ||
|
||||
result.data.error === 'application_not_enabled'
|
||||
) {
|
||||
OC.redirect(OC.generateUrl('apps/files'));
|
||||
}
|
||||
OC.Notification.showTemporary(result.data.message);
|
||||
if (status === 401) {
|
||||
// TODO: append current URL to be able to get back after logging in again
|
||||
OC.redirect(OC.generateUrl('apps/files'));
|
||||
OC.Notification.show(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Firewall Blocked request?
|
||||
if (result.status === 403) {
|
||||
if (status === 403) {
|
||||
// Go home
|
||||
this.changeDirectory('/');
|
||||
OC.Notification.showTemporary(t('files', 'This operation is forbidden'));
|
||||
|
@ -1386,32 +1418,49 @@
|
|||
}
|
||||
|
||||
// Did share service die or something else fail?
|
||||
if (result.status === 500) {
|
||||
if (status === 500) {
|
||||
// Go home
|
||||
this.changeDirectory('/');
|
||||
OC.Notification.showTemporary(t('files', 'This directory is unavailable, please check the logs or contact the administrator'));
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'This directory is unavailable, please check the logs or contact the administrator')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result.status === 404) {
|
||||
if (status === 503) {
|
||||
// Go home
|
||||
if (this.getCurrentDirectory() !== '/') {
|
||||
this.changeDirectory('/');
|
||||
// TODO: read error message from exception
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Storage not available')
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status === 404) {
|
||||
// go back home
|
||||
this.changeDirectory('/');
|
||||
return false;
|
||||
}
|
||||
// aborted ?
|
||||
if (result.status === 0){
|
||||
if (status === 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: should rather return upload file size through
|
||||
// the files list ajax call
|
||||
// TODO: parse remaining quota from PROPFIND response
|
||||
this.updateStorageStatistics(true);
|
||||
|
||||
if (result.data.permissions) {
|
||||
this.setDirectoryPermissions(result.data.permissions);
|
||||
// first entry is the root
|
||||
this.dirInfo = result.shift();
|
||||
|
||||
if (this.dirInfo.permissions) {
|
||||
this.setDirectoryPermissions(this.dirInfo.permissions);
|
||||
}
|
||||
|
||||
this.setFiles(result.data.files);
|
||||
result.sort(this._sortComparator);
|
||||
this.setFiles(result);
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -1419,12 +1468,15 @@
|
|||
OCA.Files.Files.updateStorageStatistics(this.getCurrentDirectory(), force);
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated do not use nor override
|
||||
*/
|
||||
getAjaxUrl: function(action, params) {
|
||||
return OCA.Files.Files.getAjaxUrl(action, params);
|
||||
},
|
||||
|
||||
getDownloadUrl: function(files, dir) {
|
||||
return OCA.Files.Files.getDownloadUrl(files, dir || this.getCurrentDirectory());
|
||||
getDownloadUrl: function(files, dir, isDir) {
|
||||
return OCA.Files.Files.getDownloadUrl(files, dir || this.getCurrentDirectory(), isDir);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1489,8 +1541,6 @@
|
|||
if (etag){
|
||||
// use etag as cache buster
|
||||
urlSpec.c = etag;
|
||||
} else {
|
||||
console.warn('OCA.Files.FileList.lazyLoadPreview(): missing etag argument');
|
||||
}
|
||||
|
||||
previewURL = self.generatePreviewUrl(urlSpec);
|
||||
|
@ -1514,6 +1564,9 @@
|
|||
img.src = previewURL;
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
setDirectoryPermissions: function(permissions) {
|
||||
var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0;
|
||||
this.$el.find('#permissions').val(permissions);
|
||||
|
@ -1610,7 +1663,7 @@
|
|||
* fileData should be inserted, considering the current
|
||||
* sorting
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileData file info
|
||||
* @param {OC.Files.FileInfo} fileData file info
|
||||
*/
|
||||
_findInsertionIndex: function(fileData) {
|
||||
var index = 0;
|
||||
|
@ -1628,6 +1681,9 @@
|
|||
move: function(fileNames, targetPath) {
|
||||
var self = this;
|
||||
var dir = this.getCurrentDirectory();
|
||||
if (dir.charAt(dir.length - 1) !== '/') {
|
||||
dir += '/';
|
||||
}
|
||||
var target = OC.basename(targetPath);
|
||||
if (!_.isArray(fileNames)) {
|
||||
fileNames = [fileNames];
|
||||
|
@ -1635,46 +1691,42 @@
|
|||
_.each(fileNames, function(fileName) {
|
||||
var $tr = self.findFileEl(fileName);
|
||||
self.showFileBusyState($tr, true);
|
||||
// TODO: improve performance by sending all file names in a single call
|
||||
$.post(
|
||||
OC.filePath('files', 'ajax', 'move.php'),
|
||||
{
|
||||
dir: dir,
|
||||
file: fileName,
|
||||
target: targetPath
|
||||
},
|
||||
function(result) {
|
||||
if (result) {
|
||||
if (result.status === 'success') {
|
||||
// if still viewing the same directory
|
||||
if (self.getCurrentDirectory() === dir) {
|
||||
// recalculate folder size
|
||||
var oldFile = self.findFileEl(target);
|
||||
var newFile = self.findFileEl(fileName);
|
||||
var oldSize = oldFile.data('size');
|
||||
var newSize = oldSize + newFile.data('size');
|
||||
oldFile.data('size', newSize);
|
||||
oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize));
|
||||
if (targetPath.charAt(targetPath.length - 1) !== '/') {
|
||||
// make sure we move the files into the target dir,
|
||||
// not overwrite it
|
||||
targetPath = targetPath + '/';
|
||||
}
|
||||
self.filesClient.move(dir + fileName, targetPath + fileName)
|
||||
.done(function() {
|
||||
// if still viewing the same directory
|
||||
if (OC.joinPaths(self.getCurrentDirectory(), '/') === dir) {
|
||||
// recalculate folder size
|
||||
var oldFile = self.findFileEl(target);
|
||||
var newFile = self.findFileEl(fileName);
|
||||
var oldSize = oldFile.data('size');
|
||||
var newSize = oldSize + newFile.data('size');
|
||||
oldFile.data('size', newSize);
|
||||
oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize));
|
||||
|
||||
// TODO: also update entry in FileList.files
|
||||
|
||||
self.remove(fileName);
|
||||
}
|
||||
} else {
|
||||
OC.Notification.hide();
|
||||
if (result.status === 'error' && result.data.message) {
|
||||
OC.Notification.showTemporary(result.data.message);
|
||||
}
|
||||
else {
|
||||
OC.Notification.showTemporary(t('files', 'Error moving file.'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
|
||||
// TODO: also update entry in FileList.files
|
||||
self.remove(fileName);
|
||||
}
|
||||
})
|
||||
.fail(function(status) {
|
||||
if (status === 412) {
|
||||
// TODO: some day here we should invoke the conflict dialog
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not move "{file}", target exists', {file: fileName})
|
||||
);
|
||||
} else {
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not move "{file}"', {file: fileName})
|
||||
);
|
||||
}
|
||||
})
|
||||
.always(function() {
|
||||
self.showFileBusyState($tr, false);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
@ -1700,16 +1752,16 @@
|
|||
* Triggers file rename input field for the given file name.
|
||||
* If the user enters a new name, the file will be renamed.
|
||||
*
|
||||
* @param oldname file name of the file to rename
|
||||
* @param oldName file name of the file to rename
|
||||
*/
|
||||
rename: function(oldname) {
|
||||
rename: function(oldName) {
|
||||
var self = this;
|
||||
var tr, td, input, form;
|
||||
tr = this.findFileEl(oldname);
|
||||
tr = this.findFileEl(oldName);
|
||||
var oldFileInfo = this.files[tr.index()];
|
||||
tr.data('renaming',true);
|
||||
td = tr.children('td.filename');
|
||||
input = $('<input type="text" class="filename"/>').val(oldname);
|
||||
input = $('<input type="text" class="filename"/>').val(oldName);
|
||||
form = $('<form></form>');
|
||||
form.append(input);
|
||||
td.children('a.name').hide();
|
||||
|
@ -1724,11 +1776,11 @@
|
|||
input.selectRange(0, len);
|
||||
var checkInput = function () {
|
||||
var filename = input.val();
|
||||
if (filename !== oldname) {
|
||||
if (filename !== oldName) {
|
||||
// Files.isFileNameValid(filename) throws an exception itself
|
||||
OCA.Files.Files.isFileNameValid(filename);
|
||||
if (self.inList(filename)) {
|
||||
throw t('files', '{new_name} already exists', {new_name: filename});
|
||||
throw t('files', '{newName} already exists', {newName: filename});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1741,6 +1793,14 @@
|
|||
td.children('a.name').show();
|
||||
}
|
||||
|
||||
function updateInList(fileInfo) {
|
||||
tr.remove();
|
||||
tr = self.add(fileInfo, {updateSummary: false, silent: true});
|
||||
self.$fileList.trigger($.Event('fileActionsReady', {fileList: self, $files: $(tr)}));
|
||||
self._updateDetailsView(fileInfo.name);
|
||||
}
|
||||
|
||||
// TODO: too many nested blocks, move parts into functions
|
||||
form.submit(function(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
@ -1753,7 +1813,7 @@
|
|||
input.tooltip('hide');
|
||||
form.remove();
|
||||
|
||||
if (newName !== oldname) {
|
||||
if (newName !== oldName) {
|
||||
checkInput();
|
||||
// mark as loading (temp element)
|
||||
self.showFileBusyState(tr, true);
|
||||
|
@ -1765,34 +1825,46 @@
|
|||
td.find('a.name span.nametext').text(basename);
|
||||
td.children('a.name').show();
|
||||
|
||||
$.ajax({
|
||||
url: OC.filePath('files','ajax','rename.php'),
|
||||
data: {
|
||||
dir : tr.attr('data-path') || self.getCurrentDirectory(),
|
||||
newname: newName,
|
||||
file: oldname
|
||||
},
|
||||
success: function(result) {
|
||||
var fileInfo;
|
||||
if (!result || result.status === 'error') {
|
||||
OC.dialogs.alert(result.data.message, t('files', 'Could not rename file'));
|
||||
fileInfo = oldFileInfo;
|
||||
if (result.data.code === 'sourcenotfound') {
|
||||
self.remove(result.data.newname, {updateSummary: true});
|
||||
return;
|
||||
}
|
||||
var path = tr.attr('data-path') || self.getCurrentDirectory();
|
||||
self.filesClient.move(path + '/' + oldName, path + '/' + newName)
|
||||
.done(function() {
|
||||
var fileInfo = self.files.splice(tr.index(), 1)[0];
|
||||
fileInfo.name = newName;
|
||||
updateInList(fileInfo);
|
||||
})
|
||||
.fail(function(status) {
|
||||
// TODO: 409 means current folder does not exist, redirect ?
|
||||
if (status === 404) {
|
||||
// source not found, so remove it from the list
|
||||
OC.Notification.showTemporary(
|
||||
t(
|
||||
'files',
|
||||
'Could not rename "{fileName}", it does not exist any more',
|
||||
{fileName: oldName}
|
||||
)
|
||||
);
|
||||
self.remove(newName, {updateSummary: true});
|
||||
return;
|
||||
} else if (status === 412) {
|
||||
// target exists
|
||||
OC.Notification.showTemporary(
|
||||
t(
|
||||
'files',
|
||||
'The name "{targetName}" is already used in the folder "{dir}". Please choose a different name.',
|
||||
{
|
||||
targetName: newName,
|
||||
dir: self.getCurrentDirectory()
|
||||
}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// restore the item to its previous state
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not rename "{fileName}"', {fileName: oldName})
|
||||
);
|
||||
}
|
||||
else {
|
||||
fileInfo = result.data;
|
||||
}
|
||||
// reinsert row
|
||||
self.files.splice(tr.index(), 1);
|
||||
tr.remove();
|
||||
tr = self.add(fileInfo, {updateSummary: false, silent: true});
|
||||
self.$fileList.trigger($.Event('fileActionsReady', {fileList: self, $files: $(tr)}));
|
||||
self._updateDetailsView(fileInfo.name, false);
|
||||
}
|
||||
});
|
||||
updateInList(oldFileInfo);
|
||||
});
|
||||
} else {
|
||||
// add back the old file info when cancelled
|
||||
self.files.splice(tr.index(), 1);
|
||||
|
@ -1849,32 +1921,44 @@
|
|||
var promise = deferred.promise();
|
||||
|
||||
OCA.Files.Files.isFileNameValid(name);
|
||||
name = this.getUniqueName(name);
|
||||
|
||||
if (this.lastAction) {
|
||||
this.lastAction();
|
||||
}
|
||||
|
||||
$.post(
|
||||
OC.generateUrl('/apps/files/ajax/newfile.php'),
|
||||
{
|
||||
dir: this.getCurrentDirectory(),
|
||||
filename: name
|
||||
},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
self.add(result.data, {animate: true, scrollTo: true});
|
||||
deferred.resolve(result.status, result.data);
|
||||
} else {
|
||||
if (result.data && result.data.message) {
|
||||
OC.Notification.showTemporary(result.data.message);
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('core', 'Could not create file'));
|
||||
}
|
||||
deferred.reject(result.status, result.data);
|
||||
name = this.getUniqueName(name);
|
||||
var targetPath = this.getCurrentDirectory() + '/' + name;
|
||||
|
||||
self.filesClient.putFileContents(
|
||||
targetPath,
|
||||
'',
|
||||
{
|
||||
contentType: 'text/plain',
|
||||
overwrite: true
|
||||
}
|
||||
}
|
||||
);
|
||||
)
|
||||
.done(function() {
|
||||
// TODO: error handling / conflicts
|
||||
self.filesClient.getFileInfo(targetPath)
|
||||
.then(function(status, data) {
|
||||
self.add(data, {animate: true, scrollTo: true});
|
||||
deferred.resolve(status, data);
|
||||
})
|
||||
.fail(function(status) {
|
||||
OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name}));
|
||||
deferred.reject(status);
|
||||
});
|
||||
})
|
||||
.fail(function(status) {
|
||||
if (status === 412) {
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not create file "{file}" because it already exists', {file: name})
|
||||
);
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name}));
|
||||
}
|
||||
deferred.reject(status);
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
@ -1895,32 +1979,50 @@
|
|||
var promise = deferred.promise();
|
||||
|
||||
OCA.Files.Files.isFileNameValid(name);
|
||||
name = this.getUniqueName(name);
|
||||
|
||||
if (this.lastAction) {
|
||||
this.lastAction();
|
||||
}
|
||||
|
||||
$.post(
|
||||
OC.generateUrl('/apps/files/ajax/newfolder.php'),
|
||||
{
|
||||
dir: this.getCurrentDirectory(),
|
||||
foldername: name
|
||||
},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
self.add(result.data, {animate: true, scrollTo: true});
|
||||
deferred.resolve(result.status, result.data);
|
||||
name = this.getUniqueName(name);
|
||||
var targetPath = this.getCurrentDirectory() + '/' + name;
|
||||
|
||||
this.filesClient.createDirectory(targetPath)
|
||||
.done(function(createStatus) {
|
||||
self.filesClient.getFileInfo(targetPath)
|
||||
.done(function(status, data) {
|
||||
self.add(data, {animate: true, scrollTo: true});
|
||||
deferred.resolve(status, data);
|
||||
})
|
||||
.fail(function() {
|
||||
OC.Notification.showTemporary(t('files', 'Could not create folder "{dir}"', {dir: name}));
|
||||
deferred.reject(createStatus);
|
||||
});
|
||||
})
|
||||
.fail(function(createStatus) {
|
||||
// method not allowed, folder might exist already
|
||||
if (createStatus === 405) {
|
||||
self.filesClient.getFileInfo(targetPath)
|
||||
.done(function(status, data) {
|
||||
// add it to the list, for completeness
|
||||
self.add(data, {animate: true, scrollTo: true});
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not create folder "{dir}" because it already exists', {dir: name})
|
||||
);
|
||||
// still consider a failure
|
||||
deferred.reject(createStatus, data);
|
||||
})
|
||||
.fail(function() {
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Could not create folder "{dir}"', {dir: name})
|
||||
);
|
||||
deferred.reject(status);
|
||||
});
|
||||
} else {
|
||||
if (result.data && result.data.message) {
|
||||
OC.Notification.showTemporary(result.data.message);
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('core', 'Could not create folder'));
|
||||
}
|
||||
deferred.reject(result.status);
|
||||
OC.Notification.showTemporary(t('files', 'Could not create folder "{dir}"', {dir: name}));
|
||||
deferred.reject(createStatus);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
@ -1981,76 +2083,59 @@
|
|||
*/
|
||||
do_delete:function(files, dir) {
|
||||
var self = this;
|
||||
var params;
|
||||
if (files && files.substr) {
|
||||
files=[files];
|
||||
}
|
||||
if (!files) {
|
||||
// delete all files in directory
|
||||
files = _.pluck(this.files, 'name');
|
||||
}
|
||||
if (files) {
|
||||
this.showFileBusyState(files, true);
|
||||
for (var i=0; i<files.length; i++) {
|
||||
}
|
||||
}
|
||||
// Finish any existing actions
|
||||
if (this.lastAction) {
|
||||
this.lastAction();
|
||||
}
|
||||
|
||||
params = {
|
||||
dir: dir || this.getCurrentDirectory()
|
||||
};
|
||||
if (files) {
|
||||
params.files = JSON.stringify(files);
|
||||
}
|
||||
else {
|
||||
// no files passed, delete all in current dir
|
||||
params.allfiles = true;
|
||||
// show spinner for all files
|
||||
this.showFileBusyState(this.$fileList.find('tr'), true);
|
||||
dir = dir || this.getCurrentDirectory();
|
||||
|
||||
function removeFromList(file) {
|
||||
var fileEl = self.remove(file, {updateSummary: false});
|
||||
// FIXME: not sure why we need this after the
|
||||
// element isn't even in the DOM any more
|
||||
fileEl.find('.selectCheckBox').prop('checked', false);
|
||||
fileEl.removeClass('selected');
|
||||
self.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')});
|
||||
// TODO: this info should be returned by the ajax call!
|
||||
self.updateEmptyContent();
|
||||
self.fileSummary.update();
|
||||
self.updateSelectionSummary();
|
||||
// FIXME: don't repeat this, do it once all files are done
|
||||
self.updateStorageStatistics();
|
||||
}
|
||||
|
||||
$.post(OC.filePath('files', 'ajax', 'delete.php'),
|
||||
params,
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
if (params.allfiles) {
|
||||
self.setFiles([]);
|
||||
}
|
||||
else {
|
||||
$.each(files,function(index,file) {
|
||||
var fileEl = self.remove(file, {updateSummary: false});
|
||||
// FIXME: not sure why we need this after the
|
||||
// element isn't even in the DOM any more
|
||||
fileEl.find('.selectCheckBox').prop('checked', false);
|
||||
fileEl.removeClass('selected');
|
||||
self.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')});
|
||||
});
|
||||
}
|
||||
// TODO: this info should be returned by the ajax call!
|
||||
self.updateEmptyContent();
|
||||
self.fileSummary.update();
|
||||
self.updateSelectionSummary();
|
||||
self.updateStorageStatistics();
|
||||
// in case there was a "storage full" permanent notification
|
||||
OC.Notification.hide();
|
||||
_.each(files, function(file) {
|
||||
self.filesClient.remove(dir + '/' + file)
|
||||
.done(function() {
|
||||
removeFromList(file);
|
||||
})
|
||||
.fail(function(status) {
|
||||
if (status === 404) {
|
||||
// the file already did not exist, remove it from the list
|
||||
removeFromList(file);
|
||||
} else {
|
||||
if (result.status === 'error' && result.data.message) {
|
||||
OC.Notification.showTemporary(result.data.message);
|
||||
}
|
||||
else {
|
||||
OC.Notification.showTemporary(t('files', 'Error deleting file.'));
|
||||
}
|
||||
if (params.allfiles) {
|
||||
// reload the page as we don't know what files were deleted
|
||||
// and which ones remain
|
||||
self.reload();
|
||||
}
|
||||
else {
|
||||
$.each(files,function(index,file) {
|
||||
self.showFileBusyState(file, false);
|
||||
});
|
||||
}
|
||||
// only reset the spinner for that one file
|
||||
OC.Notification.showTemporary(
|
||||
t('files', 'Error deleting file "{fileName}".', {fileName: file}),
|
||||
{timeout: 10}
|
||||
);
|
||||
var deleteAction = self.findFileEl(file).find('.action.delete');
|
||||
deleteAction.removeClass('icon-loading-small').addClass('icon-delete');
|
||||
self.showFileBusyState(files, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Creates the file summary section
|
||||
|
@ -2659,8 +2744,8 @@
|
|||
* Compares two file infos by name, making directories appear
|
||||
* first.
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OCA.Files.FileInfo} fileInfo2 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo2 file info
|
||||
* @return {int} -1 if the first file must appear before the second one,
|
||||
* 0 if they are identify, 1 otherwise.
|
||||
*/
|
||||
|
@ -2676,8 +2761,8 @@
|
|||
/**
|
||||
* Compares two file infos by size.
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OCA.Files.FileInfo} fileInfo2 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo2 file info
|
||||
* @return {int} -1 if the first file must appear before the second one,
|
||||
* 0 if they are identify, 1 otherwise.
|
||||
*/
|
||||
|
@ -2687,8 +2772,8 @@
|
|||
/**
|
||||
* Compares two file infos by timestamp.
|
||||
*
|
||||
* @param {OCA.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OCA.Files.FileInfo} fileInfo2 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo1 file info
|
||||
* @param {OC.Files.FileInfo} fileInfo2 file info
|
||||
* @return {int} -1 if the first file must appear before the second one,
|
||||
* 0 if they are identify, 1 otherwise.
|
||||
*/
|
||||
|
@ -2700,23 +2785,14 @@
|
|||
/**
|
||||
* File info attributes.
|
||||
*
|
||||
* @todo make this a real class in the future
|
||||
* @typedef {Object} OCA.Files.FileInfo
|
||||
* @typedef {Object} OC.Files.FileInfo
|
||||
*
|
||||
* @lends OC.Files.FileInfo
|
||||
*
|
||||
* @deprecated use OC.Files.FileInfo instead
|
||||
*
|
||||
* @property {int} id file id
|
||||
* @property {String} name file name
|
||||
* @property {String} [path] file path, defaults to the list's current path
|
||||
* @property {String} mimetype mime type
|
||||
* @property {String} type "file" for files or "dir" for directories
|
||||
* @property {int} permissions file permissions
|
||||
* @property {int} mtime modification time in milliseconds
|
||||
* @property {boolean} [isShareMountPoint] whether the file is a share mount
|
||||
* point
|
||||
* @property {boolean} [isPreviewAvailable] whether a preview is available
|
||||
* for the given file type
|
||||
* @property {String} [icon] path to the mime type icon
|
||||
* @property {String} etag etag of the file
|
||||
*/
|
||||
OCA.Files.FileInfo = OC.Files.FileInfo;
|
||||
|
||||
OCA.Files.FileList = FileList;
|
||||
})();
|
||||
|
|
|
@ -136,13 +136,27 @@
|
|||
|
||||
/**
|
||||
* Returns the download URL of the given file(s)
|
||||
* @param filename string or array of file names to download
|
||||
* @param dir optional directory in which the file name is, defaults to the current directory
|
||||
* @param {string} filename string or array of file names to download
|
||||
* @param {string} [dir] optional directory in which the file name is, defaults to the current directory
|
||||
* @param {bool} [isDir=false] whether the given filename is a directory and might need a special URL
|
||||
*/
|
||||
getDownloadUrl: function(filename, dir) {
|
||||
if ($.isArray(filename)) {
|
||||
getDownloadUrl: function(filename, dir, isDir) {
|
||||
if (!_.isArray(filename) && !isDir) {
|
||||
var pathSections = dir.split('/');
|
||||
pathSections.push(filename);
|
||||
var encodedPath = '';
|
||||
_.each(pathSections, function(section) {
|
||||
if (section !== '') {
|
||||
encodedPath += '/' + encodeURIComponent(section);
|
||||
}
|
||||
});
|
||||
return OC.linkToRemoteBase('webdav') + encodedPath;
|
||||
}
|
||||
|
||||
if (_.isArray(filename)) {
|
||||
filename = JSON.stringify(filename);
|
||||
}
|
||||
|
||||
var params = {
|
||||
dir: dir,
|
||||
files: filename
|
||||
|
@ -356,8 +370,10 @@ scanFiles.scanning=false;
|
|||
|
||||
// TODO: move to FileList
|
||||
var createDragShadow = function(event) {
|
||||
// FIXME: inject file list instance somehow
|
||||
/* global FileList, Files */
|
||||
|
||||
//select dragged file
|
||||
var FileList = OCA.Files.App.fileList;
|
||||
var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked');
|
||||
if (!isDragSelected) {
|
||||
//select dragged file
|
||||
|
@ -394,7 +410,7 @@ var createDragShadow = function(event) {
|
|||
.css('background-image', 'url(' + OC.imagePath('core', 'filetypes/folder.png') + ')');
|
||||
} else {
|
||||
var path = dir + '/' + elem.name;
|
||||
OCA.Files.App.files.lazyLoadPreview(path, elem.mime, function(previewpath) {
|
||||
Files.lazyLoadPreview(path, elem.mimetype, function(previewpath) {
|
||||
newtr.find('td.filename')
|
||||
.css('background-image', 'url(' + previewpath + ')');
|
||||
}, null, null, elem.etag);
|
||||
|
@ -441,7 +457,7 @@ var folderDropOptions = {
|
|||
hoverClass: "canDrop",
|
||||
drop: function( event, ui ) {
|
||||
// don't allow moving a file into a selected folder
|
||||
var FileList = OCA.Files.App.fileList;
|
||||
/* global FileList */
|
||||
if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,108 +28,22 @@
|
|||
namespace OCA\Files;
|
||||
|
||||
class App {
|
||||
/**
|
||||
* @var \OC_L10N
|
||||
*/
|
||||
private $l10n;
|
||||
|
||||
/**
|
||||
* @var \OCP\INavigationManager
|
||||
*/
|
||||
private static $navigationManager;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\View
|
||||
*/
|
||||
private $view;
|
||||
|
||||
public function __construct($view, $l10n) {
|
||||
$this->view = $view;
|
||||
$this->l10n = $l10n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app's navigation manager
|
||||
*
|
||||
* @return \OCP\INavigationManager
|
||||
*/
|
||||
public static function getNavigationManager() {
|
||||
// TODO: move this into a service in the Application class
|
||||
if (self::$navigationManager === null) {
|
||||
self::$navigationManager = new \OC\NavigationManager();
|
||||
}
|
||||
return self::$navigationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* rename a file
|
||||
*
|
||||
* @param string $dir
|
||||
* @param string $oldname
|
||||
* @param string $newname
|
||||
* @return array
|
||||
*/
|
||||
public function rename($dir, $oldname, $newname) {
|
||||
$result = array(
|
||||
'success' => false,
|
||||
'data' => NULL
|
||||
);
|
||||
|
||||
try {
|
||||
// check if the new name is conform to file name restrictions
|
||||
$this->view->verifyPath($dir, $newname);
|
||||
} catch (\OCP\Files\InvalidPathException $ex) {
|
||||
$result['data'] = array(
|
||||
'message' => $this->l10n->t($ex->getMessage()),
|
||||
'code' => 'invalidname',
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$normalizedOldPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $oldname);
|
||||
$normalizedNewPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname);
|
||||
|
||||
// rename to non-existing folder is denied
|
||||
if (!$this->view->file_exists($normalizedOldPath)) {
|
||||
$result['data'] = array(
|
||||
'message' => $this->l10n->t('%s could not be renamed as it has been deleted', array($oldname)),
|
||||
'code' => 'sourcenotfound',
|
||||
'oldname' => $oldname,
|
||||
'newname' => $newname,
|
||||
);
|
||||
}else if (!$this->view->file_exists($dir)) {
|
||||
$result['data'] = array('message' => (string)$this->l10n->t(
|
||||
'The target folder has been moved or deleted.',
|
||||
array($dir)),
|
||||
'code' => 'targetnotfound'
|
||||
);
|
||||
// rename to existing file is denied
|
||||
} else if ($this->view->file_exists($normalizedNewPath)) {
|
||||
|
||||
$result['data'] = array(
|
||||
'message' => $this->l10n->t(
|
||||
"The name %s is already used in the folder %s. Please choose a different name.",
|
||||
array($newname, $dir))
|
||||
);
|
||||
} else if (
|
||||
// rename to "." is denied
|
||||
$newname !== '.' and
|
||||
// THEN try to rename
|
||||
$this->view->rename($normalizedOldPath, $normalizedNewPath)
|
||||
) {
|
||||
// successful rename
|
||||
$meta = $this->view->getFileInfo($normalizedNewPath);
|
||||
$meta = \OCA\Files\Helper::populateTags(array($meta));
|
||||
$fileInfo = \OCA\Files\Helper::formatFileInfo(current($meta));
|
||||
$fileInfo['path'] = dirname($normalizedNewPath);
|
||||
$result['success'] = true;
|
||||
$result['data'] = $fileInfo;
|
||||
} else {
|
||||
// rename failed
|
||||
$result['data'] = array(
|
||||
'message' => $this->l10n->t('%s could not be renamed', array($oldname))
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -139,9 +139,6 @@ class Helper {
|
|||
$entry['parentId'] = $i['parent'];
|
||||
$entry['mtime'] = $i['mtime'] * 1000;
|
||||
// only pick out the needed attributes
|
||||
if (\OC::$server->getPreviewManager()->isAvailable($i)) {
|
||||
$entry['isPreviewAvailable'] = true;
|
||||
}
|
||||
$entry['name'] = $i->getName();
|
||||
$entry['permissions'] = $i['permissions'];
|
||||
$entry['mimetype'] = $i['mimetype'];
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Christopher Schäpers <kondou@ts.unde.re>
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
class Test_OC_Files_App_Rename extends \Test\TestCase {
|
||||
private static $user;
|
||||
|
||||
/**
|
||||
* @var PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $viewMock;
|
||||
|
||||
/**
|
||||
* @var \OCA\Files\App
|
||||
*/
|
||||
private $files;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// mock OC_L10n
|
||||
if (!self::$user) {
|
||||
self::$user = uniqid();
|
||||
}
|
||||
\OC_User::createUser(self::$user, 'password');
|
||||
$this->loginAsUser(self::$user);
|
||||
|
||||
$l10nMock = $this->getMock('\OC_L10N', array('t'), array(), '', false);
|
||||
$l10nMock->expects($this->any())
|
||||
->method('t')
|
||||
->will($this->returnArgument(0));
|
||||
$viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo', 'file_exists'), array(), '', false);
|
||||
$viewMock->expects($this->any())
|
||||
->method('normalizePath')
|
||||
->will($this->returnArgument(0));
|
||||
$viewMock->expects($this->any())
|
||||
->method('rename')
|
||||
->will($this->returnValue(true));
|
||||
$this->viewMock = $viewMock;
|
||||
$this->files = new \OCA\Files\App($viewMock, $l10nMock);
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
$result = \OC_User::deleteUser(self::$user);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$this->logout();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* test rename of file/folder
|
||||
*/
|
||||
function testRenameFolder() {
|
||||
$dir = '/';
|
||||
$oldname = 'oldname';
|
||||
$newname = 'newname';
|
||||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('file_exists')
|
||||
->with($this->anything())
|
||||
->will($this->returnValueMap(array(
|
||||
array('/', true),
|
||||
array('/oldname', true)
|
||||
)));
|
||||
|
||||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('getFileInfo')
|
||||
->will($this->returnValue(new \OC\Files\FileInfo(
|
||||
'/new_name',
|
||||
new \OC\Files\Storage\Local(array('datadir' => '/')),
|
||||
'/',
|
||||
array(
|
||||
'fileid' => 123,
|
||||
'type' => 'dir',
|
||||
'mimetype' => 'httpd/unix-directory',
|
||||
'mtime' => 0,
|
||||
'permissions' => 31,
|
||||
'size' => 18,
|
||||
'etag' => 'abcdef',
|
||||
'directory' => '/',
|
||||
'name' => 'new_name',
|
||||
), null)));
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEquals(123, $result['data']['id']);
|
||||
$this->assertEquals('new_name', $result['data']['name']);
|
||||
$this->assertEquals(18, $result['data']['size']);
|
||||
$this->assertEquals('httpd/unix-directory', $result['data']['mimetype']);
|
||||
$this->assertEquals('abcdef', $result['data']['etag']);
|
||||
$this->assertFalse(isset($result['data']['tags']));
|
||||
$this->assertEquals('/', $result['data']['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test rename of file with tag
|
||||
*/
|
||||
function testRenameFileWithTag() {
|
||||
$taggerMock = $this->getMock('\OCP\ITags');
|
||||
$taggerMock->expects($this->any())
|
||||
->method('getTagsForObjects')
|
||||
->with(array(123))
|
||||
->will($this->returnValue(array(123 => array('tag1', 'tag2'))));
|
||||
$tagManagerMock = $this->getMock('\OCP\ITagManager');
|
||||
$tagManagerMock->expects($this->any())
|
||||
->method('load')
|
||||
->with('files')
|
||||
->will($this->returnValue($taggerMock));
|
||||
$oldTagManager = \OC::$server->query('TagManager');
|
||||
\OC::$server->registerService('TagManager', function ($c) use ($tagManagerMock) {
|
||||
return $tagManagerMock;
|
||||
});
|
||||
|
||||
$dir = '/';
|
||||
$oldname = 'oldname.txt';
|
||||
$newname = 'newname.txt';
|
||||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('file_exists')
|
||||
->with($this->anything())
|
||||
->will($this->returnValueMap(array(
|
||||
array('/', true),
|
||||
array('/oldname.txt', true)
|
||||
)));
|
||||
|
||||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('getFileInfo')
|
||||
->will($this->returnValue(new \OC\Files\FileInfo(
|
||||
'/new_name.txt',
|
||||
new \OC\Files\Storage\Local(array('datadir' => '/')),
|
||||
'/',
|
||||
array(
|
||||
'fileid' => 123,
|
||||
'type' => 'file',
|
||||
'mimetype' => 'text/plain',
|
||||
'mtime' => 0,
|
||||
'permissions' => 31,
|
||||
'size' => 18,
|
||||
'etag' => 'abcdef',
|
||||
'directory' => '/',
|
||||
'name' => 'new_name.txt',
|
||||
), null)));
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEquals(123, $result['data']['id']);
|
||||
$this->assertEquals('new_name.txt', $result['data']['name']);
|
||||
$this->assertEquals(18, $result['data']['size']);
|
||||
$this->assertEquals('text/plain', $result['data']['mimetype']);
|
||||
$this->assertEquals('abcdef', $result['data']['etag']);
|
||||
$this->assertEquals(array('tag1', 'tag2'), $result['data']['tags']);
|
||||
$this->assertEquals('/', $result['data']['path']);
|
||||
|
||||
\OC::$server->registerService('TagManager', function ($c) use ($oldTagManager) {
|
||||
return $oldTagManager;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rename inside a folder that doesn't exist any more
|
||||
*/
|
||||
function testRenameInNonExistingFolder() {
|
||||
$dir = '/unexist';
|
||||
$oldname = 'oldname';
|
||||
$newname = 'newname';
|
||||
|
||||
$this->viewMock->expects($this->at(0))
|
||||
->method('file_exists')
|
||||
->with('/unexist/oldname')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('getFileInfo')
|
||||
->will($this->returnValue(array(
|
||||
'fileid' => 123,
|
||||
'type' => 'dir',
|
||||
'mimetype' => 'httpd/unix-directory',
|
||||
'size' => 18,
|
||||
'etag' => 'abcdef',
|
||||
'directory' => '/unexist',
|
||||
'name' => 'new_name',
|
||||
)));
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertEquals('sourcenotfound', $result['data']['code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test move to invalid name
|
||||
*/
|
||||
function testRenameToInvalidName() {
|
||||
$dir = '/';
|
||||
$oldname = 'oldname';
|
||||
$newname = 'abc\\';
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertEquals('File name contains at least one invalid character', $result['data']['message']);
|
||||
$this->assertEquals('invalidname', $result['data']['code']);
|
||||
}
|
||||
}
|
|
@ -100,8 +100,7 @@ describe('OCA.Files.FavoritesFileList tests', function() {
|
|||
expect($tr.attr('data-mtime')).toEqual('11111000');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Fsomedir&files=test.txt'
|
||||
'/remote.php/webdav/somedir/test.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('test.txt');
|
||||
});
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global FileList */
|
||||
|
||||
describe('OC.Upload tests', function() {
|
||||
var $dummyUploader;
|
||||
var testFile;
|
||||
|
|
|
@ -584,7 +584,7 @@ describe('OCA.Files.FileActions tests', function() {
|
|||
expect(busyStub.calledWith('testName.txt', true)).toEqual(true);
|
||||
expect(handleDownloadStub.calledOnce).toEqual(true);
|
||||
expect(handleDownloadStub.getCall(0).args[0]).toEqual(
|
||||
OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=testName.txt'
|
||||
OC.webroot + '/remote.php/webdav/subdir/testName.txt'
|
||||
);
|
||||
busyStub.reset();
|
||||
handleDownloadStub.yield();
|
||||
|
|
|
@ -237,8 +237,8 @@ describe('OCA.Files.FileActionsMenu tests', function() {
|
|||
expect(redirectStub.calledOnce).toEqual(true);
|
||||
expect(redirectStub.getCall(0).args[0]).toContain(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Fsubdir&files=testName.txt');
|
||||
'/remote.php/webdav/subdir/testName.txt'
|
||||
);
|
||||
redirectStub.restore();
|
||||
});
|
||||
it('takes the file\'s path into account when clicking download', function() {
|
||||
|
@ -269,8 +269,7 @@ describe('OCA.Files.FileActionsMenu tests', function() {
|
|||
|
||||
expect(redirectStub.calledOnce).toEqual(true);
|
||||
expect(redirectStub.getCall(0).args[0]).toContain(
|
||||
OC.webroot + '/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Fanotherpath%2Fthere&files=testName.txt'
|
||||
OC.webroot + '/remote.php/webdav/anotherpath/there/testName.txt'
|
||||
);
|
||||
redirectStub.restore();
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -76,11 +76,11 @@ describe('OCA.Files.Files tests', function() {
|
|||
describe('getDownloadUrl', function() {
|
||||
it('returns the ajax download URL when filename and dir specified', function() {
|
||||
var url = Files.getDownloadUrl('test file.txt', '/subdir');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20file.txt');
|
||||
expect(url).toEqual(OC.webroot + '/remote.php/webdav/subdir/test%20file.txt');
|
||||
});
|
||||
it('returns the ajax download URL when filename and root dir specific', function() {
|
||||
it('returns the webdav download URL when filename and root dir specified', function() {
|
||||
var url = Files.getDownloadUrl('test file.txt', '/');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=test%20file.txt');
|
||||
expect(url).toEqual(OC.webroot + '/remote.php/webdav/test%20file.txt');
|
||||
});
|
||||
it('returns the ajax download URL when multiple files specified', function() {
|
||||
var url = Files.getDownloadUrl(['test file.txt', 'abc.txt'], '/subdir');
|
||||
|
|
|
@ -231,6 +231,7 @@
|
|||
files = _.chain(files)
|
||||
// convert share data to file data
|
||||
.map(function(share) {
|
||||
// TODO: use OC.Files.FileInfo
|
||||
var file = {
|
||||
id: share.file_source,
|
||||
icon: OC.MimeType.getIconUrl(share.mimetype),
|
||||
|
@ -242,9 +243,6 @@
|
|||
}
|
||||
else {
|
||||
file.type = 'file';
|
||||
if (share.isPreviewAvailable) {
|
||||
file.isPreviewAvailable = true;
|
||||
}
|
||||
}
|
||||
file.share = {
|
||||
id: share.id,
|
||||
|
|
|
@ -166,8 +166,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt'
|
||||
'/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
|
||||
|
@ -185,8 +184,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-id')).toEqual('8');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2F&files=b.txt'
|
||||
'/remote.php/webdav/b.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('b.txt');
|
||||
});
|
||||
|
@ -338,8 +336,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt'
|
||||
'/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
|
@ -429,9 +426,8 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt');
|
||||
OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
|
@ -498,9 +494,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7,8,9');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt'
|
||||
OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
|
@ -592,9 +586,8 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-owner')).not.toBeDefined();
|
||||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt');
|
||||
OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
|
||||
);
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
|
@ -634,8 +627,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
expect($tr.attr('data-share-id')).toEqual('7');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(
|
||||
OC.webroot +
|
||||
'/index.php/apps/files/ajax/download.php' +
|
||||
'?dir=%2Flocal%20path&files=local%20name.txt');
|
||||
'/remote.php/webdav/local%20path/local%20name.txt');
|
||||
|
||||
expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
|
||||
});
|
||||
|
|
|
@ -283,7 +283,77 @@
|
|||
|
||||
isSelectedDeletable: function() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads the file list using ajax call
|
||||
*
|
||||
* @return ajax call object
|
||||
*/
|
||||
reload: function() {
|
||||
this._selectedFiles = {};
|
||||
this._selectionSummary.clear();
|
||||
this.$el.find('.select-all').prop('checked', false);
|
||||
this.showMask();
|
||||
if (this._reloadCall) {
|
||||
this._reloadCall.abort();
|
||||
}
|
||||
this._reloadCall = $.ajax({
|
||||
url: this.getAjaxUrl('list'),
|
||||
data: {
|
||||
dir : this.getCurrentDirectory(),
|
||||
sort: this._sort,
|
||||
sortdirection: this._sortDirection
|
||||
}
|
||||
});
|
||||
var callBack = this.reloadCallback.bind(this);
|
||||
return this._reloadCall.then(callBack, callBack);
|
||||
},
|
||||
reloadCallback: function(result) {
|
||||
delete this._reloadCall;
|
||||
this.hideMask();
|
||||
|
||||
if (!result || result.status === 'error') {
|
||||
// if the error is not related to folder we're trying to load, reload the page to handle logout etc
|
||||
if (result.data.error === 'authentication_error' ||
|
||||
result.data.error === 'token_expired' ||
|
||||
result.data.error === 'application_not_enabled'
|
||||
) {
|
||||
OC.redirect(OC.generateUrl('apps/files'));
|
||||
}
|
||||
OC.Notification.show(result.data.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Firewall Blocked request?
|
||||
if (result.status === 403) {
|
||||
// Go home
|
||||
this.changeDirectory('/');
|
||||
OC.Notification.show(t('files', 'This operation is forbidden'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Did share service die or something else fail?
|
||||
if (result.status === 500) {
|
||||
// Go home
|
||||
this.changeDirectory('/');
|
||||
OC.Notification.show(t('files', 'This directory is unavailable, please check the logs or contact the administrator'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result.status === 404) {
|
||||
// go back home
|
||||
this.changeDirectory('/');
|
||||
return false;
|
||||
}
|
||||
// aborted ?
|
||||
if (result.status === 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
this.setFiles(result.data.files);
|
||||
return true;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -759,7 +759,7 @@ var OCdialogs = {
|
|||
filename: entry.name,
|
||||
date: OC.Util.relativeModifiedDate(entry.mtime)
|
||||
});
|
||||
if (entry.isPreviewAvailable) {
|
||||
if (entry.type === 'file') {
|
||||
var urlSpec = {
|
||||
file: dir + '/' + entry.name
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue