@@ -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 (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 (result.status === 404) { | |||
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)); | |||
// 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.')); | |||
} | |||
} | |||
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); | |||
} | |||
}) | |||
.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.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error')); | |||
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; | |||
} | |||
} | |||
else { | |||
fileInfo = result.data; | |||
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}) | |||
); | |||
} | |||
// 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); | |||
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 { | |||
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); | |||
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); | |||
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(); | |||
} | |||
else { | |||
// no files passed, delete all in current dir | |||
params.allfiles = true; | |||
// show spinner for all files | |||
this.showFileBusyState(this.$fileList.find('tr'), true); | |||
} | |||
$.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(); | |||
}); |
@@ -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 | |||
}; |